From ce60e4845a1e20316e1cb627bdc4f7cb061dee7e Mon Sep 17 00:00:00 2001 From: ashrod98 Date: Wed, 30 Apr 2025 15:02:11 -0400 Subject: [PATCH 01/52] [Doc] Address code block issue Copy-paste issues with code-block::console, changing to bash Change-Id: I857fcba4db74f19087529c6183dc67a888735209 --- doc/source/contributor/functional-tests.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/source/contributor/functional-tests.rst b/doc/source/contributor/functional-tests.rst index 95c19ee3..bee3713e 100644 --- a/doc/source/contributor/functional-tests.rst +++ b/doc/source/contributor/functional-tests.rst @@ -28,7 +28,7 @@ run manila, a good place to start would be the `manila contributor guide`_. You can use the following local.conf file to configure DevStack including Manila using a few fake back ends: -.. code-block:: console +.. code-block:: bash [[local|localrc]] @@ -117,7 +117,7 @@ For DevStack On your DevStack machine, you can run the following script. It assumes that ``devstack`` is cloned onto your base folder. -.. code-block:: console +.. code-block:: bash DEST=${DEST:-/opt/stack} MANILACLIENT_DIR=${MANILACLIENT_DIR:-$DEST/python-manilaclient} @@ -163,7 +163,7 @@ On your DevStack machine, you can run the following script. It assumes that # Create share network and use it for functional tests if required USE_SHARE_NETWORK=$(trueorfalse True USE_SHARE_NETWORK) -.. code-block:: console +.. code-block:: bash if [[ ${USE_SHARE_NETWORK} = True ]]; then SHARE_NETWORK_NAME=${SHARE_NETWORK_NAME:-ci} @@ -177,7 +177,7 @@ On your DevStack machine, you can run the following script. It assumes that fi -.. code-block:: console +.. code-block:: bash # Set share type if required if [[ "$SHARE_TYPE" ]]; then From 0a6c1f08ca426268a9c30daa69a564b79e45c67a Mon Sep 17 00:00:00 2001 From: Takashi Kajinami Date: Wed, 11 Jun 2025 15:48:25 +0900 Subject: [PATCH 02/52] pre-commit: Bump hacking and use native flake8 hook Pull the latest content in manila repo to use the consistent setting across repos. Change-Id: Ib0d3678f558b273df5b4cb6d389f2073afd3fca8 --- .pre-commit-config.yaml | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 11db1d1c..70f5408d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,10 +1,7 @@ --- -default_language_version: - # force all unspecified python hooks to run python3 - python: python3 repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v4.6.0 hooks: - id: trailing-whitespace - id: mixed-line-ending @@ -27,13 +24,9 @@ repos: hooks: - id: bashate args: ['--ignore', 'E006,E042,E043'] - - repo: local + - repo: https://opendev.org/openstack/hacking + rev: 6.1.0 hooks: - - id: flake8 - name: flake8 - additional_dependencies: - - hacking>=6.1.0,<6.2.0 - language: python - entry: flake8 - files: '^.*\.py$' - exclude: '^(doc|releasenotes|tools)/.*$' \ No newline at end of file + - id: hacking + additional_dependencies: [] + exclude: '^(doc|releasenotes|tools)/.*$' From 6c56e45aec6b8fb0c8b6885137253e82518a9861 Mon Sep 17 00:00:00 2001 From: Takashi Kajinami Date: Wed, 11 Jun 2025 00:11:38 +0900 Subject: [PATCH 03/52] Remove Python 3.9 support Python 3.9 is no longer part of the tested runtimes[1]. [1] https://governance.openstack.org/tc/reference/runtimes/2025.2.html Change-Id: Id6a260410e0f7b1f9edf0b9b7a4ae73bceb5f44b --- releasenotes/notes/remove-py39-5278e896dc045854.yaml | 5 +++++ setup.cfg | 3 +-- 2 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 releasenotes/notes/remove-py39-5278e896dc045854.yaml diff --git a/releasenotes/notes/remove-py39-5278e896dc045854.yaml b/releasenotes/notes/remove-py39-5278e896dc045854.yaml new file mode 100644 index 00000000..eaf3014b --- /dev/null +++ b/releasenotes/notes/remove-py39-5278e896dc045854.yaml @@ -0,0 +1,5 @@ +--- +upgrade: + - | + Support for Python 3.9 has been removed. Now Python 3.10 is the minimum + version supported. diff --git a/setup.cfg b/setup.cfg index 0045e07b..e9734f93 100644 --- a/setup.cfg +++ b/setup.cfg @@ -6,7 +6,7 @@ description_file = author = OpenStack author_email = openstack-discuss@lists.openstack.org home_page = https://docs.openstack.org/python-manilaclient/latest/ -python_requires = >=3.9 +python_requires = >=3.10 classifier = Development Status :: 5 - Production/Stable Environment :: Console @@ -18,7 +18,6 @@ classifier = Programming Language :: Python Programming Language :: Python :: 3 :: Only Programming Language :: Python :: 3 - Programming Language :: Python :: 3.9 Programming Language :: Python :: 3.10 Programming Language :: Python :: 3.11 Programming Language :: Python :: 3.12 From c21de5e5b7f9db6e43c1b1816b93c5f88d42ad6f Mon Sep 17 00:00:00 2001 From: Cyril Roelandt Date: Fri, 27 Jun 2025 02:52:34 +0200 Subject: [PATCH 04/52] Zuul: do not use USE_PYTHON3 Devstack has removed the USE_PYTHON3 variable[1][2] and now always uses Python 3. [1] https://review.opendev.org/c/openstack/devstack/+/920658 [2] Commit 5412dbfe7b797149f1f68100de8003b1876398fe Change-Id: If18479450113ba766262b1ca7ddb001e57408a65 --- zuul.d/python-manilaclient-jobs.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/zuul.d/python-manilaclient-jobs.yaml b/zuul.d/python-manilaclient-jobs.yaml index 0984a95f..a6477da7 100644 --- a/zuul.d/python-manilaclient-jobs.yaml +++ b/zuul.d/python-manilaclient-jobs.yaml @@ -23,7 +23,6 @@ devstack_plugins: manila: https://opendev.org/openstack/manila devstack_localrc: - USE_PYTHON3: true INSTALL_TEMPEST: false # Enable manila with a fake driver that supports all capabilities MANILA_CONFIGURE_DEFAULT_TYPES: true From 55862819eea027c7ef21df11c8606cccc894a96a Mon Sep 17 00:00:00 2001 From: Riane Torres Date: Wed, 2 Jul 2025 14:37:36 -0400 Subject: [PATCH 05/52] Add negative functional test for message Messages had positive tests, this commit introduces the negative tests for the messages. Change-Id: I4c7f75e470005e00a78f9e5c27bb4b7c3b67b1e7 Signed-off-by: Riane Torres --- .../tests/functional/osc/test_messages.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/manilaclient/tests/functional/osc/test_messages.py b/manilaclient/tests/functional/osc/test_messages.py index 0e44d6b9..da841a5b 100644 --- a/manilaclient/tests/functional/osc/test_messages.py +++ b/manilaclient/tests/functional/osc/test_messages.py @@ -11,6 +11,8 @@ # under the License. +from tempest.lib import exceptions + from manilaclient.tests.functional.osc import base @@ -101,3 +103,17 @@ def test_delete_message(self): messages = [msg for msg in messages if msg['ID'] == message["ID"]] self.assertEqual(0, len(messages)) + + def test_delete_message_wrong_id(self): + self.assertRaises( + exceptions.CommandFailed, + self.openstack, + 'share message delete 0' + ) + + def test_show_message_wrong_id(self): + self.assertRaises( + exceptions.CommandFailed, + self.openstack, + 'share message show' + ) From 50add9103e7de75f9e48210155d2f99d8cbf8209 Mon Sep 17 00:00:00 2001 From: Riane Torres Date: Thu, 10 Jul 2025 16:58:05 -0400 Subject: [PATCH 06/52] Fixed negative user messages test names Fixed negative user message test names (test_delete_message_invalid_id & test_show_message_missing_id) This amended commit is a follow up to another change. Also removed __init__.py file Change-Id: I7abccf64b6fa8d69c347d65c801da72763966a4e Signed-off-by: Riane Torres --- manilaclient/tests/functional/osc/test_messages.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/manilaclient/tests/functional/osc/test_messages.py b/manilaclient/tests/functional/osc/test_messages.py index da841a5b..cb2b8186 100644 --- a/manilaclient/tests/functional/osc/test_messages.py +++ b/manilaclient/tests/functional/osc/test_messages.py @@ -104,14 +104,14 @@ def test_delete_message(self): if msg['ID'] == message["ID"]] self.assertEqual(0, len(messages)) - def test_delete_message_wrong_id(self): + def test_delete_message_invalid_id(self): self.assertRaises( exceptions.CommandFailed, self.openstack, 'share message delete 0' ) - def test_show_message_wrong_id(self): + def test_show_message_missing_id(self): self.assertRaises( exceptions.CommandFailed, self.openstack, From 0953eff609addcf4d04b752cd141134e95f7ad2e Mon Sep 17 00:00:00 2001 From: Kiran Pawar Date: Tue, 20 May 2025 13:14:50 +0000 Subject: [PATCH 07/52] Add option to override API endpoint Provide an option to override API endpoint to address multiple manila deployments on same cloud. Usage as following: "openstack --os-endpoint-override share list" Closes-bug: #2111331 Co-authored-by: Chuan Miao Change-Id: I5e11256473ab88b08e7374fd68f58a0257adab1f Signed-off-by: Kiran Pawar --- doc/source/cli/osc_plugin_cli.rst | 7 +++++++ manilaclient/osc/plugin.py | 13 +++++++++++++ ...t-of-api-endpoint-override-e36e75246d39a367.yaml | 6 ++++++ 3 files changed, 26 insertions(+) create mode 100644 releasenotes/notes/add-support-of-api-endpoint-override-e36e75246d39a367.yaml diff --git a/doc/source/cli/osc_plugin_cli.rst b/doc/source/cli/osc_plugin_cli.rst index b43aead9..88e30318 100644 --- a/doc/source/cli/osc_plugin_cli.rst +++ b/doc/source/cli/osc_plugin_cli.rst @@ -31,6 +31,13 @@ environment variables:: export OS_AUTH_URL=http://... export OS_SHARE_API_VERSION=2.51 +It is possible to use different Manila endpoint while using Openstack +Client. In this case, you can use configuration option +``--os-endpoint-override`` or set the corresponding environment +variable:: + + export OS_ENDPOINT_OVERRIDE=http://... + Getting help ============ diff --git a/manilaclient/osc/plugin.py b/manilaclient/osc/plugin.py index 568b2f3f..e6392d65 100644 --- a/manilaclient/osc/plugin.py +++ b/manilaclient/osc/plugin.py @@ -113,4 +113,17 @@ def build_option_parser(parser): 'version supported by both the client and the server). ' '(Env: OS_SHARE_API_VERSION)', ) + parser.add_argument( + "--os-endpoint-override", + metavar="", + default=utils.env( + "OS_ENDPOINT_OVERRIDE", + "OS_MANILA_BYPASS_URL", + "MANILACLIENT_BYPASS_URL", + ), + help=( + "Use this API endpoint instead of the Service Catalog. " + "Defaults to env[OS_ENDPOINT_OVERRIDE]." + ), + ) return parser diff --git a/releasenotes/notes/add-support-of-api-endpoint-override-e36e75246d39a367.yaml b/releasenotes/notes/add-support-of-api-endpoint-override-e36e75246d39a367.yaml new file mode 100644 index 00000000..9eddf873 --- /dev/null +++ b/releasenotes/notes/add-support-of-api-endpoint-override-e36e75246d39a367.yaml @@ -0,0 +1,6 @@ +--- +features: + - Manilaclient is updated to consider API endpoint override option + `--os-endpoint-override`. For example, "openstack share list" command + for different API endpoint will be "openstack --os-endpoint-override + share list". From cc5c1f8c5bb43e91b51d266e18724069c8a43a98 Mon Sep 17 00:00:00 2001 From: Kiran Pawar Date: Mon, 20 Jan 2025 14:06:08 +0000 Subject: [PATCH 08/52] Add support of encryption_key_ref option for share create Implemented encryption_key_ref option for share create API from microversion 2.90. Added encryption_keys quota set support. partially-implements: blueprint share-encryption Change-Id: I54caefb77cb4d5af3fa7d4527592cf60f09b54c4 Signed-off-by: Kiran Pawar --- manilaclient/api_versions.py | 2 +- manilaclient/osc/v2/quotas.py | 18 ++++- manilaclient/osc/v2/share.py | 35 ++++++++- manilaclient/tests/unit/osc/v2/fakes.py | 2 + manilaclient/tests/unit/osc/v2/test_quotas.py | 44 ++++++++++++ manilaclient/tests/unit/osc/v2/test_share.py | 71 ++++++++++++++++++- manilaclient/tests/unit/v2/test_shares.py | 23 ++++++ manilaclient/v2/quotas.py | 26 ++++++- manilaclient/v2/shares.py | 22 +++++- ...for-share-create-api-035aec5b31d7c37b.yaml | 11 +++ 10 files changed, 246 insertions(+), 8 deletions(-) create mode 100644 releasenotes/notes/add-encryption-key-ref-option-for-share-create-api-035aec5b31d7c37b.yaml diff --git a/manilaclient/api_versions.py b/manilaclient/api_versions.py index e6b6f512..18f9ca7d 100644 --- a/manilaclient/api_versions.py +++ b/manilaclient/api_versions.py @@ -27,7 +27,7 @@ LOG = logging.getLogger(__name__) -MAX_VERSION = '2.89' +MAX_VERSION = '2.90' MIN_VERSION = '2.0' DEPRECATED_VERSION = '1.0' _VERSIONED_METHOD_MAP = {} diff --git a/manilaclient/osc/v2/quotas.py b/manilaclient/osc/v2/quotas.py index bde7d341..c03112bb 100644 --- a/manilaclient/osc/v2/quotas.py +++ b/manilaclient/osc/v2/quotas.py @@ -134,6 +134,14 @@ def get_parser(self, prog_name): help=_("New value for the 'per-share-gigabytes' quota." "Available only for microversion >= 2.62") ) + parser.add_argument( + '--encryption-keys', + metavar='', + type=int, + default=None, + help=_("New value for the 'encryption-keys' quota." + "Available only for microversion >= 2.90") + ) parser.add_argument( '--force', dest='force', @@ -200,6 +208,13 @@ def take_action(self, parsed_args): "starting with '2.62' API microversion.") ) kwargs["per_share_gigabytes"] = parsed_args.per_share_gigabytes + if parsed_args.encryption_keys is not None: + if share_client.api_version < api_versions.APIVersion('2.90'): + raise exceptions.CommandError(_( + "'encryption keys' quotas are available only " + "starting with '2.90' API microversion.") + ) + kwargs["encryption_keys"] = parsed_args.encryption_keys if all(value is None for value in kwargs.values()): raise exceptions.CommandError(_( @@ -208,7 +223,8 @@ def take_action(self, parsed_args): "resources: 'shares', 'snapshots', 'gigabytes', " "'snapshot-gigabytes', 'share-networks', 'share-type', " "'share-groups', 'share-group-snapshots', 'share-replicas', " - "'replica-gigabytes', 'per-share-gigabytes'")) + "'replica-gigabytes', 'per-share-gigabytes', " + "'encryption_keys'")) if parsed_args.quota_class: kwargs.update({ diff --git a/manilaclient/osc/v2/share.py b/manilaclient/osc/v2/share.py index 57f5e635..68273496 100644 --- a/manilaclient/osc/v2/share.py +++ b/manilaclient/osc/v2/share.py @@ -58,7 +58,8 @@ 'replication_type', 'has_replicas', 'created_at', - 'metadata' + 'metadata', + 'encryption_key_ref' ] SHARE_ATTRIBUTES_HEADERS = [ @@ -90,6 +91,7 @@ 'Has Replicas', 'Created At', 'Properties', + 'Encryption Key Ref' ] @@ -195,6 +197,14 @@ def get_parser(self, prog_name): help=_('Optional custom export location. Available for ' 'microversion >= 2.84') ) + parser.add_argument( + '--encryption-key-ref', + metavar="", + default=None, + help=_('Set encryption key reference i.e. UUID of the secret ' + 'stored in the key manager. Available for ' + 'microversion >= 2.90') + ) return parser @@ -248,6 +258,15 @@ def take_action(self, parsed_args): else: mount_point_name = parsed_args.mount_point_name + encryption_key_ref = None + if parsed_args.encryption_key_ref: + if share_client.api_version < api_versions.APIVersion('2.90'): + raise exceptions.CommandError( + 'Setting share encryption key reference is ' + 'available only for API microversion >= 2.90') + else: + encryption_key_ref = parsed_args.encryption_key_ref + scheduler_hints = {} if parsed_args.scheduler_hint: if share_client.api_version < api_versions.APIVersion('2.65'): @@ -289,6 +308,7 @@ def take_action(self, parsed_args): 'share_group_id': share_group, 'scheduler_hints': scheduler_hints, 'mount_point_name': mount_point_name, + 'encryption_key_ref': encryption_key_ref, } share = share_client.shares.create(**body) @@ -537,6 +557,12 @@ def get_parser(self, prog_name): help=_("Filter results matching a share description pattern." "Available only for microversion >= 2.36.") ) + parser.add_argument( + '--encryption-key-ref', + metavar="", + help=_('Filter shares by their encryption key ref. ' + 'Available for microversion >= 2.90'), + ) return parser @@ -648,6 +674,13 @@ def take_action(self, parsed_args): "Filtering by export location is only " "available with manila API version >= 2.35") + if share_client.api_version >= api_versions.APIVersion('2.90'): + search_opts['encryption_key_ref'] = parsed_args.encryption_key_ref + elif (getattr(parsed_args, 'encryption_key_ref')): + raise exceptions.CommandError( + "Filtering shares by encryption key ref is only " + "available with manila API version >= 2.90") + # NOTE(vkmc) We implemented sorting and filtering in manilaclient # but we will use the one provided by osc if share_client.api_version >= api_versions.APIVersion("2.36"): diff --git a/manilaclient/tests/unit/osc/v2/fakes.py b/manilaclient/tests/unit/osc/v2/fakes.py index 15bc79e1..d574eb08 100644 --- a/manilaclient/tests/unit/osc/v2/fakes.py +++ b/manilaclient/tests/unit/osc/v2/fakes.py @@ -140,6 +140,7 @@ def create_one_share(attrs=None, methods=None): "source_share_group_snapshot_member_id": None, "scheduler_hints": {}, "mount_point_name": None, + "encryption_key_ref": None, } # Overwrite default attributes. @@ -420,6 +421,7 @@ def create_fake_quotas(attrs=None): 'shapshot_gigabytes': 1000, 'snapshots': 50, 'per_share_gigabytes': -1, + 'encryption_keys': 100, } quotas_info.update(attrs) diff --git a/manilaclient/tests/unit/osc/v2/test_quotas.py b/manilaclient/tests/unit/osc/v2/test_quotas.py index 3de79469..c25fd41b 100644 --- a/manilaclient/tests/unit/osc/v2/test_quotas.py +++ b/manilaclient/tests/unit/osc/v2/test_quotas.py @@ -349,6 +349,50 @@ def test_quota_set_per_share_gigabytes(self): user_id=None) self.assertIsNone(result) + def test_quota_set_encryption_keys_exception(self): + self.app.client_manager.share.api_version = api_versions.APIVersion( + '2.89') + arglist = [ + self.project.id, + '--encryption-keys', '10', + ] + verifylist = [ + ('project', self.project.id), + ('encryption_keys', 10) + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + self.assertRaises( + exceptions.CommandError, self.cmd.take_action, parsed_args) + + def test_quota_set_encryption_keys(self): + arglist = [ + self.project.id, + '--encryption-keys', '10', + ] + verifylist = [ + ('project', self.project.id), + ('encryption_keys', 10) + ] + + with mock.patch('osc_lib.utils.find_resource') as mock_find_resource: + mock_find_resource.return_value = self.project + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + result = self.cmd.take_action(parsed_args) + self.quotas_mock.update.assert_called_with( + force=None, + gigabytes=None, + share_networks=None, + shares=None, + snapshot_gigabytes=None, + snapshots=None, + encryption_keys=10, + tenant_id=self.project.id, + user_id=None) + self.assertIsNone(result) + class TestQuotaShow(TestQuotas): project = identity_fakes.FakeProject.create_one_project() diff --git a/manilaclient/tests/unit/osc/v2/test_share.py b/manilaclient/tests/unit/osc/v2/test_share.py index 67647ee5..fe6a5de0 100644 --- a/manilaclient/tests/unit/osc/v2/test_share.py +++ b/manilaclient/tests/unit/osc/v2/test_share.py @@ -133,6 +133,7 @@ def test_share_create_required_args(self): snapshot_id=None, scheduler_hints={}, mount_point_name=None, + encryption_key_ref=None, ) self.assertCountEqual(self.columns, columns) @@ -182,6 +183,7 @@ def test_share_create_metadata(self): snapshot_id=None, scheduler_hints={}, mount_point_name=None, + encryption_key_ref=None, ) self.assertCountEqual(self.columns, columns) @@ -229,6 +231,7 @@ def test_share_create_scheduler_hints(self): scheduler_hints={'same_host': shares[0].id, 'different_host': shares[1].id}, mount_point_name=None, + encryption_key_ref=None, ) self.assertCountEqual(self.columns, columns) @@ -271,6 +274,49 @@ def test_share_create_mount_point_name(self): snapshot_id=None, scheduler_hints={}, mount_point_name='fake_mp', + encryption_key_ref=None, + ) + + self.assertCountEqual(self.columns, columns) + self.assertCountEqual(self.datalist, data) + + def test_share_create_encryption_key_ref(self): + self.app.client_manager.share.api_version = api_versions.APIVersion( + "2.90") + + encryption_key_ref = 'fake_ekr' + + arglist = [ + self.new_share.share_proto, + str(self.new_share.size), + '--share-type', self.share_type.id, + '--encryption-key-ref', encryption_key_ref, + ] + verifylist = [ + ('share_proto', self.new_share.share_proto), + ('size', self.new_share.size), + ('encryption_key_ref', encryption_key_ref), + ('share_type', self.share_type.id), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + + self.shares_mock.create.assert_called_with( + availability_zone=None, + description=None, + is_public=False, + metadata={}, + name=None, + share_group_id=None, + share_network=None, + share_proto=self.new_share.share_proto, + share_type=self.share_type.id, + size=self.new_share.size, + snapshot_id=None, + scheduler_hints={}, + mount_point_name=None, + encryption_key_ref=encryption_key_ref, ) self.assertCountEqual(self.columns, columns) @@ -315,6 +361,7 @@ def test_share_create_with_snapshot(self): snapshot_id=self.share_snapshot.id, scheduler_hints={}, mount_point_name=None, + encryption_key_ref=None, ) self.assertCountEqual(self.columns, columns) self.assertCountEqual(self.datalist, data) @@ -352,6 +399,7 @@ def test_share_create_wait(self): snapshot_id=None, scheduler_hints={}, mount_point_name=None, + encryption_key_ref=None, ) self.shares_mock.get.assert_called_with(self.new_share.id) @@ -393,6 +441,7 @@ def test_share_create_wait_error(self, mock_logger): snapshot_id=None, scheduler_hints={}, mount_point_name=None, + encryption_key_ref=None, ) mock_logger.error.assert_called_with( @@ -701,6 +750,7 @@ def _get_search_opts(self): 'export_location': None, 'name~': None, 'description~': None, + 'encryption_key_ref': None, } return search_opts @@ -977,6 +1027,7 @@ def test_share_list_long(self): 'Has Replicas', 'Created At', 'Properties', + 'Encryption Key Ref' ] self.assertEqual(collist, cmd_columns) @@ -1008,7 +1059,8 @@ def test_share_list_long(self): self.new_share.replication_type, self.new_share.has_replicas, self.new_share.created_at, - self.new_share.metadata + self.new_share.metadata, + self.new_share.encryption_key_ref ),) self.assertEqual(data, tuple(cmd_data)) @@ -1103,6 +1155,23 @@ def test_list_share_soft_deleted_api_version_exception(self): self.cmd.take_action, parsed_args) + def test_list_share_encryption_key_ref_api_version_exception(self): + self.app.client_manager.share.api_version = api_versions.APIVersion( + "2.89") + arglist = [ + '--encryption-key-ref', 'fake', + ] + verifylist = [ + ('encryption_key_ref', 'fake'), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + self.assertRaises( + osc_exceptions.CommandError, + self.cmd.take_action, + parsed_args) + def test_list_share_api_version_exception(self): self.app.client_manager.share.api_version = api_versions.APIVersion( "2.35") diff --git a/manilaclient/tests/unit/v2/test_shares.py b/manilaclient/tests/unit/v2/test_shares.py index e5ce890c..43e57140 100644 --- a/manilaclient/tests/unit/v2/test_shares.py +++ b/manilaclient/tests/unit/v2/test_shares.py @@ -163,6 +163,29 @@ def test_create_share_with_mount_point_name(self, mount_point_name): cs.shares.create('nfs', 1, mount_point_name=mount_point_name) cs.assert_called('POST', '/shares', body) + @ddt.data({'encryption_key_ref': 'fake_key1'}, + {'encryption_key_ref': 'fake_key2'}) + @ddt.unpack + def test_create_share_with_encryption_key_ref(self, encryption_key_ref): + body = { + 'share': { + 'is_public': False, + 'share_type': None, + 'name': None, + 'snapshot_id': None, + 'description': None, + 'metadata': {}, + 'share_proto': 'nfs', + 'share_network_id': None, + 'size': 1, + 'availability_zone': None, + 'scheduler_hints': {}, + 'encryption_key_ref': encryption_key_ref, + } + } + cs.shares.create('nfs', 1, encryption_key_ref=encryption_key_ref) + cs.assert_called('POST', '/shares', body) + @ddt.data( type('ShareUUID', (object, ), {'uuid': '1234'}), type('ShareID', (object, ), {'id': '1234'}), diff --git a/manilaclient/v2/quotas.py b/manilaclient/v2/quotas.py index a4a68838..39a9745c 100644 --- a/manilaclient/v2/quotas.py +++ b/manilaclient/v2/quotas.py @@ -94,7 +94,7 @@ def _do_update(self, tenant_id, shares=None, snapshots=None, force=None, user_id=None, share_type=None, share_groups=None, share_group_snapshots=None, share_replicas=None, replica_gigabytes=None, - per_share_gigabytes=None, + per_share_gigabytes=None, encryption_keys=None, resource_path=RESOURCE_PATH): self._check_user_id_and_share_type_args(user_id, share_type) body = { @@ -111,6 +111,7 @@ def _do_update(self, tenant_id, shares=None, snapshots=None, 'share_replicas': share_replicas, 'replica_gigabytes': replica_gigabytes, 'per_share_gigabytes': per_share_gigabytes, + 'encryption_keys': encryption_keys, }, } @@ -202,7 +203,7 @@ def update(self, tenant_id, user_id=None, share_type=None, # noqa resource_path=RESOURCE_PATH ) - @api_versions.wraps("2.62") # noqa + @api_versions.wraps("2.62", "2.89") # noqa def update(self, tenant_id, user_id=None, share_type=None, # noqa shares=None, snapshots=None, gigabytes=None, snapshot_gigabytes=None, share_networks=None, @@ -222,6 +223,27 @@ def update(self, tenant_id, user_id=None, share_type=None, # noqa resource_path=RESOURCE_PATH ) + @api_versions.wraps("2.90") # noqa + def update(self, tenant_id, user_id=None, share_type=None, # noqa + shares=None, snapshots=None, gigabytes=None, + snapshot_gigabytes=None, share_networks=None, + share_groups=None, share_group_snapshots=None, + share_replicas=None, replica_gigabytes=None, force=None, + per_share_gigabytes=None, encryption_keys=None): + self._validate_st_and_sn_in_same_request(share_type, share_networks) + return self._do_update( + tenant_id, shares, snapshots, gigabytes, snapshot_gigabytes, + share_networks, force, user_id, + share_type=share_type, + share_groups=share_groups, + share_group_snapshots=share_group_snapshots, + share_replicas=share_replicas, + replica_gigabytes=replica_gigabytes, + per_share_gigabytes=per_share_gigabytes, + encryption_keys=encryption_keys, + resource_path=RESOURCE_PATH + ) + @api_versions.wraps("1.0", "2.6") def defaults(self, tenant_id): return self._get( diff --git a/manilaclient/v2/shares.py b/manilaclient/v2/shares.py index 2f419a48..5782e8e6 100644 --- a/manilaclient/v2/shares.py +++ b/manilaclient/v2/shares.py @@ -125,7 +125,7 @@ def create(self, share_proto, size, snapshot_id=None, name=None, description=None, metadata=None, share_network=None, share_type=None, is_public=False, availability_zone=None, share_group_id=None, scheduler_hints=None, return_raw=False, - mount_point_name=None): + mount_point_name=None, encryption_key_ref=None): """Create a share. :param share_proto: text - share protocol for new share available @@ -146,6 +146,8 @@ def create(self, share_proto, size, snapshot_id=None, name=None, :param mount_point_name: text - share human-readable mount point name. This name will be reflected in export location once share is created. + :param encryption_key_ref: text - encryption key reference, i.e. UUID + of the secret stored in the key manager. :rtype: :class:`Share` """ share_metadata = metadata if metadata is not None else dict() @@ -170,6 +172,9 @@ def create(self, share_proto, size, snapshot_id=None, name=None, if mount_point_name: body['mount_point_name'] = mount_point_name + if encryption_key_ref: + body['encryption_key_ref'] = encryption_key_ref + return self._create('/shares', {'share': body}, 'share', return_raw=return_raw) @@ -356,6 +361,7 @@ def list(self, detailed=True, search_opts=None, search_opts = search_opts or {} search_opts.pop("export_location", None) search_opts.pop("is_soft_deleted", None) + search_opts.pop("encryption_key_ref", None) return self.do_list(detailed=detailed, search_opts=search_opts, sort_key=sort_key, sort_dir=sort_dir, return_raw=return_raw) @@ -367,11 +373,22 @@ def list(self, detailed=True, search_opts=None, # noqa if search_opts is None: search_opts = {} search_opts.pop("is_soft_deleted", None) + search_opts.pop("encryption_key_ref", None) + return self.do_list(detailed=detailed, search_opts=search_opts, + sort_key=sort_key, sort_dir=sort_dir, + return_raw=return_raw) + + @api_versions.wraps("2.69", "2.89") # noqa + def list(self, detailed=True, search_opts=None, # noqa + sort_key=None, sort_dir=None, return_raw=False): + """Get a list of all shares.""" + search_opts = search_opts or {} + search_opts.pop("encryption_key_ref", None) return self.do_list(detailed=detailed, search_opts=search_opts, sort_key=sort_key, sort_dir=sort_dir, return_raw=return_raw) - @api_versions.wraps("2.69") # noqa + @api_versions.wraps("2.90") # noqa def list(self, detailed=True, search_opts=None, # noqa sort_key=None, sort_dir=None, return_raw=False): """Get a list of all shares.""" @@ -400,6 +417,7 @@ def do_list(self, detailed=True, search_opts=None, - (('share_type_id', 'share_type'), text) - (('snapshot_id', 'snapshot'), text) - ('is_soft_deleted', bool) + - ('encryption_key_ref', text) Note, that member context will have restricted set of available search opts. For admin context filtering also available by each share attr from its Model. So, this list is not full for diff --git a/releasenotes/notes/add-encryption-key-ref-option-for-share-create-api-035aec5b31d7c37b.yaml b/releasenotes/notes/add-encryption-key-ref-option-for-share-create-api-035aec5b31d7c37b.yaml new file mode 100644 index 00000000..621dfc58 --- /dev/null +++ b/releasenotes/notes/add-encryption-key-ref-option-for-share-create-api-035aec5b31d7c37b.yaml @@ -0,0 +1,11 @@ +--- +features: + - | + Starting microversion 2.90, Manila supports 'bring your own key' feature + that allows user to pass encryption key reference in share creation. The + encryption key reference must be the UUID of a secret encryption key that + is stored on a key manager configured in the Shared File Systems service. + Encryption key reference can belongs to either share or share-server which + will be decided by storage driver capability and the share type. + Added 'encryption_keys' per project quota which controls how many share + and share server encryption keys will be created within project. From 4996e2b86746e359f1662ea4545c9b6ed3809107 Mon Sep 17 00:00:00 2001 From: Zachary Goggin Date: Fri, 11 Apr 2025 14:30:09 +0000 Subject: [PATCH 09/52] Add support for out of place share backup restores Add CLI support and tests for performing a restore operation with Manilas share backup API that targets a non-source share i.e. a share other then that used to create the backup.) Partially-Implements: blueprint out-of-place-restore Depends-On: I060b0dc579e3057f2cb046ebe3271287f8fbc9f9 Change-Id: I8414c62010cd369e27cc5b693612c59d4e7516a3 Signed-off-by: Zachary Goggin --- manilaclient/api_versions.py | 2 +- manilaclient/osc/v2/share_backups.py | 43 ++++++++++++++++++- .../functional/osc/test_share_backups.py | 18 ++++++++ .../tests/unit/osc/v2/test_share_backups.py | 22 ++++++++++ .../tests/unit/v2/test_share_backups.py | 14 +++++- manilaclient/v2/share_backups.py | 11 +++-- ...out-of-place-restore-98740badef59ba32.yaml | 7 +++ 7 files changed, 109 insertions(+), 8 deletions(-) create mode 100644 releasenotes/notes/share-backup-out-of-place-restore-98740badef59ba32.yaml diff --git a/manilaclient/api_versions.py b/manilaclient/api_versions.py index 18f9ca7d..af613fb5 100644 --- a/manilaclient/api_versions.py +++ b/manilaclient/api_versions.py @@ -27,7 +27,7 @@ LOG = logging.getLogger(__name__) -MAX_VERSION = '2.90' +MAX_VERSION = '2.91' MIN_VERSION = '2.0' DEPRECATED_VERSION = '1.0' _VERSIONED_METHOD_MAP = {} diff --git a/manilaclient/osc/v2/share_backups.py b/manilaclient/osc/v2/share_backups.py index 8c9dc9e0..f48ebbe9 100644 --- a/manilaclient/osc/v2/share_backups.py +++ b/manilaclient/osc/v2/share_backups.py @@ -20,10 +20,12 @@ from osc_lib import exceptions from osc_lib import utils as osc_utils +from manilaclient import api_versions from manilaclient.common._i18n import _ from manilaclient.common import constants from manilaclient.osc import utils + LOG = logging.getLogger(__name__) @@ -282,14 +284,51 @@ def get_parser(self, prog_name): metavar="", help=_('ID of backup to restore.') ) + parser.add_argument( + "--target-share", + metavar="", + default=None, + help=_('share to restore backup to. Source share if none supplied') + ) + parser.add_argument( + '--wait', + action='store_true', + default=False, + help=_('Wait for restore conclusion') + ) return parser def take_action(self, parsed_args): share_client = self.app.client_manager.share + kwargs = {} + share_backup = osc_utils.find_resource( share_client.share_backups, - parsed_args.backup) - share_client.share_backups.restore(share_backup.id) + parsed_args.backup + ) + target_share_id = None + if parsed_args.target_share is not None: + if share_client.api_version < api_versions.APIVersion('2.91'): + raise exceptions.CommandError( + 'performing targeted restores is only available ' + 'for API microversion >= 2.91') + else: + target_share_id = osc_utils.find_resource( + share_client.shares, + parsed_args.target_share + ).id + kwargs['target_share_id'] = target_share_id + + share_client.share_backups.restore(share_backup.id, **kwargs) + + if parsed_args.wait: + if not osc_utils.wait_for_status( + status_f=share_client.shares.get, + res_id=(target_share_id or share_backup.share_id), + success_status=['available'], + error_status=['error', 'backup_restoring_error'] + ): + LOG.error(_("ERROR: share is in error state.")) class SetShareBackup(command.Command): diff --git a/manilaclient/tests/functional/osc/test_share_backups.py b/manilaclient/tests/functional/osc/test_share_backups.py index 6c7ed6dd..978c617c 100644 --- a/manilaclient/tests/functional/osc/test_share_backups.py +++ b/manilaclient/tests/functional/osc/test_share_backups.py @@ -69,6 +69,24 @@ def test_share_backup_show(self): self.assertEqual('test_backup_show', show_result["name"]) self.assertEqual('Description', show_result["description"]) + def test_share_backup_restore(self): + share = self.create_share() + + backup = self.create_backup( + share_id=share['id'], + backup_options={'dummy': True}) + + self.openstack( + f'share backup restore {backup["id"]} --wait') + + backup = json.loads(self.openstack( + f'share backup show -f json {backup["id"]}')) + share = json.loads(self.openstack( + f'share show -f json {share["id"]}')) + + self.assertEqual('available', backup['status']) + self.assertEqual('available', share['status']) + def test_share_backup_set(self): share = self.create_share() diff --git a/manilaclient/tests/unit/osc/v2/test_share_backups.py b/manilaclient/tests/unit/osc/v2/test_share_backups.py index 5c8cdb65..4c9b76e3 100644 --- a/manilaclient/tests/unit/osc/v2/test_share_backups.py +++ b/manilaclient/tests/unit/osc/v2/test_share_backups.py @@ -309,7 +309,11 @@ def setUp(self): self.share_backup = ( manila_fakes.FakeShareBackup.create_one_backup() ) + self.target_share = ( + manila_fakes.FakeShare.create_one_share() + ) self.backups_mock.get.return_value = self.share_backup + self.shares_mock.get.return_value = self.target_share self.cmd = osc_share_backups.RestoreShareBackup( self.app, None) @@ -325,6 +329,24 @@ def test_share_backup_restore(self): self.backups_mock.restore.assert_called_with(self.share_backup.id) self.assertIsNone(result) + def test_share_backup_restore_to_target(self): + arglist = [ + self.share_backup.id, + '--target-share', self.target_share.id + ] + verifylist = [ + ('backup', self.share_backup.id), + ('target_share', self.target_share.id), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + result = self.cmd.take_action(parsed_args) + self.backups_mock.restore.assert_called_with( + self.share_backup.id, + target_share_id=self.target_share.id + ) + self.assertIsNone(result) + class TestShareBackupSet(TestShareBackup): diff --git a/manilaclient/tests/unit/v2/test_share_backups.py b/manilaclient/tests/unit/v2/test_share_backups.py index 954bd98b..9c027b75 100644 --- a/manilaclient/tests/unit/v2/test_share_backups.py +++ b/manilaclient/tests/unit/v2/test_share_backups.py @@ -20,6 +20,7 @@ from manilaclient.v2 import share_backups FAKE_BACKUP = 'fake_backup' +FAKE_TARGET_SHARE_ID = 'fake_target_share_id' @ddt.ddt @@ -30,7 +31,7 @@ class _FakeShareBackup(object): def setUp(self): super(ShareBackupsTest, self).setUp() - microversion = api_versions.APIVersion("2.80") + microversion = api_versions.APIVersion("2.91") self.manager = share_backups.ShareBackupManager( fakes.FakeClient(api_version=microversion)) @@ -58,7 +59,16 @@ def test_restore(self): with mock.patch.object(self.manager, '_action', mock.Mock()): self.manager.restore(FAKE_BACKUP) self.manager._action.assert_called_once_with( - 'restore', FAKE_BACKUP) + 'restore', FAKE_BACKUP, info=None) + + def test_restore_to_target(self): + with mock.patch.object(self.manager, '_action', mock.Mock()): + self.manager.restore( + FAKE_BACKUP, + target_share_id=FAKE_TARGET_SHARE_ID + ) + self.manager._action.assert_called_once_with( + 'restore', FAKE_BACKUP, info=FAKE_TARGET_SHARE_ID) def test_list(self): with mock.patch.object(self.manager, '_list', mock.Mock()): diff --git a/manilaclient/v2/share_backups.py b/manilaclient/v2/share_backups.py index 3f2bccc8..9714dbda 100644 --- a/manilaclient/v2/share_backups.py +++ b/manilaclient/v2/share_backups.py @@ -110,10 +110,15 @@ def delete(self, backup): url = RESOURCE_PATH % backup_id self._delete(url) - @api_versions.wraps("2.80") + @api_versions.wraps("2.80", "2.90") + @api_versions.experimental_api + def restore(self, backup_id): + return self._action('restore', backup_id) + + @api_versions.wraps("2.91") @api_versions.experimental_api - def restore(self, backup): - return self._action('restore', backup) + def restore(self, backup_id, target_share_id=None): # noqa F811 + return self._action('restore', backup_id, info=target_share_id) @api_versions.wraps("2.80") @api_versions.experimental_api diff --git a/releasenotes/notes/share-backup-out-of-place-restore-98740badef59ba32.yaml b/releasenotes/notes/share-backup-out-of-place-restore-98740badef59ba32.yaml new file mode 100644 index 00000000..9481b1cb --- /dev/null +++ b/releasenotes/notes/share-backup-out-of-place-restore-98740badef59ba32.yaml @@ -0,0 +1,7 @@ +--- +features: + - | + Added support for targeted share backup restores via the openstackclient + plugin. You can use the openstack client to restore a share backup from + one source share to another target share, given the backup or share driver + provides support for the operation. Available from microversion 2.91. From 43ee9f0e59e6c44d3975e31129aefb124c96473d Mon Sep 17 00:00:00 2001 From: Carlos da Silva Date: Fri, 29 Aug 2025 17:26:03 -0300 Subject: [PATCH 10/52] Fixes an issue that prevented ensure shares to be run A typo in the URL for ensure shares was created and the API endpoint did not match as a result. Fixed the issue by replacing '_' by '-' to match the endpoint correctly. Closes-bug: #2109376 Change-Id: I025d0f853bced49a2d484dc75db809b3d7edb498 Signed-off-by: Carlos da Silva --- manilaclient/v2/services.py | 2 +- ...g-2109376-fix-ensure-shares-command-69feb1794fea418a.yaml | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 releasenotes/notes/bug-2109376-fix-ensure-shares-command-69feb1794fea418a.yaml diff --git a/manilaclient/v2/services.py b/manilaclient/v2/services.py index f87fff6a..0fd288c3 100644 --- a/manilaclient/v2/services.py +++ b/manilaclient/v2/services.py @@ -89,7 +89,7 @@ def disable(self, host, binary, disable_reason=None): # noqa @api_versions.wraps("2.86") def ensure_shares(self, host): # noqa - resource_path = f'{RESOURCE_PATH}/ensure_shares' + resource_path = f'{RESOURCE_PATH}/ensure-shares' body = {"host": host} return self.api.client.post(resource_path, body=body) diff --git a/releasenotes/notes/bug-2109376-fix-ensure-shares-command-69feb1794fea418a.yaml b/releasenotes/notes/bug-2109376-fix-ensure-shares-command-69feb1794fea418a.yaml new file mode 100644 index 00000000..03cf4ac9 --- /dev/null +++ b/releasenotes/notes/bug-2109376-fix-ensure-shares-command-69feb1794fea418a.yaml @@ -0,0 +1,5 @@ +--- +fixes: + - | + Fixed an issue while running ensure shares and getting a not found + response. The command should now work properly. From 30e949159f5cb8d2e93fc9089c69e321d3905f2a Mon Sep 17 00:00:00 2001 From: OpenStack Release Bot Date: Fri, 5 Sep 2025 12:30:53 +0000 Subject: [PATCH 11/52] Update master for stable/2025.2 Add file to the reno documentation build to show release notes for stable/2025.2. Use pbr instruction to increment the minor version number automatically so that master versions are higher than the versions on stable/2025.2. Sem-Ver: feature Change-Id: I16d12c811f12e1de4301ac38f4c9bf992f82b5fa Signed-off-by: OpenStack Release Bot Generated-By: openstack/project-config:roles/copy-release-tools-scripts/files/release-tools/add_release_note_page.sh --- releasenotes/source/2025.2.rst | 6 ++++++ releasenotes/source/index.rst | 1 + 2 files changed, 7 insertions(+) create mode 100644 releasenotes/source/2025.2.rst diff --git a/releasenotes/source/2025.2.rst b/releasenotes/source/2025.2.rst new file mode 100644 index 00000000..4dae18d8 --- /dev/null +++ b/releasenotes/source/2025.2.rst @@ -0,0 +1,6 @@ +=========================== +2025.2 Series Release Notes +=========================== + +.. release-notes:: + :branch: stable/2025.2 diff --git a/releasenotes/source/index.rst b/releasenotes/source/index.rst index ba7efdbe..9ad580fc 100644 --- a/releasenotes/source/index.rst +++ b/releasenotes/source/index.rst @@ -7,6 +7,7 @@ python-manilaclient Release Notes :maxdepth: 1 unreleased + 2025.2 2025.1 2024.2 2024.1 From 529d860e80e5606f9521e5cc1bc7c0e5b6e1fa92 Mon Sep 17 00:00:00 2001 From: Premlata Date: Thu, 23 Oct 2025 00:50:55 +0530 Subject: [PATCH 12/52] Add --wait flag to share-server-unmanage This change adds the --wait flag to the share-server-unmanage command, allowing users to wait for the asynchronous operation to complete before returning to the command prompt. When --wait is specified, share-server-unmanage waits until the server is removed. Closes-Bug: #1898315 Change-Id: I90f9c7048a1d5cc21064c4b1d000732dc5fd50d6 Signed-off-by: Premlata --- manilaclient/tests/unit/v2/test_shell.py | 24 +++++++++++++++++++ manilaclient/v2/shell.py | 10 ++++++++ ...hare-server-unmanage-819dd42abc2a4d2b.yaml | 6 +++++ 3 files changed, 40 insertions(+) create mode 100644 releasenotes/notes/add-wait-flag-share-server-unmanage-819dd42abc2a4d2b.yaml diff --git a/manilaclient/tests/unit/v2/test_shell.py b/manilaclient/tests/unit/v2/test_shell.py index 58e1dc65..41343d9b 100644 --- a/manilaclient/tests/unit/v2/test_shell.py +++ b/manilaclient/tests/unit/v2/test_shell.py @@ -1027,6 +1027,30 @@ def test_share_server_unmanage_force(self): self.assert_called('POST', '/share-servers/1234/action', body={'unmanage': {'force': True}}) + @mock.patch.object(shell_v2, '_wait_for_resource_status', mock.Mock()) + def test_share_server_unmanage_wait(self): + self.run_command('share-server-unmanage 1234 --wait') + + self.assert_called('POST', '/share-servers/1234/action', + body={'unmanage': {'force': False}}, pos=-2) + expected_share_server = shell_v2._find_share_server( + self.shell.cs, '1234') + shell_v2._wait_for_resource_status.assert_called_once_with( + self.shell.cs, expected_share_server, + resource_type='share_server', expected_status='unmanaged') + + @mock.patch.object(shell_v2, '_wait_for_resource_status', mock.Mock()) + def test_share_server_unmanage_wait_with_force(self): + self.run_command('share-server-unmanage 1234 --force --wait') + + self.assert_called('POST', '/share-servers/1234/action', + body={'unmanage': {'force': True}}, pos=-2) + expected_share_server = shell_v2._find_share_server( + self.shell.cs, '1234') + shell_v2._wait_for_resource_status.assert_called_once_with( + self.shell.cs, expected_share_server, + resource_type='share_server', expected_status='unmanaged') + @ddt.data({'cmd_args': '--driver_options opt1=opt1 opt2=opt2', 'valid_params': { 'driver_options': {'opt1': 'opt1', 'opt2': 'opt2'}, diff --git a/manilaclient/v2/shell.py b/manilaclient/v2/shell.py index b83884c1..999552c9 100644 --- a/manilaclient/v2/shell.py +++ b/manilaclient/v2/shell.py @@ -1766,12 +1766,22 @@ def do_unmanage(cs, args): default=False, help="Enforces the unmanage share server operation, even if the back-end " "driver does not support it.") +@cliutils.arg( + '--wait', + action='store_true', + default=False, + help='Wait for share server(s) to be unmanaged') def do_share_server_unmanage(cs, args): """Unmanage share server (Admin only).""" failure_count = 0 for server in args.share_server: try: cs.share_servers.unmanage(server, args.force) + if args.wait: + share_server_ref = _find_share_server(cs, server) + _wait_for_resource_status( + cs, share_server_ref, resource_type='share_server', + expected_status='unmanaged') except Exception as e: failure_count += 1 print("Unmanage for share server %s failed: %s" % (server, e), diff --git a/releasenotes/notes/add-wait-flag-share-server-unmanage-819dd42abc2a4d2b.yaml b/releasenotes/notes/add-wait-flag-share-server-unmanage-819dd42abc2a4d2b.yaml new file mode 100644 index 00000000..8d5543bc --- /dev/null +++ b/releasenotes/notes/add-wait-flag-share-server-unmanage-819dd42abc2a4d2b.yaml @@ -0,0 +1,6 @@ +--- +features: + - | + The command "manila share-server-unmanage" now accepts an optional + "--wait" flag that allows users to let the client poll for the + completion of the operation. From d0060a45a94f787b956e966912970def0fad85f4 Mon Sep 17 00:00:00 2001 From: llmtech-dev Date: Wed, 22 Oct 2025 16:32:28 +0000 Subject: [PATCH 13/52] Allow settings --task-state without value (to send null) or None The osc commands `openstack share set --task-state` and `openstack share server set --task-state` were failing when no value was provided, or when None was passed as an argument, leading to the API receive the string "null" instead of the JSON null value. This change makes the --task-state argument optional, allowing it to be specified without a value or with the string "None". In both cases, the command correctly interprets these inputs as a request to clear the task state by sending a proper null value to the API. Test Plan: - Added unittests for --task-state argument handling both share set and share server set commands. - Verified cases when --task-state is provided without a value (interpreted as None) or with value "None" (ensuring it is properly converted to None). Closes-Bug: #2108991 Change-Id: Ic2a9eed81154bfbe8517c7411da72f1e4d0e1e64 Signed-off-by: llmtech-dev --- manilaclient/osc/v2/share.py | 8 +++- manilaclient/osc/v2/share_servers.py | 8 +++- manilaclient/tests/unit/osc/v2/test_share.py | 28 ++++++++++++++ .../tests/unit/osc/v2/test_share_servers.py | 38 +++++++++++++++++++ ...ing-in-osc-share-set-307f3f4a2b232dd8.yaml | 7 ++++ 5 files changed, 85 insertions(+), 4 deletions(-) create mode 100644 releasenotes/notes/bug-2108991-fix-task-state-none-handling-in-osc-share-set-307f3f4a2b232dd8.yaml diff --git a/manilaclient/osc/v2/share.py b/manilaclient/osc/v2/share.py index 68273496..1309dccb 100644 --- a/manilaclient/osc/v2/share.py +++ b/manilaclient/osc/v2/share.py @@ -796,6 +796,7 @@ def get_parser(self, prog_name): metavar="", required=False, default=None, + nargs='?', help=_("Indicate which task state to assign the share. Options " "include migration_starting, migration_in_progress, " "migration_completing, migration_success, migration_error, " @@ -844,9 +845,12 @@ def take_action(self, parsed_args): LOG.error(_( "Failed to set status for the share: %s"), e) result += 1 - if parsed_args.task_state: + if hasattr(parsed_args, 'task_state'): + task_state = parsed_args.task_state + if task_state and task_state.lower() == "none": + task_state = None try: - share_obj.reset_task_state(parsed_args.task_state) + share_obj.reset_task_state(task_state) except Exception as e: LOG.error(_("Failed to update share task state " "%s"), e) diff --git a/manilaclient/osc/v2/share_servers.py b/manilaclient/osc/v2/share_servers.py index dda2d976..31de153a 100644 --- a/manilaclient/osc/v2/share_servers.py +++ b/manilaclient/osc/v2/share_servers.py @@ -435,6 +435,7 @@ def get_parser(self, prog_name): metavar="", required=False, default=None, + nargs='?', help=_("Indicate which task state to assign the share server. " "Options include migration_starting, migration_in_progress," " migration_completing, migration_success, migration_error," @@ -471,16 +472,19 @@ def take_action(self, parsed_args): LOG.error(msg) raise exceptions.CommandError(msg) - if parsed_args.task_state: + if hasattr(parsed_args, 'task_state'): if share_client.api_version < api_versions.APIVersion("2.57"): raise exceptions.CommandError( "Setting the state of a share server is only available " "with manila API version >= 2.57") else: + task_state = parsed_args.task_state + if task_state and task_state.lower() == "none": + task_state = None result = 0 try: share_client.share_servers.reset_task_state( - share_server, parsed_args.task_state) + share_server, task_state) except Exception as e: LOG.error(_("Failed to update share server task state " "%s"), e) diff --git a/manilaclient/tests/unit/osc/v2/test_share.py b/manilaclient/tests/unit/osc/v2/test_share.py index fe6a5de0..ff9cf52c 100644 --- a/manilaclient/tests/unit/osc/v2/test_share.py +++ b/manilaclient/tests/unit/osc/v2/test_share.py @@ -1406,6 +1406,34 @@ def test_share_set_task_state(self): self._share.reset_task_state.assert_called_with(new_task_state) self.assertIsNone(result) + def test_share_set_task_state_none(self): + arglist = [ + self._share.id, + '--task-state' + ] + verifylist = [ + ('share', self._share.id), + ('task_state', None) + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + result = self.cmd.take_action(parsed_args) + self._share.reset_task_state.assert_called_with(None) + self.assertIsNone(result) + + def test_share_set_task_state_string_none(self): + arglist = [ + self._share.id, + '--task-state', 'None' + ] + verifylist = [ + ('share', self._share.id), + ('task_state', 'None') + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + result = self.cmd.take_action(parsed_args) + self._share.reset_task_state.assert_called_with(None) + self.assertIsNone(result) + class TestShareUnset(TestShare): diff --git a/manilaclient/tests/unit/osc/v2/test_share_servers.py b/manilaclient/tests/unit/osc/v2/test_share_servers.py index dcb2f12a..f029cce2 100644 --- a/manilaclient/tests/unit/osc/v2/test_share_servers.py +++ b/manilaclient/tests/unit/osc/v2/test_share_servers.py @@ -564,6 +564,44 @@ def test_share_server_set_task_state(self): parsed_args.task_state) self.assertIsNone(result) + def test_share_server_set_task_state_none(self): + arglist = [ + self.share_server.id, + '--task-state', + ] + verifylist = [ + ('share_server', self.share_server.id), + ('task_state', None) + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + result = self.cmd.take_action(parsed_args) + + self.servers_mock.reset_task_state.assert_called_with( + self.share_server, + None) + self.assertIsNone(result) + + def test_share_server_set_task_state_string_none(self): + arglist = [ + self.share_server.id, + '--task-state', 'None' + ] + verifylist = [ + ('share_server', self.share_server.id), + ('task_state', 'None') + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + result = self.cmd.take_action(parsed_args) + + self.servers_mock.reset_task_state.assert_called_with( + self.share_server, + None) + self.assertIsNone(result) + def test_share_server_set_status_exception(self): arglist = [ self.share_server.id, diff --git a/releasenotes/notes/bug-2108991-fix-task-state-none-handling-in-osc-share-set-307f3f4a2b232dd8.yaml b/releasenotes/notes/bug-2108991-fix-task-state-none-handling-in-osc-share-set-307f3f4a2b232dd8.yaml new file mode 100644 index 00000000..1b2d4a80 --- /dev/null +++ b/releasenotes/notes/bug-2108991-fix-task-state-none-handling-in-osc-share-set-307f3f4a2b232dd8.yaml @@ -0,0 +1,7 @@ +--- +fixes: + - | + The `openstack share set` and `openstack share server set` commands now + properly handle the `--task-state` argument when given no value or "None", + sending a proper null value to the API. For more details, please refer to + `Launchpad bug #2108991 `_. From 8019cc5ac0850e00ff8d52a82a627aa4a97ab11c Mon Sep 17 00:00:00 2001 From: denver-baraka Date: Thu, 23 Oct 2025 20:26:59 +0300 Subject: [PATCH 14/52] fix respect region name in client initialization when initializing manila python client, the region name was being ignored. As a result, the client could connect to the wrong region endpoint. This change ensures that region name is passed to session.get_endpoint() so the correct endpoint is used. Test, -Updated unit tests to verify that the region name is respected during client initialization. Closes-Bug: #2057951 Change-Id: I2d971f2c4771d62a1776c995ef8a16594fd04c99 Signed-off-by: denver-baraka Assisted-By: Copilot --- manilaclient/tests/unit/v2/test_client.py | 19 +++++++++++++++++++ manilaclient/v2/client.py | 2 +- ...x-client-region-name-67fed93b76429b63.yaml | 9 +++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 releasenotes/notes/bug-2057951-fix-client-region-name-67fed93b76429b63.yaml diff --git a/manilaclient/tests/unit/v2/test_client.py b/manilaclient/tests/unit/v2/test_client.py index 04f13b4b..79c12e7c 100644 --- a/manilaclient/tests/unit/v2/test_client.py +++ b/manilaclient/tests/unit/v2/test_client.py @@ -137,6 +137,25 @@ def test_regions_with_same_name(self): api_version=manilaclient.API_MIN_VERSION) self.assertIsNotNone(c.client) + def test_client_respects_region_name(self): + mock_session = mock.Mock() + mock_auth = mock.Mock() + region = 'region1' + mock_session.get_endpoint.return_value = 'http://fake-endpoint/' + client.Client( + session=mock_session, + auth=mock_auth, + service_type='sharev2', + endpoint_type='public', + region_name=region, + ) + mock_session.get_endpoint.assert_called_once_with( + mock_auth, + service_type='sharev2', + interface='public', + region_name=region, + ) + def _get_client_args(self, **kwargs): client_args = { 'auth_url': 'http://identity.example.com', diff --git a/manilaclient/v2/client.py b/manilaclient/v2/client.py index c0ff0a97..af534529 100644 --- a/manilaclient/v2/client.py +++ b/manilaclient/v2/client.py @@ -159,7 +159,7 @@ def __init__(self, username=None, project_id=None, auth_url=None, if session and not service_catalog_url: service_catalog_url = self.keystone_client.session.get_endpoint( auth, interface=endpoint_type, - service_type=service_type) + service_type=service_type, region_name=region_name) elif not service_catalog_url: catalog = self.keystone_client.service_catalog.get_endpoints( service_type) diff --git a/releasenotes/notes/bug-2057951-fix-client-region-name-67fed93b76429b63.yaml b/releasenotes/notes/bug-2057951-fix-client-region-name-67fed93b76429b63.yaml new file mode 100644 index 00000000..e4955f1b --- /dev/null +++ b/releasenotes/notes/bug-2057951-fix-client-region-name-67fed93b76429b63.yaml @@ -0,0 +1,9 @@ +fixes: + - | + Fixed Bug #2057951: The manila python client previously + ignored the "region_name" parameter when initializing a + client session. This caused the client to use wrong API + endpoint in multi-region deployments. The client now + correctly respects the "region_name" value ensuring + requests are routed to the intended region + From 53ca6e9f873e04e2a14c46739f859aecd9ea74f3 Mon Sep 17 00:00:00 2001 From: denver-baraka Date: Sat, 18 Oct 2025 17:51:56 +0300 Subject: [PATCH 15/52] Fix neutron validation in share network creation The 'share network create' command previously attempted to fetch the subnet directly, which could lead to errors when the neuron network data was invalid or missing. This change updates the logic to properly handle invalid neutron network or subnet IDs during share network creation. Test Plan: - Added unit tests to verify valid and invalid neutron info. Closes-Bug: #2051394 Change-Id: Ib233f02ad94326d5b8ffadf962fb911d417b024a Signed-off-by: denver-baraka Assisted-By: Copilot --- manilaclient/osc/v2/share_network_subnets.py | 36 +++++- manilaclient/osc/v2/share_networks.py | 26 ++++- .../unit/osc/v2/test_share_network_subnets.py | 103 ++++++++++++++++++ .../tests/unit/osc/v2/test_share_networks.py | 90 +++++++++++++++ ...alidate-neutron-info-ebe679675111eec9.yaml | 12 ++ 5 files changed, 259 insertions(+), 8 deletions(-) create mode 100644 releasenotes/notes/bug-2051394-fix-validate-neutron-info-ebe679675111eec9.yaml diff --git a/manilaclient/osc/v2/share_network_subnets.py b/manilaclient/osc/v2/share_network_subnets.py index 09e0385b..df9befc7 100644 --- a/manilaclient/osc/v2/share_network_subnets.py +++ b/manilaclient/osc/v2/share_network_subnets.py @@ -110,13 +110,37 @@ def take_action(self, parsed_args): "Property can be specified only with manila API " "version >= 2.78.") - if xor(bool(parsed_args.neutron_net_id), - bool(parsed_args.neutron_subnet_id)): + neutron_client = getattr(self.app.client_manager, 'network', None) + neutron_net_id = parsed_args.neutron_net_id + neutron_subnet_id = parsed_args.neutron_subnet_id + + if xor(bool(neutron_net_id), + bool(neutron_subnet_id)): raise exceptions.CommandError( "Both neutron_net_id and neutron_subnet_id should be " "specified. Alternatively, neither of them should be " "specified.") + if neutron_client and neutron_net_id: + try: + neutron_net_id = neutron_client.find_network( + neutron_net_id, + ignore_missing=False).id + except Exception: + raise exceptions.CommandError( + f"Neutron network '{neutron_net_id}'" + f" not found.") + + if neutron_client and neutron_subnet_id: + try: + neutron_subnet_id = neutron_client.find_subnet( + neutron_subnet_id, + ignore_missing=False).id + except Exception: + raise exceptions.CommandError( + f"Neutron subnet '{neutron_subnet_id}'" + f" not found.") + share_network_id = oscutils.find_resource( share_client.share_networks, parsed_args.share_network).id @@ -129,8 +153,8 @@ def take_action(self, parsed_args): subnet_create_check = ( share_client.share_networks.share_network_subnet_create_check( - neutron_net_id=parsed_args.neutron_net_id, - neutron_subnet_id=parsed_args.neutron_subnet_id, + neutron_net_id=neutron_net_id, + neutron_subnet_id=neutron_subnet_id, availability_zone=parsed_args.availability_zone, reset_operation=parsed_args.restart_check, share_network_id=share_network_id) @@ -147,8 +171,8 @@ def take_action(self, parsed_args): subnet_data[k] = dict_values else: share_network_subnet = share_client.share_network_subnets.create( - neutron_net_id=parsed_args.neutron_net_id, - neutron_subnet_id=parsed_args.neutron_subnet_id, + neutron_net_id=neutron_net_id, + neutron_subnet_id=neutron_subnet_id, availability_zone=parsed_args.availability_zone, share_network_id=share_network_id, metadata=parsed_args.property diff --git a/manilaclient/osc/v2/share_networks.py b/manilaclient/osc/v2/share_networks.py index fbad5aa8..d81c3a7c 100644 --- a/manilaclient/osc/v2/share_networks.py +++ b/manilaclient/osc/v2/share_networks.py @@ -300,6 +300,28 @@ def get_parser(self, prog_name): def take_action(self, parsed_args): share_client = self.app.client_manager.share + neutron_client = getattr(self.app.client_manager, 'network', None) + neutron_net_id = parsed_args.neutron_net_id + neutron_subnet_id = parsed_args.neutron_subnet_id + + if neutron_client and neutron_net_id: + try: + neutron_net_id = neutron_client.find_network( + neutron_net_id, + ignore_missing=False).id + except Exception: + raise exceptions.CommandError( + f"Neutron network '{parsed_args.neutron_net_id}'" + f" not found.") + if neutron_client and neutron_subnet_id: + try: + neutron_subnet_id = neutron_client.find_subnet( + neutron_subnet_id, + ignore_missing=False).id + except Exception: + raise exceptions.CommandError( + f"Neutron subnet '{parsed_args.neutron_subnet_id}'" + f" not found.") availability_zone = None if (parsed_args.availability_zone and @@ -313,8 +335,8 @@ def take_action(self, parsed_args): kwargs = { "name": parsed_args.name, "description": parsed_args.description, - "neutron_net_id": parsed_args.neutron_net_id, - "neutron_subnet_id": parsed_args.neutron_subnet_id, + "neutron_net_id": neutron_net_id, + "neutron_subnet_id": neutron_subnet_id, } if availability_zone: kwargs['availability_zone'] = availability_zone diff --git a/manilaclient/tests/unit/osc/v2/test_share_network_subnets.py b/manilaclient/tests/unit/osc/v2/test_share_network_subnets.py index 3fba08e4..bd2b5863 100644 --- a/manilaclient/tests/unit/osc/v2/test_share_network_subnets.py +++ b/manilaclient/tests/unit/osc/v2/test_share_network_subnets.py @@ -93,6 +93,109 @@ def test_share_network_subnet_create(self): self.assertCountEqual(self.columns, columns) self.assertCountEqual(self.data, data) + def test_share_network_subnet_create_valid_neutron_info(self): + fake_neutron_net_id = str(uuid.uuid4()) + fake_neutron_subnet_id = str(uuid.uuid4()) + + neutron_client = mock.Mock() + self.app.client_manager.network = neutron_client + neutron_client.find_network.return_value = mock.Mock( + id=fake_neutron_net_id) + neutron_client.find_subnet.return_value = mock.Mock( + id=fake_neutron_subnet_id) + + arglist = [ + self.share_network.id, + '--neutron-net-id', fake_neutron_net_id, + '--neutron-subnet-id', fake_neutron_subnet_id, + ] + verifylist = [ + ('share_network', self.share_network.id), + ('neutron_net_id', fake_neutron_net_id), + ('neutron_subnet_id', fake_neutron_subnet_id), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + neutron_client.find_network.assert_called_once_with( + fake_neutron_net_id, + ignore_missing=False + ) + neutron_client.find_subnet.assert_called_once_with( + fake_neutron_subnet_id, + ignore_missing=False + ) + self.share_subnets_mock.create.assert_called_once_with( + share_network_id=self.share_network.id, + neutron_net_id=fake_neutron_net_id, + neutron_subnet_id=fake_neutron_subnet_id, + availability_zone=None, + metadata={}, + ) + self.assertCountEqual(self.columns, columns) + self.assertCountEqual(self.data, data) + + def test_share_network_subnet_create_invalid_neutron_network(self): + fake_neutron_net_id = str(uuid.uuid4()) + fake_neutron_net_id = str(uuid.uuid4()) + + neutron_client = mock.Mock() + self.app.client_manager.network = neutron_client + neutron_client.find_network.side_effect = Exception( + "Network not found.") + + arglist = [ + self.share_network.id, + '--neutron-net-id', fake_neutron_net_id, + '--neutron-subnet-id', fake_neutron_net_id, + ] + verifylist = [ + ('share_network', self.share_network.id), + ('neutron_net_id', fake_neutron_net_id), + ('neutron_subnet_id', fake_neutron_net_id), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + self.assertRaises(exceptions.CommandError, + self.cmd.take_action, + parsed_args) + neutron_client.find_network.assert_called_once_with( + fake_neutron_net_id, + ignore_missing=False + ) + neutron_client.find_subnet.assert_not_called() + self.share_subnets_mock.create.assert_not_called() + + def test_share_network_subnet_create_invalid_neutron_subnet(self): + fake_neutron_net_id = str(uuid.uuid4()) + fake_neutron_subnet_id = str(uuid.uuid4()) + neutron_client = mock.Mock() + self.app.client_manager.network = neutron_client + neutron_client.find_subnet.side_effect = Exception( + "Subnet not found.") + arglist = [ + self.share_network.id, + '--neutron-net-id', fake_neutron_net_id, + '--neutron-subnet-id', fake_neutron_subnet_id, + ] + verifylist = [ + ('share_network', self.share_network.id), + ('neutron_net_id', fake_neutron_net_id), + ('neutron_subnet_id', fake_neutron_subnet_id), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + self.assertRaises(exceptions.CommandError, + self.cmd.take_action, + parsed_args) + neutron_client.find_network.assert_called_once_with( + fake_neutron_net_id, + ignore_missing=False + ) + neutron_client.find_subnet.assert_called_once_with( + fake_neutron_subnet_id, + ignore_missing=False + ) + self.share_subnets_mock.create.assert_not_called() + def test_share_network_subnet_create_arg_group_exception(self): fake_neutron_net_id = str(uuid.uuid4()) diff --git a/manilaclient/tests/unit/osc/v2/test_share_networks.py b/manilaclient/tests/unit/osc/v2/test_share_networks.py index a66efb7a..91dcbd04 100644 --- a/manilaclient/tests/unit/osc/v2/test_share_networks.py +++ b/manilaclient/tests/unit/osc/v2/test_share_networks.py @@ -122,6 +122,96 @@ def test_share_network_create_with_args(self): self.assertCountEqual(self.columns, columns) self.assertCountEqual(self.data, data) + def test_share_network_create_with_valid_neutron_info(self): + fake_neutron_net_id = str(uuid.uuid4()) + fake_neutron_subnet_id = str(uuid.uuid4()) + + neutron_client = mock.Mock() + self.app.client_manager.network = neutron_client + + neutron_client.find_network.return_value = mock.Mock( + id=fake_neutron_net_id) + neutron_client.find_subnet.return_value = mock.Mock( + id=fake_neutron_subnet_id) + + arglist = [ + '--neutron-net-id', fake_neutron_net_id, + '--neutron-subnet-id', fake_neutron_subnet_id, + ] + verifylist = [ + ('neutron_net_id', fake_neutron_net_id), + ('neutron_subnet_id', fake_neutron_subnet_id), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + neutron_client.find_network.assert_called_once_with( + fake_neutron_net_id, ignore_missing=False) + neutron_client.find_subnet.assert_called_once_with( + fake_neutron_subnet_id, ignore_missing=False) + self.share_networks_mock.create.assert_called_once_with( + name=None, + description=None, + neutron_net_id=fake_neutron_net_id, + neutron_subnet_id=fake_neutron_subnet_id + ) + self.assertCountEqual(self.columns, columns) + self.assertCountEqual(self.data, data) + + def test_share_network_create_with_invalid_neutron_network(self): + fake_neutron_net_id = str(uuid.uuid4()) + + neutron_client = mock.Mock() + self.app.client_manager.network = neutron_client + + neutron_client.find_network.side_effect = Exception( + "Network not found") + + arglist = [ + '--neutron-net-id', fake_neutron_net_id + ] + verifylist = [ + ('neutron_net_id', fake_neutron_net_id) + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + self.assertRaises( + exceptions.CommandError, + self.cmd.take_action, + parsed_args + ) + + neutron_client.find_network.assert_called_once_with( + fake_neutron_net_id, ignore_missing=False) + self.share_networks_mock.create.assert_not_called() + + def test_share_network_create_with_invalid_neutron_subnet(self): + fake_neutron_subnet_id = str(uuid.uuid4()) + + neutron_client = mock.Mock() + self.app.client_manager.network = neutron_client + + neutron_client.find_subnet.side_effect = Exception( + "Subnet not found") + + arglist = [ + '--neutron-subnet-id', fake_neutron_subnet_id + ] + verifylist = [ + ('neutron_subnet_id', fake_neutron_subnet_id) + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + self.assertRaises( + exceptions.CommandError, + self.cmd.take_action, + parsed_args + ) + + neutron_client.find_subnet.assert_called_once_with( + fake_neutron_subnet_id, ignore_missing=False) + self.share_networks_mock.create.assert_not_called() + @ddt.ddt class TestShareNetworkDelete(TestShareNetwork): diff --git a/releasenotes/notes/bug-2051394-fix-validate-neutron-info-ebe679675111eec9.yaml b/releasenotes/notes/bug-2051394-fix-validate-neutron-info-ebe679675111eec9.yaml new file mode 100644 index 00000000..81e6f871 --- /dev/null +++ b/releasenotes/notes/bug-2051394-fix-validate-neutron-info-ebe679675111eec9.yaml @@ -0,0 +1,12 @@ +fixes: + - | + The "openstack share network create" and + "openstack share network subnet create" commands + now validate Neutron network information provided + before sending the request. + + Previously, validation only occured in the Manila service + which could result in client-side errors when invalid network + or subnet IDs were supplied. The client now performs + proper validation and handles missing or invalid + network data gracefully. \ No newline at end of file From 845d6e87e431127b3d5d88d1abdb7dc2d9c8dc9c Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Fri, 10 Oct 2025 10:49:10 +0100 Subject: [PATCH 16/52] Migrate setup configuration to pyproject.toml Change-Id: I10d630f70b543498b33045ba5819dc68be0e6960 Signed-off-by: Stephen Finucane --- pyproject.toml | 200 +++++++++++++++++++++++++++++++++++++++++++++++++ setup.cfg | 187 --------------------------------------------- 2 files changed, 200 insertions(+), 187 deletions(-) create mode 100644 pyproject.toml diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..18567e1e --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,200 @@ +[build-system] +requires = ["pbr>=6.1.1"] +build-backend = "pbr.build" + +[project] +name = "python-manilaclient" +description = "Client library for OpenStack Shared File System Storage" +authors = [ + {name = "OpenStack", email = "openstack-discuss@lists.openstack.org"}, +] +readme = {file = "README.rst", content-type = "text/x-rst"} +license = {text = "Apache-2.0"} +dynamic = ["version", "dependencies"] +requires-python = ">=3.10" +classifiers = [ + "Environment :: OpenStack", + "Intended Audience :: Information Technology", + "Intended Audience :: System Administrators", + "License :: OSI Approved :: Apache Software License", + "Operating System :: POSIX :: Linux", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", +] + +[project.urls] +Homepage = "https://docs.openstack.org/python-manilaclient/" +Repository = "https://opendev.org/openstack/python-manilaclient/" + +[project.scripts] +manila = "manilaclient.shell:main" + +[project.entry-points."oslo.config.opts"] +"manilaclient.config" = "manilaclient.config:list_opts" + +[project.entry-points."openstack.cli.extension"] +share = "manilaclient.osc.plugin" + +[project.entry-points."openstack.share.v2"] +share_list = "manilaclient.osc.v2.share:ListShare" +share_create = "manilaclient.osc.v2.share:CreateShare" +share_delete = " manilaclient.osc.v2.share:DeleteShare" +share_show = "manilaclient.osc.v2.share:ShowShare" +share_set = "manilaclient.osc.v2.share:SetShare" +share_unset = "manilaclient.osc.v2.share:UnsetShare" +share_resize = "manilaclient.osc.v2.share:ResizeShare" +share_adopt = "manilaclient.osc.v2.share:AdoptShare" +share_abandon = "manilaclient.osc.v2.share:AbandonShare" +share_migration_start = "manilaclient.osc.v2.share:ShareMigrationStart" +share_migration_cancel = "manilaclient.osc.v2.share:ShareMigrationCancel" +share_migration_complete = "manilaclient.osc.v2.share:ShareMigrationComplete" +share_migration_show = "manilaclient.osc.v2.share:ShareMigrationShow" +share_export_location_show = "manilaclient.osc.v2.share:ShareExportLocationShow" +share_export_location_list = "manilaclient.osc.v2.share:ShareExportLocationList" +share_export_location_set = "manilaclient.osc.v2.share:ShareExportLocationSet" +share_export_location_unset = "manilaclient.osc.v2.share:ShareExportLocationUnset" +share_properties_show = "manilaclient.osc.v2.share:ShowShareProperties" +share_restore = "manilaclient.osc.v2.share:RestoreShare" +share_revert = "manilaclient.osc.v2.share:RevertShare" +share_access_create = "manilaclient.osc.v2.share_access_rules:ShareAccessAllow" +share_access_delete = "manilaclient.osc.v2.share_access_rules:ShareAccessDeny" +share_access_list = "manilaclient.osc.v2.share_access_rules:ListShareAccess" +share_access_show = "manilaclient.osc.v2.share_access_rules:ShowShareAccess" +share_access_set = "manilaclient.osc.v2.share_access_rules:SetShareAccess" +share_access_unset = "manilaclient.osc.v2.share_access_rules:UnsetShareAccess" +share_backup_create = "manilaclient.osc.v2.share_backups:CreateShareBackup" +share_backup_delete = "manilaclient.osc.v2.share_backups:DeleteShareBackup" +share_backup_list = "manilaclient.osc.v2.share_backups:ListShareBackup" +share_backup_show = "manilaclient.osc.v2.share_backups:ShowShareBackup" +share_backup_restore = "manilaclient.osc.v2.share_backups:RestoreShareBackup" +share_backup_set = "manilaclient.osc.v2.share_backups:SetShareBackup" +share_backup_unset = "manilaclient.osc.v2.share_backups:UnsetShareBackup" +share_type_create = "manilaclient.osc.v2.share_types:CreateShareType" +share_type_delete = "manilaclient.osc.v2.share_types:DeleteShareType" +share_type_set = "manilaclient.osc.v2.share_types:SetShareType" +share_type_unset = "manilaclient.osc.v2.share_types:UnsetShareType" +share_type_list = "manilaclient.osc.v2.share_types:ListShareType" +share_type_show = "manilaclient.osc.v2.share_types:ShowShareType" +share_type_access_create = "manilaclient.osc.v2.share_type_access:ShareTypeAccessAllow" +share_type_access_list = "manilaclient.osc.v2.share_type_access:ListShareTypeAccess" +share_type_access_delete = "manilaclient.osc.v2.share_type_access:ShareTypeAccessDeny" +share_quota_set = "manilaclient.osc.v2.quotas:QuotaSet" +share_quota_show = "manilaclient.osc.v2.quotas:QuotaShow" +share_quota_delete = "manilaclient.osc.v2.quotas:QuotaDelete" +share_snapshot_create = "manilaclient.osc.v2.share_snapshots:CreateShareSnapshot" +share_snapshot_delete = "manilaclient.osc.v2.share_snapshots:DeleteShareSnapshot" +share_snapshot_show = "manilaclient.osc.v2.share_snapshots:ShowShareSnapshot" +share_snapshot_set = "manilaclient.osc.v2.share_snapshots:SetShareSnapshot" +share_snapshot_unset = "manilaclient.osc.v2.share_snapshots:UnsetShareSnapshot" +share_snapshot_list = "manilaclient.osc.v2.share_snapshots:ListShareSnapshot" +share_snapshot_adopt = "manilaclient.osc.v2.share_snapshots:AdoptShareSnapshot" +share_snapshot_abandon = "manilaclient.osc.v2.share_snapshots:AbandonShareSnapshot" +share_snapshot_access_create = "manilaclient.osc.v2.share_snapshots:ShareSnapshotAccessAllow" +share_snapshot_access_delete = "manilaclient.osc.v2.share_snapshots:ShareSnapshotAccessDeny" +share_snapshot_access_list = "manilaclient.osc.v2.share_snapshots:ShareSnapshotAccessList" +share_snapshot_export_location_list = "manilaclient.osc.v2.share_snapshots:ShareSnapshotListExportLocation" +share_snapshot_export_location_show = "manilaclient.osc.v2.share_snapshots:ShareSnapshotShowExportLocation" +share_snapshot_instance_list = "manilaclient.osc.v2.share_snapshot_instances:ListShareSnapshotInstance" +share_snapshot_instance_show = "manilaclient.osc.v2.share_snapshot_instances:ShowShareSnapshotInstance" +share_snapshot_instance_set = "manilaclient.osc.v2.share_snapshot_instances:SetShareSnapshotInstance" +share_snapshot_instance_export_location_list = "manilaclient.osc.v2.share_snapshot_instance_export_locations:ShareSnapshotInstanceExportLocationList" +share_snapshot_instance_export_location_show = "manilaclient.osc.v2.share_snapshot_instance_export_locations:ShareSnapshotInstanceExportLocationShow" +share_message_delete = "manilaclient.osc.v2.messages:DeleteMessage" +share_message_list = "manilaclient.osc.v2.messages:ListMessage" +share_message_show = "manilaclient.osc.v2.messages:ShowMessage" +share_replica_create = "manilaclient.osc.v2.share_replicas:CreateShareReplica" +share_replica_delete = "manilaclient.osc.v2.share_replicas:DeleteShareReplica" +share_replica_list = "manilaclient.osc.v2.share_replicas:ListShareReplica" +share_replica_show = "manilaclient.osc.v2.share_replicas:ShowShareReplica" +share_replica_set = "manilaclient.osc.v2.share_replicas:SetShareReplica" +share_replica_promote = "manilaclient.osc.v2.share_replicas:PromoteShareReplica" +share_replica_resync = "manilaclient.osc.v2.share_replicas:ResyncShareReplica" +share_replica_export_location_list = "manilaclient.osc.v2.share_replica_export_locations:ShareReplicaListExportLocation" +share_replica_export_location_show = "manilaclient.osc.v2.share_replica_export_locations:ShareReplicaShowExportLocation" +share_availability_zone_list = "manilaclient.osc.v2.availability_zones:ShareAvailabilityZoneList" +share_service_set = "manilaclient.osc.v2.services:SetShareService" +share_service_list = "manilaclient.osc.v2.services:ListShareService" +share_service_ensure_shares = "manilaclient.osc.v2.services:EnsureShareService" +share_security_service_create = "manilaclient.osc.v2.security_services:CreateShareSecurityService" +share_security_service_delete = "manilaclient.osc.v2.security_services:DeleteShareSecurityService" +share_security_service_show = "manilaclient.osc.v2.security_services:ShowShareSecurityService" +share_security_service_set = "manilaclient.osc.v2.security_services:SetShareSecurityService" +share_security_service_unset = "manilaclient.osc.v2.security_services:UnsetShareSecurityService" +share_security_service_list = "manilaclient.osc.v2.security_services:ListShareSecurityService" +share_pool_list = "manilaclient.osc.v2.share_pools:ListSharePools" +share_instance_delete = "manilaclient.osc.v2.share_instances:ShareInstanceDelete" +share_instance_list = "manilaclient.osc.v2.share_instances:ShareInstanceList" +share_instance_set = "manilaclient.osc.v2.share_instances:ShareInstanceSet" +share_instance_show = "manilaclient.osc.v2.share_instances:ShareInstanceShow" +share_instance_export_location_show = "manilaclient.osc.v2.share_instance_export_locations:ShareInstanceShowExportLocation" +share_instance_export_location_list = "manilaclient.osc.v2.share_instance_export_locations:ShareInstanceListExportLocation" +share_limits_show = "manilaclient.osc.v2.share_limits:ShareLimitsShow" +share_network_list = "manilaclient.osc.v2.share_networks:ListShareNetwork" +share_network_show = "manilaclient.osc.v2.share_networks:ShowShareNetwork" +share_network_create = "manilaclient.osc.v2.share_networks:CreateShareNetwork" +share_network_delete = "manilaclient.osc.v2.share_networks:DeleteShareNetwork" +share_network_set = "manilaclient.osc.v2.share_networks:SetShareNetwork" +share_network_unset = "manilaclient.osc.v2.share_networks:UnsetShareNetwork" +share_network_subnet_create = "manilaclient.osc.v2.share_network_subnets:CreateShareNetworkSubnet" +share_network_subnet_delete = "manilaclient.osc.v2.share_network_subnets:DeleteShareNetworkSubnet" +share_network_subnet_show = "manilaclient.osc.v2.share_network_subnets:ShowShareNetworkSubnet" +share_network_subnet_set = "manilaclient.osc.v2.share_network_subnets:SetShareNetworkSubnet" +share_network_subnet_unset = "manilaclient.osc.v2.share_network_subnets:UnsetShareNetworkSubnet" +share_group_create = "manilaclient.osc.v2.share_groups:CreateShareGroup" +share_group_delete = "manilaclient.osc.v2.share_groups:DeleteShareGroup" +share_group_list = "manilaclient.osc.v2.share_groups:ListShareGroup" +share_group_show = "manilaclient.osc.v2.share_groups:ShowShareGroup" +share_group_set = "manilaclient.osc.v2.share_groups:SetShareGroup" +share_group_unset = "manilaclient.osc.v2.share_groups:UnsetShareGroup" +share_group_type_create = "manilaclient.osc.v2.share_group_types:CreateShareGroupType" +share_group_type_delete = "manilaclient.osc.v2.share_group_types:DeleteShareGroupType" +share_group_type_list = "manilaclient.osc.v2.share_group_types:ListShareGroupType" +share_group_type_show = "manilaclient.osc.v2.share_group_types:ShowShareGroupType" +share_group_type_set = "manilaclient.osc.v2.share_group_types:SetShareGroupType" +share_group_type_unset = "manilaclient.osc.v2.share_group_types:UnsetShareGroupType" +share_group_type_access_create = "manilaclient.osc.v2.share_group_type_access:ShareGroupTypeAccessAllow" +share_group_type_access_list = "manilaclient.osc.v2.share_group_type_access:ListShareGroupTypeAccess" +share_group_type_access_delete = "manilaclient.osc.v2.share_group_type_access:ShareGroupTypeAccessDeny" +share_group_snapshot_create = "manilaclient.osc.v2.share_group_snapshots:CreateShareGroupSnapshot" +share_group_snapshot_delete = "manilaclient.osc.v2.share_group_snapshots:DeleteShareGroupSnapshot" +share_group_snapshot_show= "manilaclient.osc.v2.share_group_snapshots:ShowShareGroupSnapshot" +share_group_snapshot_list = "manilaclient.osc.v2.share_group_snapshots:ListShareGroupSnapshot" +share_group_snapshot_set = "manilaclient.osc.v2.share_group_snapshots:SetShareGroupSnapshot" +share_group_snapshot_unset = "manilaclient.osc.v2.share_group_snapshots:UnsetShareGroupSnapshot" +share_group_snapshot_members_list = "manilaclient.osc.v2.share_group_snapshots:ListShareGroupSnapshotMembers" +share_server_delete = "manilaclient.osc.v2.share_servers:DeleteShareServer" +share_server_show = "manilaclient.osc.v2.share_servers:ShowShareServer" +share_server_list = "manilaclient.osc.v2.share_servers:ListShareServer" +share_server_adopt = "manilaclient.osc.v2.share_servers:AdoptShareServer" +share_server_abandon = "manilaclient.osc.v2.share_servers:AbandonShareServer" +share_server_set = "manilaclient.osc.v2.share_servers:SetShareServer" +share_server_migration_cancel = "manilaclient.osc.v2.share_servers:ShareServerMigrationCancel" +share_server_migration_complete = "manilaclient.osc.v2.share_servers:ShareServerMigrationComplete" +share_server_migration_show = "manilaclient.osc.v2.share_servers:ShareServerMigrationShow" +share_server_migration_start = "manilaclient.osc.v2.share_servers:ShareServerMigrationStart" +share_transfer_create = "manilaclient.osc.v2.share_transfers:CreateShareTransfer" +share_transfer_delete = "manilaclient.osc.v2.share_transfers:DeleteShareTransfer" +share_transfer_list = "manilaclient.osc.v2.share_transfers:ListShareTransfer" +share_transfer_show = "manilaclient.osc.v2.share_transfers:ShowShareTransfer" +share_transfer_accept = "manilaclient.osc.v2.share_transfers:AcceptShareTransfer" +share_lock_create = "manilaclient.osc.v2.resource_locks:CreateResourceLock" +share_lock_list = "manilaclient.osc.v2.resource_locks:ListResourceLock" +share_lock_show = "manilaclient.osc.v2.resource_locks:ShowResourceLock" +share_lock_set = " manilaclient.osc.v2.resource_locks:SetResourceLock" +share_lock_unset = "manilaclient.osc.v2.resource_locks:UnsetResourceLock" +share_lock_delete = "manilaclient.osc.v2.resource_locks:DeleteResourceLock" + +[tool.setuptools] +packages = [ + "manilaclient" +] + +[tool.coverage.run] +omit = [ + "manilaclient/tests/*", +] +branch = true diff --git a/setup.cfg b/setup.cfg index e9734f93..3ad97f23 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,189 +1,2 @@ [metadata] name = python-manilaclient -summary = Client library for OpenStack Manila API. -description_file = - README.rst -author = OpenStack -author_email = openstack-discuss@lists.openstack.org -home_page = https://docs.openstack.org/python-manilaclient/latest/ -python_requires = >=3.10 -classifier = - Development Status :: 5 - Production/Stable - Environment :: Console - Environment :: OpenStack - Intended Audience :: Developers - Intended Audience :: Information Technology - License :: OSI Approved :: Apache Software License - Operating System :: OS Independent - Programming Language :: Python - Programming Language :: Python :: 3 :: Only - Programming Language :: Python :: 3 - Programming Language :: Python :: 3.10 - Programming Language :: Python :: 3.11 - Programming Language :: Python :: 3.12 - -[files] -packages = - manilaclient - -[entry_points] -console_scripts = - manila = manilaclient.shell:main -oslo.config.opts = - manilaclient.config = manilaclient.config:list_opts - -openstack.cli.extension = - share = manilaclient.osc.plugin - -openstack.share.v2 = - share_list = manilaclient.osc.v2.share:ListShare - share_create = manilaclient.osc.v2.share:CreateShare - share_delete = manilaclient.osc.v2.share:DeleteShare - share_show = manilaclient.osc.v2.share:ShowShare - share_set = manilaclient.osc.v2.share:SetShare - share_unset = manilaclient.osc.v2.share:UnsetShare - share_resize = manilaclient.osc.v2.share:ResizeShare - share_adopt = manilaclient.osc.v2.share:AdoptShare - share_abandon = manilaclient.osc.v2.share:AbandonShare - share_migration_start = manilaclient.osc.v2.share:ShareMigrationStart - share_migration_cancel = manilaclient.osc.v2.share:ShareMigrationCancel - share_migration_complete = manilaclient.osc.v2.share:ShareMigrationComplete - share_migration_show = manilaclient.osc.v2.share:ShareMigrationShow - share_export_location_show = manilaclient.osc.v2.share:ShareExportLocationShow - share_export_location_list = manilaclient.osc.v2.share:ShareExportLocationList - share_export_location_set = manilaclient.osc.v2.share:ShareExportLocationSet - share_export_location_unset = manilaclient.osc.v2.share:ShareExportLocationUnset - share_properties_show = manilaclient.osc.v2.share:ShowShareProperties - share_restore = manilaclient.osc.v2.share:RestoreShare - share_revert = manilaclient.osc.v2.share:RevertShare - share_access_create = manilaclient.osc.v2.share_access_rules:ShareAccessAllow - share_access_delete = manilaclient.osc.v2.share_access_rules:ShareAccessDeny - share_access_list = manilaclient.osc.v2.share_access_rules:ListShareAccess - share_access_show = manilaclient.osc.v2.share_access_rules:ShowShareAccess - share_access_set = manilaclient.osc.v2.share_access_rules:SetShareAccess - share_access_unset = manilaclient.osc.v2.share_access_rules:UnsetShareAccess - share_backup_create = manilaclient.osc.v2.share_backups:CreateShareBackup - share_backup_delete = manilaclient.osc.v2.share_backups:DeleteShareBackup - share_backup_list = manilaclient.osc.v2.share_backups:ListShareBackup - share_backup_show = manilaclient.osc.v2.share_backups:ShowShareBackup - share_backup_restore = manilaclient.osc.v2.share_backups:RestoreShareBackup - share_backup_set = manilaclient.osc.v2.share_backups:SetShareBackup - share_backup_unset = manilaclient.osc.v2.share_backups:UnsetShareBackup - share_type_create = manilaclient.osc.v2.share_types:CreateShareType - share_type_delete = manilaclient.osc.v2.share_types:DeleteShareType - share_type_set = manilaclient.osc.v2.share_types:SetShareType - share_type_unset = manilaclient.osc.v2.share_types:UnsetShareType - share_type_list = manilaclient.osc.v2.share_types:ListShareType - share_type_show = manilaclient.osc.v2.share_types:ShowShareType - share_type_access_create = manilaclient.osc.v2.share_type_access:ShareTypeAccessAllow - share_type_access_list = manilaclient.osc.v2.share_type_access:ListShareTypeAccess - share_type_access_delete = manilaclient.osc.v2.share_type_access:ShareTypeAccessDeny - share_quota_set = manilaclient.osc.v2.quotas:QuotaSet - share_quota_show = manilaclient.osc.v2.quotas:QuotaShow - share_quota_delete = manilaclient.osc.v2.quotas:QuotaDelete - share_snapshot_create = manilaclient.osc.v2.share_snapshots:CreateShareSnapshot - share_snapshot_delete = manilaclient.osc.v2.share_snapshots:DeleteShareSnapshot - share_snapshot_show = manilaclient.osc.v2.share_snapshots:ShowShareSnapshot - share_snapshot_set = manilaclient.osc.v2.share_snapshots:SetShareSnapshot - share_snapshot_unset = manilaclient.osc.v2.share_snapshots:UnsetShareSnapshot - share_snapshot_list = manilaclient.osc.v2.share_snapshots:ListShareSnapshot - share_snapshot_adopt = manilaclient.osc.v2.share_snapshots:AdoptShareSnapshot - share_snapshot_abandon = manilaclient.osc.v2.share_snapshots:AbandonShareSnapshot - share_snapshot_access_create = manilaclient.osc.v2.share_snapshots:ShareSnapshotAccessAllow - share_snapshot_access_delete = manilaclient.osc.v2.share_snapshots:ShareSnapshotAccessDeny - share_snapshot_access_list = manilaclient.osc.v2.share_snapshots:ShareSnapshotAccessList - share_snapshot_export_location_list = manilaclient.osc.v2.share_snapshots:ShareSnapshotListExportLocation - share_snapshot_export_location_show = manilaclient.osc.v2.share_snapshots:ShareSnapshotShowExportLocation - share_snapshot_instance_list = manilaclient.osc.v2.share_snapshot_instances:ListShareSnapshotInstance - share_snapshot_instance_show = manilaclient.osc.v2.share_snapshot_instances:ShowShareSnapshotInstance - share_snapshot_instance_set = manilaclient.osc.v2.share_snapshot_instances:SetShareSnapshotInstance - share_snapshot_instance_export_location_list = manilaclient.osc.v2.share_snapshot_instance_export_locations:ShareSnapshotInstanceExportLocationList - share_snapshot_instance_export_location_show = manilaclient.osc.v2.share_snapshot_instance_export_locations:ShareSnapshotInstanceExportLocationShow - share_message_delete = manilaclient.osc.v2.messages:DeleteMessage - share_message_list = manilaclient.osc.v2.messages:ListMessage - share_message_show = manilaclient.osc.v2.messages:ShowMessage - share_replica_create = manilaclient.osc.v2.share_replicas:CreateShareReplica - share_replica_delete = manilaclient.osc.v2.share_replicas:DeleteShareReplica - share_replica_list = manilaclient.osc.v2.share_replicas:ListShareReplica - share_replica_show = manilaclient.osc.v2.share_replicas:ShowShareReplica - share_replica_set = manilaclient.osc.v2.share_replicas:SetShareReplica - share_replica_promote = manilaclient.osc.v2.share_replicas:PromoteShareReplica - share_replica_resync = manilaclient.osc.v2.share_replicas:ResyncShareReplica - share_replica_export_location_list = manilaclient.osc.v2.share_replica_export_locations:ShareReplicaListExportLocation - share_replica_export_location_show = manilaclient.osc.v2.share_replica_export_locations:ShareReplicaShowExportLocation - share_availability_zone_list = manilaclient.osc.v2.availability_zones:ShareAvailabilityZoneList - share_service_set = manilaclient.osc.v2.services:SetShareService - share_service_list = manilaclient.osc.v2.services:ListShareService - share_service_ensure_shares = manilaclient.osc.v2.services:EnsureShareService - share_security_service_create = manilaclient.osc.v2.security_services:CreateShareSecurityService - share_security_service_delete = manilaclient.osc.v2.security_services:DeleteShareSecurityService - share_security_service_show = manilaclient.osc.v2.security_services:ShowShareSecurityService - share_security_service_set = manilaclient.osc.v2.security_services:SetShareSecurityService - share_security_service_unset = manilaclient.osc.v2.security_services:UnsetShareSecurityService - share_security_service_list = manilaclient.osc.v2.security_services:ListShareSecurityService - share_pool_list = manilaclient.osc.v2.share_pools:ListSharePools - share_instance_delete = manilaclient.osc.v2.share_instances:ShareInstanceDelete - share_instance_list = manilaclient.osc.v2.share_instances:ShareInstanceList - share_instance_set = manilaclient.osc.v2.share_instances:ShareInstanceSet - share_instance_show = manilaclient.osc.v2.share_instances:ShareInstanceShow - share_instance_export_location_show = manilaclient.osc.v2.share_instance_export_locations:ShareInstanceShowExportLocation - share_instance_export_location_list = manilaclient.osc.v2.share_instance_export_locations:ShareInstanceListExportLocation - share_limits_show = manilaclient.osc.v2.share_limits:ShareLimitsShow - share_network_list = manilaclient.osc.v2.share_networks:ListShareNetwork - share_network_show = manilaclient.osc.v2.share_networks:ShowShareNetwork - share_network_create = manilaclient.osc.v2.share_networks:CreateShareNetwork - share_network_delete = manilaclient.osc.v2.share_networks:DeleteShareNetwork - share_network_set = manilaclient.osc.v2.share_networks:SetShareNetwork - share_network_unset = manilaclient.osc.v2.share_networks:UnsetShareNetwork - share_network_subnet_create = manilaclient.osc.v2.share_network_subnets:CreateShareNetworkSubnet - share_network_subnet_delete = manilaclient.osc.v2.share_network_subnets:DeleteShareNetworkSubnet - share_network_subnet_show = manilaclient.osc.v2.share_network_subnets:ShowShareNetworkSubnet - share_network_subnet_set = manilaclient.osc.v2.share_network_subnets:SetShareNetworkSubnet - share_network_subnet_unset = manilaclient.osc.v2.share_network_subnets:UnsetShareNetworkSubnet - share_group_create = manilaclient.osc.v2.share_groups:CreateShareGroup - share_group_delete = manilaclient.osc.v2.share_groups:DeleteShareGroup - share_group_list = manilaclient.osc.v2.share_groups:ListShareGroup - share_group_show = manilaclient.osc.v2.share_groups:ShowShareGroup - share_group_set = manilaclient.osc.v2.share_groups:SetShareGroup - share_group_unset = manilaclient.osc.v2.share_groups:UnsetShareGroup - share_group_type_create = manilaclient.osc.v2.share_group_types:CreateShareGroupType - share_group_type_delete = manilaclient.osc.v2.share_group_types:DeleteShareGroupType - share_group_type_list = manilaclient.osc.v2.share_group_types:ListShareGroupType - share_group_type_show = manilaclient.osc.v2.share_group_types:ShowShareGroupType - share_group_type_set = manilaclient.osc.v2.share_group_types:SetShareGroupType - share_group_type_unset = manilaclient.osc.v2.share_group_types:UnsetShareGroupType - share_group_type_access_create = manilaclient.osc.v2.share_group_type_access:ShareGroupTypeAccessAllow - share_group_type_access_list = manilaclient.osc.v2.share_group_type_access:ListShareGroupTypeAccess - share_group_type_access_delete = manilaclient.osc.v2.share_group_type_access:ShareGroupTypeAccessDeny - share_group_snapshot_create = manilaclient.osc.v2.share_group_snapshots:CreateShareGroupSnapshot - share_group_snapshot_delete = manilaclient.osc.v2.share_group_snapshots:DeleteShareGroupSnapshot - share_group_snapshot_show= manilaclient.osc.v2.share_group_snapshots:ShowShareGroupSnapshot - share_group_snapshot_list = manilaclient.osc.v2.share_group_snapshots:ListShareGroupSnapshot - share_group_snapshot_set = manilaclient.osc.v2.share_group_snapshots:SetShareGroupSnapshot - share_group_snapshot_unset = manilaclient.osc.v2.share_group_snapshots:UnsetShareGroupSnapshot - share_group_snapshot_members_list = manilaclient.osc.v2.share_group_snapshots:ListShareGroupSnapshotMembers - share_server_delete = manilaclient.osc.v2.share_servers:DeleteShareServer - share_server_show = manilaclient.osc.v2.share_servers:ShowShareServer - share_server_list = manilaclient.osc.v2.share_servers:ListShareServer - share_server_adopt = manilaclient.osc.v2.share_servers:AdoptShareServer - share_server_abandon = manilaclient.osc.v2.share_servers:AbandonShareServer - share_server_set = manilaclient.osc.v2.share_servers:SetShareServer - share_server_migration_cancel = manilaclient.osc.v2.share_servers:ShareServerMigrationCancel - share_server_migration_complete = manilaclient.osc.v2.share_servers:ShareServerMigrationComplete - share_server_migration_show = manilaclient.osc.v2.share_servers:ShareServerMigrationShow - share_server_migration_start = manilaclient.osc.v2.share_servers:ShareServerMigrationStart - share_transfer_create = manilaclient.osc.v2.share_transfers:CreateShareTransfer - share_transfer_delete = manilaclient.osc.v2.share_transfers:DeleteShareTransfer - share_transfer_list = manilaclient.osc.v2.share_transfers:ListShareTransfer - share_transfer_show = manilaclient.osc.v2.share_transfers:ShowShareTransfer - share_transfer_accept = manilaclient.osc.v2.share_transfers:AcceptShareTransfer - share_lock_create = manilaclient.osc.v2.resource_locks:CreateResourceLock - share_lock_list = manilaclient.osc.v2.resource_locks:ListResourceLock - share_lock_show = manilaclient.osc.v2.resource_locks:ShowResourceLock - share_lock_set = manilaclient.osc.v2.resource_locks:SetResourceLock - share_lock_unset = manilaclient.osc.v2.resource_locks:UnsetResourceLock - share_lock_delete = manilaclient.osc.v2.resource_locks:DeleteResourceLock - -[coverage:run] -omit = manilaclient/tests/* -branch = true From b255a5c28d8abdad3556bf631d7d8e79c3c3fea6 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Fri, 10 Oct 2025 10:50:50 +0100 Subject: [PATCH 17/52] pre-commit: Bump versions Change-Id: If0980b7a181fee04c832f6568cba00cba0626958 Signed-off-by: Stephen Finucane --- .pre-commit-config.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 70f5408d..ccb477b7 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,13 +1,13 @@ --- repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.6.0 + rev: v6.0.0 hooks: - id: trailing-whitespace - id: mixed-line-ending args: ['--fix', 'lf'] exclude: '.*\.(svg)$' - - id: check-byte-order-marker + - id: fix-byte-order-marker - id: check-executables-have-shebangs - id: check-merge-conflict - id: debug-statements @@ -15,7 +15,7 @@ repos: files: .*\.(yaml|yml)$ exclude: '^(zuul.d|rally-jobs)/.*$' - repo: https://github.com/PyCQA/doc8 - rev: v1.1.1 + rev: v2.0.0 hooks: - id: doc8 args: ['--ignore', 'D001'] @@ -25,7 +25,7 @@ repos: - id: bashate args: ['--ignore', 'E006,E042,E043'] - repo: https://opendev.org/openstack/hacking - rev: 6.1.0 + rev: 7.0.0 hooks: - id: hacking additional_dependencies: [] From 0ef57c0f49b9c0a6be358a87fff67869c0dc95b4 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Fri, 10 Oct 2025 10:51:18 +0100 Subject: [PATCH 18/52] Add ruff This is mostly auto-generated, save for having to manually move some 'noqa' lines and move some printf arguments outside of localized string calls. Change-Id: I48cd5ead0953d7d9b03535172a60f4727e95e935 Signed-off-by: Stephen Finucane --- .pre-commit-config.yaml | 18 +- doc/source/conf.py | 19 +- manilaclient/__init__.py | 3 +- manilaclient/api_versions.py | 210 +- manilaclient/base.py | 119 +- manilaclient/client.py | 12 +- manilaclient/common/apiclient/exceptions.py | 81 +- manilaclient/common/apiclient/utils.py | 23 +- manilaclient/common/cliutils.py | 36 +- manilaclient/common/constants.py | 48 +- manilaclient/common/httpclient.py | 72 +- manilaclient/config.py | 415 +- manilaclient/exceptions.py | 4 + manilaclient/extension.py | 2 +- manilaclient/osc/plugin.py | 74 +- manilaclient/osc/utils.py | 43 +- manilaclient/osc/v2/availability_zones.py | 12 +- manilaclient/osc/v2/messages.py | 112 +- manilaclient/osc/v2/quotas.py | 291 +- manilaclient/osc/v2/resource_locks.py | 195 +- manilaclient/osc/v2/security_services.py | 316 +- manilaclient/osc/v2/services.py | 82 +- manilaclient/osc/v2/share.py | 960 +++-- manilaclient/osc/v2/share_access_rules.py | 302 +- manilaclient/osc/v2/share_backups.py | 254 +- manilaclient/osc/v2/share_group_snapshots.py | 200 +- .../osc/v2/share_group_type_access.py | 106 +- manilaclient/osc/v2/share_group_types.py | 185 +- manilaclient/osc/v2/share_groups.py | 271 +- .../osc/v2/share_instance_export_locations.py | 33 +- manilaclient/osc/v2/share_instances.py | 104 +- manilaclient/osc/v2/share_limits.py | 12 +- manilaclient/osc/v2/share_network_subnets.py | 243 +- manilaclient/osc/v2/share_networks.py | 476 ++- manilaclient/osc/v2/share_pools.py | 64 +- .../osc/v2/share_replica_export_locations.py | 36 +- manilaclient/osc/v2/share_replicas.py | 269 +- manilaclient/osc/v2/share_servers.py | 387 +- ...hare_snapshot_instance_export_locations.py | 37 +- .../osc/v2/share_snapshot_instances.py | 91 +- manilaclient/osc/v2/share_snapshots.py | 548 +-- manilaclient/osc/v2/share_transfers.py | 167 +- manilaclient/osc/v2/share_type_access.py | 45 +- manilaclient/osc/v2/share_types.py | 268 +- manilaclient/shell.py | 738 ++-- manilaclient/tests/functional/base.py | 309 +- manilaclient/tests/functional/client.py | 1421 +++--- manilaclient/tests/functional/exceptions.py | 13 +- manilaclient/tests/functional/osc/base.py | 333 +- .../functional/osc/test_availability_zones.py | 8 +- .../tests/functional/osc/test_messages.py | 98 +- .../functional/osc/test_resource_locks.py | 166 +- .../functional/osc/test_share_access_rules.py | 156 +- .../functional/osc/test_share_backups.py | 118 +- .../osc/test_share_group_type_access.py | 46 +- .../tests/functional/osc/test_share_limits.py | 36 +- .../osc/test_share_network_subnets.py | 7 +- .../functional/osc/test_share_networks.py | 79 +- .../tests/functional/osc/test_share_pools.py | 26 +- .../test_share_replica_export_locations.py | 45 +- .../functional/osc/test_share_replicas.py | 41 +- .../functional/osc/test_share_services.py | 48 +- .../osc/test_share_snapshot_instances.py | 81 +- .../functional/osc/test_share_snapshots.py | 158 +- .../functional/osc/test_share_transfers.py | 70 +- .../tests/functional/osc/test_share_types.py | 99 +- .../tests/functional/osc/test_shares.py | 106 +- .../functional/osc/test_shares_group_type.py | 113 +- .../functional/test_availability_zones.py | 4 +- manilaclient/tests/functional/test_common.py | 22 +- .../tests/functional/test_export_locations.py | 57 +- manilaclient/tests/functional/test_limits.py | 1 - .../tests/functional/test_messages.py | 24 +- manilaclient/tests/functional/test_quotas.py | 199 +- .../tests/functional/test_scheduler_stats.py | 16 +- .../functional/test_security_services.py | 3 +- .../tests/functional/test_services.py | 1 - .../tests/functional/test_share_access.py | 207 +- .../functional/test_share_network_subnets.py | 44 +- .../tests/functional/test_share_networks.py | 354 +- .../test_share_replica_export_locations.py | 58 +- .../tests/functional/test_share_replicas.py | 10 +- .../tests/functional/test_share_servers.py | 163 +- .../tests/functional/test_share_transfers.py | 21 +- .../tests/functional/test_share_types.py | 373 +- manilaclient/tests/functional/test_shares.py | 147 +- .../tests/functional/test_shares_listing.py | 166 +- .../tests/functional/test_shares_metadata.py | 34 +- .../tests/functional/test_snapshot_access.py | 163 +- .../functional/test_snapshot_instances.py | 79 +- ...est_snapshot_instances_export_locations.py | 64 +- .../test_snapshots_export_locations.py | 40 +- manilaclient/tests/functional/utils.py | 75 +- .../tests/unit/common/test_httpclient.py | 126 +- manilaclient/tests/unit/fakes.py | 31 +- manilaclient/tests/unit/osc/osc_fakes.py | 44 +- manilaclient/tests/unit/osc/osc_utils.py | 17 +- manilaclient/tests/unit/osc/v2/fakes.py | 372 +- .../unit/osc/v2/test_availability_zones.py | 18 +- .../tests/unit/osc/v2/test_messages.py | 116 +- manilaclient/tests/unit/osc/v2/test_quotas.py | 259 +- .../tests/unit/osc/v2/test_resource_locks.py | 162 +- .../unit/osc/v2/test_security_services.py | 337 +- .../tests/unit/osc/v2/test_services.py | 146 +- manilaclient/tests/unit/osc/v2/test_share.py | 1123 +++-- .../unit/osc/v2/test_share_access_rules.py | 259 +- .../tests/unit/osc/v2/test_share_backups.py | 283 +- .../unit/osc/v2/test_share_group_snapshots.py | 381 +- .../unit/osc/v2/test_share_group_type.py | 275 +- .../osc/v2/test_share_group_type_access.py | 79 +- .../tests/unit/osc/v2/test_share_groups.py | 425 +- .../test_share_instance_export_locations.py | 82 +- .../tests/unit/osc/v2/test_share_instances.py | 204 +- .../tests/unit/osc/v2/test_share_limits.py | 36 +- .../unit/osc/v2/test_share_network_subnets.py | 316 +- .../tests/unit/osc/v2/test_share_networks.py | 562 +-- .../tests/unit/osc/v2/test_share_pools.py | 74 +- .../v2/test_share_replica_export_locations.py | 73 +- .../tests/unit/osc/v2/test_share_replicas.py | 425 +- .../tests/unit/osc/v2/test_share_servers.py | 497 +-- ...hare_snapshot_instance_export_locations.py | 126 +- .../osc/v2/test_share_snapshot_instances.py | 167 +- .../tests/unit/osc/v2/test_share_snapshots.py | 762 ++-- .../tests/unit/osc/v2/test_share_transfers.py | 170 +- .../tests/unit/osc/v2/test_share_type.py | 322 +- .../unit/osc/v2/test_share_type_access.py | 86 +- manilaclient/tests/unit/test_api_versions.py | 161 +- manilaclient/tests/unit/test_base.py | 10 +- manilaclient/tests/unit/test_client.py | 44 +- .../tests/unit/test_functional_utils.py | 177 +- manilaclient/tests/unit/test_shell.py | 287 +- manilaclient/tests/unit/utils.py | 22 +- manilaclient/tests/unit/v1/test_limits.py | 9 +- .../tests/unit/v1/test_quota_classes.py | 9 +- manilaclient/tests/unit/v1/test_quotas.py | 9 +- .../tests/unit/v1/test_scheduler_stats.py | 9 +- .../tests/unit/v1/test_security_services.py | 9 +- manilaclient/tests/unit/v1/test_services.py | 9 +- .../tests/unit/v1/test_share_networks.py | 9 +- .../tests/unit/v1/test_share_servers.py | 9 +- .../tests/unit/v1/test_share_snapshots.py | 9 +- .../tests/unit/v1/test_share_type_access.py | 9 +- .../tests/unit/v1/test_share_types.py | 9 +- manilaclient/tests/unit/v1/test_shares.py | 9 +- manilaclient/tests/unit/v2/fake_clients.py | 60 +- manilaclient/tests/unit/v2/fakes.py | 584 ++- .../tests/unit/v2/test_availability_zones.py | 12 +- manilaclient/tests/unit/v2/test_client.py | 172 +- manilaclient/tests/unit/v2/test_limits.py | 100 +- manilaclient/tests/unit/v2/test_messages.py | 70 +- .../tests/unit/v2/test_quota_classes.py | 35 +- manilaclient/tests/unit/v2/test_quotas.py | 188 +- .../tests/unit/v2/test_scheduler_stats.py | 25 +- .../tests/unit/v2/test_security_services.py | 118 +- manilaclient/tests/unit/v2/test_services.py | 24 +- .../tests/unit/v2/test_share_backups.py | 39 +- .../unit/v2/test_share_export_locations.py | 15 +- .../unit/v2/test_share_group_snapshots.py | 146 +- .../unit/v2/test_share_group_type_access.py | 51 +- .../tests/unit/v2/test_share_group_types.py | 105 +- .../tests/unit/v2/test_share_groups.py | 114 +- .../test_share_instance_export_locations.py | 23 +- .../tests/unit/v2/test_share_instances.py | 47 +- .../unit/v2/test_share_network_subnets.py | 32 +- .../tests/unit/v2/test_share_networks.py | 160 +- .../v2/test_share_replica_export_locations.py | 12 +- .../tests/unit/v2/test_share_replicas.py | 51 +- .../tests/unit/v2/test_share_servers.py | 185 +- .../test_share_snapshot_export_locations.py | 14 +- ...hare_snapshot_instance_export_locations.py | 25 +- .../unit/v2/test_share_snapshot_instances.py | 24 +- .../tests/unit/v2/test_share_snapshots.py | 119 +- .../tests/unit/v2/test_share_transfers.py | 18 +- manilaclient/tests/unit/v2/test_shares.py | 669 ++- manilaclient/tests/unit/v2/test_shell.py | 3211 ++++++++------ .../tests/unit/v2/test_type_access.py | 33 +- manilaclient/tests/unit/v2/test_types.py | 320 +- manilaclient/utils.py | 5 +- manilaclient/v1/__init__.py | 2 +- manilaclient/v1/client.py | 123 +- manilaclient/v1/contrib/list_extensions.py | 8 +- manilaclient/v1/limits.py | 12 +- manilaclient/v1/quota_classes.py | 12 +- manilaclient/v1/quotas.py | 12 +- manilaclient/v1/scheduler_stats.py | 12 +- manilaclient/v1/security_services.py | 17 +- manilaclient/v1/services.py | 12 +- manilaclient/v1/share_networks.py | 12 +- manilaclient/v1/share_servers.py | 12 +- manilaclient/v1/share_snapshots.py | 12 +- manilaclient/v1/share_type_access.py | 17 +- manilaclient/v1/share_types.py | 12 +- manilaclient/v1/shares.py | 12 +- manilaclient/v2/__init__.py | 2 +- manilaclient/v2/availability_zones.py | 4 +- manilaclient/v2/client.py | 162 +- manilaclient/v2/limits.py | 45 +- manilaclient/v2/messages.py | 17 +- manilaclient/v2/quota_classes.py | 177 +- manilaclient/v2/quotas.py | 331 +- manilaclient/v2/resource_locks.py | 39 +- manilaclient/v2/scheduler_stats.py | 14 +- manilaclient/v2/security_services.py | 173 +- manilaclient/v2/services.py | 24 +- manilaclient/v2/share_access_rules.py | 10 +- manilaclient/v2/share_backups.py | 32 +- manilaclient/v2/share_export_locations.py | 30 +- manilaclient/v2/share_group_snapshots.py | 76 +- manilaclient/v2/share_group_type_access.py | 18 +- manilaclient/v2/share_group_types.py | 37 +- manilaclient/v2/share_groups.py | 118 +- .../v2/share_instance_export_locations.py | 20 +- manilaclient/v2/share_instances.py | 10 +- manilaclient/v2/share_network_subnets.py | 90 +- manilaclient/v2/share_networks.py | 123 +- .../v2/share_replica_export_locations.py | 31 +- manilaclient/v2/share_replicas.py | 51 +- manilaclient/v2/share_servers.py | 121 +- .../v2/share_snapshot_export_locations.py | 18 +- ...hare_snapshot_instance_export_locations.py | 18 +- manilaclient/v2/share_snapshot_instances.py | 13 +- manilaclient/v2/share_snapshots.py | 92 +- manilaclient/v2/share_transfers.py | 42 +- manilaclient/v2/share_type_access.py | 11 +- manilaclient/v2/share_types.py | 160 +- manilaclient/v2/shares.py | 489 ++- manilaclient/v2/shell.py | 3800 ++++++++++------- pyproject.toml | 19 + releasenotes/source/conf.py | 36 +- setup.py | 4 +- tox.ini | 33 +- 231 files changed, 21133 insertions(+), 15499 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ccb477b7..935d4fff 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,6 +14,18 @@ repos: - id: check-yaml files: .*\.(yaml|yml)$ exclude: '^(zuul.d|rally-jobs)/.*$' + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.14.0 + hooks: + - id: ruff-check + args: ['--fix', '--unsafe-fixes'] + - id: ruff-format + - repo: https://opendev.org/openstack/hacking + rev: 7.0.0 + hooks: + - id: hacking + additional_dependencies: [] + exclude: '^(doc|releasenotes|tools)/.*$' - repo: https://github.com/PyCQA/doc8 rev: v2.0.0 hooks: @@ -24,9 +36,3 @@ repos: hooks: - id: bashate args: ['--ignore', 'E006,E042,E043'] - - repo: https://opendev.org/openstack/hacking - rev: 7.0.0 - hooks: - - id: hacking - additional_dependencies: [] - exclude: '^(doc|releasenotes|tools)/.*$' diff --git a/doc/source/conf.py b/doc/source/conf.py index 52b03f1c..198d7d5a 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -29,10 +29,12 @@ # Add any Sphinx extension module names here, as strings. They can be # extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['sphinx.ext.autodoc', - 'openstackdocstheme', - 'sphinxcontrib.programoutput', - 'cliff.sphinxext'] +extensions = [ + 'sphinx.ext.autodoc', + 'openstackdocstheme', + 'sphinxcontrib.programoutput', + 'cliff.sphinxext', +] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -87,8 +89,13 @@ # (source start file, target name, title, author, documentclass # [howto/manual]). latex_documents = [ - ('index', 'Manila-client.tex', 'Manila Python Client Documentation', - 'Manila contributors', 'manual'), + ( + 'index', + 'Manila-client.tex', + 'Manila Python Client Documentation', + 'Manila contributors', + 'manual', + ), ] # The name of an image file (relative to this directory) to place at the top of diff --git a/manilaclient/__init__.py b/manilaclient/__init__.py index c4d5a667..404b965b 100644 --- a/manilaclient/__init__.py +++ b/manilaclient/__init__.py @@ -32,4 +32,5 @@ API_MAX_VERSION = api_versions.APIVersion(api_versions.MAX_VERSION) API_MIN_VERSION = api_versions.APIVersion(api_versions.MIN_VERSION) API_DEPRECATED_VERSION = api_versions.APIVersion( - api_versions.DEPRECATED_VERSION) + api_versions.DEPRECATED_VERSION +) diff --git a/manilaclient/api_versions.py b/manilaclient/api_versions.py index af613fb5..19f34544 100644 --- a/manilaclient/api_versions.py +++ b/manilaclient/api_versions.py @@ -33,7 +33,7 @@ _VERSIONED_METHOD_MAP = {} -class APIVersion(object): +class APIVersion: """Top level object to support Manila API Versioning. This class represents an API Version with convenience @@ -54,44 +54,57 @@ def __init__(self, version_str=None): self.ver_major = int(match.group(1)) self.ver_minor = int(match.group(2)) else: - msg = _("Invalid format of client version '%s'. " + msg = ( + _( + "Invalid format of client version '%s'. " "Expected format 'X.Y', where X is a major part and Y " - "is a minor part of version.") % version_str + "is a minor part of version." + ) + % version_str + ) raise exceptions.UnsupportedVersion(msg) def __str__(self): """Debug/Logging representation of object.""" - return ("API Version Major: %s, Minor: %s" - % (self.ver_major, self.ver_minor)) + return f"API Version Major: {self.ver_major}, Minor: {self.ver_minor}" def __repr__(self): if self.is_null(): return "" else: - return "" % self.get_string() + return f"" def __lt__(self, other): if not isinstance(other, APIVersion): - raise TypeError(self.TYPE_ERROR_MSG % {"other": other, - "cls": self.__class__}) + raise TypeError( + self.TYPE_ERROR_MSG % {"other": other, "cls": self.__class__} + ) - return ((self.ver_major, self.ver_minor) < - (other.ver_major, other.ver_minor)) + return (self.ver_major, self.ver_minor) < ( + other.ver_major, + other.ver_minor, + ) def __eq__(self, other): if not isinstance(other, APIVersion): - raise TypeError(self.TYPE_ERROR_MSG % {"other": other, - "cls": self.__class__}) + raise TypeError( + self.TYPE_ERROR_MSG % {"other": other, "cls": self.__class__} + ) - return ((self.ver_major, self.ver_minor) == - (other.ver_major, other.ver_minor)) + return (self.ver_major, self.ver_minor) == ( + other.ver_major, + other.ver_minor, + ) def __gt__(self, other): if not isinstance(other, APIVersion): - raise TypeError(self.TYPE_ERROR_MSG % {"other": other, - "cls": self.__class__}) - return ((self.ver_major, self.ver_minor) > - (other.ver_major, other.ver_minor)) + raise TypeError( + self.TYPE_ERROR_MSG % {"other": other, "cls": self.__class__} + ) + return (self.ver_major, self.ver_minor) > ( + other.ver_major, + other.ver_minor, + ) def __le__(self, other): return self < other or self == other @@ -139,15 +152,15 @@ def get_string(self): """String representation of an APIVersion object.""" if self.is_null(): raise ValueError( - _("Null APIVersion cannot be converted to string.")) - return "%s.%s" % (self.ver_major, self.ver_minor) + _("Null APIVersion cannot be converted to string.") + ) + return f"{self.ver_major}.{self.ver_minor}" def get_major_version(self): - return "%s" % self.ver_major + return f"{self.ver_major}" -class VersionedMethod(object): - +class VersionedMethod: def __init__(self, name, start_version, end_version, func): """Versioning information for a single method @@ -164,11 +177,10 @@ def __init__(self, name, start_version, end_version, func): self.func = func def __str__(self): - return ("Version Method %s: min: %s, max: %s" - % (self.name, self.start_version, self.end_version)) + return f"Version Method {self.name}: min: {self.start_version}, max: {self.end_version}" def __repr__(self): - return "" % self.name + return f"" def check_version_supported(api_version): @@ -176,23 +188,27 @@ def check_version_supported(api_version): :warn Sends warning if version is not supported. """ - if (check_version_matches_min_max(api_version) or - check_version_deprecated(api_version)): + if check_version_matches_min_max(api_version) or check_version_deprecated( + api_version + ): return True return False def check_version_matches_min_max(api_version): """Returns True if the API version is within the supported range.""" - if (not api_version.matches( - manilaclient.API_MIN_VERSION, - manilaclient.API_MAX_VERSION)): - msg = _("Invalid client version '%(version)s'. " - "Current version range is '%(min)s' through " - " '%(max)s'") % { + if not api_version.matches( + manilaclient.API_MIN_VERSION, manilaclient.API_MAX_VERSION + ): + msg = _( + "Invalid client version '%(version)s'. " + "Current version range is '%(min)s' through " + " '%(max)s'" + ) % { "version": api_version.get_string(), "min": manilaclient.API_MIN_VERSION.get_string(), - "max": manilaclient.API_MAX_VERSION.get_string()} + "max": manilaclient.API_MAX_VERSION.get_string(), + } warnings.warn(msg) return False return True @@ -202,7 +218,8 @@ def check_version_deprecated(api_version): """Returns True if API version is deprecated.""" if api_version == manilaclient.API_DEPRECATED_VERSION: msg = _("Client version '%(version)s' is deprecated.") % { - "version": api_version.get_string()} + "version": api_version.get_string() + } warnings.warn(msg) return True return False @@ -249,27 +266,29 @@ def discover_version(client, requested_version): :returns: APIVersion """ server_start_version, server_end_version = _get_server_version_range( - client) + client + ) valid_version = requested_version if server_start_version.is_null() and server_end_version.is_null(): - msg = ("Server does not support microversions. Changing server " - "version to %(min_version)s.") + msg = ( + "Server does not support microversions. Changing server " + "version to %(min_version)s." + ) LOG.debug(msg, {"min_version": DEPRECATED_VERSION}) valid_version = APIVersion(DEPRECATED_VERSION) else: valid_version = _validate_requested_version( - requested_version, - server_start_version, - server_end_version) + requested_version, server_start_version, server_end_version + ) _validate_server_version(server_start_version, server_end_version) return valid_version -def _validate_requested_version(requested_version, - server_start_version, - server_end_version): +def _validate_requested_version( + requested_version, server_start_version, server_end_version +): """Validates the requested version. Checks 'requested_version' is within the min/max range supported by the @@ -284,21 +303,34 @@ def _validate_requested_version(requested_version, valid_version = requested_version if not requested_version.matches(server_start_version, server_end_version): if server_end_version <= requested_version: - if (manilaclient.API_MIN_VERSION <= server_end_version and - server_end_version <= manilaclient.API_MAX_VERSION): - msg = _("Requested version %(requested_version)s is " - "not supported. Downgrading requested version " - "to %(server_end_version)s.") - LOG.debug(msg, { - "requested_version": requested_version, - "server_end_version": server_end_version}) + if ( + manilaclient.API_MIN_VERSION <= server_end_version + and server_end_version <= manilaclient.API_MAX_VERSION + ): + msg = _( + "Requested version %(requested_version)s is " + "not supported. Downgrading requested version " + "to %(server_end_version)s." + ) + LOG.debug( + msg, + { + "requested_version": requested_version, + "server_end_version": server_end_version, + }, + ) valid_version = server_end_version else: raise exceptions.UnsupportedVersion( - _("The specified version isn't supported by server. The valid " - "version range is '%(min)s' to '%(max)s'") % { + _( + "The specified version isn't supported by server. The valid " + "version range is '%(min)s' to '%(max)s'" + ) + % { "min": server_start_version.get_string(), - "max": server_end_version.get_string()}) + "max": server_end_version.get_string(), + } + ) return valid_version @@ -316,22 +348,32 @@ def _validate_server_version(server_start_version, server_end_version): """ if manilaclient.API_MIN_VERSION > server_end_version: raise exceptions.UnsupportedVersion( - _("Server's version is too old. The client's valid version range " - "is '%(client_min)s' to '%(client_max)s'. The server valid " - "version range is '%(server_min)s' to '%(server_max)s'.") % { - 'client_min': manilaclient.API_MIN_VERSION.get_string(), - 'client_max': manilaclient.API_MAX_VERSION.get_string(), - 'server_min': server_start_version.get_string(), - 'server_max': server_end_version.get_string()}) + _( + "Server's version is too old. The client's valid version range " + "is '%(client_min)s' to '%(client_max)s'. The server valid " + "version range is '%(server_min)s' to '%(server_max)s'." + ) + % { + 'client_min': manilaclient.API_MIN_VERSION.get_string(), + 'client_max': manilaclient.API_MAX_VERSION.get_string(), + 'server_min': server_start_version.get_string(), + 'server_max': server_end_version.get_string(), + } + ) elif manilaclient.API_MAX_VERSION < server_start_version: raise exceptions.UnsupportedVersion( - _("Server's version is too new. The client's valid version range " - "is '%(client_min)s' to '%(client_max)s'. The server valid " - "version range is '%(server_min)s' to '%(server_max)s'.") % { - 'client_min': manilaclient.API_MIN_VERSION.get_string(), - 'client_max': manilaclient.API_MAX_VERSION.get_string(), - 'server_min': server_start_version.get_string(), - 'server_max': server_end_version.get_string()}) + _( + "Server's version is too new. The client's valid version range " + "is '%(client_min)s' to '%(client_max)s'. The server valid " + "version range is '%(server_min)s' to '%(server_max)s'." + ) + % { + 'client_min': manilaclient.API_MIN_VERSION.get_string(), + 'client_max': manilaclient.API_MAX_VERSION.get_string(), + 'server_min': server_start_version.get_string(), + 'server_max': server_end_version.get_string(), + } + ) def add_versioned_method(versioned_method): @@ -342,8 +384,11 @@ def add_versioned_method(versioned_method): def get_versioned_methods(func_name, api_version=None): versioned_methods = _VERSIONED_METHOD_MAP.get(func_name, []) if api_version and not api_version.is_null(): - return [m for m in versioned_methods - if api_version.matches(m.start_version, m.end_version)] + return [ + m + for m in versioned_methods + if api_version.matches(m.start_version, m.end_version) + ] return versioned_methods @@ -353,11 +398,13 @@ def experimental_api(f): @functools.wraps(f) def _wrapper(*args, **kwargs): client = args[0] - if (isinstance(client, manilaclient.v2.client.Client) or - hasattr(client, 'client')): + if isinstance(client, manilaclient.v2.client.Client) or hasattr( + client, 'client' + ): dh = client.client.default_headers dh[constants.EXPERIMENTAL_HTTP_HEADER] = 'true' return f(*args, **kwargs) + return _wrapper @@ -378,8 +425,9 @@ def wraps(start_version, end_version=MAX_VERSION): def decor(func): func.versioned = True name = utils.get_function_name(func) - versioned_method = VersionedMethod(name, start_version, - end_version, func) + versioned_method = VersionedMethod( + name, start_version, end_version, func + ) add_versioned_method(versioned_method) @functools.wraps(func) @@ -388,11 +436,15 @@ def substitution(obj, *args, **kwargs): if not methods: raise exceptions.UnsupportedVersion( - _("API version '%(version)s' is not supported on " - "'%(method)s' method.") % { + _( + "API version '%(version)s' is not supported on " + "'%(method)s' method." + ) + % { "version": obj.api_version.get_string(), "method": name, - }) + } + ) method = max(methods, key=lambda f: f.start_version) diff --git a/manilaclient/base.py b/manilaclient/base.py index a636a96e..eb79dfe4 100644 --- a/manilaclient/base.py +++ b/manilaclient/base.py @@ -54,6 +54,7 @@ class Manager(utils.HookableMixin): Managers interact with a particular type of API (shares, snapshots, etc.) and provide CRUD operations for them. """ + resource_class = None def __init__(self, api): @@ -64,8 +65,9 @@ def __init__(self, api): def api_version(self): return self.api.api_version - def _list(self, url, response_key, manager=None, body=None, - return_raw=None): + def _list( + self, url, response_key, manager=None, body=None, return_raw=None + ): """List the collection. :param url: a partial URL, e.g., '/shares' @@ -100,8 +102,9 @@ def _list(self, url, response_key, manager=None, body=None, with self.completion_cache('uuid', obj_class, mode="w"): if return_raw: return data - resource = [obj_class(manager, res, loaded=True) - for res in data if res] + resource = [ + obj_class(manager, res, loaded=True) for res in data if res + ] if 'count' in body: return resource, body['count'] else: @@ -121,16 +124,19 @@ def completion_cache(self, cache_type, obj_class, mode): Delete is not handled because listings are assumed to be performed often enough to keep the cache reasonably up-to-date. """ - base_dir = cliutils.env('manilaclient_UUID_CACHE_DIR', - 'MANILACLIENT_UUID_CACHE_DIR', - default="~/.cache/manilaclient") + base_dir = cliutils.env( + 'manilaclient_UUID_CACHE_DIR', + 'MANILACLIENT_UUID_CACHE_DIR', + default="~/.cache/manilaclient", + ) # NOTE(sirp): Keep separate UUID caches for each username + endpoint # pair username = cliutils.env('OS_USERNAME', 'MANILA_USERNAME') url = cliutils.env('OS_URL', 'MANILA_URL') - uniqifier = hashlib.sha256(username.encode('utf-8') + - url.encode('utf-8')).hexdigest() + uniqifier = hashlib.sha256( + username.encode('utf-8') + url.encode('utf-8') + ).hexdigest() cache_dir = os.path.expanduser(os.path.join(base_dir, uniqifier)) @@ -143,14 +149,14 @@ def completion_cache(self, cache_type, obj_class, mode): pass resource = obj_class.__name__.lower() - filename = "%s-%s-cache" % (resource, cache_type.replace('_', '-')) + filename = "{}-{}-cache".format(resource, cache_type.replace('_', '-')) path = os.path.join(cache_dir, filename) - cache_attr = "_%s_cache" % cache_type + cache_attr = f"_{cache_type}_cache" try: setattr(self, cache_attr, open(path, mode)) - except IOError: + except OSError: # NOTE(kiall): This is typically a permission denied while # attempting to write the cache file. pass @@ -164,10 +170,10 @@ def completion_cache(self, cache_type, obj_class, mode): delattr(self, cache_attr) def write_to_completion_cache(self, cache_type, val): - cache = getattr(self, "_%s_cache" % cache_type, None) + cache = getattr(self, f"_{cache_type}_cache", None) if cache: try: - cache.write("%s\n" % val) + cache.write(f"{val}\n") except UnicodeEncodeError: pass @@ -183,8 +189,11 @@ def _get(self, url, response_key, return_raw=False): def _get_with_base_url(self, url, response_key=None): resp, body = self.api.client.get_with_base_url(url) if response_key: - return [self.resource_class(self, res, loaded=True) - for res in body[response_key] if res] + return [ + self.resource_class(self, res, loaded=True) + for res in body[response_key] + if res + ] else: return self.resource_class(self, body, loaded=True) @@ -215,14 +224,14 @@ def _update(self, url, body, response_key=None, **kwargs): def _build_query_string(self, search_opts): search_opts = search_opts or {} - params = sorted( - [(k, v) for (k, v) in search_opts.items() if v]) - query_string = "?%s" % utils.safe_urlencode(params) if params else '' + params = sorted([(k, v) for (k, v) in search_opts.items() if v]) + query_string = f"?{utils.safe_urlencode(params)}" if params else '' return query_string class ManagerWithFind(Manager): """Like a `Manager`, but with additional `find()`/`findall()` methods.""" + def find(self, **kwargs): """Find a single item with attributes matching ``**kwargs``. @@ -232,7 +241,7 @@ def find(self, **kwargs): matches = self.findall(**kwargs) num_matches = len(matches) if num_matches == 0: - msg = "No %s matching %s." % (self.resource_class.__name__, kwargs) + msg = f"No {self.resource_class.__name__} matching {kwargs}." raise exceptions.NotFound(404, msg) elif num_matches > 1: raise exceptions.NoUniqueMatch @@ -250,16 +259,17 @@ def findall(self, **kwargs): search_opts = {'all_tenants': 1} resources = self.list(search_opts=search_opts) - if ('v2.shares.ShareManager' in str(self.__class__) and - self.api_version >= api_versions.APIVersion("2.69")): - search_opts_2 = {'all_tenants': 1, - 'is_soft_deleted': True} + if 'v2.shares.ShareManager' in str( + self.__class__ + ) and self.api_version >= api_versions.APIVersion("2.69"): + search_opts_2 = {'all_tenants': 1, 'is_soft_deleted': True} shares_soft_deleted = self.list(search_opts=search_opts_2) resources += shares_soft_deleted for obj in resources: try: - if all(getattr(obj, attr) == value - for (attr, value) in searches): + if all( + getattr(obj, attr) == value for (attr, value) in searches + ): found.append(obj) except AttributeError: continue @@ -270,7 +280,7 @@ def list(self, search_opts=None): raise NotImplementedError -class Resource(object): +class Resource: """Base class for OpenStack resources (tenant, user, etc.). This is pretty much just a bag for attributes. @@ -292,11 +302,11 @@ def __init__(self, manager, info, loaded=False): self._loaded = loaded def __repr__(self): - reprkeys = sorted(k - for k in self.__dict__.keys() - if k[0] != '_' and k != 'manager') - info = ", ".join("%s=%s" % (k, getattr(self, k)) for k in reprkeys) - return "<%s %s>" % (self.__class__.__name__, info) + reprkeys = sorted( + k for k in self.__dict__.keys() if k[0] != '_' and k != 'manager' + ) + info = ", ".join(f"{k}={getattr(self, k)}" for k in reprkeys) + return f"<{self.__class__.__name__} {info}>" @property def human_id(self): @@ -308,7 +318,7 @@ def human_id(self): return None def _add_details(self, info): - for (k, v) in info.items(): + for k, v in info.items(): try: setattr(self, k, v) self._info[k] = v @@ -366,7 +376,6 @@ def to_dict(self): class MetadataCapableResource(Resource, metaclass=abc.ABCMeta): - superresource = None def _get_subresource_and_resource(self, superresource): @@ -388,7 +397,8 @@ def get_metadata(self, superresource=None): """ resource, subresource = self._get_subresource_and_resource( - superresource) + superresource + ) return self.manager.get_metadata(resource, subresource=subresource) @@ -403,10 +413,12 @@ def set_metadata(self, metadata, superresource=None): by default """ resource, subresource = self._get_subresource_and_resource( - superresource) + superresource + ) - return self.manager.set_metadata(resource, metadata, - subresource=subresource) + return self.manager.set_metadata( + resource, metadata, subresource=subresource + ) def delete_metadata(self, keys, superresource=None): """Delete specified keys from the given resource. @@ -418,10 +430,12 @@ def delete_metadata(self, keys, superresource=None): by default """ resource, subresource = self._get_subresource_and_resource( - superresource) + superresource + ) - return self.manager.delete_metadata(resource, keys, - subresource=subresource) + return self.manager.delete_metadata( + resource, keys, subresource=subresource + ) def update_all_metadata(self, metadata, superresource=None): """Update all metadata for this resource. @@ -434,11 +448,12 @@ def update_all_metadata(self, metadata, superresource=None): by default """ resource, subresource = self._get_subresource_and_resource( - superresource) + superresource + ) - return self.manager.update_all_metadata(resource, - metadata, - subresource=subresource) + return self.manager.update_all_metadata( + resource, metadata, subresource=subresource + ) class MetadataCapableManager(ManagerWithFind, metaclass=abc.ABCMeta): @@ -458,8 +473,9 @@ def get_metadata(self, resource, subresource=None): subresource = getid(subresource) resource = f"{resource}{self.subresource_path}/{subresource}" - return self._get(f"{self.resource_path}/{resource}/metadata", - "metadata") + return self._get( + f"{self.resource_path}/{resource}/metadata", "metadata" + ) def set_metadata(self, resource, metadata, subresource=None): """Set or update metadata for resource. @@ -475,9 +491,9 @@ def set_metadata(self, resource, metadata, subresource=None): subresource = getid(subresource) resource = f"{resource}{self.subresource_path}/{subresource}" - return self._create(f"{self.resource_path}/{resource}/metadata", - body, - "metadata") + return self._create( + f"{self.resource_path}/{resource}/metadata", body, "metadata" + ) def delete_metadata(self, resource, keys, subresource=None): """Delete specified keys from resource metadata. @@ -508,5 +524,4 @@ def update_all_metadata(self, resource, metadata, subresource=None): subresource = getid(subresource) resource = f"{resource}{self.subresource_path}/{subresource}" - return self._update(f"{self.resource_path}/{resource}/metadata", - body) + return self._update(f"{self.resource_path}/{resource}/metadata", body) diff --git a/manilaclient/client.py b/manilaclient/client.py index 4868e802..f1a708e5 100644 --- a/manilaclient/client.py +++ b/manilaclient/client.py @@ -34,15 +34,15 @@ def get_client_class(version): try: client_path = version_map[str(version)] except (KeyError, ValueError): - msg = "Invalid client version '%s'. must be one of: %s" % ( - (version, ', '.join(version_map))) + msg = "Invalid client version '{}'. must be one of: {}".format( + version, ', '.join(version_map) + ) raise exceptions.UnsupportedVersion(msg) return importutils.import_class(client_path) def Client(client_version, *args, **kwargs): - def _convert_to_api_version(version): """Convert version to an APIVersion object unless it already is one.""" @@ -51,7 +51,8 @@ def _convert_to_api_version(version): else: if version in ('1', '1.0'): api_version = api_versions.APIVersion( - api_versions.DEPRECATED_VERSION) + api_versions.DEPRECATED_VERSION + ) elif version == '2': api_version = api_versions.APIVersion(api_versions.MIN_VERSION) else: @@ -64,6 +65,7 @@ def _convert_to_api_version(version): # Make sure the kwarg api_version is set with an APIVersion object. # 1st choice is to use the incoming kwarg. 2nd choice is the positional. kwargs['api_version'] = _convert_to_api_version( - kwargs.get('api_version', api_version)) + kwargs.get('api_version', api_version) + ) return client_class(*args, **kwargs) diff --git a/manilaclient/common/apiclient/exceptions.py b/manilaclient/common/apiclient/exceptions.py index 71418f72..ef95f0bc 100644 --- a/manilaclient/common/apiclient/exceptions.py +++ b/manilaclient/common/apiclient/exceptions.py @@ -41,87 +41,107 @@ class ClientException(Exception): """The base exception class for all exceptions this library raises.""" + pass class ValidationError(ClientException): """Error in validation on API client side.""" + pass class UnsupportedVersion(ClientException): """User is trying to use an unsupported version of the API.""" + pass class CommandError(ClientException): """Error in CLI tool.""" + pass class AuthorizationFailure(ClientException): """Cannot authorize API client.""" + pass class ConnectionError(ClientException): """Cannot connect to API service.""" + pass class ConnectionRefused(ConnectionError): """Connection refused while trying to connect to API service.""" + pass class AuthPluginOptionsMissing(AuthorizationFailure): """Auth plugin misses some options.""" + def __init__(self, opt_names): - super(AuthPluginOptionsMissing, self).__init__( - _("Authentication failed. Missing options: %s") % - ", ".join(opt_names)) + super().__init__( + _("Authentication failed. Missing options: %s") + % ", ".join(opt_names) + ) self.opt_names = opt_names class AuthSystemNotFound(AuthorizationFailure): """User has specified an AuthSystem that is not installed.""" + def __init__(self, auth_system): - super(AuthSystemNotFound, self).__init__( - _("AuthSystemNotFound: %r") % auth_system) + super().__init__(_("AuthSystemNotFound: %r") % auth_system) self.auth_system = auth_system class NoUniqueMatch(ClientException): """Multiple entities found instead of one.""" + pass class EndpointException(ClientException): """Something is rotten in Service Catalog.""" + pass class EndpointNotFound(EndpointException): """Could not find requested endpoint in Service Catalog.""" + pass class AmbiguousEndpoints(EndpointException): """Found more than one matching endpoint in Service Catalog.""" + def __init__(self, endpoints=None): - super(AmbiguousEndpoints, self).__init__( - _("AmbiguousEndpoints: %r") % endpoints) + super().__init__(_("AmbiguousEndpoints: %r") % endpoints) self.endpoints = endpoints class HttpError(ClientException): """The base exception class for all HTTP exceptions.""" + http_status = 0 message = _("HTTP Error") - def __init__(self, message=None, details=None, - response=None, request_id=None, - url=None, method=None, http_status=None): + def __init__( + self, + message=None, + details=None, + response=None, + request_id=None, + url=None, + method=None, + http_status=None, + ): self.http_status = http_status or self.http_status self.message = message or self.message self.details = details @@ -129,14 +149,15 @@ def __init__(self, message=None, details=None, self.response = response self.url = url self.method = method - formatted_string = "%s (HTTP %s)" % (self.message, self.http_status) + formatted_string = f"{self.message} (HTTP {self.http_status})" if request_id: - formatted_string += " (Request-ID: %s)" % request_id - super(HttpError, self).__init__(formatted_string) + formatted_string += f" (Request-ID: {request_id})" + super().__init__(formatted_string) class HTTPRedirection(HttpError): """HTTP Redirection.""" + message = _("HTTP Redirection") @@ -145,6 +166,7 @@ class HTTPClientError(HttpError): Exception for cases in which the client seems to have erred. """ + message = _("HTTP Client Error") @@ -154,6 +176,7 @@ class HttpServerError(HttpError): Exception for cases in which the server is aware that it has erred or is incapable of performing the request. """ + message = _("HTTP Server Error") @@ -172,6 +195,7 @@ class BadRequest(HTTPClientError): The request cannot be fulfilled due to bad syntax. """ + http_status = 400 message = _("Bad Request") @@ -182,6 +206,7 @@ class Unauthorized(HTTPClientError): Similar to 403 Forbidden, but specifically for use when authentication is required and has failed or has not yet been provided. """ + http_status = 401 message = _("Unauthorized") @@ -191,6 +216,7 @@ class PaymentRequired(HTTPClientError): Reserved for future use. """ + http_status = 402 message = _("Payment Required") @@ -201,6 +227,7 @@ class Forbidden(HTTPClientError): The request was a valid request, but the server is refusing to respond to it. """ + http_status = 403 message = _("Forbidden") @@ -211,6 +238,7 @@ class NotFound(HTTPClientError): The requested resource could not be found but may be available again in the future. """ + http_status = 404 message = _("Not Found") @@ -221,6 +249,7 @@ class MethodNotAllowed(HTTPClientError): A request was made of a resource using a request method not supported by that resource. """ + http_status = 405 message = _("Method Not Allowed") @@ -231,6 +260,7 @@ class NotAcceptable(HTTPClientError): The requested resource is only capable of generating content not acceptable according to the Accept headers sent in the request. """ + http_status = 406 message = _("Not Acceptable") @@ -240,6 +270,7 @@ class ProxyAuthenticationRequired(HTTPClientError): The client must first authenticate itself with the proxy. """ + http_status = 407 message = _("Proxy Authentication Required") @@ -249,6 +280,7 @@ class RequestTimeout(HTTPClientError): The server timed out waiting for the request. """ + http_status = 408 message = _("Request Timeout") @@ -259,6 +291,7 @@ class Conflict(HTTPClientError): Indicates that the request could not be processed because of conflict in the request, such as an edit conflict. """ + http_status = 409 message = _("Conflict") @@ -269,6 +302,7 @@ class Gone(HTTPClientError): Indicates that the resource requested is no longer available and will not be available again. """ + http_status = 410 message = _("Gone") @@ -279,6 +313,7 @@ class LengthRequired(HTTPClientError): The request did not specify the length of its content, which is required by the requested resource. """ + http_status = 411 message = _("Length Required") @@ -289,6 +324,7 @@ class PreconditionFailed(HTTPClientError): The server does not meet one of the preconditions that the requester put on the request. """ + http_status = 412 message = _("Precondition Failed") @@ -298,6 +334,7 @@ class RequestEntityTooLarge(HTTPClientError): The request is larger than the server is willing or able to process. """ + http_status = 413 message = _("Request Entity Too Large") @@ -307,7 +344,7 @@ def __init__(self, *args, **kwargs): except (KeyError, ValueError): self.retry_after = 0 - super(RequestEntityTooLarge, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) class RequestUriTooLong(HTTPClientError): @@ -315,6 +352,7 @@ class RequestUriTooLong(HTTPClientError): The URI provided was too long for the server to process. """ + http_status = 414 message = _("Request-URI Too Long") @@ -325,6 +363,7 @@ class UnsupportedMediaType(HTTPClientError): The request entity has a media type which the server or resource does not support. """ + http_status = 415 message = _("Unsupported Media Type") @@ -335,6 +374,7 @@ class RequestedRangeNotSatisfiable(HTTPClientError): The client has asked for a portion of the file, but the server cannot supply that portion. """ + http_status = 416 message = _("Requested Range Not Satisfiable") @@ -344,6 +384,7 @@ class ExpectationFailed(HTTPClientError): The server cannot meet the requirements of the Expect request-header field. """ + http_status = 417 message = _("Expectation Failed") @@ -354,6 +395,7 @@ class UnprocessableEntity(HTTPClientError): The request was well-formed but was unable to be followed due to semantic errors. """ + http_status = 422 message = _("Unprocessable Entity") @@ -363,6 +405,7 @@ class InternalServerError(HttpServerError): A generic error message, given when no more specific message is suitable. """ + http_status = 500 message = _("Internal Server Error") @@ -374,6 +417,7 @@ class HttpNotImplemented(HttpServerError): The server either does not recognize the request method, or it lacks the ability to fulfill the request. """ + http_status = 501 message = _("Not Implemented") @@ -384,6 +428,7 @@ class BadGateway(HttpServerError): The server was acting as a gateway or proxy and received an invalid response from the upstream server. """ + http_status = 502 message = _("Bad Gateway") @@ -393,6 +438,7 @@ class ServiceUnavailable(HttpServerError): The server is currently unavailable. """ + http_status = 503 message = _("Service Unavailable") @@ -403,6 +449,7 @@ class GatewayTimeout(HttpServerError): The server was acting as a gateway or proxy and did not receive a timely response from the upstream server. """ + http_status = 504 message = _("Gateway Timeout") @@ -412,6 +459,7 @@ class HttpVersionNotSupported(HttpServerError): The server does not support the HTTP protocol version used in the request. """ + http_status = 505 message = _("HTTP Version Not Supported") @@ -456,8 +504,9 @@ def from_response(response, method, url): if isinstance(body, dict): error = body.get(list(body)[0]) if isinstance(error, dict): - kwargs["message"] = (error.get("message") or - error.get("faultstring")) + kwargs["message"] = error.get("message") or error.get( + "faultstring" + ) kwargs["details"] = error.get("details") or str(body) elif content_type.startswith("text/"): kwargs["details"] = response.text diff --git a/manilaclient/common/apiclient/utils.py b/manilaclient/common/apiclient/utils.py index 2b361d85..5b333009 100644 --- a/manilaclient/common/apiclient/utils.py +++ b/manilaclient/common/apiclient/utils.py @@ -27,7 +27,7 @@ def find_resource(manager, name_or_id, **find_args): .. code-block:: python def _find_hypervisor(cs, hypervisor): - #Get a hypervisor by name or ID. + # Get a hypervisor by name or ID. return cliutils.find_resource(cs.hypervisors, hypervisor) """ # first try to get entity as integer id @@ -66,14 +66,19 @@ def _find_hypervisor(cs, hypervisor): kwargs.update(find_args) return manager.find(**kwargs) except exceptions.NotFound: - msg = _("No %(name)s with a name or " - "ID of '%(name_or_id)s' exists.") % \ - {"name": manager.resource_class.__name__.lower(), - "name_or_id": name_or_id} + msg = _( + "No %(name)s with a name or ID of '%(name_or_id)s' exists." + ) % { + "name": manager.resource_class.__name__.lower(), + "name_or_id": name_or_id, + } raise exceptions.CommandError(msg) except exceptions.NoUniqueMatch: - msg = _("Multiple %(name)s matches found for " - "'%(name_or_id)s', use an ID to be more specific.") % \ - {"name": manager.resource_class.__name__.lower(), - "name_or_id": name_or_id} + msg = _( + "Multiple %(name)s matches found for " + "'%(name_or_id)s', use an ID to be more specific." + ) % { + "name": manager.resource_class.__name__.lower(), + "name_or_id": name_or_id, + } raise exceptions.CommandError(msg) diff --git a/manilaclient/common/cliutils.py b/manilaclient/common/cliutils.py index 552653a5..143de946 100644 --- a/manilaclient/common/cliutils.py +++ b/manilaclient/common/cliutils.py @@ -31,10 +31,11 @@ class MissingArgs(Exception): """Supplied arguments are not sufficient for calling a function.""" + def __init__(self, missing): self.missing = missing msg = _("Missing arguments: %s") % ", ".join(missing) - super(MissingArgs, self).__init__(msg) + super().__init__(msg) def validate_args(fn, *args, **kwargs): @@ -56,7 +57,7 @@ def validate_args(fn, *args, **kwargs): argspec = inspect.getfullargspec(fn) num_defaults = len(argspec.defaults or []) - required_args = argspec.args[:len(argspec.args) - num_defaults] + required_args = argspec.args[: len(argspec.args) - num_defaults] def isbound(method): return getattr(method, '__self__', None) is not None @@ -65,7 +66,7 @@ def isbound(method): required_args.pop(0) missing = [arg for arg in required_args if arg not in kwargs] - missing = missing[len(args):] + missing = missing[len(args) :] if missing: raise MissingArgs(missing) @@ -79,9 +80,11 @@ def arg(*args, **kwargs): ... def entity_create(args): ... pass """ + def _decorator(func): add_arg(func, *args, **kwargs) return func + return _decorator @@ -134,8 +137,14 @@ def isunauthenticated(func): return getattr(func, 'unauthenticated', False) -def print_list(objs, fields, formatters=None, sortby_index=0, - mixed_case_fields=None, field_labels=None): +def print_list( + objs, + fields, + formatters=None, + sortby_index=0, + mixed_case_fields=None, + field_labels=None, +): """Print a list or objects as a table, one row per object. :param objs: iterable of :class:`Resource` @@ -151,9 +160,13 @@ def print_list(objs, fields, formatters=None, sortby_index=0, mixed_case_fields = mixed_case_fields or [] field_labels = field_labels or fields if len(field_labels) != len(fields): - raise ValueError(_("Field labels list %(labels)s has different number " - "of elements than fields list %(fields)s"), - {'labels': field_labels, 'fields': fields}) + raise ValueError( + _( + "Field labels list %(labels)s has different number " + "of elements than fields list %(fields)s" + ), + {'labels': field_labels, 'fields': fields}, + ) if sortby_index is None: kwargs = {} @@ -240,9 +253,11 @@ def service_type(stype): def mymethod(f): ... """ + def inner(f): f.service_type = stype return f + return inner @@ -252,7 +267,7 @@ def get_service_type(f): def pretty_choice_list(choices): - return ', '.join("'%s'" % choice for choice in choices) + return ', '.join(f"'{choice}'" for choice in choices) def exit(msg=''): @@ -273,6 +288,5 @@ def convert_dict_list_to_string(data, ignored_keys=None): datum_dict = datum for k, v in datum_dict.items(): if k not in ignored_keys: - data_string += '\n%(k)s = %(v)s' % { - 'k': k, 'v': v} + data_string += f'\n{k} = {v}' return data_string diff --git a/manilaclient/common/constants.py b/manilaclient/common/constants.py index 08e609f9..08d6a70e 100644 --- a/manilaclient/common/constants.py +++ b/manilaclient/common/constants.py @@ -19,14 +19,25 @@ SORT_DIR_VALUES = ('asc', 'desc') SHARE_SORT_KEY_VALUES = ( - 'id', 'status', 'size', 'host', 'share_proto', - 'availability_zone_id', 'availability_zone', - 'user_id', 'project_id', - 'created_at', 'updated_at', - 'display_name', 'name', - 'share_type_id', 'share_type', - 'share_network_id', 'share_network', - 'snapshot_id', 'snapshot', + 'id', + 'status', + 'size', + 'host', + 'share_proto', + 'availability_zone_id', + 'availability_zone', + 'user_id', + 'project_id', + 'created_at', + 'updated_at', + 'display_name', + 'name', + 'share_type_id', + 'share_type', + 'share_network_id', + 'share_network', + 'snapshot_id', + 'snapshot', ) SNAPSHOT_SORT_KEY_VALUES = ( @@ -85,8 +96,7 @@ 'updated_at', 'resource_id', 'resource_type', - 'resource_action' - 'lock_reason', + 'resource_actionlock_reason', ) BACKUP_SORT_KEY_VALUES = ( @@ -119,9 +129,17 @@ EXTENSION_PLUGIN_NAMESPACE = 'manilaclient.common.apiclient.auth' MESSAGE_SORT_KEY_VALUES = ( - 'id', 'project_id', 'request_id', 'resource_type', 'action_id', - 'detail_id', 'resource_id', 'message_level', 'expires_at', - 'request_id', 'created_at' + 'id', + 'project_id', + 'request_id', + 'resource_type', + 'action_id', + 'detail_id', + 'resource_id', + 'message_level', + 'expires_at', + 'request_id', + 'created_at', ) STATUS_AVAILABLE = 'available' @@ -147,9 +165,7 @@ ) # share group types -GROUP_BOOL_SPECS = ( - CONSISTENT_SNAPSHOT_SUPPORT, -) +GROUP_BOOL_SPECS = (CONSISTENT_SNAPSHOT_SUPPORT,) REPLICA_GRADUATION_VERSION = '2.56' REPLICA_PRE_GRADUATION_VERSION = '2.55' diff --git a/manilaclient/common/httpclient.py b/manilaclient/common/httpclient.py index d7a79c16..ba4ab548 100644 --- a/manilaclient/common/httpclient.py +++ b/manilaclient/common/httpclient.py @@ -36,7 +36,7 @@ pass -class HTTPClient(object): +class HTTPClient: """HTTP Client class used by multiple clients. The imported Requests module caches and reuses objects with the same @@ -45,18 +45,30 @@ class HTTPClient(object): execution. This class is shared by multiple client versions so that the client can be changed to another version during execution. """ + API_VERSION_HEADER = "X-Openstack-Manila-Api-Version" - def __init__(self, endpoint_url, token, user_agent, api_version, - insecure=False, cacert=None, timeout=None, retries=None, - http_log_debug=False, cert=None): + def __init__( + self, + endpoint_url, + token, + user_agent, + api_version, + insecure=False, + cacert=None, + timeout=None, + retries=None, + http_log_debug=False, + cert=None, + ): self.endpoint_url = endpoint_url self.base_url = self._get_base_url(self.endpoint_url) self.retries = int(retries or 0) self.http_log_debug = http_log_debug self.request_options = self._set_request_options( - insecure, cacert, timeout, cert) + insecure, cacert, timeout, cert + ) self.default_headers = { 'X-Auth-Token': token, @@ -85,9 +97,13 @@ def _get_base_url(self, url): """Truncates url and returns base endpoint""" service_endpoint = parse.urlparse(url) service_endpoint_base_path = re.search( - r'(.+?)/v([0-9]+|[0-9]+\.[0-9]+)(/.*|$)', service_endpoint.path) - base_path = (service_endpoint_base_path.group(1) - if service_endpoint_base_path else '') + r'(.+?)/v([0-9]+|[0-9]+\.[0-9]+)(/.*|$)', service_endpoint.path + ) + base_path = ( + service_endpoint_base_path.group(1) + if service_endpoint_base_path + else '' + ) base_url = service_endpoint._replace(path=base_path) return parse.urlunparse(base_url) + '/' @@ -138,15 +154,13 @@ def request(self, url, method, **kwargs): def _cs_request(self, url, method, **kwargs): return self._cs_request_with_retries( - self.endpoint_url + url, - method, - **kwargs) + self.endpoint_url + url, method, **kwargs + ) def _cs_request_base_url(self, url, method, **kwargs): return self._cs_request_with_retries( - self.base_url + url, - method, - **kwargs) + self.base_url + url, method, **kwargs + ) def _cs_request_with_retries(self, url, method, **kwargs): attempts = 0 @@ -156,9 +170,11 @@ def _cs_request_with_retries(self, url, method, **kwargs): try: resp, body = self.request(url, method, **kwargs) return resp, body - except (exceptions.BadRequest, - requests.exceptions.RequestException, - exceptions.ClientException) as e: + except ( + exceptions.BadRequest, + requests.exceptions.RequestException, + exceptions.ClientException, + ) as e: if attempts > self.retries: raise @@ -166,11 +182,9 @@ def _cs_request_with_retries(self, url, method, **kwargs): self._logger.debug( "Failed attempt(%(current)s of %(total)s), " - " retrying in %(sec)s seconds", { - 'current': attempts, - 'total': self.retries, - 'sec': timeout - }) + " retrying in %(sec)s seconds", + {'current': attempts, 'total': self.retries, 'sec': timeout}, + ) sleep(timeout) timeout *= 2 @@ -193,24 +207,26 @@ def log_request(self, method, url, headers, data=None): if not self.http_log_debug: return - string_parts = ['curl -i', ' -X %s' % method, ' %s' % url] + string_parts = ['curl -i', f' -X {method}', f' {url}'] for element in headers: - header = ' -H "%s: %s"' % (element, headers[element]) + header = f' -H "{element}: {headers[element]}"' string_parts.append(header) if data: if "password" in data: data = strutils.mask_password(data) - string_parts.append(" -d '%s'" % data) + string_parts.append(f" -d '{data}'") self._logger.debug("\nREQ: %s\n", "".join(string_parts)) def log_response(self, resp): if not self.http_log_debug: return self._logger.debug( - "RESP: [%(code)s] %(headers)s\nRESP BODY: %(body)s\n", { + "RESP: [%(code)s] %(headers)s\nRESP BODY: %(body)s\n", + { 'code': resp.status_code, 'headers': resp.headers, - 'body': resp.text - }) + 'body': resp.text, + }, + ) diff --git a/manilaclient/config.py b/manilaclient/config.py index 94e41489..a838a6bf 100644 --- a/manilaclient/config.py +++ b/manilaclient/config.py @@ -27,171 +27,255 @@ # directory "%project_root%/manilaclient/tests/functional" auth_opts = [ # Options for user with 'member' role. - cfg.StrOpt("username", - help="This should be the username of a user WITHOUT " - "administrative privileges."), - cfg.StrOpt("tenant_name", - help="The non-administrative user's tenant name."), - cfg.StrOpt("password", - secret=True, - help="The non-administrative user's password."), - cfg.StrOpt("auth_url", - help="URL for where to find the OpenStack Identity public " - "API endpoint."), - cfg.StrOpt("project_domain_name", - help=("Project domain Name of user with 'member' role " - "as specified for auth v3.")), - cfg.StrOpt("project_domain_id", - help=("Project domain ID of user with 'member' role " - "as specified for auth v3.")), - cfg.StrOpt("user_domain_name", - help=("User domain Name of user with 'member' role " - "as specified for auth v3.")), - cfg.StrOpt("user_domain_id", - help=("User domain ID of user with 'member' role " - "as specified for auth v3.")), - + cfg.StrOpt( + "username", + help="This should be the username of a user WITHOUT " + "administrative privileges.", + ), + cfg.StrOpt( + "tenant_name", help="The non-administrative user's tenant name." + ), + cfg.StrOpt( + "password", secret=True, help="The non-administrative user's password." + ), + cfg.StrOpt( + "auth_url", + help="URL for where to find the OpenStack Identity public " + "API endpoint.", + ), + cfg.StrOpt( + "project_domain_name", + help=( + "Project domain Name of user with 'member' role " + "as specified for auth v3." + ), + ), + cfg.StrOpt( + "project_domain_id", + help=( + "Project domain ID of user with 'member' role " + "as specified for auth v3." + ), + ), + cfg.StrOpt( + "user_domain_name", + help=( + "User domain Name of user with 'member' role " + "as specified for auth v3." + ), + ), + cfg.StrOpt( + "user_domain_id", + help=( + "User domain ID of user with 'member' role " + "as specified for auth v3." + ), + ), # Options for user with 'admin' role. - cfg.StrOpt("admin_username", - help="This should be the username of a user WITH " - "administrative privileges."), - cfg.StrOpt("admin_tenant_name", - help="The administrative user's tenant name."), - cfg.StrOpt("admin_password", - secret=True, - help="The administrative user's password."), - cfg.StrOpt("admin_auth_url", - help="URL for where to find the OpenStack Identity admin " - "API endpoint."), - cfg.StrOpt("admin_project_domain_name", - help=("Project domain Name of user with 'admin' role " - "as specified for auth v3.")), - cfg.StrOpt("admin_project_domain_id", - help=("Project domain ID of user with 'admin' role " - "as specified for auth v3.")), - cfg.StrOpt("admin_user_domain_name", - help=("User domain Name of user with 'admin' role " - "as specified for auth v3.")), - cfg.StrOpt("admin_user_domain_id", - help=("User domain ID of user with 'admin' role " - "as specified for auth v3.")), - + cfg.StrOpt( + "admin_username", + help="This should be the username of a user WITH " + "administrative privileges.", + ), + cfg.StrOpt( + "admin_tenant_name", help="The administrative user's tenant name." + ), + cfg.StrOpt( + "admin_password", + secret=True, + help="The administrative user's password.", + ), + cfg.StrOpt( + "admin_auth_url", + help="URL for where to find the OpenStack Identity admin " + "API endpoint.", + ), + cfg.StrOpt( + "admin_project_domain_name", + help=( + "Project domain Name of user with 'admin' role " + "as specified for auth v3." + ), + ), + cfg.StrOpt( + "admin_project_domain_id", + help=( + "Project domain ID of user with 'admin' role " + "as specified for auth v3." + ), + ), + cfg.StrOpt( + "admin_user_domain_name", + help=( + "User domain Name of user with 'admin' role " + "as specified for auth v3." + ), + ), + cfg.StrOpt( + "admin_user_domain_id", + help=( + "User domain ID of user with 'admin' role " + "as specified for auth v3." + ), + ), # Other auth options - cfg.BoolOpt("insecure", - default=False, - help="Disable SSL certificate verification."), + cfg.BoolOpt( + "insecure", default=False, help="Disable SSL certificate verification." + ), ] base_opts = [ - cfg.StrOpt("manila_exec_dir", - default=os.environ.get( - 'OS_MANILA_EXEC_DIR', - os.path.join(os.path.abspath('.'), '.tox/functional/bin')), - help="The path to manilaclient to be executed."), - cfg.BoolOpt("suppress_errors_in_cleanup", - default=True, - help="Whether to suppress errors with clean up operation " - "or not."), + cfg.StrOpt( + "manila_exec_dir", + default=os.environ.get( + 'OS_MANILA_EXEC_DIR', + os.path.join(os.path.abspath('.'), '.tox/functional/bin'), + ), + help="The path to manilaclient to be executed.", + ), + cfg.BoolOpt( + "suppress_errors_in_cleanup", + default=True, + help="Whether to suppress errors with clean up operation or not.", + ), ] share_opts = [ - cfg.StrOpt("min_api_microversion", - default="1.0", - help="The minimum API microversion is configured to be the " - "value of the minimum microversion supported by " - "Manilaclient functional tests. Defaults to 1.0."), - cfg.StrOpt("max_api_microversion", - default=api_versions.MAX_VERSION, - help="The maximum API microversion is configured to be the " - "value of the latest microversion supported by " - "Manilaclient functional tests. Defaults to " - "manilaclient's max supported API microversion."), - cfg.StrOpt("share_network", - help="Share network Name or ID, that will be used for shares. " - "Some backend drivers require a share network for share " - "creation."), - cfg.StrOpt("share_network_subnet", - help="Share network subnet ID. Some backend drivers require a " - "share network for share creation."), - cfg.StrOpt("admin_share_network", - help="Share network Name or ID, that will be used for shares " - "in admin tenant."), - cfg.StrOpt("share_type", - help="Share type Name or ID, that will be used with share " - "creation scheduling. Optional."), - cfg.ListOpt("enable_protocols", - default=["nfs", "cifs"], - help="List of all enabled protocols. The first protocol in " - "the list will be used as the default protocol."), - cfg.IntOpt("build_interval", - default=3, - help="Time in seconds between share availability checks."), - cfg.IntOpt("build_timeout", - default=500, - help="Timeout in seconds to wait for a share to become " - "available."), - cfg.DictOpt('access_types_mapping', - default={'nfs': 'ip', 'cifs': 'ip'}, - help="Dict contains access types mapping to share " - "protocol. It will be used to create access rules " - "for shares. Format: ': ',..." - "Allowed share protocols: nfs, cifs, cephfs, glusterfs, " - "hdfs."), - cfg.DictOpt('access_levels_mapping', - default={'nfs': 'rw ro', 'cifs': 'rw'}, - help="Dict contains access levels mapping to share " - "protocol. It will be used to create access rules for " - "shares. Format: ': ',... " - "Allowed share protocols: nfs, cifs, cephfs, glusterfs, " - "hdfs."), - cfg.StrOpt("username_for_user_rules", - default="stack", - help="Username, that will be used in share access tests for " - "user type of access."), - cfg.StrOpt("replication_type", - default="readable", - choices=["readable", "writable", "dr"], - help="Replication type to be used when running replication " - "tests. This option is ignored if run_replication_tests " - "is set to False."), - cfg.BoolOpt("run_replication_tests", - default=True, - help="Defines whether to run tests for share replication " - "or not. Disable this feature if manila driver used " - "doesn't support share replication."), - cfg.BoolOpt("run_snapshot_tests", - default=True, - help="Defines whether to run tests that use share snapshots " - "or not. Disable this feature if used driver doesn't " - "support it."), - cfg.BoolOpt("run_share_servers_tests", - default=True, - help="Defines whether to run tests that use share servers " - "or not. Disable this feature if used driver doesn't " - "support it or when autodeletion of share servers " - "is enabled."), - cfg.BoolOpt("run_migration_tests", - default=False, - help="Defines whether to run share migration tests or not. " - "Disable this feature if there is no more than one " - "storage pool being tested or if used driver does not " - "support it."), - cfg.BoolOpt("run_mount_snapshot_tests", - default=False, - help="Defines whether to run mountable snapshots tests or " - "not. Disable this feature if used driver doesn't " - "support it."), - cfg.BoolOpt("run_manage_tests", - default=False, - help="Defines whether to run manage/unmanage tests or " - "not. Disable this feature if used driver does not " - "support it."), - cfg.BoolOpt("run_share_servers_migration_tests", - default=False, - help="Defines whether to run share server migration tests or " - "not. Disable this feature if used driver does not " - "support it."), - + cfg.StrOpt( + "min_api_microversion", + default="1.0", + help="The minimum API microversion is configured to be the " + "value of the minimum microversion supported by " + "Manilaclient functional tests. Defaults to 1.0.", + ), + cfg.StrOpt( + "max_api_microversion", + default=api_versions.MAX_VERSION, + help="The maximum API microversion is configured to be the " + "value of the latest microversion supported by " + "Manilaclient functional tests. Defaults to " + "manilaclient's max supported API microversion.", + ), + cfg.StrOpt( + "share_network", + help="Share network Name or ID, that will be used for shares. " + "Some backend drivers require a share network for share " + "creation.", + ), + cfg.StrOpt( + "share_network_subnet", + help="Share network subnet ID. Some backend drivers require a " + "share network for share creation.", + ), + cfg.StrOpt( + "admin_share_network", + help="Share network Name or ID, that will be used for shares " + "in admin tenant.", + ), + cfg.StrOpt( + "share_type", + help="Share type Name or ID, that will be used with share " + "creation scheduling. Optional.", + ), + cfg.ListOpt( + "enable_protocols", + default=["nfs", "cifs"], + help="List of all enabled protocols. The first protocol in " + "the list will be used as the default protocol.", + ), + cfg.IntOpt( + "build_interval", + default=3, + help="Time in seconds between share availability checks.", + ), + cfg.IntOpt( + "build_timeout", + default=500, + help="Timeout in seconds to wait for a share to become available.", + ), + cfg.DictOpt( + 'access_types_mapping', + default={'nfs': 'ip', 'cifs': 'ip'}, + help="Dict contains access types mapping to share " + "protocol. It will be used to create access rules " + "for shares. Format: ': ',..." + "Allowed share protocols: nfs, cifs, cephfs, glusterfs, " + "hdfs.", + ), + cfg.DictOpt( + 'access_levels_mapping', + default={'nfs': 'rw ro', 'cifs': 'rw'}, + help="Dict contains access levels mapping to share " + "protocol. It will be used to create access rules for " + "shares. Format: ': ',... " + "Allowed share protocols: nfs, cifs, cephfs, glusterfs, " + "hdfs.", + ), + cfg.StrOpt( + "username_for_user_rules", + default="stack", + help="Username, that will be used in share access tests for " + "user type of access.", + ), + cfg.StrOpt( + "replication_type", + default="readable", + choices=["readable", "writable", "dr"], + help="Replication type to be used when running replication " + "tests. This option is ignored if run_replication_tests " + "is set to False.", + ), + cfg.BoolOpt( + "run_replication_tests", + default=True, + help="Defines whether to run tests for share replication " + "or not. Disable this feature if manila driver used " + "doesn't support share replication.", + ), + cfg.BoolOpt( + "run_snapshot_tests", + default=True, + help="Defines whether to run tests that use share snapshots " + "or not. Disable this feature if used driver doesn't " + "support it.", + ), + cfg.BoolOpt( + "run_share_servers_tests", + default=True, + help="Defines whether to run tests that use share servers " + "or not. Disable this feature if used driver doesn't " + "support it or when autodeletion of share servers " + "is enabled.", + ), + cfg.BoolOpt( + "run_migration_tests", + default=False, + help="Defines whether to run share migration tests or not. " + "Disable this feature if there is no more than one " + "storage pool being tested or if used driver does not " + "support it.", + ), + cfg.BoolOpt( + "run_mount_snapshot_tests", + default=False, + help="Defines whether to run mountable snapshots tests or " + "not. Disable this feature if used driver doesn't " + "support it.", + ), + cfg.BoolOpt( + "run_manage_tests", + default=False, + help="Defines whether to run manage/unmanage tests or " + "not. Disable this feature if used driver does not " + "support it.", + ), + cfg.BoolOpt( + "run_share_servers_migration_tests", + default=False, + help="Defines whether to run share server migration tests or " + "not. Disable this feature if used driver does not " + "support it.", + ), ] # 2. Generate config @@ -199,16 +283,17 @@ PROJECT_NAME = 'manilaclient' DEFAULT_CONFIG_FILE = ( - os.environ.get('OS_%s_CONFIG_FILE' % PROJECT_NAME.upper()) or - '%s.conf' % PROJECT_NAME) -DEFAULT_CONFIG_DIR = ( - os.environ.get('OS_%s_CONFIG_DIR' % PROJECT_NAME.upper()) or - os.path.join(os.path.abspath(os.path.dirname(os.path.dirname(__file__))), - "etc/manilaclient") + os.environ.get(f'OS_{PROJECT_NAME.upper()}_CONFIG_FILE') + or f'{PROJECT_NAME}.conf' +) +DEFAULT_CONFIG_DIR = os.environ.get( + f'OS_{PROJECT_NAME.upper()}_CONFIG_DIR' +) or os.path.join( + os.path.abspath(os.path.dirname(os.path.dirname(__file__))), + "etc/manilaclient", ) DEFAULT_CONFIG_PATH = os.path.join(DEFAULT_CONFIG_DIR, DEFAULT_CONFIG_FILE) -FAILOVER_CONFIG_PATH = '/etc/%(pn)s/%(cn)s' % { - 'pn': PROJECT_NAME, 'cn': DEFAULT_CONFIG_FILE} +FAILOVER_CONFIG_PATH = f'/etc/{PROJECT_NAME}/{DEFAULT_CONFIG_FILE}' CONFIG_FILES = [] if os.path.isfile(DEFAULT_CONFIG_PATH): diff --git a/manilaclient/exceptions.py b/manilaclient/exceptions.py index efe3f20b..3a1d8ebb 100644 --- a/manilaclient/exceptions.py +++ b/manilaclient/exceptions.py @@ -23,6 +23,7 @@ class ManilaclientException(Exception): """A generic client error.""" + message = _("An unexpected error occured.") def __init__(self, message): @@ -34,11 +35,13 @@ def __str__(self): class ResourceInErrorState(ManilaclientException): """A resource is in an unexpected 'error' state.""" + message = _("Resource is in error state") class TimeoutException(ManilaclientException): """A request has timed out""" + message = _("Request has timed out") @@ -48,6 +51,7 @@ class NoTokenLookupException(ClientException): # noqa: F405 This form of authentication does not support looking up endpoints from an existing token. """ + pass diff --git a/manilaclient/extension.py b/manilaclient/extension.py index 01529f26..2f7f9d80 100644 --- a/manilaclient/extension.py +++ b/manilaclient/extension.py @@ -36,4 +36,4 @@ def _parse_extension_module(self): self.manager_class = attr_value def __repr__(self): - return "" % self.name + return f"" diff --git a/manilaclient/osc/plugin.py b/manilaclient/osc/plugin.py index e6392d65..9da1ec50 100644 --- a/manilaclient/osc/plugin.py +++ b/manilaclient/osc/plugin.py @@ -34,26 +34,30 @@ API_VERSIONS = { - '2.%d' % i: CLIENT_CLASS - for i in range(0, int(LATEST_MINOR_VERSION) + 1) + '2.%d' % i: CLIENT_CLASS for i in range(0, int(LATEST_MINOR_VERSION) + 1) } def _get_manila_url_from_service_catalog(instance): service_type = constants.SFS_SERVICE_TYPE url = instance.get_endpoint_for_service_type( - constants.SFS_SERVICE_TYPE, region_name=instance._region_name, - interface=instance.interface) + constants.SFS_SERVICE_TYPE, + region_name=instance._region_name, + interface=instance.interface, + ) # Fallback if cloud is using an older service type name if not url: url = instance.get_endpoint_for_service_type( - constants.V2_SERVICE_TYPE, region_name=instance._region_name, - interface=instance.interface) + constants.V2_SERVICE_TYPE, + region_name=instance._region_name, + interface=instance.interface, + ) service_type = constants.V2_SERVICE_TYPE if url is None: raise exceptions.EndpointNotFound( message="Could not find manila / shared-file-system endpoint in " - "the service catalog.") + "the service catalog." + ) return service_type, url @@ -62,38 +66,45 @@ def make_client(instance): requested_api_version = instance._api_version[API_NAME] service_type, manila_endpoint_url = _get_manila_url_from_service_catalog( - instance) + instance + ) instance.setup_auth() debugging_enabled = instance._cli_options.debug - client_args = dict(session=instance.session, - service_catalog_url=manila_endpoint_url, - endpoint_type=instance.interface, - region_name=instance.region_name, - service_type=service_type, - auth=instance.auth, - http_log_debug=debugging_enabled, - cacert=instance.cacert, - cert=instance.cert, - insecure=not instance.verify) + client_args = dict( + session=instance.session, + service_catalog_url=manila_endpoint_url, + endpoint_type=instance.interface, + region_name=instance.region_name, + service_type=service_type, + auth=instance.auth, + http_log_debug=debugging_enabled, + cacert=instance.cacert, + cert=instance.cert, + insecure=not instance.verify, + ) # Cast the API version into an object for further processing requested_api_version = api_versions.APIVersion( - version_str=requested_api_version) + version_str=requested_api_version + ) max_version = api_versions.APIVersion(api_versions.MAX_VERSION) client_args.update(dict(api_version=max_version)) temp_client = client.Client(max_version, **client_args) - discovered_version = api_versions.discover_version(temp_client, - requested_api_version) + discovered_version = api_versions.discover_version( + temp_client, requested_api_version + ) shared_file_system_client = utils.get_client_class( - API_NAME, discovered_version.get_string(), API_VERSIONS) + API_NAME, discovered_version.get_string(), API_VERSIONS + ) - LOG.debug('Instantiating Shared File System (share) client: %s', - shared_file_system_client) - LOG.debug('Shared File System API version: %s', - discovered_version) + LOG.debug( + 'Instantiating Shared File System (share) client: %s', + shared_file_system_client, + ) + LOG.debug('Shared File System API version: %s', discovered_version) client_args.update(dict(api_version=discovered_version)) return shared_file_system_client(**client_args) @@ -107,11 +118,12 @@ def build_option_parser(parser): metavar='', default=default_api_version, choices=sorted( - API_VERSIONS, - key=lambda k: [int(x) for x in k.split('.')]), - help='Shared File System API version, default=' + default_api_version + - 'version supported by both the client and the server). ' - '(Env: OS_SHARE_API_VERSION)', + API_VERSIONS, key=lambda k: [int(x) for x in k.split('.')] + ), + help='Shared File System API version, default=' + + default_api_version + + 'version supported by both the client and the server). ' + '(Env: OS_SHARE_API_VERSION)', ) parser.add_argument( "--os-endpoint-override", diff --git a/manilaclient/osc/utils.py b/manilaclient/osc/utils.py index abf36c4f..67583aab 100644 --- a/manilaclient/osc/utils.py +++ b/manilaclient/osc/utils.py @@ -36,7 +36,7 @@ def extract_key_value_options(pairs): if pairs and len(duplicate_options) > 0: duplicate_str = ', '.join(duplicate_options) - msg = "Following options were duplicated: %s" % duplicate_str + msg = f"Following options were duplicated: {duplicate_str}" raise exceptions.CommandError(msg) return result_dict @@ -46,7 +46,7 @@ def format_properties(properties): formatted_data = [] for item in properties: - formatted_data.append("%s : %s" % (item, properties[item])) + formatted_data.append(f"{item} : {properties[item]}") return "\n".join(formatted_data) @@ -57,7 +57,8 @@ def extract_properties(properties): (key, value) = item.split('=', 1) if key in result_dict: raise exceptions.CommandError( - "Argument '%s' is specified twice." % key) + f"Argument '{key}' is specified twice." + ) else: result_dict[key] = value except ValueError: @@ -67,42 +68,44 @@ def extract_properties(properties): return result_dict -def extract_extra_specs(extra_specs, specs_to_add, - bool_specs=constants.BOOL_SPECS): +def extract_extra_specs( + extra_specs, specs_to_add, bool_specs=constants.BOOL_SPECS +): try: for item in specs_to_add: (key, value) = item.split('=', 1) if key in extra_specs: - msg = ("Argument '%s' value specified twice." % key) + msg = f"Argument '{key}' value specified twice." raise exceptions.CommandError(msg) elif key in bool_specs: if strutils.is_valid_boolstr(value): extra_specs[key] = value.capitalize() else: msg = ( - "Argument '%s' is of boolean " - "type and has invalid value: %s" - % (key, str(value))) + f"Argument '{key}' is of boolean " + f"type and has invalid value: {str(value)}" + ) raise exceptions.CommandError(msg) else: extra_specs[key] = value except ValueError: - msg = LOG.error(_( - "Wrong format: specs should be key=value pairs.")) + msg = LOG.error(_("Wrong format: specs should be key=value pairs.")) raise exceptions.CommandError(msg) return extra_specs def extract_group_specs(extra_specs, specs_to_add): - return extract_extra_specs(extra_specs, - specs_to_add, constants.GROUP_BOOL_SPECS) + return extract_extra_specs( + extra_specs, specs_to_add, constants.GROUP_BOOL_SPECS + ) def format_column_headers(columns): column_headers = [] for column in columns: column_headers.append( - column.replace('_', ' ').title().replace('Id', 'ID')) + column.replace('_', ' ').title().replace('Id', 'ID') + ) return column_headers @@ -112,13 +115,15 @@ def format_share_group_type(share_group_type, formatter='table'): is_public = printable_share_group_type.pop('is_public') printable_share_group_type['visibility'] = ( - 'public' if is_public else 'private') + 'public' if is_public else 'private' + ) if formatter == 'table': - printable_share_group_type['group_specs'] = ( - format_properties(share_group_type.group_specs)) - printable_share_group_type['share_types'] = ( - "\n".join(printable_share_group_type['share_types']) + printable_share_group_type['group_specs'] = format_properties( + share_group_type.group_specs + ) + printable_share_group_type['share_types'] = "\n".join( + printable_share_group_type['share_types'] ) return printable_share_group_type diff --git a/manilaclient/osc/v2/availability_zones.py b/manilaclient/osc/v2/availability_zones.py index f8c8c00d..a084e5fc 100644 --- a/manilaclient/osc/v2/availability_zones.py +++ b/manilaclient/osc/v2/availability_zones.py @@ -23,8 +23,7 @@ class ShareAvailabilityZoneList(command.Lister): _description = _("List all availability zones") def get_parser(self, prog_name): - parser = super(ShareAvailabilityZoneList, self).get_parser( - prog_name) + parser = super().get_parser(prog_name) return parser def take_action(self, parsed_args): @@ -33,5 +32,10 @@ def take_action(self, parsed_args): fields = ("Id", "Name", "Created At", "Updated At") - return (fields, (oscutils.get_item_properties - (s, fields) for s in availability_zones)) + return ( + fields, + ( + oscutils.get_item_properties(s, fields) + for s in availability_zones + ), + ) diff --git a/manilaclient/osc/v2/messages.py b/manilaclient/osc/v2/messages.py index 632c5116..fcf8d3b8 100644 --- a/manilaclient/osc/v2/messages.py +++ b/manilaclient/osc/v2/messages.py @@ -33,21 +33,23 @@ 'detail_id', 'created_at', 'expires_at', - 'request_id' + 'request_id', ] class DeleteMessage(command.Command): """Remove one or more messages.""" + _description = _("Remove one or more messages") def get_parser(self, prog_name): - parser = super(DeleteMessage, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'message', metavar='', nargs='+', - help=_('ID of the message(s).')) + help=_('ID of the message(s).'), + ) return parser def take_action(self, parsed_args): @@ -57,78 +59,98 @@ def take_action(self, parsed_args): for message in parsed_args.message: try: message_ref = apiutils.find_resource( - share_client.messages, - message) + share_client.messages, message + ) share_client.messages.delete(message_ref) except Exception as e: failure_count += 1 - LOG.error(_( - "Delete for message %(message)s failed: %(e)s"), - {'message': message, 'e': e}) + LOG.error( + _("Delete for message %(message)s failed: %(e)s"), + {'message': message, 'e': e}, + ) if failure_count > 0: - raise exceptions.CommandError(_( - "Unable to delete some or all of the specified messages.")) + raise exceptions.CommandError( + _("Unable to delete some or all of the specified messages.") + ) class ListMessage(command.Lister): """Lists all messages.""" + _description = _("Lists all messages") def get_parser(self, prog_name): - parser = super(ListMessage, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( '--resource-id', metavar='', default=None, - help=_('Filters results by a resource uuid. Default=None.')) + help=_('Filters results by a resource uuid. Default=None.'), + ) parser.add_argument( '--resource-type', metavar='', default=None, - help=_('Filters results by a resource type. Default=None. ' - 'Example: "openstack message list --resource-type share"')) + help=_( + 'Filters results by a resource type. Default=None. ' + 'Example: "openstack message list --resource-type share"' + ), + ) parser.add_argument( '--action-id', metavar='', default=None, - help=_('Filters results by action id. Default=None.')) + help=_('Filters results by action id. Default=None.'), + ) parser.add_argument( '--detail-id', metavar='', default=None, - help=_('Filters results by detail id. Default=None.')) + help=_('Filters results by detail id. Default=None.'), + ) parser.add_argument( '--request-id', metavar='', default=None, - help=_('Filters results by request id. Default=None.')) + help=_('Filters results by request id. Default=None.'), + ) parser.add_argument( '--message-level', metavar='', default=None, - help=_('Filters results by the message level. Default=None. ' - 'Example: "openstack message list --message-level ERROR".')) + help=_( + 'Filters results by the message level. Default=None. ' + 'Example: "openstack message list --message-level ERROR".' + ), + ) parser.add_argument( '--limit', metavar='', type=int, default=None, - help=_('Maximum number of messages to return. (Default=None)')) + help=_('Maximum number of messages to return. (Default=None)'), + ) parser.add_argument( '--since', metavar='', default=None, - help=_('Return only user messages created since given date. ' - 'The date format must be conforming to ISO8601. ' - 'Available only for microversion >= 2.52.')) + help=_( + 'Return only user messages created since given date. ' + 'The date format must be conforming to ISO8601. ' + 'Available only for microversion >= 2.52.' + ), + ) parser.add_argument( '--before', metavar='', default=None, - help=_('Return only user messages created before given date. ' - 'The date format must be conforming to ISO8601. ' - 'Available only for microversion >= 2.52.')) + help=_( + 'Return only user messages created before given date. ' + 'The date format must be conforming to ISO8601. ' + 'Available only for microversion >= 2.52.' + ), + ) return parser def take_action(self, parsed_args): @@ -141,14 +163,17 @@ def take_action(self, parsed_args): 'resource_id': parsed_args.resource_id, 'action_id': parsed_args.action_id, 'detail_id': parsed_args.detail_id, - 'message_level': parsed_args.message_level + 'message_level': parsed_args.message_level, } if share_client.api_version < api_versions.APIVersion("2.52"): if getattr(parsed_args, 'since') or getattr(parsed_args, 'before'): - raise exceptions.CommandError(_( - "Filtering messages by 'since' and 'before'" - " is possible only with Manila API version >=2.52")) + raise exceptions.CommandError( + _( + "Filtering messages by 'since' and 'before'" + " is possible only with Manila API version >=2.52" + ) + ) else: search_opts['created_since'] = parsed_args.since search_opts['created_before'] = parsed_args.before @@ -161,30 +186,35 @@ def take_action(self, parsed_args): 'Action ID', 'User Message', 'Detail ID', - 'Created At'] + 'Created At', + ] - return (columns, (oscutils.get_item_properties - (m, columns) for m in messages)) + return ( + columns, + (oscutils.get_item_properties(m, columns) for m in messages), + ) class ShowMessage(command.ShowOne): """Show details about a message.""" + _description = _("Show details about a message") def get_parser(self, prog_name): - parser = super(ShowMessage, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( - 'message', - metavar='', - help=_('ID of the message.')) + 'message', metavar='', help=_('ID of the message.') + ) return parser def take_action(self, parsed_args): share_client = self.app.client_manager.share message = apiutils.find_resource( - share_client.messages, - parsed_args.message) + share_client.messages, parsed_args.message + ) - return (MESSAGE_ATTRIBUTES, oscutils.get_dict_properties( - message._info, MESSAGE_ATTRIBUTES)) + return ( + MESSAGE_ATTRIBUTES, + oscutils.get_dict_properties(message._info, MESSAGE_ATTRIBUTES), + ) diff --git a/manilaclient/osc/v2/quotas.py b/manilaclient/osc/v2/quotas.py index c03112bb..b851f68d 100644 --- a/manilaclient/osc/v2/quotas.py +++ b/manilaclient/osc/v2/quotas.py @@ -24,131 +24,150 @@ class QuotaSet(command.Command): It can be used to set the default class for all projects. """ - _description = _("Set Quota for a project, or project/user or " - "project/share-type or a class.") + _description = _( + "Set Quota for a project, or project/user or " + "project/share-type or a class." + ) def get_parser(self, prog_name): - parser = super(QuotaSet, self).get_parser(prog_name) + parser = super().get_parser(prog_name) quota_type = parser.add_mutually_exclusive_group() parser.add_argument( 'project', metavar='', - help=_("A project (name/ID) or a class (e.g.: default).") + help=_("A project (name/ID) or a class (e.g.: default)."), ) quota_type.add_argument( '--class', dest='quota_class', action='store_true', default=False, - help=_("Update class quota to all projects. " - "Mutually exclusive with '--user' and '--share-type'.") + help=_( + "Update class quota to all projects. " + "Mutually exclusive with '--user' and '--share-type'." + ), ) quota_type.add_argument( '--user', metavar='', default=None, - help=_("Name or ID of a user to set the quotas for. " - "Mutually exclusive with '--share-type' and '--class'.") + help=_( + "Name or ID of a user to set the quotas for. " + "Mutually exclusive with '--share-type' and '--class'." + ), ) quota_type.add_argument( '--share-type', metavar='', type=str, default=None, - help=_("Name or ID of a share type to set the quotas for. " - "Mutually exclusive with '--user' and '--class'. " - "Available only for microversion >= 2.39") + help=_( + "Name or ID of a share type to set the quotas for. " + "Mutually exclusive with '--user' and '--class'. " + "Available only for microversion >= 2.39" + ), ) parser.add_argument( '--shares', metavar='', type=int, default=None, - help=_('New value for the "shares" quota.') + help=_('New value for the "shares" quota.'), ) parser.add_argument( '--snapshots', metavar='', type=int, default=None, - help=_('New value for the "snapshots" quota.') + help=_('New value for the "snapshots" quota.'), ) parser.add_argument( '--gigabytes', metavar='', type=int, default=None, - help=_('New value for the "gigabytes" quota.') + help=_('New value for the "gigabytes" quota.'), ) parser.add_argument( '--snapshot-gigabytes', metavar='', type=int, default=None, - help=_('New value for the "snapshot-gigabytes" quota.') + help=_('New value for the "snapshot-gigabytes" quota.'), ) parser.add_argument( '--share-networks', metavar='', type=int, default=None, - help=_('New value for the "share-networks" quota.') + help=_('New value for the "share-networks" quota.'), ) parser.add_argument( '--share-groups', metavar='', type=int, default=None, - help=_('New value for the "share-groups" quota. ' - 'Available only for microversion >= 2.40') + help=_( + 'New value for the "share-groups" quota. ' + 'Available only for microversion >= 2.40' + ), ) parser.add_argument( '--share-group-snapshots', metavar='', type=int, default=None, - help=_('New value for the "share-group-snapshots" quota. ' - 'Available only for microversion >= 2.40') + help=_( + 'New value for the "share-group-snapshots" quota. ' + 'Available only for microversion >= 2.40' + ), ) parser.add_argument( '--share-replicas', metavar='', type=int, default=None, - help=_("Number of share replicas. " - "Available only for microversion >= 2.53") + help=_( + "Number of share replicas. " + "Available only for microversion >= 2.53" + ), ) parser.add_argument( '--replica-gigabytes', metavar='', type=int, default=None, - help=_("Capacity of share replicas in total. " - "Available only for microversion >= 2.53") + help=_( + "Capacity of share replicas in total. " + "Available only for microversion >= 2.53" + ), ) parser.add_argument( '--per-share-gigabytes', metavar='', type=int, default=None, - help=_("New value for the 'per-share-gigabytes' quota." - "Available only for microversion >= 2.62") + help=_( + "New value for the 'per-share-gigabytes' quota." + "Available only for microversion >= 2.62" + ), ) parser.add_argument( '--encryption-keys', metavar='', type=int, default=None, - help=_("New value for the 'encryption-keys' quota." - "Available only for microversion >= 2.90") + help=_( + "New value for the 'encryption-keys' quota." + "Available only for microversion >= 2.90" + ), ) parser.add_argument( '--force', dest='force', action="store_true", default=None, - help=_('Force update the quota. ' - 'Not applicable for class update.') + help=_('Force update the quota. Not applicable for class update.'), ) return parser @@ -159,8 +178,8 @@ def take_action(self, parsed_args): user_id = None if parsed_args.user: user_id = utils.find_resource( - identity_client.users, - parsed_args.user).id + identity_client.users, parsed_args.user + ).id kwargs = { "shares": parsed_args.shares, @@ -172,130 +191,164 @@ def take_action(self, parsed_args): if parsed_args.share_type is not None: if share_client.api_version < api_versions.APIVersion('2.39'): - raise exceptions.CommandError(_( - "'share type' quotas are available only starting with " - "'2.39' API microversion.")) + raise exceptions.CommandError( + _( + "'share type' quotas are available only starting with " + "'2.39' API microversion." + ) + ) kwargs["share_type"] = parsed_args.share_type if parsed_args.share_groups is not None: if share_client.api_version < api_versions.APIVersion('2.40'): - raise exceptions.CommandError(_( - "'share group' quotas are available only starting with " - "'2.40' API microversion.")) + raise exceptions.CommandError( + _( + "'share group' quotas are available only starting with " + "'2.40' API microversion." + ) + ) kwargs["share_groups"] = parsed_args.share_groups if parsed_args.share_group_snapshots is not None: if share_client.api_version < api_versions.APIVersion('2.40'): - raise exceptions.CommandError(_( - "'share group snapshots' quotas are available only " - "starting with '2.40' API microversion.")) + raise exceptions.CommandError( + _( + "'share group snapshots' quotas are available only " + "starting with '2.40' API microversion." + ) + ) kwargs["share_group_snapshots"] = parsed_args.share_group_snapshots if parsed_args.share_replicas is not None: if share_client.api_version < api_versions.APIVersion('2.53'): - raise exceptions.CommandError(_( - "setting the number of 'share replicas' is available only " - "starting with API microversion '2.53'.")) + raise exceptions.CommandError( + _( + "setting the number of 'share replicas' is available only " + "starting with API microversion '2.53'." + ) + ) kwargs["share_replicas"] = parsed_args.share_replicas if parsed_args.replica_gigabytes is not None: if share_client.api_version < api_versions.APIVersion('2.53'): - raise exceptions.CommandError(_( - "setting the capacity of share replicas in total " - "is available only starting with API microversion '2.53'.") + raise exceptions.CommandError( + _( + "setting the capacity of share replicas in total " + "is available only starting with API microversion '2.53'." + ) ) kwargs["replica_gigabytes"] = parsed_args.replica_gigabytes if parsed_args.per_share_gigabytes is not None: if share_client.api_version < api_versions.APIVersion('2.62'): - raise exceptions.CommandError(_( - "'per share gigabytes' quotas are available only " - "starting with '2.62' API microversion.") + raise exceptions.CommandError( + _( + "'per share gigabytes' quotas are available only " + "starting with '2.62' API microversion." + ) ) kwargs["per_share_gigabytes"] = parsed_args.per_share_gigabytes if parsed_args.encryption_keys is not None: if share_client.api_version < api_versions.APIVersion('2.90'): - raise exceptions.CommandError(_( - "'encryption keys' quotas are available only " - "starting with '2.90' API microversion.") + raise exceptions.CommandError( + _( + "'encryption keys' quotas are available only " + "starting with '2.90' API microversion." + ) ) kwargs["encryption_keys"] = parsed_args.encryption_keys if all(value is None for value in kwargs.values()): - raise exceptions.CommandError(_( - "Nothing to set. " - "New quota must be specified to at least one of the following " - "resources: 'shares', 'snapshots', 'gigabytes', " - "'snapshot-gigabytes', 'share-networks', 'share-type', " - "'share-groups', 'share-group-snapshots', 'share-replicas', " - "'replica-gigabytes', 'per-share-gigabytes', " - "'encryption_keys'")) + raise exceptions.CommandError( + _( + "Nothing to set. " + "New quota must be specified to at least one of the following " + "resources: 'shares', 'snapshots', 'gigabytes', " + "'snapshot-gigabytes', 'share-networks', 'share-type', " + "'share-groups', 'share-group-snapshots', 'share-replicas', " + "'replica-gigabytes', 'per-share-gigabytes', " + "'encryption_keys'" + ) + ) if parsed_args.quota_class: - kwargs.update({ - "class_name": parsed_args.project, - }) + kwargs.update( + { + "class_name": parsed_args.project, + } + ) try: share_client.quota_classes.update(**kwargs) except Exception as e: - raise exceptions.CommandError(_( - "Failed to set quotas for %s class: '%s'") - % (parsed_args.project, e)) + raise exceptions.CommandError( + _("Failed to set quotas for %s class: '%s'") + % (parsed_args.project, e) + ) else: project_id = utils.find_resource( - identity_client.projects, - parsed_args.project).id + identity_client.projects, parsed_args.project + ).id - kwargs.update({ - "tenant_id": project_id, - "force": parsed_args.force, - "user_id": user_id - }) + kwargs.update( + { + "tenant_id": project_id, + "force": parsed_args.force, + "user_id": user_id, + } + ) try: share_client.quotas.update(**kwargs) except Exception as e: - raise exceptions.CommandError(_( - "Failed to set quotas for project '%s' : '%s'") - % (parsed_args.project, e)) + raise exceptions.CommandError( + _("Failed to set quotas for project '%s' : '%s'") + % (parsed_args.project, e) + ) class QuotaShow(command.ShowOne): """List the quotas for a project or project/user or project/share-type.""" + _description = _("Show Quota") def get_parser(self, prog_name): - parser = super(QuotaShow, self).get_parser(prog_name) + parser = super().get_parser(prog_name) quota_type = parser.add_mutually_exclusive_group() parser.add_argument( 'project', metavar='', - help=_('Name or ID of the project to list quotas for.') + help=_('Name or ID of the project to list quotas for.'), ) quota_type.add_argument( '--user', metavar='', default=None, - help=_("Name or ID of user to list the quotas for. Optional. " - "Mutually exclusive with '--share-type'.") + help=_( + "Name or ID of user to list the quotas for. Optional. " + "Mutually exclusive with '--share-type'." + ), ) quota_type.add_argument( '--share-type', metavar='', type=str, default=None, - help=_("Name or ID of a share type to list the quotas for. " - "Optional. " - "Mutually exclusive with '--user'. " - "Available only for microversion >= 2.39") + help=_( + "Name or ID of a share type to list the quotas for. " + "Optional. " + "Mutually exclusive with '--user'. " + "Available only for microversion >= 2.39" + ), ) parser.add_argument( '--detail', action='store_true', default=False, - help=_('Optional flag to indicate whether to show quota in detail.' - ' Default false, available only for microversion >= 2.25.') + help=_( + 'Optional flag to indicate whether to show quota in detail.' + ' Default false, available only for microversion >= 2.25.' + ), ) parser.add_argument( '--defaults', action='store_true', default=False, - help=_('Show the default quotas for the project.') + help=_('Show the default quotas for the project.'), ) return parser @@ -306,12 +359,12 @@ def take_action(self, parsed_args): user_id = None if parsed_args.user: user_id = utils.find_resource( - identity_client.users, - parsed_args.user).id + identity_client.users, parsed_args.user + ).id project_id = utils.find_resource( - identity_client.projects, - parsed_args.project).id + identity_client.projects, parsed_args.project + ).id quotas = {} if parsed_args.defaults: @@ -324,9 +377,12 @@ def take_action(self, parsed_args): } if parsed_args.share_type is not None: if share_client.api_version < api_versions.APIVersion("2.39"): - raise exceptions.CommandError(_( - "'share type' quotas are available only starting with " - "'2.39' API microversion.")) + raise exceptions.CommandError( + _( + "'share type' quotas are available only starting with " + "'2.39' API microversion." + ) + ) kwargs["share_type"] = parsed_args.share_type quotas = share_client.quotas.get(**kwargs) @@ -335,7 +391,8 @@ def take_action(self, parsed_args): for quota_k, quota_v in sorted(quotas.to_dict().items()): if isinstance(quota_v, dict): quota_v = '\n'.join( - ['%s = %s' % (k, v) for k, v in sorted(quota_v.items())]) + [f'{k} = {v}' for k, v in sorted(quota_v.items())] + ) printable_quotas[quota_k] = quota_v return self.dict2columns(printable_quotas) @@ -350,29 +407,33 @@ class QuotaDelete(command.Command): _description = _("Delete Quota") def get_parser(self, prog_name): - parser = super(QuotaDelete, self).get_parser(prog_name) + parser = super().get_parser(prog_name) quota_type = parser.add_mutually_exclusive_group() parser.add_argument( 'project', metavar='', - help=_('Name or ID of the project to delete quotas for.') + help=_('Name or ID of the project to delete quotas for.'), ) quota_type.add_argument( '--user', metavar='', default=None, - help=_("Name or ID of user to delete the quotas for. Optional. " - "Mutually exclusive with '--share-type'.") + help=_( + "Name or ID of user to delete the quotas for. Optional. " + "Mutually exclusive with '--share-type'." + ), ) quota_type.add_argument( '--share-type', metavar='', type=str, default=None, - help=_("Name or ID of a share type to delete the quotas for. " - "Optional. " - "Mutually exclusive with '--user'. " - "Available only for microversion >= 2.39") + help=_( + "Name or ID of a share type to delete the quotas for. " + "Optional. " + "Mutually exclusive with '--user'. " + "Available only for microversion >= 2.39" + ), ) return parser @@ -383,22 +444,22 @@ def take_action(self, parsed_args): user_id = None if parsed_args.user: user_id = utils.find_resource( - identity_client.users, - parsed_args.user).id + identity_client.users, parsed_args.user + ).id project_id = utils.find_resource( - identity_client.projects, - parsed_args.project).id + identity_client.projects, parsed_args.project + ).id - kwargs = { - "tenant_id": project_id, - "user_id": user_id - } + kwargs = {"tenant_id": project_id, "user_id": user_id} if parsed_args.share_type: if share_client.api_version < api_versions.APIVersion("2.39"): - raise exceptions.CommandError(_( - "'share type' quotas are available only starting with " - "API microversion '2.39'.")) + raise exceptions.CommandError( + _( + "'share type' quotas are available only starting with " + "API microversion '2.39'." + ) + ) kwargs["share_type"] = parsed_args.share_type share_client.quotas.delete(**kwargs) diff --git a/manilaclient/osc/v2/resource_locks.py b/manilaclient/osc/v2/resource_locks.py index 6f0ca873..d1f5b1e6 100644 --- a/manilaclient/osc/v2/resource_locks.py +++ b/manilaclient/osc/v2/resource_locks.py @@ -48,36 +48,41 @@ RESOURCE_TYPE_MANAGERS = { 'share': 'shares', - 'access_rule': 'share_access_rules' + 'access_rule': 'share_access_rules', } class CreateResourceLock(command.ShowOne): """Create a new resource lock.""" + _description = _("Lock a resource action from occurring on a resource") def get_parser(self, prog_name): - parser = super(CreateResourceLock, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'resource', metavar='', - help='Name or ID of resource to lock.') + help='Name or ID of resource to lock.', + ) parser.add_argument( 'resource_type', metavar='', - help='Type of the resource (e.g.: share, access).') + help='Type of the resource (e.g.: share, access).', + ) parser.add_argument( '--resource-action', '--resource_action', metavar='', default='delete', - help='Action to lock on the resource (default="delete")') + help='Action to lock on the resource (default="delete")', + ) parser.add_argument( '--lock-reason', '--lock_reason', '--reason', metavar='', - help='Reason for the resource lock.') + help='Reason for the resource lock.', + ) return parser def take_action(self, parsed_args): @@ -87,13 +92,14 @@ def take_action(self, parsed_args): raise exceptions.CommandError(_("Unsupported resource type")) res_manager = RESOURCE_TYPE_MANAGERS[resource_type] - resource = osc_utils.find_resource(getattr(share_client, res_manager), - parsed_args.resource) + resource = osc_utils.find_resource( + getattr(share_client, res_manager), parsed_args.resource + ) resource_lock = share_client.resource_locks.create( resource.id, resource_type, parsed_args.resource_action, - parsed_args.lock_reason + parsed_args.lock_reason, ) resource_lock._info.pop('links', None) @@ -103,15 +109,14 @@ def take_action(self, parsed_args): class DeleteResourceLock(command.Command): """Remove one or more resource locks.""" + _description = _("Remove one or more resource locks") def get_parser(self, prog_name): - parser = super(DeleteResourceLock, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( - 'lock', - metavar='', - nargs='+', - help='ID(s) of the lock(s).') + 'lock', metavar='', nargs='+', help='ID(s) of the lock(s).' + ) return parser def take_action(self, parsed_args): @@ -121,50 +126,57 @@ def take_action(self, parsed_args): for lock in parsed_args.lock: try: lock = apiutils.find_resource( - share_client.resource_locks, - lock + share_client.resource_locks, lock ) lock.delete() except Exception as e: failure_count += 1 - LOG.error(_( - "Failed to delete %(lock)s: %(e)s"), - {'lock': lock, 'e': e}) + LOG.error( + _("Failed to delete %(lock)s: %(e)s"), + {'lock': lock, 'e': e}, + ) if failure_count > 0: - raise exceptions.CommandError(_( - "Unable to delete some or all of the specified locks.")) + raise exceptions.CommandError( + _("Unable to delete some or all of the specified locks.") + ) class ListResourceLock(command.Lister): """Lists all resource locks.""" + _description = _("Lists all resource locks") def get_parser(self, prog_name): - parser = super(ListResourceLock, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( '--all-projects', action='store_true', - help=_("Filter resource locks for all projects. (Admin only).") + help=_("Filter resource locks for all projects. (Admin only)."), ) parser.add_argument( '--project', default=None, - help=_("Filter resource locks for specific project by name or ID, " - "combine with --all-projects (Admin only).") + help=_( + "Filter resource locks for specific project by name or ID, " + "combine with --all-projects (Admin only)." + ), ) parser.add_argument( '--user', default=None, - help=_("Filter resource locks for specific user by name or ID, " - "combine with --all-projects to search across projects " - "(Admin only).") + help=_( + "Filter resource locks for specific user by name or ID, " + "combine with --all-projects to search across projects " + "(Admin only)." + ), ) parser.add_argument( '--id', metavar='', default=None, - help='Filter resource locks by ID. Default=None.') + help='Filter resource locks by ID. Default=None.', + ) parser.add_argument( '--resource', '--resource-id', @@ -172,22 +184,24 @@ def get_parser(self, prog_name): default=None, metavar='', dest='resource', - help=_("Filter resource locks for a resource by ID, specify " - "--resource-type to look up by name.") + help=_( + "Filter resource locks for a resource by ID, specify " + "--resource-type to look up by name." + ), ) parser.add_argument( '--resource-type', '--resource_type', default=None, metavar='', - help=_("Filter resource locks by type of resource.") + help=_("Filter resource locks by type of resource."), ) parser.add_argument( '--resource-action', '--resource_action', default=None, metavar='', - help=_("Filter resource locks by resource action.") + help=_("Filter resource locks by resource action."), ) parser.add_argument( @@ -197,52 +211,60 @@ def get_parser(self, prog_name): default=None, choices=['user', 'admin', 'service'], metavar='', - help=_("Filter resource locks by context.") + help=_("Filter resource locks by context."), ) parser.add_argument( '--since', default=None, metavar='', - help=_("Filter resource locks created since given date. " - "The date format must be conforming to ISO8601. ") + help=_( + "Filter resource locks created since given date. " + "The date format must be conforming to ISO8601. " + ), ) parser.add_argument( '--before', default=None, metavar='', - help=_("Filter resource locks created before given date. " - "The date format must be conforming to ISO8601. ") + help=_( + "Filter resource locks created before given date. " + "The date format must be conforming to ISO8601. " + ), ) parser.add_argument( '--limit', metavar='', type=int, default=None, - help=_("Number of resource locks to list. (Default=None)")) + help=_("Number of resource locks to list. (Default=None)"), + ) parser.add_argument( '--offset', metavar="", default=None, help='Starting position of resource lock records ' - 'in a paginated list.') + 'in a paginated list.', + ) parser.add_argument( - '--sort-key', '--sort_key', + '--sort-key', + '--sort_key', metavar='', type=str, default=None, choices=constants.RESOURCE_LOCK_SORT_KEY_VALUES, - help='Key to be sorted, available keys are %(keys)s. ' - 'Default=None.' - % {'keys': constants.RESOURCE_LOCK_SORT_KEY_VALUES}) + help=f'Key to be sorted, available keys are {constants.RESOURCE_LOCK_SORT_KEY_VALUES}. ' + 'Default=None.', + ) parser.add_argument( - '--sort-dir', '--sort_dir', + '--sort-dir', + '--sort_dir', metavar='', type=str, default=None, choices=constants.SORT_DIR_VALUES, - help='Sort direction, available values are %(values)s. ' - 'OPTIONAL: Default=None.' % { - 'values': constants.SORT_DIR_VALUES}) + help=f'Sort direction, available values are {constants.SORT_DIR_VALUES}. ' + 'OPTIONAL: Default=None.', + ) parser.add_argument( '--detailed', dest='detailed', @@ -251,7 +273,8 @@ def get_parser(self, prog_name): type=int, const=1, default=0, - help="Show detailed information about filtered resource locks.") + help="Show detailed information about filtered resource locks.", + ) return parser def take_action(self, parsed_args): @@ -270,11 +293,12 @@ def take_action(self, parsed_args): project_id = identity_common.find_project( identity_client, parsed_args.project, - parsed_args.project_domain).id + parsed_args.project_domain, + ).id if parsed_args.user: - user_id = identity_common.find_user(identity_client, - parsed_args.user, - parsed_args.user_domain).id + user_id = identity_common.find_user( + identity_client, parsed_args.user, parsed_args.user_domain + ).id # set all_projects when using project option all_projects = bool(parsed_args.project) or parsed_args.all_projects @@ -286,12 +310,12 @@ def take_action(self, parsed_args): if resource_id is not None: res_manager = RESOURCE_TYPE_MANAGERS[resource_type] resource_id = osc_utils.find_resource( - getattr(share_client, res_manager), - parsed_args.resource + getattr(share_client, res_manager), parsed_args.resource ).id elif resource_id and not uuidutils.is_uuid_like(resource_id): raise exceptions.CommandError( - _("Provide resource ID or specify --resource-type.")) + _("Provide resource ID or specify --resource-type.") + ) search_opts = { 'all_projects': all_projects, @@ -311,60 +335,68 @@ def take_action(self, parsed_args): resource_locks = share_client.resource_locks.list( search_opts=search_opts, sort_key=parsed_args.sort_key, - sort_dir=parsed_args.sort_dir + sort_dir=parsed_args.sort_dir, ) - return (columns, (osc_utils.get_item_properties - (m, columns) for m in resource_locks)) + return ( + columns, + ( + osc_utils.get_item_properties(m, columns) + for m in resource_locks + ), + ) class ShowResourceLock(command.ShowOne): """Show details about a resource lock.""" + _description = _("Show details about a resource lock") def get_parser(self, prog_name): - parser = super(ShowResourceLock, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( - 'lock', - metavar='', - help=_('ID of resource lock to show.')) + 'lock', metavar='', help=_('ID of resource lock to show.') + ) return parser def take_action(self, parsed_args): share_client = self.app.client_manager.share resource_lock = apiutils.find_resource( - share_client.resource_locks, - parsed_args.lock) + share_client.resource_locks, parsed_args.lock + ) return ( LOCK_DETAIL_ATTRIBUTES, - osc_utils.get_dict_properties(resource_lock._info, - LOCK_DETAIL_ATTRIBUTES) + osc_utils.get_dict_properties( + resource_lock._info, LOCK_DETAIL_ATTRIBUTES + ), ) class SetResourceLock(command.Command): """Set resource lock properties.""" + _description = _("Update resource lock properties") def get_parser(self, prog_name): - parser = super(SetResourceLock, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( - 'lock', - metavar='', - help='ID of lock to update.') + 'lock', metavar='', help='ID of lock to update.' + ) parser.add_argument( '--resource-action', '--resource_action', metavar='', - help='Resource action to set in the resource lock') + help='Resource action to set in the resource lock', + ) parser.add_argument( '--lock-reason', '--lock_reason', '--reason', dest='lock_reason', - help="Reason for the resource lock") + help="Reason for the resource lock", + ) return parser def take_action(self, parsed_args): @@ -377,21 +409,20 @@ def take_action(self, parsed_args): update_kwargs['lock_reason'] = parsed_args.lock_reason if update_kwargs: share_client.resource_locks.update( - parsed_args.lock, - **update_kwargs + parsed_args.lock, **update_kwargs ) class UnsetResourceLock(command.Command): """Unsets a property on a resource lock.""" + _description = _("Remove resource lock properties") def get_parser(self, prog_name): - parser = super(UnsetResourceLock, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( - 'lock', - metavar='', - help='ID of resource lock to update.') + 'lock', metavar='', help='ID of resource lock to update.' + ) parser.add_argument( '--lock-reason', '--lock_reason', @@ -399,7 +430,8 @@ def get_parser(self, prog_name): dest='lock_reason', action='store_true', default=False, - help="Unset the lock reason. (Default=False)") + help="Unset the lock reason. (Default=False)", + ) return parser def take_action(self, parsed_args): @@ -407,6 +439,5 @@ def take_action(self, parsed_args): if parsed_args.lock_reason: share_client.resource_locks.update( - parsed_args.lock, - lock_reason=None + parsed_args.lock, lock_reason=None ) diff --git a/manilaclient/osc/v2/security_services.py b/manilaclient/osc/v2/security_services.py index c8230f14..f27cafdf 100644 --- a/manilaclient/osc/v2/security_services.py +++ b/manilaclient/osc/v2/security_services.py @@ -25,76 +25,85 @@ class CreateShareSecurityService(command.ShowOne): """Create security service used by project.""" + _description = _("Create security service used by project.") def get_parser(self, prog_name): - parser = super(CreateShareSecurityService, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'type', metavar='', default=None, choices=['ldap', 'kerberos', 'active_directory'], - help=_("Security service type. Possible options are: " - "'ldap', 'kerberos', 'active_directory'.") + help=_( + "Security service type. Possible options are: " + "'ldap', 'kerberos', 'active_directory'." + ), ) parser.add_argument( '--dns-ip', metavar='', default=None, - help=_("DNS IP address of the security service used " - "inside project's network.") + help=_( + "DNS IP address of the security service used " + "inside project's network." + ), ) parser.add_argument( '--ou', metavar='', default=None, - help=_("Security service OU (Organizational Unit). " - "Available only for microversion >= 2.44.") + help=_( + "Security service OU (Organizational Unit). " + "Available only for microversion >= 2.44." + ), ) parser.add_argument( '--server', metavar='', default=None, - help=_("Security service IP address or hostname.") + help=_("Security service IP address or hostname."), ) parser.add_argument( '--domain', metavar='', default=None, - help=_("Security service domain.") + help=_("Security service domain."), ) parser.add_argument( '--user', metavar='= 2.76. Can be provided in the " - "place of '--server' but not along with it.") + help=_( + "Default AD site. Available only for " + "microversion >= 2.76. Can be provided in the " + "place of '--server' but not along with it." + ), ) return parser @@ -116,14 +125,16 @@ def take_action(self, parsed_args): elif parsed_args.ou: raise exceptions.CommandError( "Defining a security service Organizational Unit is " - "available only for microversion >= 2.44") + "available only for microversion >= 2.44" + ) if share_client.api_version >= api_versions.APIVersion("2.76"): kwargs['default_ad_site'] = parsed_args.default_ad_site elif parsed_args.default_ad_site: raise exceptions.CommandError( "Defining a security service Default AD site is " - "available only for microversion >= 2.76") + "available only for microversion >= 2.76" + ) if parsed_args.type == 'active_directory': server = parsed_args.server @@ -132,25 +143,28 @@ def take_action(self, parsed_args): raise exceptions.CommandError( "Cannot create security service because both " "server and 'default_ad_site' were provided. " - "Specify either server or 'default_ad_site'.") + "Specify either server or 'default_ad_site'." + ) security_service = share_client.security_services.create( - parsed_args.type, **kwargs) + parsed_args.type, **kwargs + ) return self.dict2columns(security_service._info) class DeleteShareSecurityService(command.Command): """Delete one or more security services.""" + _description = _("Delete one or more security services.") def get_parser(self, prog_name): - parser = super(DeleteShareSecurityService, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'security_service', metavar='', nargs="+", - help=_("Name or ID of the security service(s) to delete.") + help=_("Name or ID of the security service(s) to delete."), ) return parser @@ -161,33 +175,36 @@ def take_action(self, parsed_args): for security_service in parsed_args.security_service: try: security_service_obj = oscutils.find_resource( - share_client.security_services, - security_service) - share_client.security_services.delete( - security_service_obj) + share_client.security_services, security_service + ) + share_client.security_services.delete(security_service_obj) except Exception as e: result += 1 - LOG.error(f"Failed to delete security service with " - f"name or ID {security_service}: {e}") + LOG.error( + f"Failed to delete security service with " + f"name or ID {security_service}: {e}" + ) if result > 0: total = len(parsed_args.security_service) - msg = (f"{result} of {total} security services failed " - f"to be deleted.") + msg = ( + f"{result} of {total} security services failed to be deleted." + ) raise exceptions.CommandError(msg) class ShowShareSecurityService(command.ShowOne): """Show security service.""" + _description = _("Show security service.") def get_parser(self, prog_name): - parser = super(ShowShareSecurityService, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'security_service', metavar='', - help=_("Security service name or ID to show.") + help=_("Security service name or ID to show."), ) return parser @@ -195,85 +212,88 @@ def take_action(self, parsed_args): share_client = self.app.client_manager.share security_service = oscutils.find_resource( - share_client.security_services, - parsed_args.security_service) + share_client.security_services, parsed_args.security_service + ) data = security_service._info if parsed_args.formatter == 'table': if 'share_networks' in data.keys(): - data['share_networks'] = "\n".join( - data['share_networks']) + data['share_networks'] = "\n".join(data['share_networks']) return self.dict2columns(data) class SetShareSecurityService(command.Command): """Set security service.""" + _description = _("Set security service.") def get_parser(self, prog_name): - parser = super(SetShareSecurityService, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'security_service', metavar='', - help=_("Security service name or ID.") + help=_("Security service name or ID."), ) parser.add_argument( '--dns-ip', metavar='', default=None, - help=_("Set DNS IP address used inside project's network.") + help=_("Set DNS IP address used inside project's network."), ) parser.add_argument( '--ou', metavar='', default=None, - help=_("Set security service OU (Organizational Unit). " - "Available only for microversion >= 2.44.") + help=_( + "Set security service OU (Organizational Unit). " + "Available only for microversion >= 2.44." + ), ) parser.add_argument( '--server', metavar='', default=None, - help=_("Set security service IP address or hostname.") + help=_("Set security service IP address or hostname."), ) parser.add_argument( '--domain', metavar='', default=None, - help=_("Set security service domain.") + help=_("Set security service domain."), ) parser.add_argument( '--user', metavar='= 2.76.") + help=_( + "Default AD site. Available only for microversion >= 2.76." + ), ) return parser @@ -281,8 +301,8 @@ def take_action(self, parsed_args): share_client = self.app.client_manager.share security_service = oscutils.find_resource( - share_client.security_services, - parsed_args.security_service) + share_client.security_services, parsed_args.security_service + ) kwargs = { 'dns_ip': parsed_args.dns_ip, @@ -297,16 +317,20 @@ def take_action(self, parsed_args): if share_client.api_version >= api_versions.APIVersion("2.44"): kwargs['ou'] = parsed_args.ou elif parsed_args.ou: - raise exceptions.CommandError(_( - "Setting a security service Organizational Unit is " - "available only for microversion >= 2.44")) + raise exceptions.CommandError( + _( + "Setting a security service Organizational Unit is " + "available only for microversion >= 2.44" + ) + ) if share_client.api_version >= api_versions.APIVersion("2.76"): kwargs['default_ad_site'] = parsed_args.default_ad_site elif parsed_args.default_ad_site: raise exceptions.CommandError( "Defining a security service Default AD site is " - "available only for microversion >= 2.76") + "available only for microversion >= 2.76" + ) if security_service.type == 'active_directory': server = parsed_args.server @@ -315,72 +339,78 @@ def take_action(self, parsed_args): raise exceptions.CommandError( "Cannot set security service because both " "server and 'default_ad_site' were provided. " - "Specify either server or 'default_ad_site'.") + "Specify either server or 'default_ad_site'." + ) try: security_service.update(**kwargs) except Exception as e: raise exceptions.CommandError( - f"One or more set operations failed: {e}") + f"One or more set operations failed: {e}" + ) class UnsetShareSecurityService(command.Command): """Unset security service.""" + _description = _("Unset security service.") def get_parser(self, prog_name): - parser = super(UnsetShareSecurityService, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'security_service', metavar='', - help=_("Security service name or ID.") + help=_("Security service name or ID."), ) parser.add_argument( '--dns-ip', action='store_true', - help=_("Unset DNS IP address used inside project's network.") + help=_("Unset DNS IP address used inside project's network."), ) parser.add_argument( '--ou', action='store_true', - help=_("Unset security service OU (Organizational Unit). " - "Available only for microversion >= 2.44.") + help=_( + "Unset security service OU (Organizational Unit). " + "Available only for microversion >= 2.44." + ), ) parser.add_argument( '--server', action='store_true', - help=_("Unset security service IP address or hostname.") + help=_("Unset security service IP address or hostname."), ) parser.add_argument( '--domain', action='store_true', - help=_("Unset security service domain.") + help=_("Unset security service domain."), ) parser.add_argument( '--user', action='store_true', - help=_("Unset security service user or group used by project.") + help=_("Unset security service user or group used by project."), ) parser.add_argument( '--password', action='store_true', - help=_("Unset password used by user.") + help=_("Unset password used by user."), ) parser.add_argument( '--name', action='store_true', - help=_("Unset security service name.") + help=_("Unset security service name."), ) parser.add_argument( '--description', action='store_true', - help=_("Unset security service description.") + help=_("Unset security service description."), ) parser.add_argument( '--default-ad-site', dest='default_ad_site', action='store_true', - help=_("Default AD site. " - "Available only for microversion >= 2.76.") + help=_( + "Default AD site. Available only for microversion >= 2.76." + ), ) return parser @@ -388,126 +418,155 @@ def take_action(self, parsed_args): share_client = self.app.client_manager.share security_service = oscutils.find_resource( - share_client.security_services, - parsed_args.security_service) + share_client.security_services, parsed_args.security_service + ) kwargs = {} - args = ['dns_ip', 'server', 'domain', 'user', 'password', - 'name', 'description'] + args = [ + 'dns_ip', + 'server', + 'domain', + 'user', + 'password', + 'name', + 'description', + ] for arg in args: if getattr(parsed_args, arg): # the SDK unsets a value if it is an empty string kwargs[arg] = '' - if (parsed_args.ou and - share_client.api_version >= api_versions.APIVersion("2.44")): + if ( + parsed_args.ou + and share_client.api_version >= api_versions.APIVersion("2.44") + ): # the SDK unsets a value if it is an empty string kwargs['ou'] = '' elif parsed_args.ou: - raise exceptions.CommandError(_( - "Unsetting a security service Organizational Unit is " - "available only for microversion >= 2.44")) - - if (parsed_args.default_ad_site and - share_client.api_version >= api_versions.APIVersion("2.76")): + raise exceptions.CommandError( + _( + "Unsetting a security service Organizational Unit is " + "available only for microversion >= 2.44" + ) + ) + + if ( + parsed_args.default_ad_site + and share_client.api_version >= api_versions.APIVersion("2.76") + ): # the SDK unsets a value if it is an empty string kwargs['default_ad_site'] = '' elif parsed_args.default_ad_site: - raise exceptions.CommandError(_( - "Unsetting a security service Default AD site is " - "available only for microversion >= 2.76")) + raise exceptions.CommandError( + _( + "Unsetting a security service Default AD site is " + "available only for microversion >= 2.76" + ) + ) try: security_service.update(**kwargs) except Exception as e: raise exceptions.CommandError( - f"One or more unset operations failed: {e}") + f"One or more unset operations failed: {e}" + ) class ListShareSecurityService(command.Lister): """List security services.""" + _description = _("List security services.") def get_parser(self, prog_name): - parser = super(ListShareSecurityService, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( '--all-projects', action='store_true', - help=_("Display information from all projects (Admin only).") + help=_("Display information from all projects (Admin only)."), ) parser.add_argument( '--share-network', metavar='', default=None, - help=_("Filter results by share network name or ID.") + help=_("Filter results by share network name or ID."), ) parser.add_argument( '--status', metavar='', default=None, - help=_("Filter results by status.") + help=_("Filter results by status."), ) parser.add_argument( '--name', metavar='', default=None, - help=_("Filter results by security service name.") + help=_("Filter results by security service name."), ) parser.add_argument( '--type', metavar='', default=None, - help=_("Filter results by security service type.") + help=_("Filter results by security service type."), ) parser.add_argument( '--user', metavar='= 2.44.") + help=_( + "Filter results by security service OU " + "(Organizational Unit). " + "Available only for microversion >= 2.44." + ), ) parser.add_argument( '--default-ad-site', metavar='', dest='default_ad_site', default=None, - help=_("Filter results by security service default_ad_site. " - "Available only for microversion >= 2.76.") + help=_( + "Filter results by security service default_ad_site. " + "Available only for microversion >= 2.76." + ), ) parser.add_argument( '--server', metavar='', default=None, - help=_("Filter results by security service IP " - "address or hostname.") + help=_( + "Filter results by security service IP address or hostname." + ), ) parser.add_argument( '--domain', metavar='', default=None, - help=_("Filter results by security service domain.") + help=_("Filter results by security service domain."), ) parser.add_argument( '--detail', action='store_true', - help=_("Show detailed information about filtered " - "security services.") + help=_( + "Show detailed information about filtered security services." + ), ) parser.add_argument( "--limit", @@ -515,12 +574,12 @@ def get_parser(self, prog_name): type=int, default=None, action=parseractions.NonNegativeAction, - help=_("Limit the number of security services returned") + help=_("Limit the number of security services returned"), ) parser.add_argument( "--marker", metavar="", - help=_("The last security service ID of the previous page") + help=_("The last security service ID of the previous page"), ) return parser @@ -548,34 +607,43 @@ def take_action(self, parsed_args): 'limit': parsed_args.limit, } - if (parsed_args.ou and - share_client.api_version >= api_versions.APIVersion("2.44")): + if ( + parsed_args.ou + and share_client.api_version >= api_versions.APIVersion("2.44") + ): search_opts['ou'] = parsed_args.ou elif parsed_args.ou: - raise exceptions.CommandError(_( - "Filtering results by security service Organizational Unit is " - "available only for microversion >= 2.44")) - - if (parsed_args.default_ad_site and - share_client.api_version >= api_versions.APIVersion("2.76")): + raise exceptions.CommandError( + _( + "Filtering results by security service Organizational Unit is " + "available only for microversion >= 2.44" + ) + ) + + if ( + parsed_args.default_ad_site + and share_client.api_version >= api_versions.APIVersion("2.76") + ): search_opts['default_ad_site'] = parsed_args.default_ad_site elif parsed_args.default_ad_site: - raise exceptions.CommandError(_( - "Filtering results by security service Default AD site is " - "available only for microversion >= 2.76")) + raise exceptions.CommandError( + _( + "Filtering results by security service Default AD site is " + "available only for microversion >= 2.76" + ) + ) if parsed_args.share_network: search_opts['share_network_id'] = oscutils.find_resource( - share_client.share_networks, - parsed_args.share_network).id + share_client.share_networks, parsed_args.share_network + ).id data = share_client.security_services.list( - search_opts=search_opts, - detailed=parsed_args.detail + search_opts=search_opts, detailed=parsed_args.detail ) return ( columns, - (oscutils.get_item_properties(s, columns) for s in data) + (oscutils.get_item_properties(s, columns) for s in data), ) diff --git a/manilaclient/osc/v2/services.py b/manilaclient/osc/v2/services.py index 68e55cee..dd4cab76 100644 --- a/manilaclient/osc/v2/services.py +++ b/manilaclient/osc/v2/services.py @@ -19,20 +19,23 @@ class SetShareService(command.Command): """Enable/disable share service (Admin only).""" + _description = _("Enable/Disable share service (Admin only).") def get_parser(self, prog_name): - parser = super(SetShareService, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'host', metavar='', - help=_("Host name as 'example_host@example_backend'.") + help=_("Host name as 'example_host@example_backend'."), ) parser.add_argument( 'binary', metavar='', - help=_("Service binary, could be 'manila-share', " - "'manila-scheduler' or 'manila-data'") + help=_( + "Service binary, could be 'manila-share', " + "'manila-scheduler' or 'manila-data'" + ), ) enable_group = parser.add_mutually_exclusive_group() enable_group.add_argument( @@ -48,15 +51,19 @@ def get_parser(self, prog_name): parser.add_argument( "--disable-reason", metavar="", - help=_("Reason for disabling the service " - "(should be used with --disable option)") + help=_( + "Reason for disabling the service " + "(should be used with --disable option)" + ), ) return parser def take_action(self, parsed_args): if parsed_args.disable_reason and not parsed_args.disable: - msg = _("Cannot specify option --disable-reason without " - "--disable specified.") + msg = _( + "Cannot specify option --disable-reason without " + "--disable specified." + ) raise exceptions.CommandError(msg) share_client = self.app.client_manager.share @@ -64,66 +71,74 @@ def take_action(self, parsed_args): if parsed_args.enable: try: share_client.services.enable( - parsed_args.host, parsed_args.binary) + parsed_args.host, parsed_args.binary + ) except Exception as e: - raise exceptions.CommandError(_( - "Failed to enable service: %s" % e)) + raise exceptions.CommandError( + _(f"Failed to enable service: {e}") + ) if parsed_args.disable: if parsed_args.disable_reason: if share_client.api_version < api_versions.APIVersion("2.83"): raise exceptions.CommandError( "Service disable reason can be specified only with " - "manila API version >= 2.83") + "manila API version >= 2.83" + ) try: if parsed_args.disable_reason: share_client.services.disable( - parsed_args.host, parsed_args.binary, - disable_reason=parsed_args.disable_reason) + parsed_args.host, + parsed_args.binary, + disable_reason=parsed_args.disable_reason, + ) else: share_client.services.disable( - parsed_args.host, parsed_args.binary) + parsed_args.host, parsed_args.binary + ) except Exception as e: - raise exceptions.CommandError(_( - "Failed to disable service: %s" % e)) + raise exceptions.CommandError( + _(f"Failed to disable service: {e}") + ) class ListShareService(command.Lister): """List share services (Admin only).""" + _description = _("List share services (Admin only).") def get_parser(self, prog_name): - parser = super(ListShareService, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "--host", metavar="", default=None, - help=_("Filter services by name of the host.") + help=_("Filter services by name of the host."), ) parser.add_argument( "--binary", metavar="", default=None, - help=_("Filter services by the name of the service.") + help=_("Filter services by the name of the service."), ) parser.add_argument( "--status", metavar="", default=None, - help=_("Filter results by status.") + help=_("Filter results by status."), ) parser.add_argument( "--state", metavar="", default=None, choices=['up', 'down'], - help=_("Filter results by state.") + help=_("Filter results by state."), ) parser.add_argument( "--zone", metavar="", default=None, - help=_("Filter services by their availability zone.") + help=_("Filter services by their availability zone."), ) return parser @@ -147,30 +162,34 @@ def take_action(self, parsed_args): 'Zone', 'Status', 'State', - 'Updated At' + 'Updated At', ] if share_client.api_version >= api_versions.APIVersion("2.83"): columns.append('Disabled Reason') if share_client.api_version >= api_versions.APIVersion("2.86"): columns.append('Ensuring') - data = (osc_utils.get_dict_properties( - service._info, columns) for service in services) + data = ( + osc_utils.get_dict_properties(service._info, columns) + for service in services + ) return (columns, data) class EnsureShareService(command.Command): """Run ensure shares in a back end (Admin only).""" + _description = _("Run ensure shares in a back end (Admin only).") def get_parser(self, prog_name): - parser = super(EnsureShareService, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'host', metavar='', - help=_("Host to run ensure shares. " - "'example_host@example_backend'.") + help=_( + "Host to run ensure shares. 'example_host@example_backend'." + ), ) return parser @@ -180,11 +199,12 @@ def take_action(self, parsed_args): if share_client.api_version < api_versions.APIVersion("2.86"): raise exceptions.CommandError( "Ensure shares API is only available in " - "manila API version >= 2.86") + "manila API version >= 2.86" + ) try: share_client.services.ensure_shares(parsed_args.host) except Exception as e: raise exceptions.CommandError( - _("Failed to run ensure shares: %s" % e) + _(f"Failed to run ensure shares: {e}") ) diff --git a/manilaclient/osc/v2/share.py b/manilaclient/osc/v2/share.py index 1309dccb..83454d06 100644 --- a/manilaclient/osc/v2/share.py +++ b/manilaclient/osc/v2/share.py @@ -59,7 +59,7 @@ 'has_replicas', 'created_at', 'metadata', - 'encryption_key_ref' + 'encryption_key_ref', ] SHARE_ATTRIBUTES_HEADERS = [ @@ -91,39 +91,38 @@ 'Has Replicas', 'Created At', 'Properties', - 'Encryption Key Ref' + 'Encryption Key Ref', ] class CreateShare(command.ShowOne): """Create a new share.""" + _description = _("Create new share") def get_parser(self, prog_name): - parser = super(CreateShare, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'share_proto', metavar="", - help=_('Share protocol (NFS, CIFS, CephFS, GlusterFS or HDFS)') + help=_('Share protocol (NFS, CIFS, CephFS, GlusterFS or HDFS)'), ) parser.add_argument( - 'size', - metavar="", - type=int, - help=_('Share size in GiB.') + 'size', metavar="", type=int, help=_('Share size in GiB.') ) parser.add_argument( '--name', metavar="", default=None, - help=_('Optional share name. (Default=None)') + help=_('Optional share name. (Default=None)'), ) parser.add_argument( '--snapshot-id', metavar="", default=None, - help=_("Optional snapshot ID to create the share from." - " (Default=None)") + help=_( + "Optional snapshot ID to create the share from. (Default=None)" + ), ) # NOTE(vkmc) --property replaces --metadata in osc parser.add_argument( @@ -131,8 +130,10 @@ def get_parser(self, prog_name): metavar="", default={}, action=parseractions.KeyValueAction, - help=_("Set a property to this share " - "(repeat option to set multiple properties)"), + help=_( + "Set a property to this share " + "(repeat option to set multiple properties)" + ), ) parser.add_argument( '--share-network', @@ -144,66 +145,78 @@ def get_parser(self, prog_name): '--description', metavar='', default=None, - help=_('Optional share description. (Default=None)') + help=_('Optional share description. (Default=None)'), ) parser.add_argument( '--public', metavar='', default=False, - help=_('Level of visibility for share. ' - 'Defines whether other tenants are able to see it or not. ' - '(Default = False)') + help=_( + 'Level of visibility for share. ' + 'Defines whether other tenants are able to see it or not. ' + '(Default = False)' + ), ) parser.add_argument( '--share-type', metavar='', default=None, - help=_('The share type to create the share with. If not ' - 'specified, unless creating from a snapshot, the default ' - 'share type will be used.') + help=_( + 'The share type to create the share with. If not ' + 'specified, unless creating from a snapshot, the default ' + 'share type will be used.' + ), ) parser.add_argument( '--availability-zone', metavar='', default=None, - help=_('Availability zone in which share should be created.') + help=_('Availability zone in which share should be created.'), ) parser.add_argument( '--share-group', metavar='', default=None, - help=_('Optional share group name or ID in which to create ' - 'the share. (Default=None).') + help=_( + 'Optional share group name or ID in which to create ' + 'the share. (Default=None).' + ), ) parser.add_argument( '--wait', action='store_true', default=False, - help=_('Wait for share creation') + help=_('Wait for share creation'), ) parser.add_argument( "--scheduler-hint", metavar="", default={}, action=parseractions.KeyValueAction, - help=_("Set Scheduler hints for the share as key=value pairs, " - "possible keys are same_host, different_host." - "(repeat option to set multiple hints)"), + help=_( + "Set Scheduler hints for the share as key=value pairs, " + "possible keys are same_host, different_host." + "(repeat option to set multiple hints)" + ), ) parser.add_argument( '--mount-point-name', metavar="", default=None, - help=_('Optional custom export location. Available for ' - 'microversion >= 2.84') + help=_( + 'Optional custom export location. Available for ' + 'microversion >= 2.84' + ), ) parser.add_argument( '--encryption-key-ref', metavar="", default=None, - help=_('Set encryption key reference i.e. UUID of the secret ' - 'stored in the key manager. Available for ' - 'microversion >= 2.90') + help=_( + 'Set encryption key reference i.e. UUID of the secret ' + 'stored in the key manager. Available for ' + 'microversion >= 2.90' + ), ) return parser @@ -214,38 +227,45 @@ def take_action(self, parsed_args): if parsed_args.name: if parsed_args.name.capitalize() == 'None': raise apiclient_exceptions.CommandError( - "Share name cannot be with the value 'None'") + "Share name cannot be with the value 'None'" + ) share_type = None if parsed_args.share_type: - share_type = apiutils.find_resource(share_client.share_types, - parsed_args.share_type).id + share_type = apiutils.find_resource( + share_client.share_types, parsed_args.share_type + ).id elif not parsed_args.snapshot_id: try: share_type = share_client.share_types.get( - share_type='default').id + share_type='default' + ).id except apiclient_exceptions.CommandError: - msg = ("There is no default share type available. You must " - "pick a valid share type to create a share.") + msg = ( + "There is no default share type available. You must " + "pick a valid share type to create a share." + ) raise exceptions.CommandError(msg) share_network = None if parsed_args.share_network: share_network = apiutils.find_resource( - share_client.share_networks, - parsed_args.share_network).id + share_client.share_networks, parsed_args.share_network + ).id share_group = None if parsed_args.share_group: - share_group = apiutils.find_resource(share_client.share_groups, - parsed_args.share_group).id + share_group = apiutils.find_resource( + share_client.share_groups, parsed_args.share_group + ).id size = parsed_args.size snapshot_id = None if parsed_args.snapshot_id: - snapshot = apiutils.find_resource(share_client.share_snapshots, - parsed_args.snapshot_id) + snapshot = apiutils.find_resource( + share_client.share_snapshots, parsed_args.snapshot_id + ) snapshot_id = snapshot.id size = max(size or 0, snapshot.size) @@ -254,7 +274,8 @@ def take_action(self, parsed_args): if share_client.api_version < api_versions.APIVersion('2.84'): raise exceptions.CommandError( 'Setting share mount point name is ' - 'available only for API microversion >= 2.84') + 'available only for API microversion >= 2.84' + ) else: mount_point_name = parsed_args.mount_point_name @@ -263,7 +284,8 @@ def take_action(self, parsed_args): if share_client.api_version < api_versions.APIVersion('2.90'): raise exceptions.CommandError( 'Setting share encryption key reference is ' - 'available only for API microversion >= 2.90') + 'available only for API microversion >= 2.90' + ) else: encryption_key_ref = parsed_args.encryption_key_ref @@ -272,27 +294,32 @@ def take_action(self, parsed_args): if share_client.api_version < api_versions.APIVersion('2.65'): raise exceptions.CommandError( 'Setting share scheduler hints for a share is ' - 'available only for API microversion >= 2.65') + 'available only for API microversion >= 2.65' + ) else: scheduler_hints = utils.extract_key_value_options( - parsed_args.scheduler_hint) + parsed_args.scheduler_hint + ) same_host_hint_shares = scheduler_hints.get('same_host') different_host_hint_shares = scheduler_hints.get( - 'different_host') + 'different_host' + ) if same_host_hint_shares: same_host_hint_shares = [ apiutils.find_resource(share_client.shares, sh).id for sh in same_host_hint_shares.split(',') ] - scheduler_hints['same_host'] = ( - ','.join(same_host_hint_shares)) + scheduler_hints['same_host'] = ','.join( + same_host_hint_shares + ) if different_host_hint_shares: different_host_hint_shares = [ apiutils.find_resource(share_client.shares, sh).id for sh in different_host_hint_shares.split(',') ] - scheduler_hints['different_host'] = ( - ','.join(different_host_hint_shares)) + scheduler_hints['different_host'] = ','.join( + different_host_hint_shares + ) body = { 'share_proto': parsed_args.share_proto, @@ -317,12 +344,11 @@ def take_action(self, parsed_args): if not oscutils.wait_for_status( status_f=share_client.shares.get, res_id=share.id, - success_status=['available'] + success_status=['available'], ): LOG.error(_("ERROR: Share is in error state.")) - share = apiutils.find_resource(share_client.shares, - share.id) + share = apiutils.find_resource(share_client.shares, share.id) printable_share = share._info printable_share.pop('links', None) @@ -333,41 +359,45 @@ def take_action(self, parsed_args): class DeleteShare(command.Command): """Delete a share.""" + _description = _("Delete a share") def get_parser(self, prog_name): - parser = super(DeleteShare, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "shares", metavar="", nargs="+", - help=_("Share(s) to delete (name or ID)") + help=_("Share(s) to delete (name or ID)"), ) parser.add_argument( "--share-group", metavar="", default=None, - help=_("Optional share group (name or ID) " - "which contains the share") + help=_( + "Optional share group (name or ID) which contains the share" + ), ) parser.add_argument( "--force", action='store_true', default=False, - help=_("Attempt forced removal of share(s), regardless of state " - "(defaults to False)") + help=_( + "Attempt forced removal of share(s), regardless of state " + "(defaults to False)" + ), ) parser.add_argument( "--wait", action='store_true', default=False, - help=_("Wait for share deletion") + help=_("Wait for share deletion"), ) parser.add_argument( "--soft", action='store_true', default=False, - help=_("Soft delete one or more shares.") + help=_("Soft delete one or more shares."), ) return parser @@ -377,61 +407,68 @@ def take_action(self, parsed_args): for share in parsed_args.shares: try: - share_obj = apiutils.find_resource( - share_client.shares, share - ) + share_obj = apiutils.find_resource(share_client.shares, share) share_group_id = None if parsed_args.share_group: share_group_id = apiutils.find_resource( - share_client.share_groups, parsed_args.share_group).id + share_client.share_groups, parsed_args.share_group + ).id if parsed_args.force: share_client.shares.force_delete(share_obj) elif parsed_args.soft: if share_client.api_version >= api_versions.APIVersion( - '2.69'): + '2.69' + ): share_client.shares.soft_delete(share_obj) else: raise exceptions.CommandError( "Soft Deleting shares is only " - "available with manila API version >= 2.69") + "available with manila API version >= 2.69" + ) else: - share_client.shares.delete(share_obj, - share_group_id) + share_client.shares.delete(share_obj, share_group_id) if parsed_args.wait: if not oscutils.wait_for_delete( - manager=share_client.shares, - res_id=share_obj.id): + manager=share_client.shares, res_id=share_obj.id + ): result += 1 except Exception as exc: result += 1 - LOG.error(_("Failed to delete share with " - "name or ID '%(share)s': %(e)s"), - {'share': share, 'e': exc}) + LOG.error( + _( + "Failed to delete share with " + "name or ID '%(share)s': %(e)s" + ), + {'share': share, 'e': exc}, + ) if result > 0: total = len(parsed_args.shares) - msg = (_("%(result)s of %(total)s shares failed " - "to delete.") % {'result': result, 'total': total}) + msg = _("%(result)s of %(total)s shares failed to delete.") % { + 'result': result, + 'total': total, + } raise exceptions.CommandError(msg) class ListShare(command.Lister): """List Shared file systems (shares).""" + _description = _("List shares") def get_parser(self, prog_name): - parser = super(ListShare, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( '--name', metavar="", - help=_('Filter shares by share name') + help=_('Filter shares by share name'), ) parser.add_argument( '--status', metavar="", - help=_('Filter shares by status') + help=_('Filter shares by status'), ) parser.add_argument( '--snapshot', @@ -441,16 +478,20 @@ def get_parser(self, prog_name): parser.add_argument( '--export-location', metavar='', - help=_('Filter shares by export location id or path. ' - 'Available only for microversion >= 2.35'), + help=_( + 'Filter shares by export location id or path. ' + 'Available only for microversion >= 2.35' + ), ) parser.add_argument( '--soft-deleted', action='store_true', - help=_('Get shares in recycle bin. If this parameter is set to ' - 'True (Default=False), only shares in the recycle bin ' - 'will be displayed. Available only for microversion >= ' - '2.69.') + help=_( + 'Get shares in recycle bin. If this parameter is set to ' + 'True (Default=False), only shares in the recycle bin ' + 'will be displayed. Available only for microversion >= ' + '2.69.' + ), ) parser.add_argument( '--public', @@ -481,19 +522,20 @@ def get_parser(self, prog_name): parser.add_argument( '--share-server', metavar='', - help=_('Filter shares exported via a given share server ' - '(admin only)'), + help=_( + 'Filter shares exported via a given share server (admin only)' + ), ) parser.add_argument( '--project', metavar='', - help=_('Filter shares by project (name or ID) (admin only)') + help=_('Filter shares by project (name or ID) (admin only)'), ) identity_common.add_project_domain_option_to_parser(parser) parser.add_argument( '--user', metavar='', - help=_('Filter results by user (name or ID) (admin only)') + help=_('Filter results by user (name or ID) (admin only)'), ) identity_common.add_user_domain_option_to_parser(parser) parser.add_argument( @@ -506,16 +548,20 @@ def get_parser(self, prog_name): '--property', metavar='', action=parseractions.KeyValueAction, - help=_('Filter shares having a given metadata key=value property ' - '(repeat option to filter by multiple properties)'), + help=_( + 'Filter shares having a given metadata key=value property ' + '(repeat option to filter by multiple properties)' + ), ) parser.add_argument( '--extra-spec', metavar='', action=parseractions.KeyValueAction, - help=_('Filter shares with extra specs (key=value) of the share ' - 'type that they belong to. ' - '(repeat option to filter by multiple extra specs)'), + help=_( + 'Filter shares with extra specs (key=value) of the share ' + 'type that they belong to. ' + '(repeat option to filter by multiple extra specs)' + ), ) parser.add_argument( '--long', @@ -527,9 +573,11 @@ def get_parser(self, prog_name): '--sort', metavar="[:]", default='name:asc', - help=_("Sort output by selected keys and directions(asc or desc) " - "(default: name:asc), multiple keys and directions can be " - "specified separated by comma"), + help=_( + "Sort output by selected keys and directions(asc or desc) " + "(default: name:asc), multiple keys and directions can be " + "specified separated by comma" + ), ) parser.add_argument( '--limit', @@ -547,21 +595,27 @@ def get_parser(self, prog_name): "--name~", metavar="", default=None, - help=_("Filter results matching a share name pattern. " - "Available only for microversion >= 2.36.") + help=_( + "Filter results matching a share name pattern. " + "Available only for microversion >= 2.36." + ), ) parser.add_argument( '--description~', metavar="", default=None, - help=_("Filter results matching a share description pattern." - "Available only for microversion >= 2.36.") + help=_( + "Filter results matching a share description pattern." + "Available only for microversion >= 2.36." + ), ) parser.add_argument( '--encryption-key-ref', metavar="", - help=_('Filter shares by their encryption key ref. ' - 'Available for microversion >= 2.90'), + help=_( + 'Filter shares by their encryption key ref. ' + 'Available for microversion >= 2.90' + ), ) return parser @@ -583,7 +637,7 @@ def take_action(self, parsed_args): 'is_public', 'share_type_name', 'host', - 'availability_zone' + 'availability_zone', ] column_headers = [ 'ID', @@ -594,7 +648,7 @@ def take_action(self, parsed_args): 'Is Public', 'Share Type Name', 'Host', - 'Availability Zone' + 'Availability Zone', ] project_id = None @@ -602,51 +656,55 @@ def take_action(self, parsed_args): project_id = identity_common.find_project( identity_client, parsed_args.project, - parsed_args.project_domain).id + parsed_args.project_domain, + ).id user_id = None if parsed_args.user: - user_id = identity_common.find_user(identity_client, - parsed_args.user, - parsed_args.user_domain).id + user_id = identity_common.find_user( + identity_client, parsed_args.user, parsed_args.user_domain + ).id # set value of 'all_tenants' when using project option all_tenants = bool(parsed_args.project) or parsed_args.all_projects share_type_id = None if parsed_args.share_type: - share_type_id = apiutils.find_resource(share_client.share_types, - parsed_args.share_type).id + share_type_id = apiutils.find_resource( + share_client.share_types, parsed_args.share_type + ).id snapshot_id = None if parsed_args.snapshot: - snapshot_id = apiutils.find_resource(share_client.share_snapshots, - parsed_args.snapshot).id + snapshot_id = apiutils.find_resource( + share_client.share_snapshots, parsed_args.snapshot + ).id share_network_id = None if parsed_args.share_network: share_network_id = apiutils.find_resource( - share_client.share_networks, - parsed_args.share_network).id + share_client.share_networks, parsed_args.share_network + ).id share_group_id = None if parsed_args.share_group: - share_group_id = apiutils.find_resource(share_client.share_groups, - parsed_args.share_group).id + share_group_id = apiutils.find_resource( + share_client.share_groups, parsed_args.share_group + ).id share_server_id = None if parsed_args.share_server: share_server_id = apiutils.find_resource( - share_client.share_servers, - parsed_args.share_server).id + share_client.share_servers, parsed_args.share_server + ).id search_opts = { 'all_tenants': all_tenants, 'is_public': parsed_args.public, - 'metadata': utils.extract_key_value_options( - parsed_args.property), + 'metadata': utils.extract_key_value_options(parsed_args.property), 'extra_specs': utils.extract_key_value_options( - parsed_args.extra_spec), + parsed_args.extra_spec + ), 'limit': parsed_args.limit, 'name': parsed_args.name, 'status': parsed_args.status, @@ -662,69 +720,84 @@ def take_action(self, parsed_args): } if share_client.api_version >= api_versions.APIVersion('2.69'): search_opts['is_soft_deleted'] = parsed_args.soft_deleted - elif (getattr(parsed_args, 'soft_deleted')): + elif getattr(parsed_args, 'soft_deleted'): raise exceptions.CommandError( "Filtering soft deleted shares is only " - "available with manila API version >= 2.69") + "available with manila API version >= 2.69" + ) if share_client.api_version >= api_versions.APIVersion("2.35"): search_opts['export_location'] = parsed_args.export_location - elif (getattr(parsed_args, 'export_location')): + elif getattr(parsed_args, 'export_location'): raise exceptions.CommandError( "Filtering by export location is only " - "available with manila API version >= 2.35") + "available with manila API version >= 2.35" + ) if share_client.api_version >= api_versions.APIVersion('2.90'): search_opts['encryption_key_ref'] = parsed_args.encryption_key_ref - elif (getattr(parsed_args, 'encryption_key_ref')): + elif getattr(parsed_args, 'encryption_key_ref'): raise exceptions.CommandError( "Filtering shares by encryption key ref is only " - "available with manila API version >= 2.90") + "available with manila API version >= 2.90" + ) # NOTE(vkmc) We implemented sorting and filtering in manilaclient # but we will use the one provided by osc if share_client.api_version >= api_versions.APIVersion("2.36"): search_opts['name~'] = getattr(parsed_args, 'name~') search_opts['description~'] = getattr(parsed_args, 'description~') - elif (getattr(parsed_args, 'name~') or - getattr(parsed_args, 'description~')): + elif getattr(parsed_args, 'name~') or getattr( + parsed_args, 'description~' + ): raise exceptions.CommandError( "Pattern based filtering (name~ and description~)" - " is only available with manila API version >= 2.36") + " is only available with manila API version >= 2.36" + ) data = share_client.shares.list(search_opts=search_opts) data = oscutils.sort_items(data, parsed_args.sort, str) - return (column_headers, (oscutils.get_item_properties - (s, columns, formatters={'Metadata': oscutils.format_dict},) - for s in data)) + return ( + column_headers, + ( + oscutils.get_item_properties( + s, + columns, + formatters={'Metadata': oscutils.format_dict}, + ) + for s in data + ), + ) class ShowShare(command.ShowOne): """Show a share.""" + _description = _("Display share details") def get_parser(self, prog_name): - parser = super(ShowShare, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( - 'share', - metavar="", - help=_('Share to display (name or ID)') + 'share', metavar="", help=_('Share to display (name or ID)') ) return parser def take_action(self, parsed_args): share_client = self.app.client_manager.share - share_obj = apiutils.find_resource(share_client.shares, - parsed_args.share) + share_obj = apiutils.find_resource( + share_client.shares, parsed_args.share + ) export_locations = share_client.share_export_locations.list(share_obj) export_locations = cliutils.convert_dict_list_to_string( export_locations, - ignored_keys=['replica_state', - 'availability_zone', - 'share_replica_id'] + ignored_keys=[ + 'replica_state', + 'availability_zone', + 'share_replica_id', + ], ) data = share_obj._info @@ -733,8 +806,9 @@ def take_action(self, parsed_args): # 'metadata' --> 'properties' data.update( { - 'properties': - format_columns.DictColumn(data.pop('metadata', {})), + 'properties': format_columns.DictColumn( + data.pop('metadata', {}) + ), }, ) @@ -747,14 +821,13 @@ def take_action(self, parsed_args): class SetShare(command.Command): """Set share properties.""" + _description = _("Set share properties") def get_parser(self, prog_name): - parser = super(SetShare, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( - 'share', - metavar="", - help=_('Share to modify (name or ID)') + 'share', metavar="", help=_('Share to modify (name or ID)') ) # 'metadata' --> 'properties' parser.add_argument( @@ -762,34 +835,40 @@ def get_parser(self, prog_name): metavar="", default={}, action=parseractions.KeyValueAction, - help=_("Set a property to this share " - "(repeat option to set multiple properties)"), + help=_( + "Set a property to this share " + "(repeat option to set multiple properties)" + ), ) parser.add_argument( '--name', metavar="", default=None, - help=_('New share name. (Default=None)') + help=_('New share name. (Default=None)'), ) parser.add_argument( '--description', metavar='', default=None, - help=_('New share description. (Default=None)') + help=_('New share description. (Default=None)'), ) parser.add_argument( '--public', metavar='', - help=_('Level of visibility for share. ' - 'Defines whether other tenants are able to see it or not. ') + help=_( + 'Level of visibility for share. ' + 'Defines whether other tenants are able to see it or not. ' + ), ) parser.add_argument( '--status', metavar='', default=None, - help=_('Explicitly update the status of a share (Admin only). ' - 'Examples include: available, error, creating, deleting, ' - 'error_deleting.') + help=_( + 'Explicitly update the status of a share (Admin only). ' + 'Examples include: available, error, creating, deleting, ' + 'error_deleting.' + ), ) parser.add_argument( '--task-state', @@ -797,31 +876,37 @@ def get_parser(self, prog_name): required=False, default=None, nargs='?', - help=_("Indicate which task state to assign the share. Options " - "include migration_starting, migration_in_progress, " - "migration_completing, migration_success, migration_error, " - "migration_cancelled, migration_driver_in_progress, " - "migration_driver_phase1_done, data_copying_starting, " - "data_copying_in_progress, data_copying_completing, " - "data_copying_completed, data_copying_cancelled, " - "data_copying_error. ") + help=_( + "Indicate which task state to assign the share. Options " + "include migration_starting, migration_in_progress, " + "migration_completing, migration_success, migration_error, " + "migration_cancelled, migration_driver_in_progress, " + "migration_driver_phase1_done, data_copying_starting, " + "data_copying_in_progress, data_copying_completing, " + "data_copying_completed, data_copying_cancelled, " + "data_copying_error. " + ), ) return parser def take_action(self, parsed_args): share_client = self.app.client_manager.share - share_obj = apiutils.find_resource(share_client.shares, - parsed_args.share) + share_obj = apiutils.find_resource( + share_client.shares, parsed_args.share + ) result = 0 if parsed_args.property: try: share_obj.set_metadata(parsed_args.property) except Exception as e: - LOG.error(_("Failed to set share properties " - "'%(properties)s': %(exception)s"), - {'properties': parsed_args.property, - 'exception': e}) + LOG.error( + _( + "Failed to set share properties " + "'%(properties)s': %(exception)s" + ), + {'properties': parsed_args.property, 'exception': e}, + ) result += 1 kwargs = {} @@ -835,15 +920,19 @@ def take_action(self, parsed_args): try: share_client.shares.update(share_obj.id, **kwargs) except Exception as e: - LOG.error(_("Failed to update share display name, visibility " - "or display description: %s"), e) + LOG.error( + _( + "Failed to update share display name, visibility " + "or display description: %s" + ), + e, + ) result += 1 if parsed_args.status: try: share_obj.reset_state(parsed_args.status) except Exception as e: - LOG.error(_( - "Failed to set status for the share: %s"), e) + LOG.error(_("Failed to set status for the share: %s"), e) result += 1 if hasattr(parsed_args, 'task_state'): task_state = parsed_args.task_state @@ -852,50 +941,50 @@ def take_action(self, parsed_args): try: share_obj.reset_task_state(task_state) except Exception as e: - LOG.error(_("Failed to update share task state " - "%s"), e) + LOG.error(_("Failed to update share task state %s"), e) result += 1 if result > 0: - raise exceptions.CommandError(_("One or more of the " - "set operations failed")) + raise exceptions.CommandError( + _("One or more of the set operations failed") + ) class UnsetShare(command.Command): """Unset share properties.""" + _description = _("Unset share properties") def get_parser(self, prog_name): - parser = super(UnsetShare, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( - 'share', - metavar="", - help=_('Share to modify (name or ID)') + 'share', metavar="", help=_('Share to modify (name or ID)') ) # 'metadata' --> 'properties' parser.add_argument( '--property', metavar='', action='append', - help=_('Remove a property from share ' - '(repeat option to remove multiple properties)'), + help=_( + 'Remove a property from share ' + '(repeat option to remove multiple properties)' + ), ) parser.add_argument( - '--name', - action='store_true', - help=_('Unset share name.') + '--name', action='store_true', help=_('Unset share name.') ) parser.add_argument( '--description', action='store_true', - help=_('Unset share description.') + help=_('Unset share description.'), ) return parser def take_action(self, parsed_args): share_client = self.app.client_manager.share - share_obj = apiutils.find_resource(share_client.shares, - parsed_args.share) + share_obj = apiutils.find_resource( + share_client.shares, parsed_args.share + ) result = 0 kwargs = {} if parsed_args.name: @@ -906,8 +995,13 @@ def take_action(self, parsed_args): try: share_client.shares.update(share_obj.id, **kwargs) except Exception as e: - LOG.error(_("Failed to unset share display name " - "or display description: %s"), e) + LOG.error( + _( + "Failed to unset share display name " + "or display description: %s" + ), + e, + ) result += 1 if parsed_args.property: @@ -915,54 +1009,55 @@ def take_action(self, parsed_args): try: share_obj.delete_metadata([key]) except Exception as e: - LOG.error(_("Failed to unset share property " - "'%(key)s': %(e)s"), - {'key': key, 'e': e}) + LOG.error( + _("Failed to unset share property '%(key)s': %(e)s"), + {'key': key, 'e': e}, + ) result += 1 if result > 0: - raise exceptions.CommandError(_( - "One or more of the " - "unset operations failed")) + raise exceptions.CommandError( + _("One or more of the unset operations failed") + ) class ResizeShare(command.Command): """Resize a share""" + _description = _("Resize a share") def get_parser(self, prog_name): - parser = super(ResizeShare, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( - 'share', - metavar="", - help=_('Name or ID of share to resize') + 'share', metavar="", help=_('Name or ID of share to resize') ) parser.add_argument( 'new_size', metavar="", type=int, - help=_('New size of share, in GiBs') + help=_('New size of share, in GiBs'), ) parser.add_argument( '--wait', action='store_true', default=False, - help=_('Wait for share resize') + help=_('Wait for share resize'), ) parser.add_argument( '--force', action='store_true', default=False, - help=_('Only applicable when increasing the size of the ' - 'share,only available with microversion ' - '2.64 and higher. (admin only)') + help=_( + 'Only applicable when increasing the size of the ' + 'share,only available with microversion ' + '2.64 and higher. (admin only)' + ), ) return parser def take_action(self, parsed_args): share_client = self.app.client_manager.share - share = apiutils.find_resource(share_client.shares, - parsed_args.share) + share = apiutils.find_resource(share_client.shares, parsed_args.share) share_size = share._info['size'] new_size = parsed_args.new_size @@ -970,16 +1065,15 @@ def take_action(self, parsed_args): try: share_client.shares.shrink(share, new_size) except Exception as e: - raise exceptions.CommandError(_( - "Share resize failed: %s" % e - )) + raise exceptions.CommandError(_("Share resize failed: %s") % e) elif share_size < new_size: force = False if parsed_args.force: if share_client.api_version < api_versions.APIVersion("2.64"): raise exceptions.CommandError( 'args force is available only for ' - 'API microversion >= 2.64') + 'API microversion >= 2.64' + ) force = True try: if force: @@ -987,65 +1081,65 @@ def take_action(self, parsed_args): else: share_client.shares.extend(share, new_size) except Exception as e: - raise exceptions.CommandError(_( - "Share resize failed: %s" % e - )) + raise exceptions.CommandError(_("Share resize failed: %s") % e) else: - raise exceptions.CommandError(_( - "Share size is already at %s GiBs" % new_size - )) + raise exceptions.CommandError( + _("Share size is already at %s GiBs") % new_size + ) if parsed_args.wait: if not oscutils.wait_for_status( status_f=share_client.shares.get, res_id=share.id, - success_status=['available'] + success_status=['available'], ): - raise exceptions.CommandError(_( - "Share not available after resize attempt.")) + raise exceptions.CommandError( + _("Share not available after resize attempt.") + ) class AdoptShare(command.ShowOne): """Adopt share not handled by Manila (Admin only).""" + _description = _("Adopt a share") def get_parser(self, prog_name): - parser = super(AdoptShare, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'service_host', metavar="", - help=_('Service host: some.host@driver#pool.') + help=_('Service host: some.host@driver#pool.'), ) parser.add_argument( 'protocol', metavar="", - help=_( - 'Protocol of the share to manage, such as NFS or CIFS.') + help=_('Protocol of the share to manage, such as NFS or CIFS.'), ) parser.add_argument( 'export_path', metavar="", - help=_('Share export path, NFS share such as: ' - '10.0.0.1:/example_path, CIFS share such as: ' - '\\\\10.0.0.1\\example_cifs_share.') + help=_( + 'Share export path, NFS share such as: ' + '10.0.0.1:/example_path, CIFS share such as: ' + '\\\\10.0.0.1\\example_cifs_share.' + ), ) parser.add_argument( '--name', metavar="", default=None, - help=_('Optional share name. (Default=None)') + help=_('Optional share name. (Default=None)'), ) parser.add_argument( '--description', metavar="", default=None, - help=_('Optional share description. (Default=None)') + help=_('Optional share description. (Default=None)'), ) parser.add_argument( '--share-type', metavar="", default=None, - help=_( - 'Optional share type assigned to share. (Default=None)') + help=_('Optional share type assigned to share. (Default=None)'), ) parser.add_argument( '--driver-options', @@ -1054,27 +1148,32 @@ def get_parser(self, prog_name): metavar='', default=None, help=_( - 'Optional driver options as key=value pairs (Default=None).') + 'Optional driver options as key=value pairs (Default=None).' + ), ) parser.add_argument( '--public', action='store_true', - help=_('Level of visibility for share. Defines whether other ' - 'projects are able to see it or not. Available only for ' - 'microversion >= 2.8. (Default=False)') + help=_( + 'Level of visibility for share. Defines whether other ' + 'projects are able to see it or not. Available only for ' + 'microversion >= 2.8. (Default=False)' + ), ) parser.add_argument( '--share-server-id', metavar="", - help=_('Share server associated with share when using a share ' - 'type with "driver_handles_share_servers" extra_spec ' - 'set to True. Available only for microversion >= 2.49. ' - '(Default=None)') + help=_( + 'Share server associated with share when using a share ' + 'type with "driver_handles_share_servers" extra_spec ' + 'set to True. Available only for microversion >= 2.49. ' + '(Default=None)' + ), ) parser.add_argument( "--wait", action='store_true', - help=_("Wait until share is adopted") + help=_("Wait until share is adopted"), ) return parser @@ -1086,19 +1185,21 @@ def take_action(self, parsed_args): 'protocol': parsed_args.protocol, 'export_path': parsed_args.export_path, 'name': parsed_args.name, - 'description': parsed_args.description + 'description': parsed_args.description, } share_type = None if parsed_args.share_type: - share_type = apiutils.find_resource(share_client.share_types, - parsed_args.share_type).id + share_type = apiutils.find_resource( + share_client.share_types, parsed_args.share_type + ).id kwargs['share_type'] = share_type driver_options = None if parsed_args.driver_options: driver_options = utils.extract_properties( - parsed_args.driver_options) + parsed_args.driver_options + ) kwargs['driver_options'] = driver_options if parsed_args.public: @@ -1107,7 +1208,8 @@ def take_action(self, parsed_args): else: raise exceptions.CommandError( 'Setting share visibility while adopting a share is ' - 'available only for API microversion >= 2.8') + 'available only for API microversion >= 2.8' + ) if parsed_args.share_server_id: if share_client.api_version >= api_versions.APIVersion("2.49"): @@ -1115,7 +1217,8 @@ def take_action(self, parsed_args): else: raise exceptions.CommandError( 'Selecting a share server ID is available only for ' - 'API microversion >= 2.49') + 'API microversion >= 2.49' + ) share = share_client.shares.manage(**kwargs) @@ -1124,12 +1227,11 @@ def take_action(self, parsed_args): status_f=share_client.shares.get, res_id=share.id, success_status=['available'], - error_status=['manage_error', 'error'] + error_status=['manage_error', 'error'], ): LOG.error(_("ERROR: Share is in error state.")) - share = apiutils.find_resource(share_client.shares, - share.id) + share = apiutils.find_resource(share_client.shares, share.id) share._info.pop('links', None) return self.dict2columns(share._info) @@ -1137,20 +1239,21 @@ def take_action(self, parsed_args): class AbandonShare(command.Command): """Abandon a share (Admin only).""" + _description = _("Abandon a share") def get_parser(self, prog_name): - parser = super(AbandonShare, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'share', metavar="", nargs="+", - help=_('Name or ID of the share(s)') + help=_('Name or ID of the share(s)'), ) parser.add_argument( "--wait", action='store_true', - help=_("Wait until share is abandoned") + help=_("Wait until share is abandoned"), ) return parser @@ -1160,9 +1263,7 @@ def take_action(self, parsed_args): for share in parsed_args.share: try: - share_obj = apiutils.find_resource( - share_client.shares, share - ) + share_obj = apiutils.find_resource(share_client.shares, share) share_client.shares.unmanage(share_obj) if parsed_args.wait: @@ -1170,20 +1271,25 @@ def take_action(self, parsed_args): # retrievable with the given 'res_id' so we can use it # to check that the share has been abandoned if not oscutils.wait_for_delete( - manager=share_client.shares, - res_id=share_obj.id): + manager=share_client.shares, res_id=share_obj.id + ): result += 1 except Exception as e: result += 1 - LOG.error(_("Failed to abandon share with " - "name or ID '%(share)s': %(e)s"), - {'share': share, 'e': e}) + LOG.error( + _( + "Failed to abandon share with " + "name or ID '%(share)s': %(e)s" + ), + {'share': share, 'e': e}, + ) if result > 0: total = len(parsed_args.share) - msg = (_("Failed to abandon %(result)s out of %(total)s shares.") - % {'result': result, 'total': total}) + msg = _( + "Failed to abandon %(result)s out of %(total)s shares." + ) % {'result': result, 'total': total} raise exceptions.CommandError(msg) @@ -1193,34 +1299,30 @@ class ShareExportLocationShow(command.ShowOne): _description = _("Show export location of a share") def get_parser(self, prog_name): - parser = super(ShareExportLocationShow, self).get_parser( - prog_name) + parser = super().get_parser(prog_name) parser.add_argument( - 'share', - metavar="", - help=_('Name or ID of share') + 'share', metavar="", help=_('Name or ID of share') ) parser.add_argument( 'export_location', metavar="", - help=_('ID of the share export location') + help=_('ID of the share export location'), ) return parser def take_action(self, parsed_args): share_client = self.app.client_manager.share - share = apiutils.find_resource(share_client.shares, - parsed_args.share) + share = apiutils.find_resource(share_client.shares, parsed_args.share) export_location = share_client.share_export_locations.get( - share=share, - export_location=parsed_args.export_location + share=share, export_location=parsed_args.export_location ) data = export_location._info data.update( { - 'properties': - format_columns.DictColumn(data.pop('metadata', {})), + 'properties': format_columns.DictColumn( + data.pop('metadata', {}) + ), }, ) @@ -1233,33 +1335,30 @@ class ShareExportLocationList(command.Lister): _description = _("List export location of a share") def get_parser(self, prog_name): - parser = super(ShareExportLocationList, self).get_parser( - prog_name) + parser = super().get_parser(prog_name) parser.add_argument( - 'share', - metavar="", - help=_('Name or ID of share') + 'share', metavar="", help=_('Name or ID of share') ) return parser def take_action(self, parsed_args): share_client = self.app.client_manager.share - share = apiutils.find_resource(share_client.shares, - parsed_args.share) + share = apiutils.find_resource(share_client.shares, parsed_args.share) export_locations = share_client.share_export_locations.list( share=share ) - list_of_keys = [ - 'ID', - 'Path', - 'Preferred' - ] + list_of_keys = ['ID', 'Path', 'Preferred'] - return (list_of_keys, (oscutils.get_item_properties - (s, list_of_keys) for s in export_locations)) + return ( + list_of_keys, + ( + oscutils.get_item_properties(s, list_of_keys) + for s in export_locations + ), + ) class ShareExportLocationSet(command.Command): @@ -1268,131 +1367,145 @@ class ShareExportLocationSet(command.Command): _description = _("Set an export location property.") def get_parser(self, prog_name): - parser = super(ShareExportLocationSet, self).get_parser( - prog_name) + parser = super().get_parser(prog_name) parser.add_argument( - 'share', - metavar="", - help=_('Name or ID of share') + 'share', metavar="", help=_('Name or ID of share') ) parser.add_argument( 'export_location', metavar="", - help=_('ID of the export location') + help=_('ID of the export location'), ) parser.add_argument( "--property", metavar="", default={}, action=parseractions.KeyValueAction, - help=_("Set a property to this export location " - "(repeat option to set multiple properties). " - "Available only for microversion >= 2.87."), + help=_( + "Set a property to this export location " + "(repeat option to set multiple properties). " + "Available only for microversion >= 2.87." + ), ) return parser def take_action(self, parsed_args): share_client = self.app.client_manager.share share_id = apiutils.find_resource( - share_client.shares, - parsed_args.share).id + share_client.shares, parsed_args.share + ).id - if (parsed_args.property and - share_client.api_version < api_versions.APIVersion("2.87")): + if ( + parsed_args.property + and share_client.api_version < api_versions.APIVersion("2.87") + ): raise exceptions.CommandError( "Property can be specified only with manila API " - "version >= 2.87.") + "version >= 2.87." + ) if parsed_args.property: try: share_client.share_export_locations.set_metadata( share_id, parsed_args.property, - subresource=parsed_args.export_location) + subresource=parsed_args.export_location, + ) except Exception as e: - raise exceptions.CommandError(_( - "Failed to set export location property " - "'%(properties)s': %(e)s") % - {'properties': parsed_args.property, 'e': e} + raise exceptions.CommandError( + _( + "Failed to set export location property " + "'%(properties)s': %(e)s" + ) + % {'properties': parsed_args.property, 'e': e} ) class ShareExportLocationUnset(command.Command): """Unset a share export location property""" + _description = _("Unset a share export location property") def get_parser(self, prog_name): - parser = super(ShareExportLocationUnset, self).get_parser( - prog_name) + parser = super().get_parser(prog_name) parser.add_argument( - 'share', - metavar="", - help=_('Name or ID of share') + 'share', metavar="", help=_('Name or ID of share') ) parser.add_argument( 'export_location', metavar="", - help=_('ID of the export location') + help=_('ID of the export location'), ) parser.add_argument( "--property", metavar="", action='append', - help=_("Remove a property from export location " - "(repeat option to remove multiple properties). " - "Available only for microversion >= 2.87."), + help=_( + "Remove a property from export location " + "(repeat option to remove multiple properties). " + "Available only for microversion >= 2.87." + ), ) return parser def take_action(self, parsed_args): share_client = self.app.client_manager.share share_id = apiutils.find_resource( - share_client.shares, - parsed_args.share).id + share_client.shares, parsed_args.share + ).id - if (parsed_args.property and - share_client.api_version < api_versions.APIVersion("2.87")): + if ( + parsed_args.property + and share_client.api_version < api_versions.APIVersion("2.87") + ): raise exceptions.CommandError( "Property can be specified only with manila API " - "version >= 2.87.") + "version >= 2.87." + ) if parsed_args.property: result = 0 for key in parsed_args.property: try: share_client.share_export_locations.delete_metadata( - share_id, [key], - subresource=parsed_args.export_location) + share_id, + [key], + subresource=parsed_args.export_location, + ) except Exception as e: result += 1 - LOG.error("Failed to unset export location property " - "'%(key)s': %(e)s", {'key': key, 'e': e}) + LOG.error( + "Failed to unset export location property " + "'%(key)s': %(e)s", + {'key': key, 'e': e}, + ) if result > 0: total = len(parsed_args.property) raise exceptions.CommandError( f"{result} of {total} export location properties failed " - f"to be unset.") + f"to be unset." + ) class ShowShareProperties(command.ShowOne): """Show properties of a share""" + _description = _("Show share properties") def get_parser(self, prog_name): - parser = super(ShowShareProperties, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( - 'share', - metavar="", - help=_('Name or ID of share') + 'share', metavar="", help=_('Name or ID of share') ) return parser def take_action(self, parsed_args): share_client = self.app.client_manager.share share_obj = apiutils.find_resource( - share_client.shares, parsed_args.share) + share_client.shares, parsed_args.share + ) share_properties = share_client.shares.get_metadata(share_obj) return self.dict2columns(share_properties._info) @@ -1404,118 +1517,139 @@ class RevertShare(command.Command): _description = _("Revert a share to the specified snapshot.") def get_parser(self, prog_name): - parser = super(RevertShare, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'snapshot', metavar="", - help=_('Name or ID of the snapshot to restore. The snapshot ' - 'must be the most recent one known to manila.') + help=_( + 'Name or ID of the snapshot to restore. The snapshot ' + 'must be the most recent one known to manila.' + ), ) parser.add_argument( '--wait', action='store_true', default=False, - help=_('Wait for share revert') + help=_('Wait for share revert'), ) return parser def take_action(self, parsed_args): share_client = self.app.client_manager.share - snapshot = apiutils.find_resource(share_client.share_snapshots, - parsed_args.snapshot) - share = apiutils.find_resource(share_client.shares, - snapshot.share_id) + snapshot = apiutils.find_resource( + share_client.share_snapshots, parsed_args.snapshot + ) + share = apiutils.find_resource(share_client.shares, snapshot.share_id) try: share.revert_to_snapshot(snapshot) except Exception as e: - raise exceptions.CommandError(_( - "Failed to revert share to snapshot: %s" % (e))) + raise exceptions.CommandError( + _("Failed to revert share to snapshot: %s") % e + ) if parsed_args.wait: if not oscutils.wait_for_status( status_f=share_client.shares.get, res_id=share.id, - success_status=['available'] + success_status=['available'], ): - raise exceptions.CommandError(_( - "Share not available after revert attempt.")) + raise exceptions.CommandError( + _("Share not available after revert attempt.") + ) class ShareMigrationStart(command.Command): """Migrates share to a new host (Admin only, Experimental).""" + _description = _("Migrates share to a new host.") def get_parser(self, prog_name): - parser = super(ShareMigrationStart, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'share', metavar="", - help=_('Name or ID of share to migrate.') + help=_('Name or ID of share to migrate.'), ) parser.add_argument( 'host', metavar="", - help=_("Destination host where share will be migrated to. Use the " - "format 'host@backend#pool'.") + help=_( + "Destination host where share will be migrated to. Use the " + "format 'host@backend#pool'." + ), ) parser.add_argument( '--force-host-assisted-migration', metavar="", choices=['True', 'False'], default=False, - help=_("Enforces the use of the host-assisted migration approach, " - "which bypasses driver optimizations. Default=False.") + help=_( + "Enforces the use of the host-assisted migration approach, " + "which bypasses driver optimizations. Default=False." + ), ) parser.add_argument( '--preserve-metadata', metavar="", required=True, choices=['True', 'False'], - help=_("Enforces migration to preserve all file metadata when " - "moving its contents. If set to True, host-assisted" - "migration will not be attempted.") + help=_( + "Enforces migration to preserve all file metadata when " + "moving its contents. If set to True, host-assisted" + "migration will not be attempted." + ), ) parser.add_argument( '--preserve-snapshots', metavar="", required=True, choices=['True', 'False'], - help=_("Enforces migration of the share snapshots to the " - "destination. If set to True, host-assisted migration" - "will not be attempted.") + help=_( + "Enforces migration of the share snapshots to the " + "destination. If set to True, host-assisted migration" + "will not be attempted." + ), ) parser.add_argument( '--writable', metavar="", required=True, choices=['True', 'False'], - help=_("Enforces migration to keep the share writable while " - "contents are being moved. If set to True, host-assisted" - "migration will not be attempted.") + help=_( + "Enforces migration to keep the share writable while " + "contents are being moved. If set to True, host-assisted" + "migration will not be attempted." + ), ) parser.add_argument( '--nondisruptive', metavar="", choices=['True', 'False'], required=True, - help=_("Enforces migration to be nondisruptive. If set to True, " - "host-assisted migration will not be attempted.") + help=_( + "Enforces migration to be nondisruptive. If set to True, " + "host-assisted migration will not be attempted." + ), ) parser.add_argument( '--new-share-network', metavar="", default=None, - help=_("Specify the new share network for the share. Do not " - "specify this parameter if the migrating share has to be" - "retained within its current share network.") + help=_( + "Specify the new share network for the share. Do not " + "specify this parameter if the migrating share has to be" + "retained within its current share network." + ), ) parser.add_argument( '--new-share-type', metavar="", default=None, - help=_("Specify the new share type for the share. Do not specify " - "this parameter if the migrating share has to be retained " - "with its current share type.") + help=_( + "Specify the new share type for the share. Do not specify " + "this parameter if the migrating share has to be retained " + "with its current share type." + ), ) return parser @@ -1525,22 +1659,24 @@ def take_action(self, parsed_args): new_share_net_id = None if parsed_args.new_share_network: new_share_net_id = apiutils.find_resource( - share_client.share_networks, - parsed_args.new_share_network).id + share_client.share_networks, parsed_args.new_share_network + ).id new_share_type_id = None if parsed_args.new_share_type: new_share_type_id = apiutils.find_resource( - share_client.share_types, - parsed_args.new_share_type).id - share = apiutils.find_resource(share_client.shares, - parsed_args.share) - share.migration_start(parsed_args.host, - parsed_args.force_host_assisted_migration, - parsed_args.preserve_metadata, - parsed_args.writable, - parsed_args.nondisruptive, - parsed_args.preserve_snapshots, - new_share_net_id, new_share_type_id) + share_client.share_types, parsed_args.new_share_type + ).id + share = apiutils.find_resource(share_client.shares, parsed_args.share) + share.migration_start( + parsed_args.host, + parsed_args.force_host_assisted_migration, + parsed_args.preserve_metadata, + parsed_args.writable, + parsed_args.nondisruptive, + parsed_args.preserve_snapshots, + new_share_net_id, + new_share_type_id, + ) class ShareMigrationCancel(command.Command): @@ -1549,41 +1685,41 @@ class ShareMigrationCancel(command.Command): (Admin only, Experimental). """ + _description = _("Cancels migration of a given share when copying") def get_parser(self, prog_name): - parser = super(ShareMigrationCancel, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'share', metavar="", - help=_('Name or ID of share to migrate.') + help=_('Name or ID of share to migrate.'), ) return parser def take_action(self, parsed_args): share_client = self.app.client_manager.share - share = apiutils.find_resource(share_client.shares, - parsed_args.share) + share = apiutils.find_resource(share_client.shares, parsed_args.share) share.migration_cancel() class ShareMigrationComplete(command.Command): """Completes migration for a given share (Admin only, Experimental).""" + _description = _("Completes migration for a given share") def get_parser(self, prog_name): - parser = super(ShareMigrationComplete, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'share', metavar="", - help=_('Name or ID of share to migrate.') + help=_('Name or ID of share to migrate.'), ) return parser def take_action(self, parsed_args): share_client = self.app.client_manager.share - share = apiutils.find_resource(share_client.shares, - parsed_args.share) + share = apiutils.find_resource(share_client.shares, parsed_args.share) share.migration_complete() @@ -1593,22 +1729,24 @@ class ShareMigrationShow(command.ShowOne): (Admin only, Experimental). """ + _description = _("Gets migration progress of a given share when copying") def get_parser(self, prog_name): - parser = super(ShareMigrationShow, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'share', metavar="", - help=_('Name or ID of the share to get share migration progress ' - 'information.') + help=_( + 'Name or ID of the share to get share migration progress ' + 'information.' + ), ) return parser def take_action(self, parsed_args): share_client = self.app.client_manager.share - share = apiutils.find_resource(share_client.shares, - parsed_args.share) + share = apiutils.find_resource(share_client.shares, parsed_args.share) result = share.migration_get_progress() return self.dict2columns(result[1]) @@ -1619,12 +1757,12 @@ class RestoreShare(command.Command): _description = _("Restores this share or more shares from the recycle bin") def get_parser(self, prog_name): - parser = super(RestoreShare, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'share', metavar="", nargs="+", - help=_('Name or ID of the share(s)') + help=_('Name or ID of the share(s)'), ) return parser @@ -1638,16 +1776,22 @@ def take_action(self, parsed_args): share_client.shares.restore(share) except Exception as e: failure_count += 1 - LOG.error(_("Failed to restore share with " - "name or ID '%(share)s': %(e)s"), - {'share': share, 'e': e}) + LOG.error( + _( + "Failed to restore share with " + "name or ID '%(share)s': %(e)s" + ), + {'share': share, 'e': e}, + ) if failure_count > 0: total = len(parsed_args.share) - msg = (f"Failed to restore {failure_count} out of " - f"{total} shares.") + msg = ( + f"Failed to restore {failure_count} out of {total} shares." + ) msg = _(msg) raise exceptions.CommandError(msg) else: raise exceptions.CommandError( "Restoring a share from the recycle bin is only " - "available with manila API version >= 2.69") + "available with manila API version >= 2.69" + ) diff --git a/manilaclient/osc/v2/share_access_rules.py b/manilaclient/osc/v2/share_access_rules.py index 05c75af0..bb3c5076 100644 --- a/manilaclient/osc/v2/share_access_rules.py +++ b/manilaclient/osc/v2/share_access_rules.py @@ -32,7 +32,7 @@ 'access_key', 'created_at', 'updated_at', - 'properties' + 'properties', ] LOG = logging.getLogger(__name__) @@ -40,25 +40,28 @@ class ShareAccessAllow(command.ShowOne): """Create a new share access rule.""" + _description = _("Create new share access rule") def get_parser(self, prog_name): - parser = super(ShareAccessAllow, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'share', metavar="", - help=_('Name or ID of the NAS share to modify.') + help=_('Name or ID of the NAS share to modify.'), ) parser.add_argument( 'access_type', metavar="", - help=_('Access rule type (only "ip", "user" (user or group), ' - '"cert" or "cephx" are supported).') + help=_( + 'Access rule type (only "ip", "user" (user or group), ' + '"cert" or "cephx" are supported).' + ), ) parser.add_argument( 'access_to', metavar="", - help=_('Value that defines access.') + help=_('Value that defines access.'), ) # metadata --> properties in osc parser.add_argument( @@ -66,9 +69,11 @@ def get_parser(self, prog_name): type=str, nargs='*', metavar='', - help=_('Space separated list of key=value pairs of properties. ' - 'OPTIONAL: Default=None. ' - 'Available only for API microversion >= 2.45.'), + help=_( + 'Space separated list of key=value pairs of properties. ' + 'OPTIONAL: Default=None. ' + 'Available only for API microversion >= 2.45.' + ), ) parser.add_argument( '--access-level', @@ -76,45 +81,52 @@ def get_parser(self, prog_name): type=str, default=None, choices=['rw', 'ro'], - help=_('Share access level ("rw" and "ro" access levels ' - 'are supported). Defaults to rw.') + help=_( + 'Share access level ("rw" and "ro" access levels ' + 'are supported). Defaults to rw.' + ), ) parser.add_argument( "--wait", action='store_true', - help=_("Wait for share access rule creation.") + help=_("Wait for share access rule creation."), ) parser.add_argument( "--lock-visibility", action='store_true', default=False, - help=_("Whether the sensitive fields of the access rule redacted " - "to other users. Only available with API version >= 2.82.") + help=_( + "Whether the sensitive fields of the access rule redacted " + "to other users. Only available with API version >= 2.82." + ), ) parser.add_argument( "--lock-deletion", action='store_true', default=False, - help=_("When enabled, a 'delete' lock will be placed against the " - "rule and the rule cannot be deleted while the lock " - "exists. Only available with API version >= 2.82.") + help=_( + "When enabled, a 'delete' lock will be placed against the " + "rule and the rule cannot be deleted while the lock " + "exists. Only available with API version >= 2.82." + ), ) parser.add_argument( '--lock-reason', metavar="", type=str, default=None, - help=_("Reason for locking the access rule. Should only be " - "provided alongside a deletion or visibility lock. " - "Only available with API version >= 2.82.") + help=_( + "Reason for locking the access rule. Should only be " + "provided alongside a deletion or visibility lock. " + "Only available with API version >= 2.82." + ), ) return parser def take_action(self, parsed_args): share_client = self.app.client_manager.share - share = apiutils.find_resource(share_client.shares, - parsed_args.share) + share = apiutils.find_resource(share_client.shares, parsed_args.share) lock_kwargs = {} if parsed_args.lock_visibility: lock_kwargs['lock_visibility'] = parsed_args.lock_visibility @@ -123,19 +135,22 @@ def take_action(self, parsed_args): if parsed_args.lock_reason: lock_kwargs['lock_reason'] = parsed_args.lock_reason - if (lock_kwargs - and share_client.api_version < api_versions.APIVersion( - "2.82")): + if lock_kwargs and share_client.api_version < api_versions.APIVersion( + "2.82" + ): raise exceptions.CommandError( 'Restricted access rules are only available starting ' - 'from API version 2.82.') + 'from API version 2.82.' + ) - if (lock_kwargs.get('lock_reason', None) - and not (lock_kwargs.get('lock_visibility', None) - or lock_kwargs.get('lock_deletion', None))): + if lock_kwargs.get('lock_reason', None) and not ( + lock_kwargs.get('lock_visibility', None) + or lock_kwargs.get('lock_deletion', None) + ): raise exceptions.CommandError( 'Lock reason can only be set while locking the deletion or ' - 'visibility.') + 'visibility.' + ) properties = {} if parsed_args.properties: @@ -144,83 +159,91 @@ def take_action(self, parsed_args): else: raise exceptions.CommandError( "Adding properties to access rules is supported only " - "with API microversion 2.45 and beyond") + "with API microversion 2.45 and beyond" + ) try: share_access_rule = share.allow( access_type=parsed_args.access_type, access=parsed_args.access_to, access_level=parsed_args.access_level, metadata=properties, - **lock_kwargs + **lock_kwargs, ) if parsed_args.wait: if not oscutils.wait_for_status( status_f=share_client.share_access_rules.get, res_id=share_access_rule['id'], - status_field='state' + status_field='state', ): LOG.error(_("ERROR: Share access rule is in error state.")) share_access_rule = oscutils.find_resource( - share_client.share_access_rules, - share_access_rule['id'])._info + share_client.share_access_rules, share_access_rule['id'] + )._info share_access_rule.update( { 'properties': utils.format_properties( - share_access_rule.pop('metadata', {})) + share_access_rule.pop('metadata', {}) + ) } ) - return (ACCESS_RULE_ATTRIBUTES, oscutils.get_dict_properties( - share_access_rule, - ACCESS_RULE_ATTRIBUTES)) + return ( + ACCESS_RULE_ATTRIBUTES, + oscutils.get_dict_properties( + share_access_rule, ACCESS_RULE_ATTRIBUTES + ), + ) except Exception as e: raise exceptions.CommandError( - "Failed to create access to share " - "'%s': %s" % (share, e)) + f"Failed to create access to share '{share}': {e}" + ) class ShareAccessDeny(command.Command): """Delete a share access rule.""" + _description = _("Delete a share access rule") def get_parser(self, prog_name): - parser = super(ShareAccessDeny, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'share', metavar="", - help=_('Name or ID of the NAS share to modify.') + help=_('Name or ID of the NAS share to modify.'), ) parser.add_argument( 'id', metavar="", - help=_('ID of the access rule to be deleted.') + help=_('ID of the access rule to be deleted.'), ) parser.add_argument( "--wait", action='store_true', default=False, - help=_("Wait for share access rule deletion") + help=_("Wait for share access rule deletion"), ) parser.add_argument( "--unrestrict", action='store_true', default=False, - help=_("Seek access rule deletion despite restrictions. Only " - "available with API version >= 2.82.") + help=_( + "Seek access rule deletion despite restrictions. Only " + "available with API version >= 2.82." + ), ) return parser def take_action(self, parsed_args): share_client = self.app.client_manager.share - share = apiutils.find_resource(share_client.shares, - parsed_args.share) + share = apiutils.find_resource(share_client.shares, parsed_args.share) kwargs = {} if parsed_args.unrestrict: if share_client.api_version < api_versions.APIVersion("2.82"): raise exceptions.CommandError( 'Restricted access rules are only available starting from ' - 'API version 2.82.') + 'API version 2.82.' + ) kwargs['unrestrict'] = True error = None @@ -228,28 +251,32 @@ def take_action(self, parsed_args): share.deny(parsed_args.id, **kwargs) if parsed_args.wait: if not oscutils.wait_for_delete( - manager=share_client.share_access_rules, - res_id=parsed_args.id): - error = _("Failed to delete share access rule with ID: %s" - % parsed_args.id) + manager=share_client.share_access_rules, + res_id=parsed_args.id, + ): + error = _( + f"Failed to delete share access rule with ID: {parsed_args.id}" + ) except Exception as e: error = e if error: - raise exceptions.CommandError(_( - "Failed to delete share access rule for share " - "'%s': %s" % (share, error))) + raise exceptions.CommandError( + _( + "Failed to delete share access rule for share " + f"'{share}': {error}" + ) + ) class ListShareAccess(command.Lister): """List share access rules.""" + _description = _("List share access rule") def get_parser(self, prog_name): - parser = super(ListShareAccess, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( - 'share', - metavar="", - help=_('Name or ID of the share.') + 'share', metavar="", help=_('Name or ID of the share.') ) # metadata --> properties in osc @@ -259,41 +286,42 @@ def get_parser(self, prog_name): nargs='*', metavar='', default=None, - help=_('Filters results by properties (key=value). ' - 'OPTIONAL: Default=None. ' - 'Available only for API microversion >= 2.45'), + help=_( + 'Filters results by properties (key=value). ' + 'OPTIONAL: Default=None. ' + 'Available only for API microversion >= 2.45' + ), ) parser.add_argument( "--access-type", metavar="", default=None, - help=_("Filter access rules by the access type.") + help=_("Filter access rules by the access type."), ) parser.add_argument( "--access-key", metavar="", default=None, - help=_("Filter access rules by the access key.") + help=_("Filter access rules by the access key."), ) parser.add_argument( "--access-to", metavar="", default=None, - help=_("Filter access rules by the access to field.") + help=_("Filter access rules by the access to field."), ) parser.add_argument( "--access-level", metavar="", default=None, - help=_("Filter access rules by the access level.") + help=_("Filter access rules by the access level."), ) return parser def take_action(self, parsed_args): share_client = self.app.client_manager.share - share = apiutils.find_resource(share_client.shares, - parsed_args.share) + share = apiutils.find_resource(share_client.shares, parsed_args.share) access_type = parsed_args.access_type access_key = parsed_args.access_key access_to = parsed_args.access_to @@ -303,16 +331,17 @@ def take_action(self, parsed_args): 'access_type': access_type, 'access_key': access_key, 'access_to': access_to, - 'access_level': access_level + 'access_level': access_level, } - if (any(extended_filter_keys.values()) - and share_client.api_version < api_versions.APIVersion( - "2.82")): + if any( + extended_filter_keys.values() + ) and share_client.api_version < api_versions.APIVersion("2.82"): raise exceptions.CommandError( 'Filtering access rules by access_type, access_key, access_to ' 'and access_level is available starting from API version ' - '2.82.') + '2.82.' + ) search_opts = {} if share_client.api_version >= api_versions.APIVersion("2.82"): @@ -324,15 +353,17 @@ def take_action(self, parsed_args): if parsed_args.properties: search_opts = { 'metadata': utils.extract_properties( - parsed_args.properties) + parsed_args.properties + ) } access_list = share_client.share_access_rules.access_list( - share, - search_opts) + share, search_opts + ) elif parsed_args.properties: raise exceptions.CommandError( "Filtering access rules by properties is supported only " - "with API microversion 2.45 and beyond.") + "with API microversion 2.45 and beyond." + ) else: access_list = share.access_list() @@ -341,7 +372,7 @@ def take_action(self, parsed_args): 'Access Type', 'Access To', 'Access Level', - 'State' + 'State', ] if share_client.api_version >= api_versions.APIVersion("2.21"): @@ -351,24 +382,27 @@ def take_action(self, parsed_args): list_of_keys.append('Created At') list_of_keys.append('Updated At') - values = (oscutils.get_item_properties( - a, list_of_keys) for a in access_list) + values = ( + oscutils.get_item_properties(a, list_of_keys) for a in access_list + ) return (list_of_keys, values) class ShowShareAccess(command.ShowOne): """Display a share access rule.""" + _description = _( "Display a share access rule. " - "Available for API microversion 2.45 and higher") + "Available for API microversion 2.45 and higher" + ) def get_parser(self, prog_name): - parser = super(ShowShareAccess, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'access_id', metavar="", - help=_('ID of the NAS share access rule.') + help=_('ID of the NAS share access rule.'), ) return parser @@ -382,30 +416,37 @@ def take_action(self, parsed_args): access_rule._info.update( { 'properties': utils.format_properties( - access_rule._info.pop('metadata', {})) + access_rule._info.pop('metadata', {}) + ) } ) - return (ACCESS_RULE_ATTRIBUTES, oscutils.get_dict_properties( - access_rule._info, - ACCESS_RULE_ATTRIBUTES)) + return ( + ACCESS_RULE_ATTRIBUTES, + oscutils.get_dict_properties( + access_rule._info, ACCESS_RULE_ATTRIBUTES + ), + ) else: raise exceptions.CommandError( "Displaying share access rule details is only available " - "with API microversion 2.45 and higher.") + "with API microversion 2.45 and higher." + ) class SetShareAccess(command.Command): """Set properties to share access rule.""" + _description = _( "Set properties to share access rule. " - "Available for API microversion 2.45 and higher") + "Available for API microversion 2.45 and higher" + ) def get_parser(self, prog_name): - parser = super(SetShareAccess, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'access_id', metavar="", - help=_('ID of the NAS share access rule.') + help=_('ID of the NAS share access rule.'), ) # metadata --> properties in osc parser.add_argument( @@ -413,34 +454,44 @@ def get_parser(self, prog_name): metavar='', default={}, action=parseractions.KeyValueAction, - help=_('Set a property to this share access rule. ' - '(Repeat option to set multiple properties) ' - 'Available only for API microversion >= 2.45.'), + help=_( + 'Set a property to this share access rule. ' + '(Repeat option to set multiple properties) ' + 'Available only for API microversion >= 2.45.' + ), ) parser.add_argument( "--access-level", metavar="", default=None, choices=['rw', 'ro'], - help=_('Share access level ("rw" and "ro" access levels ' - 'are supported) to set.') + help=_( + 'Share access level ("rw" and "ro" access levels ' + 'are supported) to set.' + ), ) return parser def take_action(self, parsed_args): share_client = self.app.client_manager.share - if (parsed_args.property and - share_client.api_version < api_versions.APIVersion("2.45")): + if ( + parsed_args.property + and share_client.api_version < api_versions.APIVersion("2.45") + ): raise exceptions.CommandError( "Setting properties to access rule is supported only " - "with API microversion 2.45 and higher") + "with API microversion 2.45 and higher" + ) - if (parsed_args.access_level and - share_client.api_version < api_versions.APIVersion("2.88")): + if ( + parsed_args.access_level + and share_client.api_version < api_versions.APIVersion("2.88") + ): raise exceptions.CommandError( "Setting access level to access rule is supported only " - "with API microversion 2.88 and higher") + "with API microversion 2.88 and higher" + ) access_rule = share_client.share_access_rules.get( parsed_args.access_id @@ -448,45 +499,51 @@ def take_action(self, parsed_args): if parsed_args.property: try: share_client.share_access_rules.set_metadata( - access_rule, - parsed_args.property) + access_rule, parsed_args.property + ) except Exception as e: raise exceptions.CommandError( "Failed to set properties to share access rule with ID " - "'%s': %s" % (access_rule.id, e)) + f"'{access_rule.id}': {e}" + ) if parsed_args.access_level: try: share_client.share_access_rules.set_access_level( - access_rule, - parsed_args.access_level) + access_rule, parsed_args.access_level + ) except Exception as e: raise exceptions.CommandError( "Failed to set access level to share access rule with ID " - "'%s': %s" % (access_rule.id, e)) + f"'{access_rule.id}': {e}" + ) class UnsetShareAccess(command.Command): """Unset properties of share access rule.""" + _description = _( "Unset properties of share access rule. " - "Available for API microversion 2.45 and higher") + "Available for API microversion 2.45 and higher" + ) def get_parser(self, prog_name): - parser = super(UnsetShareAccess, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'access_id', metavar="", - help=_('ID of the NAS share access rule.') + help=_('ID of the NAS share access rule.'), ) # metadata --> properties in osc parser.add_argument( '--property', metavar='', action='append', - help=_('Remove property from share access rule. ' - '(Repeat option to remove multiple properties) ' - 'Available only for API microversion >= 2.45.'), + help=_( + 'Remove property from share access rule. ' + '(Repeat option to remove multiple properties) ' + 'Available only for API microversion >= 2.45.' + ), ) return parser @@ -500,17 +557,20 @@ def take_action(self, parsed_args): if parsed_args.property: try: share_client.share_access_rules.unset_metadata( - access_rule, - parsed_args.property) + access_rule, parsed_args.property + ) except Exception as e: raise exceptions.CommandError( "Failed to unset properties for share access rule " - "with ID '%s': %s" % (access_rule.id, e)) + f"with ID '{access_rule.id}': {e}" + ) else: raise exceptions.CommandError( - "Please specify '--property ' to unset a property. ") + "Please specify '--property ' to unset a property. " + ) else: raise exceptions.CommandError( "Option to unset properties of access rule is available only " - "for API microversion 2.45 and higher") + "for API microversion 2.45 and higher" + ) diff --git a/manilaclient/osc/v2/share_backups.py b/manilaclient/osc/v2/share_backups.py index f48ebbe9..5dfc2547 100644 --- a/manilaclient/osc/v2/share_backups.py +++ b/manilaclient/osc/v2/share_backups.py @@ -31,46 +31,49 @@ class CreateShareBackup(command.ShowOne): """Create a share backup.""" + _description = _("Create a backup of the given share") def get_parser(self, prog_name): - parser = super(CreateShareBackup, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "share", metavar="", - help=_("Name or ID of the share to backup.") + help=_("Name or ID of the share to backup."), ) parser.add_argument( '--name', metavar='', default=None, - help=_('Optional share backup name. (Default=None).') + help=_('Optional share backup name. (Default=None).'), ) parser.add_argument( '--description', metavar='', default=None, - help=_('Optional share backup description. (Default=None).') + help=_('Optional share backup description. (Default=None).'), ) parser.add_argument( "--backup-options", metavar="", default={}, action=parseractions.KeyValueAction, - help=_("Backup driver option key=value pairs (Optional, " - "Default=None)."), + help=_( + "Backup driver option key=value pairs (Optional, " + "Default=None)." + ), ) return parser def take_action(self, parsed_args): share_client = self.app.client_manager.share - share = osc_utils.find_resource( - share_client.shares, parsed_args.share) + share = osc_utils.find_resource(share_client.shares, parsed_args.share) body = {} if parsed_args.backup_options: body['backup_options'] = utils.extract_key_value_options( - parsed_args.backup_options) + parsed_args.backup_options + ) if parsed_args.description: body['description'] = parsed_args.description if parsed_args.name: @@ -83,21 +86,22 @@ def take_action(self, parsed_args): class DeleteShareBackup(command.Command): """Delete one or more share backups.""" + _description = _("Delete one or more share backups") def get_parser(self, prog_name): - parser = super(DeleteShareBackup, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "backup", metavar="", nargs="+", - help=_("Name or ID of the backup(s) to delete") + help=_("Name or ID of the backup(s) to delete"), ) parser.add_argument( "--wait", action='store_true', default=False, - help=_("Wait for share backup deletion") + help=_("Wait for share backup deletion"), ) return parser @@ -108,70 +112,78 @@ def take_action(self, parsed_args): for backup in parsed_args.backup: try: share_backup_obj = osc_utils.find_resource( - share_client.share_backups, backup) + share_client.share_backups, backup + ) share_client.share_backups.delete(share_backup_obj) if parsed_args.wait: if not osc_utils.wait_for_delete( - manager=share_client.share_backups, - res_id=share_backup_obj.id): + manager=share_client.share_backups, + res_id=share_backup_obj.id, + ): result += 1 except Exception as e: result += 1 - LOG.error(_( - "Failed to delete a share backup with " - "name or ID '%(backup)s': %(e)s"), - {'backup': backup, 'e': e}) + LOG.error( + _( + "Failed to delete a share backup with " + "name or ID '%(backup)s': %(e)s" + ), + {'backup': backup, 'e': e}, + ) if result > 0: total = len(parsed_args.backup) - msg = (_("%(result)s of %(total)s backups failed " - "to delete.") % {'result': result, 'total': total}) + msg = _("%(result)s of %(total)s backups failed to delete.") % { + 'result': result, + 'total': total, + } raise exceptions.CommandError(msg) class ListShareBackup(command.Lister): """List share backups.""" + _description = _("List share backups") def get_parser(self, prog_name): - parser = super(ListShareBackup, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "--share", metavar="", default=None, - help=_("Name or ID of the share to list backups for.") + help=_("Name or ID of the share to list backups for."), ) parser.add_argument( "--name", metavar="", default=None, - help=_("Filter results by name. Default=None.") + help=_("Filter results by name. Default=None."), ) parser.add_argument( '--description', metavar="", default=None, - help=_("Filter results by description. Default=None.") + help=_("Filter results by description. Default=None."), ) parser.add_argument( "--name~", metavar="", default=None, - help=_("Filter results matching a share backup name pattern. ") + help=_("Filter results matching a share backup name pattern. "), ) parser.add_argument( '--description~', metavar="", default=None, - help=_("Filter results matching a share backup description ") + help=_("Filter results matching a share backup description "), ) parser.add_argument( '--status', metavar="", default=None, - help=_('Filter results by status. Default=None.') + help=_('Filter results by status. Default=None.'), ) parser.add_argument( "--limit", @@ -179,29 +191,32 @@ def get_parser(self, prog_name): type=int, default=None, action=parseractions.NonNegativeAction, - help=_("Limit the number of backups returned. Default=None.") + help=_("Limit the number of backups returned. Default=None."), ) parser.add_argument( '--offset', metavar="", default=None, - help='Start position of backup records listing.') + help='Start position of backup records listing.', + ) parser.add_argument( - '--sort-key', '--sort_key', + '--sort-key', + '--sort_key', metavar='', type=str, default=None, - help='Key to be sorted, available keys are %(keys)s. ' - 'Default=None.' - % {'keys': constants.BACKUP_SORT_KEY_VALUES}) + help=f'Key to be sorted, available keys are {constants.BACKUP_SORT_KEY_VALUES}. ' + 'Default=None.', + ) parser.add_argument( - '--sort-dir', '--sort_dir', + '--sort-dir', + '--sort_dir', metavar='', type=str, default=None, - help='Sort direction, available values are %(values)s. ' - 'OPTIONAL: Default=None.' % { - 'values': constants.SORT_DIR_VALUES}) + help=f'Sort direction, available values are {constants.SORT_DIR_VALUES}. ' + 'OPTIONAL: Default=None.', + ) parser.add_argument( '--detail', dest='detail', @@ -210,7 +225,8 @@ def get_parser(self, prog_name): type=int, const=1, default=0, - help="Show detailed information about share backups.") + help="Show detailed information about share backups.", + ) return parser def take_action(self, parsed_args): @@ -218,19 +234,25 @@ def take_action(self, parsed_args): share_id = None if parsed_args.share: - share_id = osc_utils.find_resource(share_client.shares, - parsed_args.share).id - columns = [ - 'ID', - 'Name', - 'Share ID', - 'Status' - ] + share_id = osc_utils.find_resource( + share_client.shares, parsed_args.share + ).id + columns = ['ID', 'Name', 'Share ID', 'Status'] if parsed_args.detail: - columns.extend(['Description', 'Size', 'Created At', - 'Updated At', 'Availability Zone', 'Progress', - 'Restore Progress', 'Host', 'Topic']) + columns.extend( + [ + 'Description', + 'Size', + 'Created At', + 'Updated At', + 'Availability Zone', + 'Progress', + 'Restore Progress', + 'Host', + 'Topic', + ] + ) search_opts = { 'limit': parsed_args.limit, @@ -245,56 +267,62 @@ def take_action(self, parsed_args): search_opts['description~'] = getattr(parsed_args, 'description~') backups = share_client.share_backups.list( - detailed=parsed_args.detail, search_opts=search_opts, - sort_key=parsed_args.sort_key, sort_dir=parsed_args.sort_dir) + detailed=parsed_args.detail, + search_opts=search_opts, + sort_key=parsed_args.sort_key, + sort_dir=parsed_args.sort_dir, + ) - return (columns, - (osc_utils.get_item_properties(b, columns) for b in backups)) + return ( + columns, + (osc_utils.get_item_properties(b, columns) for b in backups), + ) class ShowShareBackup(command.ShowOne): """Show share backup.""" + _description = _("Show details of a backup") def get_parser(self, prog_name): - parser = super(ShowShareBackup, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( - "backup", - metavar="", - help=_("ID of the share backup. ") + "backup", metavar="", help=_("ID of the share backup. ") ) return parser def take_action(self, parsed_args): share_client = self.app.client_manager.share - backup = osc_utils.find_resource(share_client.share_backups, - parsed_args.backup) + backup = osc_utils.find_resource( + share_client.share_backups, parsed_args.backup + ) backup._info.pop('links', None) return self.dict2columns(backup._info) class RestoreShareBackup(command.Command): """Restore share backup to share""" + _description = _("Attempt to restore share backup") def get_parser(self, prog_name): - parser = super(RestoreShareBackup, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( - "backup", - metavar="", - help=_('ID of backup to restore.') + "backup", metavar="", help=_('ID of backup to restore.') ) parser.add_argument( "--target-share", metavar="", default=None, - help=_('share to restore backup to. Source share if none supplied') + help=_( + 'share to restore backup to. Source share if none supplied' + ), ) parser.add_argument( '--wait', action='store_true', default=False, - help=_('Wait for restore conclusion') + help=_('Wait for restore conclusion'), ) return parser @@ -303,19 +331,18 @@ def take_action(self, parsed_args): kwargs = {} share_backup = osc_utils.find_resource( - share_client.share_backups, - parsed_args.backup + share_client.share_backups, parsed_args.backup ) target_share_id = None if parsed_args.target_share is not None: if share_client.api_version < api_versions.APIVersion('2.91'): raise exceptions.CommandError( 'performing targeted restores is only available ' - 'for API microversion >= 2.91') + 'for API microversion >= 2.91' + ) else: target_share_id = osc_utils.find_resource( - share_client.shares, - parsed_args.target_share + share_client.shares, parsed_args.target_share ).id kwargs['target_share_id'] = target_share_id @@ -326,42 +353,50 @@ def take_action(self, parsed_args): status_f=share_client.shares.get, res_id=(target_share_id or share_backup.share_id), success_status=['available'], - error_status=['error', 'backup_restoring_error'] + error_status=['error', 'backup_restoring_error'], ): LOG.error(_("ERROR: share is in error state.")) class SetShareBackup(command.Command): """Set share backup properties.""" + _description = _("Set share backup properties") def get_parser(self, prog_name): - parser = super(SetShareBackup, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "backup", metavar="", - help=_('Name or ID of the backup to set a property for') + help=_('Name or ID of the backup to set a property for'), ) parser.add_argument( "--name", metavar="", default=None, - help=_("Set a name to the backup.") + help=_("Set a name to the backup."), ) parser.add_argument( "--description", metavar="", default=None, - help=_("Set a description to the backup.") + help=_("Set a description to the backup."), ) parser.add_argument( "--status", metavar="", - choices=['available', 'error', 'creating', 'deleting', - 'restoring'], - help=_("Assign a status to the backup(Admin only). " - "Options include : available, error, creating, " - "deleting, restoring.") + choices=[ + 'available', + 'error', + 'creating', + 'deleting', + 'restoring', + ], + help=_( + "Assign a status to the backup(Admin only). " + "Options include : available, error, creating, " + "deleting, restoring." + ), ) return parser @@ -370,8 +405,8 @@ def take_action(self, parsed_args): result = 0 share_backup = osc_utils.find_resource( - share_client.share_backups, - parsed_args.backup) + share_client.share_backups, parsed_args.backup + ) kwargs = {} @@ -384,57 +419,60 @@ def take_action(self, parsed_args): share_client.share_backups.update(share_backup, **kwargs) except Exception as e: result += 1 - LOG.error(_( - "Failed to set share backup properties " - "'%(properties)s': %(exception)s"), - {'properties': kwargs, - 'exception': e}) + LOG.error( + _( + "Failed to set share backup properties " + "'%(properties)s': %(exception)s" + ), + {'properties': kwargs, 'exception': e}, + ) if parsed_args.status: try: share_client.share_backups.reset_status( - share_backup, - parsed_args.status + share_backup, parsed_args.status ) except Exception as e: result += 1 - LOG.error(_( - "Failed to update backup status to " - "'%(status)s': %(e)s"), - {'status': parsed_args.status, 'e': e}) + LOG.error( + _("Failed to update backup status to '%(status)s': %(e)s"), + {'status': parsed_args.status, 'e': e}, + ) if result > 0: - raise exceptions.CommandError(_("One or more of the " - "set operations failed")) + raise exceptions.CommandError( + _("One or more of the set operations failed") + ) class UnsetShareBackup(command.Command): """Unset share backup properties.""" + _description = _("Unset share backup properties") def get_parser(self, prog_name): - parser = super(UnsetShareBackup, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "backup", metavar="", - help=_('Name or ID of the backup to unset a property for') + help=_('Name or ID of the backup to unset a property for'), ) parser.add_argument( "--name", action='store_true', - help=_("Unset a name to the backup.") + help=_("Unset a name to the backup."), ) parser.add_argument( "--description", action='store_true', - help=_("Unset a description to the backup.") + help=_("Unset a description to the backup."), ) return parser def take_action(self, parsed_args): share_client = self.app.client_manager.share share_backup = osc_utils.find_resource( - share_client.share_backups, - parsed_args.backup) + share_client.share_backups, parsed_args.backup + ) kwargs = {} if parsed_args.name: @@ -448,8 +486,10 @@ def take_action(self, parsed_args): try: share_client.share_backups.update(share_backup, **kwargs) except Exception as e: - LOG.error(_( - "Failed to unset share backup properties " - "'%(properties)s': %(exception)s"), - {'properties': kwargs, - 'exception': e}) + LOG.error( + _( + "Failed to unset share backup properties " + "'%(properties)s': %(exception)s" + ), + {'properties': kwargs, 'exception': e}, + ) diff --git a/manilaclient/osc/v2/share_group_snapshots.py b/manilaclient/osc/v2/share_group_snapshots.py index 1680d490..5f3747b0 100644 --- a/manilaclient/osc/v2/share_group_snapshots.py +++ b/manilaclient/osc/v2/share_group_snapshots.py @@ -25,35 +25,35 @@ class CreateShareGroupSnapshot(command.ShowOne): """Create a share group snapshot.""" - _description = _( - "Create a share group snapshot of the given share group") + + _description = _("Create a share group snapshot of the given share group") def get_parser(self, prog_name): - parser = super( - CreateShareGroupSnapshot, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "share_group", metavar="", - help=_("Name or ID of the share group.") + help=_("Name or ID of the share group."), ) parser.add_argument( "--name", metavar="", default=None, - help=_("Optional share group snapshot name. (Default=None)") + help=_("Optional share group snapshot name. (Default=None)"), ) parser.add_argument( "--description", metavar="", default=None, - help=_("Optional share group snapshot description. " - "(Default=None)") + help=_( + "Optional share group snapshot description. (Default=None)" + ), ) parser.add_argument( '--wait', action='store_true', default=False, - help=_('Wait for share group snapshot creation') + help=_('Wait for share group snapshot creation'), ) return parser @@ -61,8 +61,8 @@ def take_action(self, parsed_args): share_client = self.app.client_manager.share share_group = osc_utils.find_resource( - share_client.share_groups, - parsed_args.share_group) + share_client.share_groups, parsed_args.share_group + ) share_group_snapshot = share_client.share_group_snapshots.create( share_group, @@ -73,13 +73,13 @@ def take_action(self, parsed_args): if not osc_utils.wait_for_status( status_f=share_client.share_group_snapshots.get, res_id=share_group_snapshot.id, - success_status=['available'] + success_status=['available'], ): LOG.error(_("ERROR: Share group snapshot is in error state.")) share_group_snapshot = osc_utils.find_resource( - share_client.share_group_snapshots, - share_group_snapshot.id) + share_client.share_group_snapshots, share_group_snapshot.id + ) data = share_group_snapshot._info data.pop('links', None) @@ -90,28 +90,31 @@ def take_action(self, parsed_args): class DeleteShareGroupSnapshot(command.Command): """Delete one or more share group snapshots.""" + _description = _("Delete one or more share group snapshot") def get_parser(self, prog_name): - parser = super(DeleteShareGroupSnapshot, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "share_group_snapshot", metavar="", nargs="+", - help=_("Name or ID of the group snapshot(s) to delete") + help=_("Name or ID of the group snapshot(s) to delete"), ) parser.add_argument( "--force", action='store_true', default=False, - help=_("Attempt to force delete the share group snapshot(s) " - "(Default=False) (Admin only).") + help=_( + "Attempt to force delete the share group snapshot(s) " + "(Default=False) (Admin only)." + ), ) parser.add_argument( "--wait", action='store_true', default=False, - help=_("Wait for share group snapshot deletion") + help=_("Wait for share group snapshot deletion"), ) return parser @@ -122,43 +125,46 @@ def take_action(self, parsed_args): for share_group_snapshot in parsed_args.share_group_snapshot: try: share_group_snapshot_obj = osc_utils.find_resource( - share_client.share_group_snapshots, - share_group_snapshot) + share_client.share_group_snapshots, share_group_snapshot + ) share_client.share_group_snapshots.delete( - share_group_snapshot_obj, - force=parsed_args.force) + share_group_snapshot_obj, force=parsed_args.force + ) if parsed_args.wait: if not osc_utils.wait_for_delete( - manager=share_client.share_group_snapshots, - res_id=share_group_snapshot_obj.id): + manager=share_client.share_group_snapshots, + res_id=share_group_snapshot_obj.id, + ): result += 1 except Exception as e: result += 1 LOG.error( 'Failed to delete a share group snapshot with ' - f'name or ID {share_group_snapshot}: {e}') + f'name or ID {share_group_snapshot}: {e}' + ) if result > 0: total = len(parsed_args.share_group_snapshot) - msg = (f'{result} of {total} share group snapshots failed ' - 'to delete.') + msg = ( + f'{result} of {total} share group snapshots failed to delete.' + ) raise exceptions.CommandError(msg) class ShowShareGroupSnapshot(command.ShowOne): """Display a share group snapshot""" - _description = _( - "Show details about a share group snapshot") + + _description = _("Show details about a share group snapshot") def get_parser(self, prog_name): - parser = super(ShowShareGroupSnapshot, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "share_group_snapshot", metavar="", - help=_("Name or ID of the share group snapshot to display") + help=_("Name or ID of the share group snapshot to display"), ) return parser @@ -167,7 +173,8 @@ def take_action(self, parsed_args): share_group_snapshot = osc_utils.find_resource( share_client.share_group_snapshots, - parsed_args.share_group_snapshot) + parsed_args.share_group_snapshot, + ) data = share_group_snapshot._info data.pop('links', None) @@ -178,36 +185,44 @@ def take_action(self, parsed_args): class SetShareGroupSnapshot(command.Command): """Set share group snapshot properties.""" + _description = _("Set share group snapshot properties") def get_parser(self, prog_name): - parser = super(SetShareGroupSnapshot, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "share_group_snapshot", metavar="", - help=_('Name or ID of the snapshot to set a property for') + help=_('Name or ID of the snapshot to set a property for'), ) parser.add_argument( "--name", metavar="", default=None, - help=_("Set a name to the snapshot.") + help=_("Set a name to the snapshot."), ) parser.add_argument( "--description", metavar="", default=None, - help=_("Set a description to the snapshot.") + help=_("Set a description to the snapshot."), ) parser.add_argument( "--status", metavar="", - choices=['available', 'error', 'creating', - 'deleting', 'error_deleting'], - help=_("Explicitly set the state of a share group snapshot" - "(Admin only). " - "Options include : available, error, creating, " - "deleting, error_deleting.") + choices=[ + 'available', + 'error', + 'creating', + 'deleting', + 'error_deleting', + ], + help=_( + "Explicitly set the state of a share group snapshot" + "(Admin only). " + "Options include : available, error, creating, " + "deleting, error_deleting." + ), ) return parser @@ -217,7 +232,8 @@ def take_action(self, parsed_args): share_group_snapshot = osc_utils.find_resource( share_client.share_group_snapshots, - parsed_args.share_group_snapshot) + parsed_args.share_group_snapshot, + ) kwargs = {} @@ -229,42 +245,46 @@ def take_action(self, parsed_args): if kwargs: try: share_client.share_group_snapshots.update( - share_group_snapshot, - **kwargs + share_group_snapshot, **kwargs ) except Exception as e: result += 1 - LOG.error('Failed to set name or desciption for ' - 'share group snapshot with ID ' - f'{share_group_snapshot.id}: {e}') + LOG.error( + 'Failed to set name or desciption for ' + 'share group snapshot with ID ' + f'{share_group_snapshot.id}: {e}' + ) if parsed_args.status: try: share_client.share_group_snapshots.reset_state( - share_group_snapshot, - parsed_args.status + share_group_snapshot, parsed_args.status ) except Exception as e: result += 1 - LOG.error('Failed to set status for ' - 'share group snapshot with ID ' - f'{share_group_snapshot.id}: {e}') + LOG.error( + 'Failed to set status for ' + 'share group snapshot with ID ' + f'{share_group_snapshot.id}: {e}' + ) if result > 0: - raise exceptions.CommandError(_( - "One or more of the set operations failed")) + raise exceptions.CommandError( + _("One or more of the set operations failed") + ) class UnsetShareGroupSnapshot(command.Command): """Unset a share group snapshot property.""" + _description = _("Unset a share group snapshot property") def get_parser(self, prog_name): - parser = super(UnsetShareGroupSnapshot, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "share_group_snapshot", metavar="", - help=_("Name or ID of the group snapshot to unset a property of") + help=_("Name or ID of the group snapshot to unset a property of"), ) parser.add_argument( "--name", @@ -283,7 +303,8 @@ def take_action(self, parsed_args): share_group_snapshot = osc_utils.find_resource( share_client.share_group_snapshots, - parsed_args.share_group_snapshot) + parsed_args.share_group_snapshot, + ) kwargs = {} if parsed_args.name: @@ -295,44 +316,45 @@ def take_action(self, parsed_args): if kwargs: try: share_client.share_group_snapshots.update( - share_group_snapshot, - **kwargs + share_group_snapshot, **kwargs ) except Exception as e: raise exceptions.CommandError( 'Failed to unset name or description for ' - f'share group snapshot : {e}') + f'share group snapshot : {e}' + ) class ListShareGroupSnapshot(command.Lister): """List share group snapshots.""" + _description = _("List share group snapshots") def get_parser(self, prog_name): - parser = super(ListShareGroupSnapshot, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "--all-projects", action='store_true', default=False, - help=_("Display information from all projects (Admin only).") + help=_("Display information from all projects (Admin only)."), ) parser.add_argument( "--name", metavar="", default=None, - help=_("Filter results by name.") + help=_("Filter results by name."), ) parser.add_argument( "--status", metavar="", default=None, - help=_("Filter results by status.") + help=_("Filter results by status."), ) parser.add_argument( "--share-group", metavar="", default=None, - help=_("Filter results by share group name or ID.") + help=_("Filter results by share group name or ID."), ) parser.add_argument( "--limit", @@ -340,26 +362,27 @@ def get_parser(self, prog_name): type=int, default=None, action=parseractions.NonNegativeAction, - help=_("Limit the number of share groups returned") + help=_("Limit the number of share groups returned"), ) parser.add_argument( "--marker", metavar="", - help=_("The last share group snapshot ID of the " - "previous page") + help=_("The last share group snapshot ID of the previous page"), ) parser.add_argument( '--sort', metavar="[:]", default='name:asc', - help=_("Sort output by selected keys and directions(asc or desc) " - "(default: name:asc), multiple keys and directions can be " - "specified separated by comma") + help=_( + "Sort output by selected keys and directions(asc or desc) " + "(default: name:asc), multiple keys and directions can be " + "specified separated by comma" + ), ) parser.add_argument( "--detailed", action="store_true", - help=_("Show detailed information about share group snapshot. ") + help=_("Show detailed information about share group snapshot. "), ) return parser @@ -369,8 +392,8 @@ def take_action(self, parsed_args): share_group_id = None if parsed_args.share_group: share_group_id = osc_utils.find_resource( - share_client.share_groups, - parsed_args.share_group).id + share_client.share_groups, parsed_args.share_group + ).id columns = [ 'ID', @@ -389,19 +412,23 @@ def take_action(self, parsed_args): } if parsed_args.detailed: - columns.extend([ - 'Created At', - 'Share Group ID', - ]) + columns.extend( + [ + 'Created At', + 'Share Group ID', + ] + ) if parsed_args.all_projects: columns.append('Project ID') share_group_snapshots = share_client.share_group_snapshots.list( - search_opts=search_opts) + search_opts=search_opts + ) share_group_snapshots = utils.sort_items( - share_group_snapshots, parsed_args.sort, str) + share_group_snapshots, parsed_args.sort, str + ) data = ( osc_utils.get_dict_properties(share_group_snapshot._info, columns) @@ -413,15 +440,15 @@ def take_action(self, parsed_args): class ListShareGroupSnapshotMembers(command.Lister): """List members for share group snapshot.""" + _description = _("List members of share group snapshot") def get_parser(self, prog_name): - parser = super( - ListShareGroupSnapshotMembers, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "share_group_snapshot", metavar="", - help=_("Name or ID of the group snapshot to list members for") + help=_("Name or ID of the group snapshot to list members for"), ) return parser @@ -432,7 +459,8 @@ def take_action(self, parsed_args): share_group_snapshot = osc_utils.find_resource( share_client.share_group_snapshots, - parsed_args.share_group_snapshot) + parsed_args.share_group_snapshot, + ) data = ( osc_utils.get_dict_properties(member, columns) diff --git a/manilaclient/osc/v2/share_group_type_access.py b/manilaclient/osc/v2/share_group_type_access.py index 1f46139e..10de8f51 100644 --- a/manilaclient/osc/v2/share_group_type_access.py +++ b/manilaclient/osc/v2/share_group_type_access.py @@ -25,21 +25,23 @@ class ShareGroupTypeAccessAllow(command.Command): """Allow a project to access a share group type.""" - _description = _("Allow a project to access a share group type " - "(Admin only).") + + _description = _( + "Allow a project to access a share group type (Admin only)." + ) def get_parser(self, prog_name): - parser = super(ShareGroupTypeAccessAllow, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'share_group_type', metavar="", - help=_("Share group type name or ID to allow access to.") + help=_("Share group type name or ID to allow access to."), ) parser.add_argument( 'projects', metavar="", nargs="+", - help=_("Project Name or ID to add share group type access for.") + help=_("Project Name or ID to add share group type access for."), ) identity_common.add_project_domain_option_to_parser(parser) return parser @@ -50,42 +52,52 @@ def take_action(self, parsed_args): result = 0 share_group_type = apiutils.find_resource( - share_client.share_group_types, parsed_args.share_group_type) + share_client.share_group_types, parsed_args.share_group_type + ) for project in parsed_args.projects: try: project_obj = identity_common.find_project( - identity_client, project, parsed_args.project_domain) + identity_client, project, parsed_args.project_domain + ) share_client.share_group_type_access.add_project_access( - share_group_type, project_obj.id) + share_group_type, project_obj.id + ) except Exception as e: result += 1 - LOG.error(_( - "Failed to allow access for project '%(project)s' " - "to share group type with name or ID " - "'%(share_group_type)s': %(e)s"), - {'project': project, - 'share_group_type': share_group_type, 'e': e}) + LOG.error( + _( + "Failed to allow access for project '%(project)s' " + "to share group type with name or ID " + "'%(share_group_type)s': %(e)s" + ), + { + 'project': project, + 'share_group_type': share_group_type, + 'e': e, + }, + ) if result > 0: total = len(parsed_args.projects) - msg = (_("Failed to allow access to " - "%(result)s of %(total)s projects") % {'result': result, - 'total': total}) + msg = _( + "Failed to allow access to %(result)s of %(total)s projects" + ) % {'result': result, 'total': total} raise exceptions.CommandError(msg) class ListShareGroupTypeAccess(command.Lister): """Get access list for share group type.""" + _description = _("Get access list for share group type (Admin only).") def get_parser(self, prog_name): - parser = super(ListShareGroupTypeAccess, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'share_group_type', metavar="", - help=_("Filter results by share group type name or ID.") + help=_("Filter results by share group type name or ID."), ) return parser @@ -93,11 +105,13 @@ def take_action(self, parsed_args): share_client = self.app.client_manager.share share_group_type = apiutils.find_resource( - share_client.share_group_types, parsed_args.share_group_type) + share_client.share_group_types, parsed_args.share_group_type + ) if share_group_type._info.get('is_public'): raise exceptions.CommandError( - 'Forbidden to get access list for public share group type.') + 'Forbidden to get access list for public share group type.' + ) data = share_client.share_group_type_access.list(share_group_type) @@ -109,22 +123,25 @@ def take_action(self, parsed_args): class ShareGroupTypeAccessDeny(command.Command): """Deny a project to access a share group type.""" - _description = _("Deny a project to access a share group type " - "(Admin only).") + + _description = _( + "Deny a project to access a share group type (Admin only)." + ) def get_parser(self, prog_name): - parser = super(ShareGroupTypeAccessDeny, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'share_group_type', metavar="", - help=_("Share group type name or ID to deny access from") + help=_("Share group type name or ID to deny access from"), ) parser.add_argument( 'projects', metavar="", nargs="+", - help=_("Project Name(s) or ID(s) " - "to deny share group type access for.") + help=_( + "Project Name(s) or ID(s) to deny share group type access for." + ), ) identity_common.add_project_domain_option_to_parser(parser) return parser @@ -135,29 +152,36 @@ def take_action(self, parsed_args): result = 0 share_group_type = apiutils.find_resource( - share_client.share_group_types, parsed_args.share_group_type) + share_client.share_group_types, parsed_args.share_group_type + ) for project in parsed_args.projects: try: project_obj = identity_common.find_project( - identity_client, - project, - parsed_args.project_domain) + identity_client, project, parsed_args.project_domain + ) share_client.share_group_type_access.remove_project_access( - share_group_type, project_obj.id) + share_group_type, project_obj.id + ) except Exception as e: result += 1 - LOG.error(_( - "Failed to deny access for project '%(project)s' " - "to share group type with name or ID " - "'%(share_group_type)s': %(e)s"), - {'project': project, - 'share_group_type': share_group_type, 'e': e}) + LOG.error( + _( + "Failed to deny access for project '%(project)s' " + "to share group type with name or ID " + "'%(share_group_type)s': %(e)s" + ), + { + 'project': project, + 'share_group_type': share_group_type, + 'e': e, + }, + ) if result > 0: total = len(parsed_args.projects) - msg = (_("Failed to deny access to " - "%(result)s of %(total)s projects") % {'result': result, - 'total': total}) + msg = _( + "Failed to deny access to %(result)s of %(total)s projects" + ) % {'result': result, 'total': total} raise exceptions.CommandError(msg) diff --git a/manilaclient/osc/v2/share_group_types.py b/manilaclient/osc/v2/share_group_types.py index 70e588b4..71117adb 100644 --- a/manilaclient/osc/v2/share_group_types.py +++ b/manilaclient/osc/v2/share_group_types.py @@ -29,32 +29,34 @@ 'share_types', 'visibility', 'is_default', - 'group_specs' + 'group_specs', ] class CreateShareGroupType(command.ShowOne): """Create new share group type.""" - _description = _( - "Create new share group type") + + _description = _("Create new share group type") log = logging.getLogger(__name__ + ".CreateShareGroupType") def get_parser(self, prog_name): - parser = super(CreateShareGroupType, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'name', metavar="", default=None, - help=_('Share group type name') + help=_('Share group type name'), ) parser.add_argument( "share_types", metavar="", nargs="+", default=None, - help=_("List of share type names or IDs. Example:" - " my-share-type-1 my-share-type-2"), + help=_( + "List of share type names or IDs. Example:" + " my-share-type-1 my-share-type-2" + ), ) parser.add_argument( "--group-specs", @@ -62,44 +64,49 @@ def get_parser(self, prog_name): nargs='*', metavar='', default=None, - help=_("Share Group type extra specs by key and value." - " OPTIONAL: Default=None. Example:" - " --group-specs consistent_snapshot_support=host."), + help=_( + "Share Group type extra specs by key and value." + " OPTIONAL: Default=None. Example:" + " --group-specs consistent_snapshot_support=host." + ), ) parser.add_argument( '--public', metavar="", default=True, - help=_('Make type accessible to the public (default true).') + help=_('Make type accessible to the public (default true).'), ) return parser def take_action(self, parsed_args): share_client = self.app.client_manager.share - kwargs = { - 'name': parsed_args.name - } + kwargs = {'name': parsed_args.name} share_types_list = [] for share_type in parsed_args.share_types: try: share_type_obj = apiutils.find_resource( - share_client.share_types, - share_type) + share_client.share_types, share_type + ) share_types_list.append(share_type_obj.name) except Exception as e: - msg = LOG.error(_("Failed to find the share type with " - "name or ID '%(share_type)s': %(e)s"), - {'share_type': share_type, 'e': e}) + msg = LOG.error( + _( + "Failed to find the share type with " + "name or ID '%(share_type)s': %(e)s" + ), + {'share_type': share_type, 'e': e}, + ) raise exceptions.CommandError(msg) kwargs['share_types'] = share_types_list if parsed_args.public: kwargs['is_public'] = strutils.bool_from_string( - parsed_args.public, default=True) + parsed_args.public, default=True + ) group_specs = {} if parsed_args.group_specs: @@ -113,25 +120,29 @@ def take_action(self, parsed_args): formatter = parsed_args.formatter formatted_group_type = utils.format_share_group_type( - share_group_type, formatter) + share_group_type, formatter + ) - return (ATTRIBUTES, oscutils.get_dict_properties( - formatted_group_type, ATTRIBUTES)) + return ( + ATTRIBUTES, + oscutils.get_dict_properties(formatted_group_type, ATTRIBUTES), + ) class DeleteShareGroupType(command.Command): """Delete a share group type.""" + _description = _("Delete a share group type") log = logging.getLogger(__name__ + ".DeleteShareGroupType") def get_parser(self, prog_name): - parser = super(DeleteShareGroupType, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'share_group_types', metavar="", nargs="+", - help=_("Name or ID of the share group type(s) to delete") + help=_("Name or ID of the share group type(s) to delete"), ) return parser @@ -142,38 +153,45 @@ def take_action(self, parsed_args): for share_group_type in parsed_args.share_group_types: try: share_group_type_obj = apiutils.find_resource( - share_client.share_group_types, - share_group_type) + share_client.share_group_types, share_group_type + ) share_client.share_group_types.delete(share_group_type_obj) except Exception as e: result += 1 - LOG.error(_( - "Failed to delete share group type with " - "name or ID '%(share_group_type)s': %(e)s"), - {'share_group_type': share_group_type, 'e': e}) + LOG.error( + _( + "Failed to delete share group type with " + "name or ID '%(share_group_type)s': %(e)s" + ), + {'share_group_type': share_group_type, 'e': e}, + ) if result > 0: total = len(parsed_args.share_group_types) - msg = (_("%(result)s of %(total)s share group types failed " - "to delete.") % {'result': result, 'total': total}) + msg = _( + "%(result)s of %(total)s share group types failed to delete." + ) % {'result': result, 'total': total} raise exceptions.CommandError(msg) class ListShareGroupType(command.Lister): """List Share Group Types.""" + _description = _("List share types") log = logging.getLogger(__name__ + ".ListShareGroupType") def get_parser(self, prog_name): - parser = super(ListShareGroupType, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( '--all', action='store_true', default=False, - help=_('Display all share group types whether public or private. ' - 'Default=False. (Admin only)'), + help=_( + 'Display all share group types whether public or private. ' + 'Default=False. (Admin only)' + ), ) parser.add_argument( '--group-specs', @@ -192,40 +210,44 @@ def take_action(self, parsed_args): if parsed_args.group_specs: search_opts = { 'group_specs': utils.extract_group_specs( - extra_specs={}, - specs_to_add=parsed_args.group_specs) + extra_specs={}, specs_to_add=parsed_args.group_specs + ) } formatter = parsed_args.formatter share_group_types = share_client.share_group_types.list( - search_opts=search_opts, - show_all=parsed_args.all) + search_opts=search_opts, show_all=parsed_args.all + ) formatted_types = [] for share_group_type in share_group_types: - formatted_types.append(utils.format_share_group_type( - share_group_type, formatter)) + formatted_types.append( + utils.format_share_group_type(share_group_type, formatter) + ) column_headers = utils.format_column_headers(ATTRIBUTES) - values = (oscutils.get_dict_properties( - sgt, ATTRIBUTES) for sgt in formatted_types) + values = ( + oscutils.get_dict_properties(sgt, ATTRIBUTES) + for sgt in formatted_types + ) return (column_headers, values) class ShowShareGroupType(command.ShowOne): """Show Share Group Types.""" + _description = _("Show share group types") log = logging.getLogger(__name__ + ".ShowShareGroupType") def get_parser(self, prog_name): - parser = super(ShowShareGroupType, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'share_group_type', metavar="", - help=_("Name or ID of the share group type to show") + help=_("Name or ID of the share group type to show"), ) return parser @@ -233,32 +255,38 @@ def take_action(self, parsed_args): share_client = self.app.client_manager.share share_group_type = apiutils.find_resource( - share_client.share_group_types, parsed_args.share_group_type) + share_client.share_group_types, parsed_args.share_group_type + ) share_group_type_obj = share_client.share_group_types.get( - share_group_type) + share_group_type + ) formatter = parsed_args.formatter formatted_group_type = utils.format_share_group_type( - share_group_type_obj, formatter) + share_group_type_obj, formatter + ) - return (ATTRIBUTES, oscutils.get_dict_properties( - formatted_group_type, ATTRIBUTES)) + return ( + ATTRIBUTES, + oscutils.get_dict_properties(formatted_group_type, ATTRIBUTES), + ) class SetShareGroupType(command.Command): """Set share type properties.""" + _description = _("Set share group type properties") log = logging.getLogger(__name__ + ".SetShareGroupType") def get_parser(self, prog_name): - parser = super(SetShareGroupType, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'share_group_type', metavar="", - help=_("Name or ID of the share group type to modify") + help=_("Name or ID of the share group type to modify"), ) parser.add_argument( "--group-specs", @@ -266,9 +294,11 @@ def get_parser(self, prog_name): nargs='*', metavar='', default=None, - help=_("Extra specs key and value of share group type that will be" - " used for share type creation. OPTIONAL: Default=None." - " Example: --group-specs consistent-snapshot-support=True"), + help=_( + "Extra specs key and value of share group type that will be" + " used for share type creation. OPTIONAL: Default=None." + " Example: --group-specs consistent-snapshot-support=True" + ), ) return parser @@ -277,12 +307,16 @@ def take_action(self, parsed_args): try: share_group_type_obj = apiutils.find_resource( - share_client.share_group_types, parsed_args.share_group_type) + share_client.share_group_types, parsed_args.share_group_type + ) except Exception as e: - msg = LOG.error(_( - "Failed to find the share group type with " - "name or ID '%(share_group_type)s': %(e)s"), - {'share_group_type': parsed_args.share_group_type, 'e': e}) + msg = LOG.error( + _( + "Failed to find the share group type with " + "name or ID '%(share_group_type)s': %(e)s" + ), + {'share_group_type': parsed_args.share_group_type, 'e': e}, + ) raise exceptions.CommandError(msg) kwargs = {} @@ -291,27 +325,29 @@ def take_action(self, parsed_args): if parsed_args.group_specs: group_specs = utils.extract_group_specs( - extra_specs={}, - specs_to_add=parsed_args.group_specs) + extra_specs={}, specs_to_add=parsed_args.group_specs + ) try: share_group_type_obj.set_keys(group_specs) except Exception as e: raise exceptions.CommandError( - "Failed to set share group type key: %s" % e) + f"Failed to set share group type key: {e}" + ) class UnsetShareGroupType(command.Command): """Unset share group type extra specs.""" + _description = _("Unset share group type extra specs") log = logging.getLogger(__name__ + ".UnsetShareGroupType") def get_parser(self, prog_name): - parser = super(UnsetShareGroupType, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'share_group_type', metavar="", - help=_("Name or ID of the share grouptype to modify") + help=_("Name or ID of the share grouptype to modify"), ) parser.add_argument( 'group_specs', @@ -326,12 +362,16 @@ def take_action(self, parsed_args): try: share_group_type_obj = apiutils.find_resource( - share_client.share_group_types, parsed_args.share_group_type) + share_client.share_group_types, parsed_args.share_group_type + ) except Exception as e: - msg = LOG.error(_( - "Failed to find the share group type with " - "name or ID '%(share_group_type)s': %(e)s"), - {'share_group_type': parsed_args.share_group_type, 'e': e}) + msg = LOG.error( + _( + "Failed to find the share group type with " + "name or ID '%(share_group_type)s': %(e)s" + ), + {'share_group_type': parsed_args.share_group_type, 'e': e}, + ) raise exceptions.CommandError(msg) if parsed_args.group_specs: @@ -339,4 +379,5 @@ def take_action(self, parsed_args): share_group_type_obj.unset_keys(parsed_args.group_specs) except Exception as e: raise exceptions.CommandError( - "Failed to remove share type group extra spec: %s" % e) + f"Failed to remove share type group extra spec: {e}" + ) diff --git a/manilaclient/osc/v2/share_groups.py b/manilaclient/osc/v2/share_groups.py index 35ba1cb7..7e3371b9 100644 --- a/manilaclient/osc/v2/share_groups.py +++ b/manilaclient/osc/v2/share_groups.py @@ -25,16 +25,16 @@ class CreateShareGroup(command.ShowOne): """Create new share group.""" - _description = _( - "Create new share group") + + _description = _("Create new share group") def get_parser(self, prog_name): - parser = super(CreateShareGroup, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( '--name', metavar="", default=None, - help=_('Share group name') + help=_('Share group name'), ) parser.add_argument( "--description", @@ -53,8 +53,9 @@ def get_parser(self, prog_name): "--share-group-type", metavar="", default=None, - help=_("Share group type name or ID of the share " - "group to be created."), + help=_( + "Share group type name or ID of the share group to be created." + ), ) parser.add_argument( "--share-network", @@ -66,21 +67,24 @@ def get_parser(self, prog_name): "--source-share-group-snapshot", metavar="", default=False, - help=_("Share group snapshot name or ID to create " - "the share group from."), + help=_( + "Share group snapshot name or ID to create " + "the share group from." + ), ) parser.add_argument( "--availability-zone", metavar='', default=None, - help=_("Optional availability zone in which group " - "should be created"), + help=_( + "Optional availability zone in which group should be created" + ), ) parser.add_argument( "--wait", action='store_true', default=False, - help=_('Wait for share group creation') + help=_('Wait for share group creation'), ) return parser @@ -98,20 +102,21 @@ def take_action(self, parsed_args): share_group_type = None if parsed_args.share_group_type: share_group_type = osc_utils.find_resource( - share_client.share_group_types, - parsed_args.share_group_type).id + share_client.share_group_types, parsed_args.share_group_type + ).id share_network = None if parsed_args.share_network: share_network = osc_utils.find_resource( - share_client.share_networks, - parsed_args.share_network).id + share_client.share_networks, parsed_args.share_network + ).id source_share_group_snapshot = None if parsed_args.source_share_group_snapshot: source_share_group_snapshot = osc_utils.find_resource( share_client.share_group_snapshots, - parsed_args.source_share_group_snapshot).id + parsed_args.source_share_group_snapshot, + ).id body = { 'name': parsed_args.name, @@ -120,7 +125,7 @@ def take_action(self, parsed_args): 'share_group_type': share_group_type, 'share_network': share_network, 'source_share_group_snapshot': source_share_group_snapshot, - 'availability_zone': parsed_args.availability_zone + 'availability_zone': parsed_args.availability_zone, } share_group = share_client.share_groups.create(**body) @@ -129,21 +134,21 @@ def take_action(self, parsed_args): if not osc_utils.wait_for_status( status_f=share_client.share_groups.get, res_id=share_group.id, - success_status=['available'] + success_status=['available'], ): LOG.error(_("ERROR: Share group is in error state.")) share_group = osc_utils.find_resource( - share_client.share_groups, - share_group.id) + share_client.share_groups, share_group.id + ) printable_share_group = share_group._info printable_share_group.pop('links', None) if printable_share_group.get('share_types'): if parsed_args.formatter == 'table': - printable_share_group['share_types'] = ( - "\n".join(printable_share_group['share_types']) + printable_share_group['share_types'] = "\n".join( + printable_share_group['share_types'] ) return self.dict2columns(printable_share_group) @@ -151,28 +156,31 @@ def take_action(self, parsed_args): class DeleteShareGroup(command.Command): """Delete one or more share groups.""" + _description = _("Delete one or more share groups") def get_parser(self, prog_name): - parser = super(DeleteShareGroup, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "share_group", metavar="", nargs="+", - help=_("Name or ID of the share group(s) to delete") + help=_("Name or ID of the share group(s) to delete"), ) parser.add_argument( "--force", action='store_true', default=False, - help=_("Attempt to force delete the share group (Default=False) " - "(Admin only).") + help=_( + "Attempt to force delete the share group (Default=False) " + "(Admin only)." + ), ) parser.add_argument( "--wait", action='store_true', default=False, - help=_("Wait for share group to delete") + help=_("Wait for share group to delete"), ) return parser @@ -183,105 +191,118 @@ def take_action(self, parsed_args): for share_group in parsed_args.share_group: try: share_group_obj = osc_utils.find_resource( - share_client.share_groups, - share_group) + share_client.share_groups, share_group + ) share_client.share_groups.delete( - share_group_obj, - force=parsed_args.force) + share_group_obj, force=parsed_args.force + ) if parsed_args.wait: if not osc_utils.wait_for_delete( - manager=share_client.share_groups, - res_id=share_group_obj.id): + manager=share_client.share_groups, + res_id=share_group_obj.id, + ): result += 1 except Exception as e: result += 1 - LOG.error(_( - "Failed to delete share group with " - "name or ID '%(share_group)s': %(e)s"), - {'share_group': share_group, 'e': e}) + LOG.error( + _( + "Failed to delete share group with " + "name or ID '%(share_group)s': %(e)s" + ), + {'share_group': share_group, 'e': e}, + ) if result > 0: total = len(parsed_args.share_group) - msg = (_("%(result)s of %(total)s share groups failed " - "to delete.") % {'result': result, 'total': total}) + msg = _( + "%(result)s of %(total)s share groups failed to delete." + ) % {'result': result, 'total': total} raise exceptions.CommandError(msg) class ListShareGroup(command.Lister): """List share groups.""" + _description = _("List share groups") def get_parser(self, prog_name): - parser = super(ListShareGroup, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "--all-projects", action='store_true', default=False, - help=_("Display share groups from all projects (Admin only).") + help=_("Display share groups from all projects (Admin only)."), ) parser.add_argument( "--name", metavar="", default=None, - help=_("Filter results by name.") + help=_("Filter results by name."), ) parser.add_argument( "--description", metavar="", default=None, - help=_("Filter results by description. Available " - "only for microversion >= 2.36.") + help=_( + "Filter results by description. Available " + "only for microversion >= 2.36." + ), ) parser.add_argument( "--status", metavar="", default=None, - help=_("Filter results by status.") + help=_("Filter results by status."), ) parser.add_argument( "--share-server", metavar="", default=None, - help=_("Filter results by share server ID.") + help=_("Filter results by share server ID."), ) parser.add_argument( "--share-group-type", metavar="", default=None, - help=_("Filter results by a share group type ID " - "or name that was used for share group " - "creation. ") + help=_( + "Filter results by a share group type ID " + "or name that was used for share group " + "creation. " + ), ) parser.add_argument( "--snapshot", metavar="", default=None, - help=_("Filter results by share group snapshot " - "name or ID that was used to create the " - "share group. ") + help=_( + "Filter results by share group snapshot " + "name or ID that was used to create the " + "share group. " + ), ) parser.add_argument( "--host", metavar="", default=None, - help=_("Filter results by host.") + help=_("Filter results by host."), ) parser.add_argument( "--share-network", metavar="", default=None, - help=_("Filter results by share-network name or " - "ID. ") + help=_("Filter results by share-network name or ID. "), ) parser.add_argument( "--project", metavar="", default=None, - help=_("Filter results by project name or ID. Useful with " - "set key '--all-projects'. ") + help=_( + "Filter results by project name or ID. Useful with " + "set key '--all-projects'. " + ), ) identity_common.add_project_domain_option_to_parser(parser) parser.add_argument( @@ -290,36 +311,42 @@ def get_parser(self, prog_name): type=int, default=None, action=parseractions.NonNegativeAction, - help=_("Limit the number of share groups returned") + help=_("Limit the number of share groups returned"), ) parser.add_argument( "--marker", metavar="", - help=_("The last share group ID of the previous page") + help=_("The last share group ID of the previous page"), ) parser.add_argument( '--sort', metavar="[:]", default='name:asc', - help=_("Sort output by selected keys and directions(asc or desc) " - "(default: name:asc), multiple keys and directions can be " - "specified separated by comma") + help=_( + "Sort output by selected keys and directions(asc or desc) " + "(default: name:asc), multiple keys and directions can be " + "specified separated by comma" + ), ) parser.add_argument( "--name~", metavar="", default=None, - help=_("Filter results matching a share group " - "name pattern. Available only for " - "microversion >= 2.36. ") + help=_( + "Filter results matching a share group " + "name pattern. Available only for " + "microversion >= 2.36. " + ), ) parser.add_argument( "--description~", metavar="", default=None, - help=_("Filter results matching a share group " - "description pattern. Available only for " - "microversion >= 2.36. ") + help=_( + "Filter results matching a share group " + "description pattern. Available only for " + "microversion >= 2.36. " + ), ) return parser @@ -330,33 +357,34 @@ def take_action(self, parsed_args): share_server_id = None if parsed_args.share_server: share_server_id = osc_utils.find_resource( - share_client.share_servers, - parsed_args.share_server).id + share_client.share_servers, parsed_args.share_server + ).id share_group_type = None if parsed_args.share_group_type: share_group_type = osc_utils.find_resource( - share_client.share_group_types, - parsed_args.share_group_type).id + share_client.share_group_types, parsed_args.share_group_type + ).id snapshot = None if parsed_args.snapshot: snapshot = apiutils.find_resource( - share_client.share_snapshots, - parsed_args.snapshot).id + share_client.share_snapshots, parsed_args.snapshot + ).id share_network = None if parsed_args.share_network: share_network = osc_utils.find_resource( - share_client.share_networks, - parsed_args.share_network).id + share_client.share_networks, parsed_args.share_network + ).id project_id = None if parsed_args.project: project_id = identity_common.find_project( identity_client, parsed_args.project, - parsed_args.project_domain).id + parsed_args.project_domain, + ).id columns = [ 'ID', @@ -383,32 +411,39 @@ def take_action(self, parsed_args): search_opts['name~'] = getattr(parsed_args, 'name~') search_opts['description~'] = getattr(parsed_args, 'description~') search_opts['description'] = parsed_args.description - elif (parsed_args.description or getattr(parsed_args, 'name~') or - getattr(parsed_args, 'description~')): + elif ( + parsed_args.description + or getattr(parsed_args, 'name~') + or getattr(parsed_args, 'description~') + ): raise exceptions.CommandError( "Pattern based filtering (name~, description~ and description)" - " is only available with manila API version >= 2.36") + " is only available with manila API version >= 2.36" + ) if parsed_args.all_projects: columns.append('Project ID') share_groups = share_client.share_groups.list(search_opts=search_opts) - data = (osc_utils.get_dict_properties( - share_group._info, columns) for share_group in share_groups) + data = ( + osc_utils.get_dict_properties(share_group._info, columns) + for share_group in share_groups + ) return (columns, data) class ShowShareGroup(command.ShowOne): """Show share group.""" + _description = _("Show details about a share group") def get_parser(self, prog_name): - parser = super(ShowShareGroup, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "share_group", metavar="", - help=_("Name or ID of the share group.") + help=_("Name or ID of the share group."), ) return parser @@ -416,8 +451,8 @@ def take_action(self, parsed_args): share_client = self.app.client_manager.share share_group = osc_utils.find_resource( - share_client.share_groups, - parsed_args.share_group) + share_client.share_groups, parsed_args.share_group + ) printable_share_group = share_group._info printable_share_group.pop('links', None) @@ -425,41 +460,45 @@ def take_action(self, parsed_args): if printable_share_group.get('share_types'): if parsed_args.formatter == 'table': printable_share_group['share_types'] = "\n".join( - printable_share_group['share_types']) + printable_share_group['share_types'] + ) return self.dict2columns(printable_share_group) class SetShareGroup(command.Command): """Set share group.""" + _description = _("Explicitly set share group status") def get_parser(self, prog_name): - parser = super(SetShareGroup, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'share_group', metavar="", - help=_('Name or ID of the share group to update.') + help=_('Name or ID of the share group to update.'), ) parser.add_argument( '--name', metavar="", default=None, - help=_('New name for the share group. (Default=None)') + help=_('New name for the share group. (Default=None)'), ) parser.add_argument( '--description', metavar='', default=None, - help=_('Share group description. (Default=None)') + help=_('Share group description. (Default=None)'), ) parser.add_argument( '--status', metavar='', default=None, - help=_('Explicitly update the status of a share group (Admin ' - 'only). Examples include: available, error, creating, ' - 'deleting, error_deleting.') + help=_( + 'Explicitly update the status of a share group (Admin ' + 'only). Examples include: available, error, creating, ' + 'deleting, error_deleting.' + ), ) return parser @@ -468,8 +507,8 @@ def take_action(self, parsed_args): result = 0 share_group = osc_utils.find_resource( - share_client.share_groups, - parsed_args.share_group) + share_client.share_groups, parsed_args.share_group + ) kwargs = {} if parsed_args.name is not None: @@ -478,38 +517,37 @@ def take_action(self, parsed_args): kwargs['description'] = parsed_args.description if kwargs: try: - share_client.share_groups.update( - share_group.id, - **kwargs - ) + share_client.share_groups.update(share_group.id, **kwargs) except Exception as e: - LOG.error(_("Failed to update share group name " - "or description: %s"), e) + LOG.error( + _("Failed to update share group name or description: %s"), + e, + ) result += 1 if parsed_args.status: try: share_group.reset_state(parsed_args.status) except Exception as e: - LOG.error(_( - "Failed to set status for the share group: %s"), e) + LOG.error(_("Failed to set status for the share group: %s"), e) result += 1 if result > 0: - raise exceptions.CommandError(_("One or more of the " - "set operations failed")) + raise exceptions.CommandError( + _("One or more of the set operations failed") + ) class UnsetShareGroup(command.Command): """Unset a share group property.""" + _description = _("Unset a share group property") def get_parser(self, prog_name): - parser = super(UnsetShareGroup, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'share_group', metavar="", - help=_("Name or ID of the share group " - "to set a property for.") + help=_("Name or ID of the share group to set a property for."), ) parser.add_argument( "--name", @@ -527,8 +565,8 @@ def take_action(self, parsed_args): share_client = self.app.client_manager.share share_group = osc_utils.find_resource( - share_client.share_groups, - parsed_args.share_group) + share_client.share_groups, parsed_args.share_group + ) kwargs = {} if parsed_args.name: @@ -537,11 +575,8 @@ def take_action(self, parsed_args): kwargs['description'] = None if kwargs: try: - share_client.share_groups.update( - share_group, - **kwargs - ) + share_client.share_groups.update(share_group, **kwargs) except Exception as e: - raise exceptions.CommandError(_( - "Failed to unset share_group name " - "or description : %s" % e)) + raise exceptions.CommandError( + _(f"Failed to unset share_group name or description : {e}") + ) diff --git a/manilaclient/osc/v2/share_instance_export_locations.py b/manilaclient/osc/v2/share_instance_export_locations.py index e8e75b70..a2ab3ad9 100644 --- a/manilaclient/osc/v2/share_instance_export_locations.py +++ b/manilaclient/osc/v2/share_instance_export_locations.py @@ -21,15 +21,15 @@ class ShareInstanceListExportLocation(command.Lister): """List share instance export locations.""" + _description = _("List share instance export locations") def get_parser(self, prog_name): - parser = super( - ShareInstanceListExportLocation, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "instance", metavar="", - help=_("ID of the share instance.") + help=_("ID of the share instance."), ) return parser @@ -37,12 +37,12 @@ def take_action(self, parsed_args): share_client = self.app.client_manager.share instance = osc_utils.find_resource( - share_client.share_instances, - parsed_args.instance) + share_client.share_instances, parsed_args.instance + ) export_locations = share_client.share_instance_export_locations.list( - instance, - search_opts=None) + instance, search_opts=None + ) columns = [ 'ID', @@ -61,21 +61,20 @@ def take_action(self, parsed_args): class ShareInstanceShowExportLocation(command.ShowOne): """Display the export location for a share instance.""" - _description = _( - "Show export location for a share instance.") + + _description = _("Show export location for a share instance.") def get_parser(self, prog_name): - parser = super( - ShareInstanceShowExportLocation, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "instance", metavar="", - help=_("Name or ID of the share instance") + help=_("Name or ID of the share instance"), ) parser.add_argument( "export_location", metavar="", - help=_("ID of the share instance export location.") + help=_("ID of the share instance export location."), ) return parser @@ -83,13 +82,13 @@ def take_action(self, parsed_args): share_client = self.app.client_manager.share share_instance = osc_utils.find_resource( - share_client.share_instances, - parsed_args.instance) + share_client.share_instances, parsed_args.instance + ) share_instance_export_locations = ( share_client.share_instance_export_locations.get( - share_instance.id, - parsed_args.export_location) + share_instance.id, parsed_args.export_location + ) ) data = share_instance_export_locations._info diff --git a/manilaclient/osc/v2/share_instances.py b/manilaclient/osc/v2/share_instances.py index 2f48c667..06e91a45 100644 --- a/manilaclient/osc/v2/share_instances.py +++ b/manilaclient/osc/v2/share_instances.py @@ -27,21 +27,22 @@ class ShareInstanceDelete(command.Command): """Forces the deletion of the share instance.""" + _description = _("Forces the deletion of a share instance") def get_parser(self, prog_name): - parser = super(ShareInstanceDelete, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'instance', metavar="", nargs="+", - help=_('ID of the share instance to delete.') + help=_('ID of the share instance to delete.'), ) parser.add_argument( "--wait", action='store_true', default=False, - help=_("Wait for share instance deletion.") + help=_("Wait for share instance deletion."), ) return parser @@ -52,48 +53,57 @@ def take_action(self, parsed_args): for instance in parsed_args.instance: try: share_instance = apiutils.find_resource( - share_client.share_instances, instance) + share_client.share_instances, instance + ) share_client.share_instances.force_delete(share_instance) if parsed_args.wait: if not osc_utils.wait_for_delete( - manager=share_client.share_instances, - res_id=share_instance.id): + manager=share_client.share_instances, + res_id=share_instance.id, + ): number_of_deletion_failures += 1 except Exception as e: number_of_deletion_failures += 1 - LOG.error(_( - "Failed to delete a share instance with " - "ID '%(instance)s': %(e)s"), - {'instance': instance, 'e': e}) + LOG.error( + _( + "Failed to delete a share instance with " + "ID '%(instance)s': %(e)s" + ), + {'instance': instance, 'e': e}, + ) if number_of_deletion_failures > 0: - msg = (_("%(number_of_deletion_failures)s of " - "%(total_of_instances)s instances failed " - "to delete.") % { + msg = _( + "%(number_of_deletion_failures)s of " + "%(total_of_instances)s instances failed " + "to delete." + ) % { 'number_of_deletion_failures': number_of_deletion_failures, - 'total_of_instances': len(parsed_args.instance)}) + 'total_of_instances': len(parsed_args.instance), + } raise exceptions.CommandError(msg) class ShareInstanceList(command.Lister): """List share instances.""" + _description = _("List share instances") def get_parser(self, prog_name): - parser = super(ShareInstanceList, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "--share", metavar="", default=None, - help=_("Name or ID of the share to list instances for.") + help=_("Name or ID of the share to list instances for."), ) parser.add_argument( "--export-location", metavar="", default=None, - help=_("Export location to list instances for.") + help=_("Export location to list instances for."), ) return parser @@ -106,7 +116,8 @@ def take_action(self, parsed_args): if parsed_args.share: # Check if the share exists share = osc_utils.find_resource( - share_client.shares, parsed_args.share) + share_client.shares, parsed_args.share + ) instances = share_client.shares.list_instances(share) else: @@ -114,7 +125,8 @@ def take_action(self, parsed_args): if parsed_args.export_location: raise exceptions.CommandError( "Filtering by export location is only " - "available with manila API version >= 2.35") + "available with manila API version >= 2.35" + ) else: if parsed_args.export_location: kwargs['export_location'] = parsed_args.export_location @@ -131,8 +143,10 @@ def take_action(self, parsed_args): 'Share Type ID', ] - data = (osc_utils.get_dict_properties( - instance._info, columns) for instance in instances) + data = ( + osc_utils.get_dict_properties(instance._info, columns) + for instance in instances + ) return (columns, data) @@ -143,19 +157,20 @@ class ShareInstanceSet(command.Command): _description = _("Explicitly reset share instance status") def get_parser(self, prog_name): - parser = super(ShareInstanceSet, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "instance", metavar="", - help=_("Instance to be modified.") + help=_("Instance to be modified."), ) parser.add_argument( "--status", metavar="", - help=_('Indicate which state to assign the instance. Options are: ' - 'available, error, creating, deleting,' - 'error_deleting, migrating, migrating_to, server_migrating.' - ) + help=_( + 'Indicate which state to assign the instance. Options are: ' + 'available, error, creating, deleting,' + 'error_deleting, migrating, migrating_to, server_migrating.' + ), ) return parser @@ -163,36 +178,38 @@ def take_action(self, parsed_args): share_client = self.app.client_manager.share instance = osc_utils.find_resource( - share_client.share_instances, - parsed_args.instance) + share_client.share_instances, parsed_args.instance + ) if parsed_args.status: try: share_client.share_instances.reset_state( - instance, - parsed_args.status + instance, parsed_args.status ) except Exception as e: - LOG.error(_( - "Failed to set status '%(status)s': %(exception)s"), - {'status': parsed_args.status, 'exception': e}) + LOG.error( + _("Failed to set status '%(status)s': %(exception)s"), + {'status': parsed_args.status, 'exception': e}, + ) raise exceptions.CommandError(_("Set operation failed")) if not instance or not parsed_args.status: - raise exceptions.CommandError(_( - "Nothing to set. Please define a '--status'.")) + raise exceptions.CommandError( + _("Nothing to set. Please define a '--status'.") + ) class ShareInstanceShow(command.ShowOne): """Show share instance.""" + _description = _("Show share instance") def get_parser(self, prog_name): - parser = super(ShareInstanceShow, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "instance", metavar="", - help=_("ID of the share instance.") + help=_("ID of the share instance."), ) return parser @@ -200,11 +217,12 @@ def take_action(self, parsed_args): share_client = self.app.client_manager.share instance = osc_utils.find_resource( - share_client.share_instances, - parsed_args.instance) + share_client.share_instances, parsed_args.instance + ) export_locations = share_client.share_instance_export_locations.list( - instance) + instance + ) instance._info['export_locations'] = [] for export_location in export_locations: @@ -214,7 +232,9 @@ def take_action(self, parsed_args): if parsed_args.formatter == 'table': instance._info['export_locations'] = ( cliutils.convert_dict_list_to_string( - instance._info['export_locations'])) + instance._info['export_locations'] + ) + ) instance._info.pop('links', None) diff --git a/manilaclient/osc/v2/share_limits.py b/manilaclient/osc/v2/share_limits.py index 1a3ff305..a93d4544 100644 --- a/manilaclient/osc/v2/share_limits.py +++ b/manilaclient/osc/v2/share_limits.py @@ -24,20 +24,20 @@ class ShareLimitsShow(command.Lister): _description = _("Show a list of share limits for a user.") def get_parser(self, prog_name): - parser = super(ShareLimitsShow, self).get_parser(prog_name) + parser = super().get_parser(prog_name) limit_type_group = parser.add_mutually_exclusive_group(required=True) limit_type_group.add_argument( '--absolute', action='store_true', default=False, - help=_('Get the absolute limits for the user') + help=_('Get the absolute limits for the user'), ) limit_type_group.add_argument( '--rate', action='store_true', default=False, - help=_('Get the API rate limits for the user') + help=_('Get the API rate limits for the user'), ) return parser @@ -66,5 +66,7 @@ def take_action(self, parsed_args): data = list(share_client.limits.get().absolute) - return (columns, (oscutils.get_item_properties(s, columns) - for s in data)) + return ( + columns, + (oscutils.get_item_properties(s, columns) for s in data), + ) diff --git a/manilaclient/osc/v2/share_network_subnets.py b/manilaclient/osc/v2/share_network_subnets.py index df9befc7..36f582f3 100644 --- a/manilaclient/osc/v2/share_network_subnets.py +++ b/manilaclient/osc/v2/share_network_subnets.py @@ -29,63 +29,76 @@ class CreateShareNetworkSubnet(command.ShowOne): """Create a share network subnet.""" + _description = _("Create a share network subnet") def get_parser(self, prog_name): - parser = super(CreateShareNetworkSubnet, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "share_network", metavar="", - help=_("Share network name or ID.") + help=_("Share network name or ID."), ) parser.add_argument( "--neutron-net-id", metavar="", default=None, - help=_("Neutron network ID. Used to set up network for share " - "servers (optional). Should be defined together with " - "'--neutron-subnet-id'.") + help=_( + "Neutron network ID. Used to set up network for share " + "servers (optional). Should be defined together with " + "'--neutron-subnet-id'." + ), ) parser.add_argument( "--neutron-subnet-id", metavar="", default=None, - help=_("Neutron subnet ID. Used to set up network for share " - "servers (optional). Should be defined together with " - "'--neutron-net-id' to which this subnet belongs to. ") + help=_( + "Neutron subnet ID. Used to set up network for share " + "servers (optional). Should be defined together with " + "'--neutron-net-id' to which this subnet belongs to. " + ), ) parser.add_argument( "--availability-zone", metavar="", default=None, - help=_("Optional availability zone that the subnet is available " - "within (Default=None). If None, the subnet will be " - "considered as being available across all availability " - "zones.") + help=_( + "Optional availability zone that the subnet is available " + "within (Default=None). If None, the subnet will be " + "considered as being available across all availability " + "zones." + ), ) parser.add_argument( '--check-only', default=False, action='store_true', - help=_("Run a dry-run of a share network subnet create. " - "Available only for microversion >= 2.70.") + help=_( + "Run a dry-run of a share network subnet create. " + "Available only for microversion >= 2.70." + ), ) parser.add_argument( '--restart-check', default=False, action='store_true', - help=_("Restart a dry-run of a share network subnet create. " - "Helpful when check results are stale. " - "Available only for microversion >= 2.70.") + help=_( + "Restart a dry-run of a share network subnet create. " + "Helpful when check results are stale. " + "Available only for microversion >= 2.70." + ), ) parser.add_argument( "--property", metavar="", default={}, action=parseractions.KeyValueAction, - help=_("Set a property to this share network subnet " - "(repeat option to set multiple properties). " - "Available only for microversion >= 2.78."), + help=_( + "Set a property to this share network subnet " + "(repeat option to set multiple properties). " + "Available only for microversion >= 2.78." + ), ) return parser @@ -93,63 +106,72 @@ def take_action(self, parsed_args): share_client = self.app.client_manager.share # check and restart check during create is only available from 2.70. - if (parsed_args.check_only and - share_client.api_version < api_versions.APIVersion("2.70")): + if ( + parsed_args.check_only + and share_client.api_version < api_versions.APIVersion("2.70") + ): raise exceptions.CommandError( "Check only can be specified only with manila API " - "version >= 2.70.") - if (parsed_args.restart_check and - share_client.api_version < api_versions.APIVersion("2.70")): + "version >= 2.70." + ) + if ( + parsed_args.restart_check + and share_client.api_version < api_versions.APIVersion("2.70") + ): raise exceptions.CommandError( "Restart check can be specified only with manila API " - "version >= 2.70.") + "version >= 2.70." + ) - if (parsed_args.property and - share_client.api_version < api_versions.APIVersion("2.78")): + if ( + parsed_args.property + and share_client.api_version < api_versions.APIVersion("2.78") + ): raise exceptions.CommandError( "Property can be specified only with manila API " - "version >= 2.78.") + "version >= 2.78." + ) neutron_client = getattr(self.app.client_manager, 'network', None) neutron_net_id = parsed_args.neutron_net_id neutron_subnet_id = parsed_args.neutron_subnet_id - if xor(bool(neutron_net_id), - bool(neutron_subnet_id)): + if xor(bool(neutron_net_id), bool(neutron_subnet_id)): raise exceptions.CommandError( "Both neutron_net_id and neutron_subnet_id should be " "specified. Alternatively, neither of them should be " - "specified.") + "specified." + ) if neutron_client and neutron_net_id: try: neutron_net_id = neutron_client.find_network( - neutron_net_id, - ignore_missing=False).id + neutron_net_id, ignore_missing=False + ).id except Exception: raise exceptions.CommandError( - f"Neutron network '{neutron_net_id}'" - f" not found.") + f"Neutron network '{neutron_net_id}' not found." + ) if neutron_client and neutron_subnet_id: try: neutron_subnet_id = neutron_client.find_subnet( - neutron_subnet_id, - ignore_missing=False).id + neutron_subnet_id, ignore_missing=False + ).id except Exception: raise exceptions.CommandError( - f"Neutron subnet '{neutron_subnet_id}'" - f" not found.") + f"Neutron subnet '{neutron_subnet_id}' not found." + ) share_network_id = oscutils.find_resource( - share_client.share_networks, - parsed_args.share_network).id + share_client.share_networks, parsed_args.share_network + ).id if parsed_args.check_only or parsed_args.restart_check: - if parsed_args.property: raise exceptions.CommandError( - "Property cannot be specified with check operation.") + "Property cannot be specified with check operation." + ) subnet_create_check = ( share_client.share_networks.share_network_subnet_create_check( @@ -157,7 +179,8 @@ def take_action(self, parsed_args): neutron_subnet_id=neutron_subnet_id, availability_zone=parsed_args.availability_zone, reset_operation=parsed_args.restart_check, - share_network_id=share_network_id) + share_network_id=share_network_id, + ) ) subnet_data = subnet_create_check[1] if subnet_data: @@ -175,7 +198,7 @@ def take_action(self, parsed_args): neutron_subnet_id=neutron_subnet_id, availability_zone=parsed_args.availability_zone, share_network_id=share_network_id, - metadata=parsed_args.property + metadata=parsed_args.property, ) subnet_data = share_network_subnet._info @@ -184,20 +207,21 @@ def take_action(self, parsed_args): class DeleteShareNetworkSubnet(command.Command): """Delete a share network subnet.""" + _description = _("Delete a share network subnet") def get_parser(self, prog_name): - parser = super(DeleteShareNetworkSubnet, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "share_network", metavar="", - help=_("Share network name or ID.") + help=_("Share network name or ID."), ) parser.add_argument( "share_network_subnet", metavar="", nargs="+", - help=_("ID(s) of share network subnet(s) to be deleted.") + help=_("ID(s) of share network subnet(s) to be deleted."), ) return parser @@ -206,41 +230,45 @@ def take_action(self, parsed_args): result = 0 share_network_id = oscutils.find_resource( - share_client.share_networks, - parsed_args.share_network).id + share_client.share_networks, parsed_args.share_network + ).id for subnet in parsed_args.share_network_subnet: try: share_client.share_network_subnets.delete( - share_network_id, - subnet) + share_network_id, subnet + ) except Exception as e: result += 1 - LOG.error(f"Failed to delete share network subnet with " - f"ID {subnet}: {e}") + LOG.error( + f"Failed to delete share network subnet with " + f"ID {subnet}: {e}" + ) if result > 0: total = len(parsed_args.share_network_subnet) raise exceptions.CommandError( f"{result} of {total} share network subnets failed to be " - f"deleted.") + f"deleted." + ) class ShowShareNetworkSubnet(command.ShowOne): """Show share network subnet.""" + _description = _("Show share network subnet") def get_parser(self, prog_name): - parser = super(ShowShareNetworkSubnet, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "share_network", metavar="", - help=_("Share network name or ID.") + help=_("Share network name or ID."), ) parser.add_argument( "share_network_subnet", metavar="", - help=_("ID of share network subnet to show.") + help=_("ID of share network subnet to show."), ) return parser @@ -248,20 +276,21 @@ def take_action(self, parsed_args): share_client = self.app.client_manager.share share_network_id = oscutils.find_resource( - share_client.share_networks, - parsed_args.share_network).id + share_client.share_networks, parsed_args.share_network + ).id share_network_subnet = share_client.share_network_subnets.get( - share_network_id, - parsed_args.share_network_subnet) + share_network_id, parsed_args.share_network_subnet + ) data = share_network_subnet._info # Special mapping for columns to make the output easier to read: # 'metadata' --> 'properties' data.update( { - 'properties': - format_columns.DictColumn(data.pop('metadata', {})), + 'properties': format_columns.DictColumn( + data.pop('metadata', {}) + ), }, ) @@ -270,107 +299,127 @@ def take_action(self, parsed_args): class SetShareNetworkSubnet(command.Command): """Set share network subnet properties.""" + _description = _("Set share network subnet properties") def get_parser(self, prog_name): - parser = super(SetShareNetworkSubnet, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "share_network", metavar="", - help=_("Share network name or ID.") + help=_("Share network name or ID."), ) parser.add_argument( "share_network_subnet", metavar="", - help=_("ID of share network subnet to set a property.") + help=_("ID of share network subnet to set a property."), ) parser.add_argument( "--property", metavar="", default={}, action=parseractions.KeyValueAction, - help=_("Set a property to this share network subnet " - "(repeat option to set multiple properties). " - "Available only for microversion >= 2.78."), + help=_( + "Set a property to this share network subnet " + "(repeat option to set multiple properties). " + "Available only for microversion >= 2.78." + ), ) return parser def take_action(self, parsed_args): share_client = self.app.client_manager.share - if (parsed_args.property and - share_client.api_version < api_versions.APIVersion("2.78")): + if ( + parsed_args.property + and share_client.api_version < api_versions.APIVersion("2.78") + ): raise exceptions.CommandError( "Property can be specified only with manila API " - "version >= 2.78.") + "version >= 2.78." + ) share_network_id = oscutils.find_resource( - share_client.share_networks, - parsed_args.share_network).id + share_client.share_networks, parsed_args.share_network + ).id if parsed_args.property: try: share_client.share_network_subnets.set_metadata( - share_network_id, parsed_args.property, - subresource=parsed_args.share_network_subnet) + share_network_id, + parsed_args.property, + subresource=parsed_args.share_network_subnet, + ) except Exception as e: - raise exceptions.CommandError(_( - "Failed to set subnet property '%(properties)s': %(e)s") % - {'properties': parsed_args.property, 'e': e}) + raise exceptions.CommandError( + _("Failed to set subnet property '%(properties)s': %(e)s") + % {'properties': parsed_args.property, 'e': e} + ) class UnsetShareNetworkSubnet(command.Command): """Unset a share network subnet property.""" + _description = _("Unset a share network subnet property") def get_parser(self, prog_name): - parser = super(UnsetShareNetworkSubnet, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "share_network", metavar="", - help=_("Share network name or ID.") + help=_("Share network name or ID."), ) parser.add_argument( "share_network_subnet", metavar="", - help=_("ID of share network subnet to set a property.") + help=_("ID of share network subnet to set a property."), ) parser.add_argument( '--property', metavar='', action='append', - help=_("Remove a property from share network subnet " - "(repeat option to remove multiple properties). " - "Available only for microversion >= 2.78."), + help=_( + "Remove a property from share network subnet " + "(repeat option to remove multiple properties). " + "Available only for microversion >= 2.78." + ), ) return parser def take_action(self, parsed_args): share_client = self.app.client_manager.share - if (parsed_args.property and - share_client.api_version < api_versions.APIVersion("2.78")): + if ( + parsed_args.property + and share_client.api_version < api_versions.APIVersion("2.78") + ): raise exceptions.CommandError( "Property can be specified only with manila API " - "version >= 2.78.") + "version >= 2.78." + ) share_network_id = oscutils.find_resource( - share_client.share_networks, - parsed_args.share_network).id + share_client.share_networks, parsed_args.share_network + ).id if parsed_args.property: result = 0 for key in parsed_args.property: try: share_client.share_network_subnets.delete_metadata( - share_network_id, [key], - subresource=parsed_args.share_network_subnet) + share_network_id, + [key], + subresource=parsed_args.share_network_subnet, + ) except Exception as e: result += 1 - LOG.error("Failed to unset subnet property " - "'%(key)s': %(e)s", {'key': key, 'e': e}) + LOG.error( + "Failed to unset subnet property '%(key)s': %(e)s", + {'key': key, 'e': e}, + ) if result > 0: total = len(parsed_args.property) raise exceptions.CommandError( f"{result} of {total} subnet properties failed to be " - f"unset.") + f"unset." + ) diff --git a/manilaclient/osc/v2/share_networks.py b/manilaclient/osc/v2/share_networks.py index d81c3a7c..08eaa4db 100644 --- a/manilaclient/osc/v2/share_networks.py +++ b/manilaclient/osc/v2/share_networks.py @@ -31,30 +31,36 @@ class ListShareNetwork(command.Lister): _description = _("List share networks") def get_parser(self, prog_name): - parser = super(ListShareNetwork, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( '--name', metavar="", - help=_('Filter share networks by name') + help=_('Filter share networks by name'), ) parser.add_argument( '--name~', metavar="", - help=_('Filter share networks by name-pattern. Available only ' - 'for microversion >= 2.36.') + help=_( + 'Filter share networks by name-pattern. Available only ' + 'for microversion >= 2.36.' + ), ) parser.add_argument( '--description', metavar="", - help=_('Filter share networks by description. Available ' - 'only for microversion >= 2.36') + help=_( + 'Filter share networks by description. Available ' + 'only for microversion >= 2.36' + ), ) parser.add_argument( '--description~', metavar="", - help=_('Filter share networks by description-pattern. Available ' - 'only for microversion >= 2.36.') + help=_( + 'Filter share networks by description-pattern. Available ' + 'only for microversion >= 2.36.' + ), ) parser.add_argument( '--all-projects', @@ -65,68 +71,83 @@ def get_parser(self, prog_name): parser.add_argument( '--project', metavar='', - help=_('Filter share networks by project (name or ID) ' - '(admin only)') + help=_( + 'Filter share networks by project (name or ID) (admin only)' + ), ) identity_common.add_project_domain_option_to_parser(parser) parser.add_argument( '--created-since', metavar='', - help=_('Filter share networks by date they were created after. ' - 'The date can be in the format yyyy-mm-dd.') + help=_( + 'Filter share networks by date they were created after. ' + 'The date can be in the format yyyy-mm-dd.' + ), ) parser.add_argument( '--created-before', metavar='', - help=_('Filter share networks by date they were created before. ' - 'The date can be in the format yyyy-mm-dd.') + help=_( + 'Filter share networks by date they were created before. ' + 'The date can be in the format yyyy-mm-dd.' + ), ) parser.add_argument( '--security-service', metavar='', - help=_('Filter share networks by the name or ID of a security ' - 'service attached to the network.') + help=_( + 'Filter share networks by the name or ID of a security ' + 'service attached to the network.' + ), ) parser.add_argument( '--neutron-net-id', metavar='', - help=_('Filter share networks by the ID of a neutron network.') + help=_('Filter share networks by the ID of a neutron network.'), ) parser.add_argument( '--neutron-subnet-id', metavar='', - help=_('Filter share networks by the ID of a neutron sub network.') + help=_( + 'Filter share networks by the ID of a neutron sub network.' + ), ) parser.add_argument( '--network-type', metavar='', - help=_('Filter share networks by the type of network. Examples ' - 'include "flat", "vlan", "vxlan", "geneve", etc.') + help=_( + 'Filter share networks by the type of network. Examples ' + 'include "flat", "vlan", "vxlan", "geneve", etc.' + ), ) parser.add_argument( '--segmentation-id', metavar='', - help=_('Filter share networks by the segmentation ID of network. ' - 'Relevant only for segmented networks such as "vlan", ' - '"vxlan", "geneve", etc.') + help=_( + 'Filter share networks by the segmentation ID of network. ' + 'Relevant only for segmented networks such as "vlan", ' + '"vxlan", "geneve", etc.' + ), ) parser.add_argument( '--cidr', metavar='', - help=_('Filter share networks by the CIDR of network.') + help=_('Filter share networks by the CIDR of network.'), ) parser.add_argument( '--ip-version', metavar='4/6', choices=['4', '6'], - help=_('Filter share networks by the IP Version of the network, ' - 'either 4 or 6.') + help=_( + 'Filter share networks by the IP Version of the network, ' + 'either 4 or 6.' + ), ) parser.add_argument( '--detail', action='store_true', default=False, - help=_("List share networks with details") + help=_("List share networks with details"), ) return parser @@ -137,19 +158,22 @@ def take_action(self, parsed_args): columns = ['ID', 'Name'] if parsed_args.detail: - columns.extend([ - 'Status', - 'Created At', - 'Updated At', - 'Description', - ]) + columns.extend( + [ + 'Status', + 'Created At', + 'Updated At', + 'Description', + ] + ) project_id = None if parsed_args.project: project_id = identity_common.find_project( identity_client, parsed_args.project, - parsed_args.project_domain).id + parsed_args.project_domain, + ).id # set value of 'all_tenants' when using project option all_tenants = bool(parsed_args.project) or parsed_args.all_projects @@ -176,30 +200,35 @@ def take_action(self, parsed_args): search_opts['name~'] = getattr(parsed_args, 'name~') search_opts['description~'] = getattr(parsed_args, 'description~') search_opts['description'] = parsed_args.description - elif (parsed_args.description or getattr(parsed_args, 'name~') or - getattr(parsed_args, 'description~')): + elif ( + parsed_args.description + or getattr(parsed_args, 'name~') + or getattr(parsed_args, 'description~') + ): raise exceptions.CommandError( "Pattern based filtering (name~, description~ and description)" - " is only available with manila API version >= 2.36") + " is only available with manila API version >= 2.36" + ) data = share_client.share_networks.list(search_opts=search_opts) return ( columns, - (oscutils.get_item_properties(s, columns) for s in data) + (oscutils.get_item_properties(s, columns) for s in data), ) class ShowShareNetwork(command.ShowOne): """Display a share network""" + _description = _("Show details about a share network") def get_parser(self, prog_name): - parser = super(ShowShareNetwork, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "share_network", metavar="", - help=_("Name or ID of the share network to display") + help=_("Name or ID of the share network to display"), ) return parser @@ -207,8 +236,8 @@ def take_action(self, parsed_args): share_client = self.app.client_manager.share share_network = oscutils.find_resource( - share_client.share_networks, - parsed_args.share_network) + share_client.share_networks, parsed_args.share_network + ) data = share_network._info if 'share_network_subnets' not in data: @@ -219,14 +248,16 @@ def take_action(self, parsed_args): for ss in data['share_network_subnets']: ss.update( { - 'properties': - format_columns.DictColumn(ss.pop('metadata', {})), + 'properties': format_columns.DictColumn( + ss.pop('metadata', {}) + ), }, ) # Add security services information security_services = share_client.security_services.list( - search_opts={'share_network_id': share_network.id}, detailed=False) + search_opts={'share_network_id': share_network.id}, detailed=False + ) data['security_services'] = [ { 'security_service_name': ss.name, @@ -238,7 +269,8 @@ def take_action(self, parsed_args): if parsed_args.formatter == 'table': data['share_network_subnets'] = ( cliutils.convert_dict_list_to_string( - data['share_network_subnets']) + data['share_network_subnets'] + ) ) data['security_services'] = cliutils.convert_dict_list_to_string( data['security_services'] @@ -251,50 +283,57 @@ def take_action(self, parsed_args): class CreateShareNetwork(command.ShowOne): """Create a share network.""" + _description = _("Create a share network") def get_parser(self, prog_name): - parser = super(CreateShareNetwork, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "--name", metavar="", - help=_("Add a name to the share network (Optional)") + help=_("Add a name to the share network (Optional)"), ) parser.add_argument( "--description", metavar="", default=None, - help=_("Add a description to the share network (Optional).") + help=_("Add a description to the share network (Optional)."), ) parser.add_argument( "--neutron-net-id", metavar="", default=None, - help=_("ID of the neutron network that must be associated with " - "the share network (Optional). The network specified will " - "be associated with the 'default' share network subnet, " - "unless 'availability-zone' is also specified.") + help=_( + "ID of the neutron network that must be associated with " + "the share network (Optional). The network specified will " + "be associated with the 'default' share network subnet, " + "unless 'availability-zone' is also specified." + ), ) parser.add_argument( "--neutron-subnet-id", metavar="", default=None, - help=_("ID of the neutron sub-network that must be associated " - "with the share network (Optional). The subnet specified " - "will be associated with the 'default' share network " - "subnet, unless 'availability-zone' is also specified.") + help=_( + "ID of the neutron sub-network that must be associated " + "with the share network (Optional). The subnet specified " + "will be associated with the 'default' share network " + "subnet, unless 'availability-zone' is also specified." + ), ) parser.add_argument( "--availability-zone", metavar="", default=None, - help=_("Name or ID of the avalilability zone to assign the " - "specified network subnet parameters to. Must be used " - "in conjunction with 'neutron-net-id' and " - "'neutron-subnet-id'. Do not specify this parameter if " - "the network must be available across all availability " - "zones ('default' share network subnet). Available " - "only for microversion >= 2.51.") + help=_( + "Name or ID of the avalilability zone to assign the " + "specified network subnet parameters to. Must be used " + "in conjunction with 'neutron-net-id' and " + "'neutron-subnet-id'. Do not specify this parameter if " + "the network must be available across all availability " + "zones ('default' share network subnet). Available " + "only for microversion >= 2.51." + ), ) return parser @@ -307,28 +346,33 @@ def take_action(self, parsed_args): if neutron_client and neutron_net_id: try: neutron_net_id = neutron_client.find_network( - neutron_net_id, - ignore_missing=False).id + neutron_net_id, ignore_missing=False + ).id except Exception: raise exceptions.CommandError( f"Neutron network '{parsed_args.neutron_net_id}'" - f" not found.") + f" not found." + ) if neutron_client and neutron_subnet_id: try: neutron_subnet_id = neutron_client.find_subnet( - neutron_subnet_id, - ignore_missing=False).id + neutron_subnet_id, ignore_missing=False + ).id except Exception: raise exceptions.CommandError( f"Neutron subnet '{parsed_args.neutron_subnet_id}'" - f" not found.") + f" not found." + ) availability_zone = None - if (parsed_args.availability_zone and - share_client.api_version < api_versions.APIVersion("2.51")): + if ( + parsed_args.availability_zone + and share_client.api_version < api_versions.APIVersion("2.51") + ): raise exceptions.CommandError( "Availability zone can be specified only with manila API " - "version >= 2.51") + "version >= 2.51" + ) elif parsed_args.availability_zone: availability_zone = parsed_args.availability_zone @@ -349,28 +393,30 @@ def take_action(self, parsed_args): if parsed_args.formatter == 'table': share_network_data['share_network_subnets'] = ( cliutils.convert_dict_list_to_string( - share_network_data['share_network_subnets']) + share_network_data['share_network_subnets'] + ) ) return self.dict2columns(share_network_data) class DeleteShareNetwork(command.Command): """Delete one or more share networks""" + _description = _("Delete one or more share networks") def get_parser(self, prog_name): - parser = super(DeleteShareNetwork, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "share_network", metavar="", nargs="+", - help=_("Name or ID of the share network(s) to delete") + help=_("Name or ID of the share network(s) to delete"), ) parser.add_argument( "--wait", action='store_true', default=False, - help=_("Wait for the share network(s) to be deleted") + help=_("Wait for the share network(s) to be deleted"), ) return parser @@ -381,20 +427,22 @@ def take_action(self, parsed_args): for share_network in parsed_args.share_network: try: share_network_obj = oscutils.find_resource( - share_client.share_networks, - share_network) - share_client.share_networks.delete( - share_network_obj) + share_client.share_networks, share_network + ) + share_client.share_networks.delete(share_network_obj) if parsed_args.wait: if not oscutils.wait_for_delete( - manager=share_client.share_networks, - res_id=share_network_obj.id): + manager=share_client.share_networks, + res_id=share_network_obj.id, + ): result += 1 except Exception as e: result += 1 - LOG.error(f"Failed to delete share network with " - f"name or ID {share_network}: {e}") + LOG.error( + f"Failed to delete share network with " + f"name or ID {share_network}: {e}" + ) if result > 0: total = len(parsed_args.share_network) @@ -404,81 +452,96 @@ def take_action(self, parsed_args): class SetShareNetwork(command.Command): """Set share network properties.""" + _description = _("Set share network properties") def get_parser(self, prog_name): - parser = super(SetShareNetwork, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "share_network", metavar="", - help=_('Name or ID of the share network to set a property for') + help=_('Name or ID of the share network to set a property for'), ) parser.add_argument( "--name", metavar="", default=None, - help=_("Set a new name to the share network.") + help=_("Set a new name to the share network."), ) parser.add_argument( "--description", metavar="", default=None, - help=_("Set a new description to the share network.") + help=_("Set a new description to the share network."), ) parser.add_argument( "--status", metavar="", choices=['active', 'error', 'network_change'], - help=_("Assign a status to the share network (Admin only). " - "Options include : active, error, network_change. " - "Available only for microversion >= 2.63.") + help=_( + "Assign a status to the share network (Admin only). " + "Options include : active, error, network_change. " + "Available only for microversion >= 2.63." + ), ) parser.add_argument( '--neutron-net-id', metavar='', - help=_("Update the neutron network associated with the default " - "share network subnet. If a default share network subnet " - "is not present or if the share network is in use, setting " - "this will fail.") + help=_( + "Update the neutron network associated with the default " + "share network subnet. If a default share network subnet " + "is not present or if the share network is in use, setting " + "this will fail." + ), ) parser.add_argument( '--neutron-subnet-id', metavar='', - help=_("Update the neutron subnetwork associated with the default " - "share network subnet. If a default share network subnet " - "is not present or if the share network is in use, setting " - "this will fail.") + help=_( + "Update the neutron subnetwork associated with the default " + "share network subnet. If a default share network subnet " + "is not present or if the share network is in use, setting " + "this will fail." + ), ) parser.add_argument( '--current-security-service', metavar='', - help=_("Name or ID of a security service that is currently " - "associated with a share network that must be replaced. " - "Replacing a security service is only available for " - "microversions >= 2.63.") + help=_( + "Name or ID of a security service that is currently " + "associated with a share network that must be replaced. " + "Replacing a security service is only available for " + "microversions >= 2.63." + ), ) parser.add_argument( '--new-security-service', metavar='', - help=_("Name or ID of a security service that must be associated " - "with the share network. When replacing a security " - "service, the current security service must also be " - "provided with the '--current-security-service' option. " - "Replacing a security service is only available for " - "microversions >= 2.63.") + help=_( + "Name or ID of a security service that must be associated " + "with the share network. When replacing a security " + "service, the current security service must also be " + "provided with the '--current-security-service' option. " + "Replacing a security service is only available for " + "microversions >= 2.63." + ), ) parser.add_argument( '--check-only', action='store_true', - help=_("Run a dry-run of a security service replacement. " - "Available only for microversion >=2.63") + help=_( + "Run a dry-run of a security service replacement. " + "Available only for microversion >=2.63" + ), ) parser.add_argument( '--restart-check', action='store_true', - help=_("Restart a dry-run of a security service " - "replacement. Helpful when check results are " - "stale. Available only for microversion >=2.63.") + help=_( + "Restart a dry-run of a security service " + "replacement. Helpful when check results are " + "stale. Available only for microversion >=2.63." + ), ) return parser @@ -486,30 +549,40 @@ def take_action(self, parsed_args): share_client = self.app.client_manager.share result = 0 - share_network = oscutils.find_resource(share_client.share_networks, - parsed_args.share_network) + share_network = oscutils.find_resource( + share_client.share_networks, parsed_args.share_network + ) kwargs = {} # some args are only for newer API micro-version if share_client.api_version < api_versions.APIVersion("2.63"): - new_args = ('status', 'check_only', 'restart_check', - 'current_security_service') + new_args = ( + 'status', + 'check_only', + 'restart_check', + 'current_security_service', + ) invalid_args = [ - arg for arg in new_args + arg + for arg in new_args if getattr(parsed_args, arg) is not None ] raise exceptions.CommandError( f"Use of {' '.join(invalid_args)} is only available for API " - f"microversions >= 2.63.") + f"microversions >= 2.63." + ) # If "--check-only" and "--restart-check" are used, a new security # service option must be supplied if parsed_args.check_only or parsed_args.restart_check: if not parsed_args.new_security_service: raise exceptions.CommandError( - _("Must provide new security service with --check-only " - "and --restart-check.")) + _( + "Must provide new security service with --check-only " + "and --restart-check." + ) + ) if parsed_args.name is not None: kwargs['name'] = parsed_args.name @@ -522,43 +595,47 @@ def take_action(self, parsed_args): if kwargs: try: - share_client.share_networks.update( - share_network, - **kwargs - ) + share_client.share_networks.update(share_network, **kwargs) except Exception as e: result += 1 - LOG.error(f"Failed to set share network properties " - f"{kwargs}: {e}") + LOG.error( + f"Failed to set share network properties {kwargs}: {e}" + ) if parsed_args.status: try: share_client.share_networks.reset_state( - share_network, - parsed_args.status + share_network, parsed_args.status ) except Exception as e: result += 1 - LOG.error(f"Failed to update share network status to " - f"{parsed_args.status}: {e}") + LOG.error( + f"Failed to update share network status to " + f"{parsed_args.status}: {e}" + ) new_security_service = current_security_service = None if parsed_args.new_security_service: new_security_service = oscutils.find_resource( share_client.security_services, - parsed_args.new_security_service) + parsed_args.new_security_service, + ) if parsed_args.current_security_service: current_security_service = oscutils.find_resource( share_client.security_services, - parsed_args.current_security_service) + parsed_args.current_security_service, + ) if new_security_service and not current_security_service: try: if parsed_args.check_only: - check_result = share_client.share_networks\ - .add_security_service_check( - share_network, new_security_service, - reset_operation=parsed_args.restart_check) + check_result = ( + share_client.share_networks.add_security_service_check( + share_network, + new_security_service, + reset_operation=parsed_args.restart_check, + ) + ) is_compatible = check_result[1].get('compatible') # NOTE(gouthamr): We're logging to the console here, # because there's no need to print useful @@ -566,39 +643,46 @@ def take_action(self, parsed_args): # logging is a hack, since other kinds of logs may # not print to console by default. if is_compatible is None: - LOG.error("Security service check has been " - "successfully initiated, please retry " - "after some time.") + LOG.error( + "Security service check has been " + "successfully initiated, please retry " + "after some time." + ) elif is_compatible: LOG.error( f"Security service " f"{parsed_args.new_security_service} can " f"be added to share network " - f"{parsed_args.share_network}.") + f"{parsed_args.share_network}." + ) else: LOG.error( f"Security service " f"{parsed_args.new_security_service} cannot " f"be added to share network " - f"{parsed_args.share_network}.") + f"{parsed_args.share_network}." + ) else: share_client.share_networks.add_security_service( - share_network, new_security_service) + share_network, new_security_service + ) except Exception as e: result += 1 - LOG.error(f"Failed to add security service " - f"{parsed_args.new_security_service} to " - f"share network {parsed_args.share_network}: {e}") + LOG.error( + f"Failed to add security service " + f"{parsed_args.new_security_service} to " + f"share network {parsed_args.share_network}: {e}" + ) if new_security_service and current_security_service: try: if parsed_args.check_only: - check_result = share_client.share_networks.\ - update_share_network_security_service_check( - share_network, - current_security_service, - new_security_service, - reset_operation=parsed_args.restart_check) + check_result = share_client.share_networks.update_share_network_security_service_check( + share_network, + current_security_service, + new_security_service, + reset_operation=parsed_args.restart_check, + ) is_compatible = check_result[1].get('compatible') # NOTE(gouthamr): We're logging to the console here, @@ -607,51 +691,59 @@ def take_action(self, parsed_args): # logging is a hack, since other kinds of logs may # not print to console by default. if is_compatible is None: - LOG.error("Security service check has been " - "successfully initiated, please retry " - "after some time.") + LOG.error( + "Security service check has been " + "successfully initiated, please retry " + "after some time." + ) elif is_compatible: LOG.error( f"Security service " f"{parsed_args.current_security_service} can " f"be replaced with security service " f"{parsed_args.new_security_service} on share " - f"network {parsed_args.share_network}.") + f"network {parsed_args.share_network}." + ) else: LOG.error( f"Security service " f"{parsed_args.current_security_service} cannot " f"be replaced with security service " f"{parsed_args.new_security_service} on share " - f"network {parsed_args.share_network}.") + f"network {parsed_args.share_network}." + ) else: - share_client.share_networks.\ - update_share_network_security_service( - share_network, - current_security_service, - new_security_service) + share_client.share_networks.update_share_network_security_service( + share_network, + current_security_service, + new_security_service, + ) except Exception as e: result += 1 - LOG.error(f"Failed to update security service " - f"{parsed_args.current_security_service} on " - f"share network " - f"{parsed_args.share_network}: {e}") + LOG.error( + f"Failed to update security service " + f"{parsed_args.current_security_service} on " + f"share network " + f"{parsed_args.share_network}: {e}" + ) if result > 0: - raise exceptions.CommandError(_("One or more of the " - "set operations failed")) + raise exceptions.CommandError( + _("One or more of the set operations failed") + ) class UnsetShareNetwork(command.Command): """Unset a share network property.""" + _description = _("Unset a share network property") def get_parser(self, prog_name): - parser = super(UnsetShareNetwork, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "share_network", metavar="", - help=_("Name or ID of the share network to unset a property of") + help=_("Name or ID of the share network to unset a property of"), ) parser.add_argument( "--name", @@ -666,8 +758,10 @@ def get_parser(self, prog_name): parser.add_argument( "--security-service", metavar="", - help=_("Disassociate a security service from the share network. " - "This is only possible with unused share networks."), + help=_( + "Disassociate a security service from the share network. " + "This is only possible with unused share networks." + ), ) return parser @@ -675,14 +769,14 @@ def take_action(self, parsed_args): share_client = self.app.client_manager.share share_network = oscutils.find_resource( - share_client.share_networks, - parsed_args.share_network) + share_client.share_networks, parsed_args.share_network + ) security_service = None if parsed_args.security_service: security_service = oscutils.find_resource( - share_client.security_services, - parsed_args.security_service) + share_client.security_services, parsed_args.security_service + ) result = 0 kwargs = {} @@ -694,25 +788,27 @@ def take_action(self, parsed_args): kwargs['description'] = '' if kwargs: try: - share_client.share_networks.update( - share_network, - **kwargs - ) + share_client.share_networks.update(share_network, **kwargs) except Exception as e: result += 1 - LOG.error(f"Failed to unset share network properties " - f"{kwargs}: {e}") + LOG.error( + f"Failed to unset share network properties {kwargs}: {e}" + ) if security_service: try: share_client.share_networks.remove_security_service( - share_network, security_service) + share_network, security_service + ) except Exception as e: result += 1 - LOG.error(f"Failed to dissociate security service" - f"{parsed_args.security_service} from " - f"{parsed_args.share_network}: {e}") + LOG.error( + f"Failed to dissociate security service" + f"{parsed_args.security_service} from " + f"{parsed_args.share_network}: {e}" + ) if result > 0: - raise exceptions.CommandError(_("One or more of the " - "unset operations failed")) + raise exceptions.CommandError( + _("One or more of the unset operations failed") + ) diff --git a/manilaclient/osc/v2/share_pools.py b/manilaclient/osc/v2/share_pools.py index 13bf815a..1805ec00 100644 --- a/manilaclient/osc/v2/share_pools.py +++ b/manilaclient/osc/v2/share_pools.py @@ -20,44 +20,54 @@ class ListSharePools(command.Lister): """List all backend storage pools known to the scheduler (Admin only).""" + _description = _( - "List all backend storage pools known to the scheduler (Admin only).") + "List all backend storage pools known to the scheduler (Admin only)." + ) def get_parser(self, prog_name): - parser = super(ListSharePools, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "--host", metavar="", default=None, - help=_("Filter results by host name. " - "Regular expressions are supported.") + help=_( + "Filter results by host name. " + "Regular expressions are supported." + ), ) parser.add_argument( "--backend", metavar="", default=None, - help=_("Filter results by backend name. " - "Regular expressions are supported.") + help=_( + "Filter results by backend name. " + "Regular expressions are supported." + ), ) parser.add_argument( "--pool", metavar="", default=None, - help=_("Filter results by pool name. " - "Regular expressions are supported.") + help=_( + "Filter results by pool name. " + "Regular expressions are supported." + ), ) parser.add_argument( "--detail", action='store_true', default=False, - help=_("Show detailed information about pools.") + help=_("Show detailed information about pools."), ) parser.add_argument( "--share-type", metavar="", default=None, - help=_("Filter results by share type name or ID. " - "Available only for microversion >= 2.23") + help=_( + "Filter results by share type name or ID. " + "Available only for microversion >= 2.23" + ), ) return parser @@ -68,12 +78,15 @@ def take_action(self, parsed_args): if parsed_args.share_type: if share_client.api_version >= api_versions.APIVersion("2.23"): share_type = osc_utils.find_resource( - share_client.share_types, - parsed_args.share_type).id + share_client.share_types, parsed_args.share_type + ).id else: - raise exceptions.CommandError(_( - "Filtering results by share type is only available with " - "manila API version >= 2.23")) + raise exceptions.CommandError( + _( + "Filtering results by share type is only available with " + "manila API version >= 2.23" + ) + ) search_opts = { 'host': parsed_args.host, @@ -83,7 +96,8 @@ def take_action(self, parsed_args): } pools = share_client.pools.list( - detailed=parsed_args.detail, search_opts=search_opts) + detailed=parsed_args.detail, search_opts=search_opts + ) columns = ["Name", "Host", "Backend", "Pool"] @@ -91,11 +105,17 @@ def take_action(self, parsed_args): columns.append("Capabilities") if parsed_args.formatter == 'table': for pool in pools: - pool._info.update({ - 'capabilities': utils.format_properties( - pool.capabilities)}) + pool._info.update( + { + 'capabilities': utils.format_properties( + pool.capabilities + ) + } + ) - data = (osc_utils.get_dict_properties( - pool._info, columns) for pool in pools) + data = ( + osc_utils.get_dict_properties(pool._info, columns) + for pool in pools + ) return (columns, data) diff --git a/manilaclient/osc/v2/share_replica_export_locations.py b/manilaclient/osc/v2/share_replica_export_locations.py index 2e219789..620a374a 100644 --- a/manilaclient/osc/v2/share_replica_export_locations.py +++ b/manilaclient/osc/v2/share_replica_export_locations.py @@ -21,12 +21,9 @@ class ShareReplicaListExportLocation(command.Lister): _description = _("List export locations of a share replica.") def get_parser(self, prog_name): - parser = super( - ShareReplicaListExportLocation, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( - "replica", - metavar="", - help=_("ID of the share replica.") + "replica", metavar="", help=_("ID of the share replica.") ) return parser @@ -42,14 +39,17 @@ def take_action(self, parsed_args): ] replica = osc_utils.find_resource( - share_client.share_replicas, - parsed_args.replica) + share_client.share_replicas, parsed_args.replica + ) export_locations = share_client.share_replica_export_locations.list( - replica) + replica + ) - data = (osc_utils.get_dict_properties( - location._info, columns) for location in export_locations) + data = ( + osc_utils.get_dict_properties(location._info, columns) + for location in export_locations + ) return (columns, data) @@ -60,17 +60,14 @@ class ShareReplicaShowExportLocation(command.ShowOne): _description = _("Show details of a share replica's export location.") def get_parser(self, prog_name): - parser = super( - ShareReplicaShowExportLocation, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( - "replica", - metavar="", - help=_("ID of the share replica.") + "replica", metavar="", help=_("ID of the share replica.") ) parser.add_argument( "export_location", metavar="", - help=_("ID of the share replica export location.") + help=_("ID of the share replica export location."), ) return parser @@ -78,10 +75,11 @@ def take_action(self, parsed_args): share_client = self.app.client_manager.share replica = osc_utils.find_resource( - share_client.share_replicas, - parsed_args.replica) + share_client.share_replicas, parsed_args.replica + ) export_location = share_client.share_replica_export_locations.get( - replica, parsed_args.export_location) + replica, parsed_args.export_location + ) return self.dict2columns(export_location._info) diff --git a/manilaclient/osc/v2/share_replicas.py b/manilaclient/osc/v2/share_replicas.py index 5b0d01e7..ca77e1bb 100644 --- a/manilaclient/osc/v2/share_replicas.py +++ b/manilaclient/osc/v2/share_replicas.py @@ -26,62 +26,72 @@ class CreateShareReplica(command.ShowOne): """Create a share replica.""" + _description = _("Create a replica of the given share") def get_parser(self, prog_name): - parser = super(CreateShareReplica, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "share", metavar="", - help=_("Name or ID of the share to replicate.") + help=_("Name or ID of the share to replicate."), ) parser.add_argument( '--availability-zone', metavar='', default=None, - help=_('Availability zone in which the replica should be created.') + help=_( + 'Availability zone in which the replica should be created.' + ), ) parser.add_argument( '--wait', action='store_true', default=False, - help=_('Wait for replica creation') + help=_('Wait for replica creation'), ) parser.add_argument( "--scheduler-hint", metavar="", default={}, action=parseractions.KeyValueAction, - help=_("Scheduler hint for the share replica as key=value pairs, " - "Supported key is only_host. Available for microversion " - ">= 2.67."), + help=_( + "Scheduler hint for the share replica as key=value pairs, " + "Supported key is only_host. Available for microversion " + ">= 2.67." + ), ) parser.add_argument( '--share-network', metavar='', default=None, - help=_('Optional network info ID or name. Available for ' - 'microversion >= 2.72') + help=_( + 'Optional network info ID or name. Available for ' + 'microversion >= 2.72' + ), ) return parser def take_action(self, parsed_args): share_client = self.app.client_manager.share - share = osc_utils.find_resource(share_client.shares, - parsed_args.share) + share = osc_utils.find_resource(share_client.shares, parsed_args.share) scheduler_hints = {} if parsed_args.scheduler_hint: if share_client.api_version < api_versions.APIVersion("2.67"): - raise exceptions.CommandError(_( - "arg '--scheduler_hint' is available only starting with " - "API microversion '2.67'.")) + raise exceptions.CommandError( + _( + "arg '--scheduler_hint' is available only starting with " + "API microversion '2.67'." + ) + ) hints = utils.extract_key_value_options(parsed_args.scheduler_hint) if 'only_host' not in hints.keys() or len(hints) > 1: raise exceptions.CommandError( "The only valid key supported with the --scheduler-hint " - "argument is 'only_host'.") + "argument is 'only_host'." + ) scheduler_hints['only_host'] = hints.get('only_host') body = { @@ -96,10 +106,11 @@ def take_action(self, parsed_args): if share_client.api_version < api_versions.APIVersion("2.72"): raise exceptions.CommandError( "'share-network' option is available only starting " - "with '2.72' API microversion.") + "with '2.72' API microversion." + ) share_network_id = osc_utils.find_resource( - share_client.share_networks, - parsed_args.share_network).id + share_client.share_networks, parsed_args.share_network + ).id body['share_network'] = share_network_id share_replica = share_client.share_replicas.create(**body) @@ -107,42 +118,45 @@ def take_action(self, parsed_args): if not osc_utils.wait_for_status( status_f=share_client.share_replicas.get, res_id=share_replica.id, - success_status=['available'] + success_status=['available'], ): LOG.error(_("ERROR: Share replica is in error state.")) share_replica = osc_utils.find_resource( - share_client.share_replicas, - share_replica.id) + share_client.share_replicas, share_replica.id + ) return self.dict2columns(share_replica._info) class DeleteShareReplica(command.Command): """Delete one or more share replicas.""" + _description = _("Delete one or more share replicas") def get_parser(self, prog_name): - parser = super(DeleteShareReplica, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "replica", metavar="", nargs="+", - help=_("Name or ID of the replica(s) to delete") + help=_("Name or ID of the replica(s) to delete"), ) parser.add_argument( "--force", action='store_true', default=False, - help=_("Attempt to force delete a replica on its backend. " - "Using this option will purge the replica from Manila " - "even if it is not cleaned up on the backend. ") + help=_( + "Attempt to force delete a replica on its backend. " + "Using this option will purge the replica from Manila " + "even if it is not cleaned up on the backend. " + ), ) parser.add_argument( "--wait", action='store_true', default=False, - help=_("Wait for share replica deletion") + help=_("Wait for share replica deletion"), ) return parser @@ -153,44 +167,51 @@ def take_action(self, parsed_args): for replica in parsed_args.replica: try: replica_obj = osc_utils.find_resource( - share_client.share_replicas, - replica) + share_client.share_replicas, replica + ) share_client.share_replicas.delete( - replica_obj, - force=parsed_args.force) + replica_obj, force=parsed_args.force + ) if parsed_args.wait: if not osc_utils.wait_for_delete( - manager=share_client.share_replicas, - res_id=replica_obj.id): + manager=share_client.share_replicas, + res_id=replica_obj.id, + ): result += 1 except Exception as e: result += 1 - LOG.error(_( - "Failed to delete a share replica with " - "name or ID '%(replica)s': %(e)s"), - {'replica': replica, 'e': e}) + LOG.error( + _( + "Failed to delete a share replica with " + "name or ID '%(replica)s': %(e)s" + ), + {'replica': replica, 'e': e}, + ) if result > 0: total = len(parsed_args.replica) - msg = (_("%(result)s of %(total)s replicas failed " - "to delete.") % {'result': result, 'total': total}) + msg = _("%(result)s of %(total)s replicas failed to delete.") % { + 'result': result, + 'total': total, + } raise exceptions.CommandError(msg) class ListShareReplica(command.Lister): """List share replicas.""" + _description = _("List share replicas") def get_parser(self, prog_name): - parser = super(ListShareReplica, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "--share", metavar="", default=None, - help=_("Name or ID of the share to list replicas for.") + help=_("Name or ID of the share to list replicas for."), ) return parser @@ -200,8 +221,8 @@ def take_action(self, parsed_args): share = None if parsed_args.share: share = osc_utils.find_resource( - share_client.shares, - parsed_args.share) + share_client.shares, parsed_args.share + ) replicas = share_client.share_replicas.list(share=share) @@ -216,46 +237,53 @@ def take_action(self, parsed_args): ] column_headers = utils.format_column_headers(columns) - data = (osc_utils.get_dict_properties( - replica._info, columns) for replica in replicas) + data = ( + osc_utils.get_dict_properties(replica._info, columns) + for replica in replicas + ) return (column_headers, data) class ShowShareReplica(command.ShowOne): """Show share replica.""" + _description = _("Show details about a replica") def get_parser(self, prog_name): - parser = super(ShowShareReplica, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "replica", metavar="", - help=_("ID of the share replica. Available only for " - "microversion >= 2.47. ") + help=_( + "ID of the share replica. Available only for " + "microversion >= 2.47. " + ), ) return parser def take_action(self, parsed_args): share_client = self.app.client_manager.share - replica = share_client.share_replicas.get( - parsed_args.replica) + replica = share_client.share_replicas.get(parsed_args.replica) replica_export_locations = ( share_client.share_replica_export_locations.list( - share_replica=replica)) + share_replica=replica + ) + ) replica._info['export_locations'] = [] for element_location in replica_export_locations: element_location._info.pop('links', None) - replica._info['export_locations'].append( - element_location._info) + replica._info['export_locations'].append(element_location._info) if parsed_args.formatter == 'table': replica._info['export_locations'] = ( cliutils.convert_dict_list_to_string( - replica._info['export_locations'])) + replica._info['export_locations'] + ) + ) replica._info.pop('links', None) @@ -265,31 +293,41 @@ def take_action(self, parsed_args): class SetShareReplica(command.Command): """Set share replica""" - _description = _("Explicitly set share replica status and/or " - "replica-state") + _description = _( + "Explicitly set share replica status and/or replica-state" + ) def get_parser(self, prog_name): - parser = super(SetShareReplica, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "replica", metavar="", - help=_("ID of the share replica to modify.") + help=_("ID of the share replica to modify."), ) parser.add_argument( "--replica-state", metavar="", choices=['in_sync', 'out_of_sync', 'active', 'error'], - help=_("Indicate which replica_state to assign the replica. " - "Options include in_sync, out_of_sync, active and error.") + help=_( + "Indicate which replica_state to assign the replica. " + "Options include in_sync, out_of_sync, active and error." + ), ) parser.add_argument( "--status", metavar="", - choices=['available', 'error', 'creating', 'deleting', - 'error_deleting'], - help=_("Indicate which status to assign the replica. Options " - "include available, error, creating, deleting and " - "error_deleting.") + choices=[ + 'available', + 'error', + 'creating', + 'deleting', + 'error_deleting', + ], + help=_( + "Indicate which status to assign the replica. Options " + "include available, error, creating, deleting and " + "error_deleting." + ), ) return parser @@ -298,69 +336,76 @@ def take_action(self, parsed_args): result = 0 replica = osc_utils.find_resource( - share_client.share_replicas, - parsed_args.replica) + share_client.share_replicas, parsed_args.replica + ) if parsed_args.replica_state: try: share_client.share_replicas.reset_replica_state( - replica, - parsed_args.replica_state + replica, parsed_args.replica_state ) except Exception as e: result += 1 - LOG.error(_( - "Failed to set replica_state " - "'%(replica_state)s': %(exception)s"), - {'replica_state': parsed_args.replica_state, - 'exception': e}) + LOG.error( + _( + "Failed to set replica_state " + "'%(replica_state)s': %(exception)s" + ), + { + 'replica_state': parsed_args.replica_state, + 'exception': e, + }, + ) if parsed_args.status: try: share_client.share_replicas.reset_state( - replica, - parsed_args.status + replica, parsed_args.status ) except Exception as e: result += 1 - LOG.error(_( - "Failed to set status '%(status)s': %(exception)s"), - {'status': parsed_args.status, 'exception': e}) + LOG.error( + _("Failed to set status '%(status)s': %(exception)s"), + {'status': parsed_args.status, 'exception': e}, + ) if not parsed_args.replica_state and not parsed_args.status: - raise exceptions.CommandError(_( - "Nothing to set. Please define " - "either '--replica_state' or '--status'.")) + raise exceptions.CommandError( + _( + "Nothing to set. Please define " + "either '--replica_state' or '--status'." + ) + ) if result > 0: - raise exceptions.CommandError(_("One or more of the " - "set operations failed")) + raise exceptions.CommandError( + _("One or more of the set operations failed") + ) class PromoteShareReplica(command.Command): """Promote share replica""" - _description = _("Promote specified replica to 'active' " - "replica_state.") + _description = _("Promote specified replica to 'active' replica_state.") def get_parser(self, prog_name): - parser = super(PromoteShareReplica, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( - "replica", - metavar="", - help=_("ID of the share replica.") + "replica", metavar="", help=_("ID of the share replica.") ) parser.add_argument( '--quiesce-wait-time', metavar='', default=None, - help=_('Quiesce wait time in seconds. Available for ' - 'microversion >= 2.75') + help=_( + 'Quiesce wait time in seconds. Available for ' + 'microversion >= 2.75' + ), ) parser.add_argument( '--wait', action='store_true', default=False, - help=_('Wait for share replica promotion') + help=_('Wait for share replica promotion'), ) return parser @@ -368,8 +413,8 @@ def take_action(self, parsed_args): share_client = self.app.client_manager.share replica = osc_utils.find_resource( - share_client.share_replicas, - parsed_args.replica) + share_client.share_replicas, parsed_args.replica + ) args = [ replica, @@ -378,37 +423,40 @@ def take_action(self, parsed_args): if share_client.api_version < api_versions.APIVersion("2.75"): raise exceptions.CommandError( "'quiesce-wait-time' option is available only starting " - "with '2.75' API microversion.") + "with '2.75' API microversion." + ) args += [parsed_args.quiesce_wait_time] try: share_client.share_replicas.promote(*args) if parsed_args.wait: if not osc_utils.wait_for_status( - status_f=share_client.share_replicas.get, - res_id=replica.id, - success_status=['active'], - status_field='replica_state' + status_f=share_client.share_replicas.get, + res_id=replica.id, + success_status=['active'], + status_field='replica_state', ): LOG.error(_("ERROR: Share replica is in error state.")) except Exception as e: - raise exceptions.CommandError(_( - "Failed to promote replica to 'active': %s" % (e))) + raise exceptions.CommandError( + _(f"Failed to promote replica to 'active': {e}") + ) class ResyncShareReplica(command.Command): """Resync share replica""" - _description = _("Attempt to update the share replica with its " - "'active' mirror.") + _description = _( + "Attempt to update the share replica with its 'active' mirror." + ) def get_parser(self, prog_name): - parser = super(ResyncShareReplica, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "replica", metavar="", - help=_("ID of the share replica to resync.") + help=_("ID of the share replica to resync."), ) return parser @@ -416,11 +464,12 @@ def take_action(self, parsed_args): share_client = self.app.client_manager.share replica = osc_utils.find_resource( - share_client.share_replicas, - parsed_args.replica) + share_client.share_replicas, parsed_args.replica + ) try: share_client.share_replicas.resync(replica) except Exception as e: - raise exceptions.CommandError(_( - "Failed to resync share replica: %s" % (e))) + raise exceptions.CommandError( + _(f"Failed to resync share replica: {e}") + ) diff --git a/manilaclient/osc/v2/share_servers.py b/manilaclient/osc/v2/share_servers.py index 31de153a..dab754f8 100644 --- a/manilaclient/osc/v2/share_servers.py +++ b/manilaclient/osc/v2/share_servers.py @@ -29,22 +29,22 @@ class DeleteShareServer(command.Command): """Delete one or more share servers (Admin only)""" - _description = _( - "Delete one or more share servers") + + _description = _("Delete one or more share servers") def get_parser(self, prog_name): - parser = super(DeleteShareServer, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "share_servers", metavar="", nargs="+", - help=_("ID(s) of the server(s) to delete") + help=_("ID(s) of the server(s) to delete"), ) parser.add_argument( "--wait", action='store_true', default=False, - help=_("Wait for share server deletion.") + help=_("Wait for share server deletion."), ) return parser @@ -55,21 +55,26 @@ def take_action(self, parsed_args): for server in parsed_args.share_servers: try: server_obj = osc_utils.find_resource( - share_client.share_servers, server) + share_client.share_servers, server + ) share_client.share_servers.delete(server_obj) if parsed_args.wait: if not osc_utils.wait_for_delete( - manager=share_client.share_servers, - res_id=server_obj.id): + manager=share_client.share_servers, + res_id=server_obj.id, + ): result += 1 except Exception as e: result += 1 - LOG.error(_( - "Failed to delete a share server with " - "ID '%(server)s': %(e)s"), - {'server': server, 'e': e}) + LOG.error( + _( + "Failed to delete a share server with " + "ID '%(server)s': %(e)s" + ), + {'server': server, 'e': e}, + ) if result > 0: total = len(parsed_args.share_servers) @@ -79,14 +84,15 @@ def take_action(self, parsed_args): class ShowShareServer(command.ShowOne): """Show share server (Admin only).""" + _description = _("Show details about a share server (Admin only).") def get_parser(self, prog_name): - parser = super(ShowShareServer, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "share_server", metavar="", - help=_("ID of share server.") + help=_("ID of share server."), ) return parser @@ -94,8 +100,8 @@ def take_action(self, parsed_args): share_client = self.app.client_manager.share share_server = osc_utils.find_resource( - share_client.share_servers, - parsed_args.share_server) + share_client.share_servers, parsed_args.share_server + ) # All 'backend_details' data already present as separated strings, # so remove big dict from view. @@ -108,10 +114,11 @@ def take_action(self, parsed_args): class ListShareServer(command.Lister): """List all share servers (Admin only).""" + _description = _("List all share servers (Admin only).") def get_parser(self, prog_name): - parser = super(ListShareServer, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( '--host', metavar='', @@ -122,7 +129,7 @@ def get_parser(self, prog_name): '--status', metavar="", default=None, - help=_('Filter results by status.') + help=_('Filter results by status.'), ) parser.add_argument( '--share-network', @@ -134,34 +141,40 @@ def get_parser(self, prog_name): '--project', metavar='', default=None, - help=_('Filter results by project name or ID.') + help=_('Filter results by project name or ID.'), ) parser.add_argument( '--share-network-subnet', metavar='', type=str, default=None, - help=_("Filter results by share network subnet that the " - "share server's network allocation exists within. " - "Available for microversion >= 2.51 (Optional, " - "Default=None)") + help=_( + "Filter results by share network subnet that the " + "share server's network allocation exists within. " + "Available for microversion >= 2.51 (Optional, " + "Default=None)" + ), ) parser.add_argument( '--source-share-server-id', metavar='', type=str, default=None, - help=_("Share server ID to be used as a filter. Available for " - "microversion >= 2.57 (Optional, Default=None)") + help=_( + "Share server ID to be used as a filter. Available for " + "microversion >= 2.57 (Optional, Default=None)" + ), ) parser.add_argument( '--identifier', metavar='', type=str, default=None, - help=_("Identifier of the share server in the share back end. " - "Available for microversion >= 2.49 " - "(Optional, Default=None)") + help=_( + "Identifier of the share server in the share back end. " + "Available for microversion >= 2.49 " + "(Optional, Default=None)" + ), ) identity_common.add_project_domain_option_to_parser(parser) return parser @@ -175,22 +188,29 @@ def take_action(self, parsed_args): project_id = identity_common.find_project( identity_client, parsed_args.project, - parsed_args.project_domain).id + parsed_args.project_domain, + ).id - if (parsed_args.identifier and - share_client.api_version < api_versions.APIVersion("2.49")): + if ( + parsed_args.identifier + and share_client.api_version < api_versions.APIVersion("2.49") + ): raise exceptions.CommandError( "Filtering by identifier is only allowed with manila API " "version >= 2.49." ) - if (parsed_args.share_network_subnet and - share_client.api_version < api_versions.APIVersion("2.51")): + if ( + parsed_args.share_network_subnet + and share_client.api_version < api_versions.APIVersion("2.51") + ): raise exceptions.CommandError( "Share network subnet can be specified only with manila API " "version >= 2.51" ) - if (parsed_args.source_share_server_id and - share_client.api_version < api_versions.APIVersion("2.57")): + if ( + parsed_args.source_share_server_id + and share_client.api_version < api_versions.APIVersion("2.57") + ): raise exceptions.CommandError( "Filtering by source_share_server_id is only allowed with " "manila API version >= 2.57." @@ -212,8 +232,8 @@ def take_action(self, parsed_args): if parsed_args.share_network: share_network_id = osc_utils.find_resource( - share_client.share_networks, - parsed_args.share_network).id + share_client.share_networks, parsed_args.share_network + ).id search_opts['share_network'] = share_network_id if parsed_args.source_share_server_id: @@ -222,19 +242,21 @@ def take_action(self, parsed_args): ) if parsed_args.identifier: - search_opts['identifier'] = ( - parsed_args.identifier - ) + search_opts['identifier'] = parsed_args.identifier if parsed_args.share_network_subnet: search_opts['share_network_subnet_id'] = ( - parsed_args.share_network_subnet) + parsed_args.share_network_subnet + ) share_servers = share_client.share_servers.list( - search_opts=search_opts) + search_opts=search_opts + ) - data = (osc_utils.get_dict_properties( - share_server._info, columns) for share_server in share_servers) + data = ( + osc_utils.get_dict_properties(share_server._info, columns) + for share_server in share_servers + ) return (columns, data) @@ -245,34 +267,39 @@ class AdoptShareServer(command.ShowOne): _description = _("Adopt share server not handled by Manila (Admin only).") def get_parser(self, prog_name): - parser = super(AdoptShareServer, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'host', metavar='', type=str, - help=_('Backend name as "@".') + help=_('Backend name as "@".'), ) parser.add_argument( "share_network", metavar="", - help=_("Share network where share server has network " - "allocations in.") + help=_( + "Share network where share server has network allocations in." + ), ) parser.add_argument( 'identifier', metavar='', type=str, - help=_("A driver-specific share server identifier required " - "by the driver to manage the share server.") + help=_( + "A driver-specific share server identifier required " + "by the driver to manage the share server." + ), ) parser.add_argument( '--driver-options', metavar='', action=parseractions.KeyValueAction, default={}, - help=_("One or more driver-specific key=value pairs that may be " - "necessary to manage the share server (Optional, " - "Default=None).") + help=_( + "One or more driver-specific key=value pairs that may be " + "necessary to manage the share server (Optional, " + "Default=None)." + ), ) parser.add_argument( '--share-network-subnet', @@ -280,14 +307,14 @@ def get_parser(self, prog_name): metavar='', default=None, help="Share network subnet where share server has network " - "allocations in.The default subnet will be used if " - "it's not specified. Available for microversion " - ">= 2.51 (Optional, Default=None)." + "allocations in.The default subnet will be used if " + "it's not specified. Available for microversion " + ">= 2.51 (Optional, Default=None).", ) parser.add_argument( "--wait", action='store_true', - help=_("Wait until share server is adopted") + help=_("Wait until share server is adopted"), ) return parser @@ -297,26 +324,29 @@ def take_action(self, parsed_args): share_network = None if parsed_args.share_network: share_network = osc_utils.find_resource( - share_client.share_networks, - parsed_args.share_network).id + share_client.share_networks, parsed_args.share_network + ).id share_network_subnet = None - if (parsed_args.share_network_subnet and - share_client.api_version < api_versions.APIVersion("2.51")): + if ( + parsed_args.share_network_subnet + and share_client.api_version < api_versions.APIVersion("2.51") + ): raise exceptions.CommandError( "Share network subnet can be specified only with manila API " "version >= 2.51" ) elif parsed_args.share_network_subnet: share_network_subnet = share_client.share_network_subnets.get( - share_network, parsed_args.share_network_subnet).id + share_network, parsed_args.share_network_subnet + ).id share_server = share_client.share_servers.manage( host=parsed_args.host, share_network_id=share_network, identifier=parsed_args.identifier, driver_options=parsed_args.driver_options, - share_network_subnet_id=share_network_subnet + share_network_subnet_id=share_network_subnet, ) if parsed_args.wait: @@ -324,12 +354,13 @@ def take_action(self, parsed_args): status_f=share_client.share_servers.get, res_id=share_server.id, success_status=['active'], - error_status=['manage_error', 'error'] + error_status=['manage_error', 'error'], ): LOG.error(_("ERROR: Share server is in error state.")) - share_server = osc_utils.find_resource(share_client.share_servers, - share_server.id) + share_server = osc_utils.find_resource( + share_client.share_servers, share_server.id + ) share_server._info.pop('links', None) @@ -346,25 +377,27 @@ class AbandonShareServer(command.Command): _description = _("Remove one or more share server(s) (Admin only).") def get_parser(self, prog_name): - parser = super(AbandonShareServer, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "share_server", metavar="", nargs='+', - help=_("ID of the server(s) to be abandoned.") + help=_("ID of the server(s) to be abandoned."), ) parser.add_argument( "--force", action='store_true', default=False, - help=_("Enforces the unmanage share server operation, even " - "if the backend driver does not support it.") + help=_( + "Enforces the unmanage share server operation, even " + "if the backend driver does not support it." + ), ) parser.add_argument( "--wait", action='store_true', default=False, - help=_("Wait until share server is abandoned") + help=_("Wait until share server is abandoned"), ) return parser @@ -375,26 +408,29 @@ def take_action(self, parsed_args): for server in parsed_args.share_server: try: server_obj = osc_utils.find_resource( - share_client.share_servers, - server) + share_client.share_servers, server + ) kwargs = {} if parsed_args.force: kwargs['force'] = parsed_args.force - share_client.share_servers.unmanage( - server_obj, **kwargs) + share_client.share_servers.unmanage(server_obj, **kwargs) if parsed_args.wait: if not osc_utils.wait_for_delete( - manager=share_client.share_servers, - res_id=server_obj.id): + manager=share_client.share_servers, + res_id=server_obj.id, + ): result += 1 except Exception as e: result += 1 - LOG.error(_( - "Failed to abandon share server with " - "ID '%(server)s': %(e)s"), - {'server': server, 'e': e}) + LOG.error( + _( + "Failed to abandon share server with " + "ID '%(server)s': %(e)s" + ), + {'server': server, 'e': e}, + ) if result > 0: total = len(parsed_args.share_server) @@ -408,27 +444,38 @@ class SetShareServer(command.Command): _description = _("Set share server properties (Admin only).") def get_parser(self, prog_name): - parser = super(SetShareServer, self).get_parser(prog_name) + parser = super().get_parser(prog_name) allowed_update_choices = [ - 'unmanage_starting', 'server_migrating_to', 'error', - 'unmanage_error', 'manage_error', 'inactive', 'active', - 'server_migrating', 'manage_starting', 'deleting', - 'network_change'] + 'unmanage_starting', + 'server_migrating_to', + 'error', + 'unmanage_error', + 'manage_error', + 'inactive', + 'active', + 'server_migrating', + 'manage_starting', + 'deleting', + 'network_change', + ] allowed_update_choices_str = ', '.join(allowed_update_choices) parser.add_argument( "share_server", metavar="", - help=_("ID of the share server to modify.") + help=_("ID of the share server to modify."), ) parser.add_argument( "--status", metavar="", required=False, default=constants.STATUS_ACTIVE, - help=_("Assign a status to the share server. Options " - "include: %s. If no state is " - "provided, active will be " - "used." % allowed_update_choices_str) + help=_( + "Assign a status to the share server. Options " + "include: %s. If no state is " + "provided, active will be " + "used." + ) + % allowed_update_choices_str, ) parser.add_argument( '--task-state', @@ -436,39 +483,42 @@ def get_parser(self, prog_name): required=False, default=None, nargs='?', - help=_("Indicate which task state to assign the share server. " - "Options include migration_starting, migration_in_progress," - " migration_completing, migration_success, migration_error," - " migration_cancelled, migration_driver_in_progress, " - "migration_driver_phase1_done, data_copying_starting, " - "data_copying_in_progress, data_copying_completing, " - "data_copying_completed, data_copying_cancelled, " - "data_copying_error. ") + help=_( + "Indicate which task state to assign the share server. " + "Options include migration_starting, migration_in_progress," + " migration_completing, migration_success, migration_error," + " migration_cancelled, migration_driver_in_progress, " + "migration_driver_phase1_done, data_copying_starting, " + "data_copying_in_progress, data_copying_completing, " + "data_copying_completed, data_copying_cancelled, " + "data_copying_error. " + ), ) return parser def take_action(self, parsed_args): if not parsed_args.status and not parsed_args.task_state: - msg = (_("A status or a task state should be provided for this " - "command.")) + msg = _( + "A status or a task state should be provided for this command." + ) LOG.error(msg) raise exceptions.CommandError(msg) share_client = self.app.client_manager.share share_server = osc_utils.find_resource( - share_client.share_servers, - parsed_args.share_server) + share_client.share_servers, parsed_args.share_server + ) if parsed_args.status: try: share_client.share_servers.reset_state( - share_server, - parsed_args.status + share_server, parsed_args.status ) except Exception as e: - msg = (_( - "Failed to set status '%(status)s': %(exception)s"), - {'status': parsed_args.status, 'exception': e}) + msg = ( + _("Failed to set status '%(status)s': %(exception)s"), + {'status': parsed_args.status, 'exception': e}, + ) LOG.error(msg) raise exceptions.CommandError(msg) @@ -476,7 +526,8 @@ def take_action(self, parsed_args): if share_client.api_version < api_versions.APIVersion("2.57"): raise exceptions.CommandError( "Setting the state of a share server is only available " - "with manila API version >= 2.57") + "with manila API version >= 2.57" + ) else: task_state = parsed_args.task_state if task_state and task_state.lower() == "none": @@ -484,15 +535,18 @@ def take_action(self, parsed_args): result = 0 try: share_client.share_servers.reset_task_state( - share_server, task_state) + share_server, task_state + ) except Exception as e: - LOG.error(_("Failed to update share server task state " - "%s"), e) + LOG.error( + _("Failed to update share server task state %s"), e + ) result += 1 if result > 0: - raise exceptions.CommandError(_("One or more of the " - "reset operations failed")) + raise exceptions.CommandError( + _("One or more of the reset operations failed") + ) class ShareServerMigrationCancel(command.Command): @@ -505,54 +559,54 @@ class ShareServerMigrationCancel(command.Command): _description = _("Cancels migration of a given share server when copying") def get_parser(self, prog_name): - parser = super(ShareServerMigrationCancel, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'share_server', metavar='', - help=_('ID of share server to cancel migration.') + help=_('ID of share server to cancel migration.'), ) return parser def take_action(self, parsed_args): share_client = self.app.client_manager.share share_server = osc_utils.find_resource( - share_client.share_servers, - parsed_args.share_server) + share_client.share_servers, parsed_args.share_server + ) if share_client.api_version >= api_versions.APIVersion("2.57"): share_server.migration_cancel() else: raise exceptions.CommandError( "Share Server Migration cancel is only available " - "with manila API version >= 2.57") + "with manila API version >= 2.57" + ) class ShareServerMigrationComplete(command.Command): - """Completes migration for a given share server (Admin only, Experimental). + """Completes migration for a given share server (Admin only, Experimental).""" - """ _description = _("Completes migration for a given share server") def get_parser(self, prog_name): - parser = super(ShareServerMigrationComplete, self).get_parser( - prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'share_server', metavar='', - help=_('ID of share server to complete migration.') + help=_('ID of share server to complete migration.'), ) return parser def take_action(self, parsed_args): share_client = self.app.client_manager.share share_server = osc_utils.find_resource( - share_client.share_servers, - parsed_args.share_server) + share_client.share_servers, parsed_args.share_server + ) if share_client.api_version >= api_versions.APIVersion("2.57"): share_server.migration_complete() else: raise exceptions.CommandError( "Share Server Migration complete is only available " - "with manila API version >= 2.57") + "with manila API version >= 2.57" + ) class ShareServerMigrationShow(command.ShowOne): @@ -565,14 +619,15 @@ class ShareServerMigrationShow(command.ShowOne): """ _description = _( - "Gets migration progress of a given share server when copying") + "Gets migration progress of a given share server when copying" + ) def get_parser(self, prog_name): - parser = super(ShareServerMigrationShow, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'share_server', metavar='', - help='ID of share server to show migration progress for.' + help='ID of share server to show migration progress for.', ) return parser @@ -580,14 +635,15 @@ def take_action(self, parsed_args): share_client = self.app.client_manager.share if share_client.api_version >= api_versions.APIVersion("2.57"): share_server = osc_utils.find_resource( - share_client.share_servers, - parsed_args.share_server) + share_client.share_servers, parsed_args.share_server + ) result = share_server.migration_get_progress() return self.dict2columns(result) else: raise exceptions.CommandError( "Share Server Migration show is only available " - "with manila API version >= 2.57") + "with manila API version >= 2.57" + ) class ShareServerMigrationStart(command.ShowOne): @@ -596,76 +652,86 @@ class ShareServerMigrationStart(command.ShowOne): _description = _("Migrates share server to a new host.") def get_parser(self, prog_name): - parser = super(ShareServerMigrationStart, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'share_server', metavar='', - help=_('ID of share server to start migration.') + help=_('ID of share server to start migration.'), ) parser.add_argument( 'host', metavar='', - help=_("Destination to migrate the share server to. Use " - "the format '@'.") + help=_( + "Destination to migrate the share server to. Use " + "the format '@'." + ), ) parser.add_argument( '--preserve-snapshots', metavar='', choices=['True', 'False'], required=True, - help=_("Set to True if snapshots must be preserved at " - "the migration destination.") + help=_( + "Set to True if snapshots must be preserved at " + "the migration destination." + ), ) parser.add_argument( '--writable', metavar='', choices=['True', 'False'], required=True, - help=_("Enforces migration to keep all its shares writable " - "while contents are being moved.") + help=_( + "Enforces migration to keep all its shares writable " + "while contents are being moved." + ), ) parser.add_argument( '--nondisruptive', metavar='', choices=['True', 'False'], required=True, - help=_("Enforces migration to be nondisruptive.") + help=_("Enforces migration to be nondisruptive."), ) parser.add_argument( '--new-share-network', metavar='', required=False, default=None, - help=_('Specify a new share network for the share server. Do not ' - 'specify this parameter if the migrating share server has ' - 'to be retained within its current share network.',) + help=_( + 'Specify a new share network for the share server. Do not ' + 'specify this parameter if the migrating share server has ' + 'to be retained within its current share network.' + ), ) parser.add_argument( '--check-only', action='store_true', default=False, - help=_("Run a dry-run of the share server migration. ") + help=_("Run a dry-run of the share server migration. "), ) return parser def take_action(self, parsed_args): share_client = self.app.client_manager.share share_server = osc_utils.find_resource( - share_client.share_servers, - parsed_args.share_server) + share_client.share_servers, parsed_args.share_server + ) if share_client.api_version >= api_versions.APIVersion("2.57"): new_share_net_id = None result = None if parsed_args.new_share_network: new_share_net_id = apiutils.find_resource( - share_client.share_networks, - parsed_args.new_share_network).id + share_client.share_networks, parsed_args.new_share_network + ).id if parsed_args.check_only: result = share_server.migration_check( - parsed_args.host, parsed_args.writable, - parsed_args.nondisruptive, parsed_args.preserve_snapshots, - new_share_net_id + parsed_args.host, + parsed_args.writable, + parsed_args.nondisruptive, + parsed_args.preserve_snapshots, + new_share_net_id, ) if result: if parsed_args.formatter == 'table': @@ -678,13 +744,16 @@ def take_action(self, parsed_args): result[k] = dict_values return self.dict2columns(result) else: - share_server.migration_start(parsed_args.host, - parsed_args.writable, - parsed_args.nondisruptive, - parsed_args.preserve_snapshots, - new_share_net_id) + share_server.migration_start( + parsed_args.host, + parsed_args.writable, + parsed_args.nondisruptive, + parsed_args.preserve_snapshots, + new_share_net_id, + ) return ({}, {}) else: raise exceptions.CommandError( "Share Server Migration is only available " - "with manila API version >= 2.57") + "with manila API version >= 2.57" + ) diff --git a/manilaclient/osc/v2/share_snapshot_instance_export_locations.py b/manilaclient/osc/v2/share_snapshot_instance_export_locations.py index 449987d8..01395b5b 100644 --- a/manilaclient/osc/v2/share_snapshot_instance_export_locations.py +++ b/manilaclient/osc/v2/share_snapshot_instance_export_locations.py @@ -19,16 +19,15 @@ class ShareSnapshotInstanceExportLocationList(command.Lister): """List export locations from a share snapshot instance.""" + _description = _("List export locations from a share snapshot instance.") def get_parser(self, prog_name): - parser = ( - super(ShareSnapshotInstanceExportLocationList, self).get_parser( - prog_name)) + parser = super().get_parser(prog_name) parser.add_argument( "instance", metavar="", - help=_("Name or ID of the share instance.") + help=_("Name or ID of the share instance."), ) return parser @@ -37,37 +36,42 @@ def take_action(self, parsed_args): share_client = self.app.client_manager.share snapshot_instance = apiutils.find_resource( - share_client.share_snapshot_instances, parsed_args.instance) + share_client.share_snapshot_instances, parsed_args.instance + ) share_snapshot_instance_export_locations = ( share_client.share_snapshot_instance_export_locations.list( - snapshot_instance=snapshot_instance)) + snapshot_instance=snapshot_instance + ) + ) columns = ["ID", "Path", "Is Admin only"] return ( columns, - (utils.get_item_properties(s, columns) for s in - share_snapshot_instance_export_locations)) + ( + utils.get_item_properties(s, columns) + for s in share_snapshot_instance_export_locations + ), + ) class ShareSnapshotInstanceExportLocationShow(command.ShowOne): """Show export location of the share snapshot instance.""" + _description = _("Show export location of the share snapshot instance.") def get_parser(self, prog_name): - parser = ( - super(ShareSnapshotInstanceExportLocationShow, self).get_parser( - prog_name)) + parser = super().get_parser(prog_name) parser.add_argument( 'snapshot_instance', metavar='', - help=_('ID of the share snapshot instance.') + help=_('ID of the share snapshot instance.'), ) parser.add_argument( 'export_location', metavar='', - help=_('ID of the share snapshot instance export location.') + help=_('ID of the share snapshot instance export location.'), ) return parser @@ -77,12 +81,15 @@ def take_action(self, parsed_args): snapshot_instance = apiutils.find_resource( share_client.share_snapshot_instances, - parsed_args.snapshot_instance) + parsed_args.snapshot_instance, + ) share_snapshot_instance_export_location = ( share_client.share_snapshot_instance_export_locations.get( parsed_args.export_location, - snapshot_instance=snapshot_instance)) + snapshot_instance=snapshot_instance, + ) + ) share_snapshot_instance_export_location._info.pop('links', None) diff --git a/manilaclient/osc/v2/share_snapshot_instances.py b/manilaclient/osc/v2/share_snapshot_instances.py index 2e44f9dd..a6ad8b60 100644 --- a/manilaclient/osc/v2/share_snapshot_instances.py +++ b/manilaclient/osc/v2/share_snapshot_instances.py @@ -20,29 +20,32 @@ class ListShareSnapshotInstance(command.Lister): """List all share snapshot instances.""" + _description = _("List all share snapshot instances") def get_parser(self, prog_name): - parser = super(ListShareSnapshotInstance, self).get_parser( - prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "--snapshot", metavar="", default=None, - help=_("Filter results by share snapshot ID.") + help=_("Filter results by share snapshot ID."), ) parser.add_argument( "--detailed", action="store_true", - help=_("Show detailed information about snapshot instances. ") + help=_("Show detailed information about snapshot instances. "), ) return parser def take_action(self, parsed_args): share_client = self.app.client_manager.share - snapshot = (share_client.share_snapshots.get(parsed_args.snapshot) - if parsed_args.snapshot else None) + snapshot = ( + share_client.share_snapshots.get(parsed_args.snapshot) + if parsed_args.snapshot + else None + ) share_snapshot_instances = share_client.share_snapshot_instances.list( detailed=parsed_args.detailed, @@ -51,26 +54,36 @@ def take_action(self, parsed_args): list_of_keys = ['ID', 'Snapshot ID', 'Status'] - if (parsed_args.detailed): - list_of_keys += ['Created At', 'Updated At', 'Share ID', - 'Share Instance ID', 'Progress', - 'Provider Location'] - - return (list_of_keys, (utils.get_item_properties - (s, list_of_keys) for s in share_snapshot_instances)) + if parsed_args.detailed: + list_of_keys += [ + 'Created At', + 'Updated At', + 'Share ID', + 'Share Instance ID', + 'Progress', + 'Provider Location', + ] + + return ( + list_of_keys, + ( + utils.get_item_properties(s, list_of_keys) + for s in share_snapshot_instances + ), + ) class ShowShareSnapshotInstance(command.ShowOne): """Show details about a share snapshot instance.""" + _description = _("Show details about a share snapshot instance.") def get_parser(self, prog_name): - parser = super(ShowShareSnapshotInstance, self).get_parser( - prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "snapshot_instance", metavar="", - help=_("ID of the share snapshot instance.") + help=_("ID of the share snapshot instance."), ) return parser @@ -78,22 +91,28 @@ def get_parser(self, prog_name): def take_action(self, parsed_args): share_client = self.app.client_manager.share snapshot_instance = share_client.share_snapshot_instances.get( - parsed_args.snapshot_instance) + parsed_args.snapshot_instance + ) snapshot_instance_export_locations = ( share_client.share_snapshot_instance_export_locations.list( - snapshot_instance=snapshot_instance)) + snapshot_instance=snapshot_instance + ) + ) snapshot_instance._info['export_locations'] = [] for element_location in snapshot_instance_export_locations: element_location._info.pop('links', None) snapshot_instance._info['export_locations'].append( - element_location._info) + element_location._info + ) if parsed_args.formatter == 'table': snapshot_instance._info['export_locations'] = ( cliutils.convert_dict_list_to_string( - snapshot_instance._info['export_locations'])) + snapshot_instance._info['export_locations'] + ) + ) snapshot_instance._info.pop('links', None) @@ -102,25 +121,33 @@ def take_action(self, parsed_args): class SetShareSnapshotInstance(command.Command): """Explicitly update the state of a share snapshot instance.""" - _description = _("Explicitly update the state of a share snapshot " - "instance.") + + _description = _( + "Explicitly update the state of a share snapshot instance." + ) def get_parser(self, prog_name): - parser = super(SetShareSnapshotInstance, self).get_parser( - prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "snapshot_instance", metavar="", - help=_("ID of the share snapshot instance to update.") + help=_("ID of the share snapshot instance to update."), ) parser.add_argument( '--status', metavar='', default='available', - choices=['available', 'error', 'creating', 'deleting', - 'error_deleting'], - help=_('Indicate state to update the snapshot instance to. ' - 'Default is available.') + choices=[ + 'available', + 'error', + 'creating', + 'deleting', + 'error_deleting', + ], + help=_( + 'Indicate state to update the snapshot instance to. ' + 'Default is available.' + ), ) return parser @@ -130,8 +157,8 @@ def take_action(self, parsed_args): try: share_client.share_snapshot_instances.reset_state( - parsed_args.snapshot_instance, parsed_args.status) + parsed_args.snapshot_instance, parsed_args.status + ) except Exception as e: - msg = _( - "Failed to update share snapshot instance status: %s" % e) + msg = _(f"Failed to update share snapshot instance status: {e}") raise exceptions.CommandError(msg) diff --git a/manilaclient/osc/v2/share_snapshots.py b/manilaclient/osc/v2/share_snapshots.py index bb4afa11..4f52164c 100644 --- a/manilaclient/osc/v2/share_snapshots.py +++ b/manilaclient/osc/v2/share_snapshots.py @@ -28,83 +28,87 @@ class CreateShareSnapshot(command.ShowOne): """Create a share snapshot.""" - _description = _( - "Create a snapshot of the given share") + + _description = _("Create a snapshot of the given share") def get_parser(self, prog_name): - parser = super(CreateShareSnapshot, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "share", metavar="", - help=_("Name or ID of the share to create snapshot of") + help=_("Name or ID of the share to create snapshot of"), ) parser.add_argument( "--force", action='store_true', default=False, - help=_("Optional flag to indicate whether to snapshot " - "a share even if it's busy. (Default=False)") + help=_( + "Optional flag to indicate whether to snapshot " + "a share even if it's busy. (Default=False)" + ), ) parser.add_argument( "--name", metavar="", default=None, - help=_("Add a name to the snapshot (Optional).") + help=_("Add a name to the snapshot (Optional)."), ) parser.add_argument( "--description", metavar="", default=None, - help=_("Add a description to the snapshot (Optional).") + help=_("Add a description to the snapshot (Optional)."), ) parser.add_argument( '--wait', action='store_true', default=False, - help=_('Wait for share snapshot creation') + help=_('Wait for share snapshot creation'), ) parser.add_argument( "--property", metavar="", default={}, action=parseractions.KeyValueAction, - help=_("Set a property to this snapshot " - "(repeat option to set multiple properties)." - "Available only for microversion >= 2.73"), + help=_( + "Set a property to this snapshot " + "(repeat option to set multiple properties)." + "Available only for microversion >= 2.73" + ), ) return parser def take_action(self, parsed_args): share_client = self.app.client_manager.share - share = utils.find_resource(share_client.shares, - parsed_args.share) + share = utils.find_resource(share_client.shares, parsed_args.share) if share_client.api_version >= api_versions.APIVersion("2.73"): property = parsed_args.property or {} elif parsed_args.property: raise exceptions.CommandError( "Setting metadtaa is only available with manila API version " - ">= 2.73") + ">= 2.73" + ) share_snapshot = share_client.share_snapshots.create( share=share, force=parsed_args.force, name=parsed_args.name or None, description=parsed_args.description or None, - metadata=property + metadata=property, ) if parsed_args.wait: if not utils.wait_for_status( status_f=share_client.share_snapshots.get, res_id=share_snapshot.id, - success_status=['available'] + success_status=['available'], ): LOG.error(_("ERROR: Share snapshot is in error state.")) share_snapshot = utils.find_resource( - share_client.share_snapshots, - share_snapshot.id) + share_client.share_snapshots, share_snapshot.id + ) share_snapshot._info.pop('links', None) return self.dict2columns(share_snapshot._info) @@ -112,28 +116,28 @@ def take_action(self, parsed_args): class DeleteShareSnapshot(command.Command): """Delete one or more share snapshots""" - _description = _( - "Delete one or more share snapshots") + + _description = _("Delete one or more share snapshots") def get_parser(self, prog_name): - parser = super(DeleteShareSnapshot, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "snapshot", metavar="", nargs="+", - help=_("Name or ID of the snapshot(s) to delete") + help=_("Name or ID of the snapshot(s) to delete"), ) parser.add_argument( "--force", action='store_true', default=False, - help=_("Delete the snapshot(s) ignoring the current state.") + help=_("Delete the snapshot(s) ignoring the current state."), ) parser.add_argument( "--wait", action='store_true', default=False, - help=_("Wait for share snapshot deletion") + help=_("Wait for share snapshot deletion"), ) return parser @@ -144,44 +148,48 @@ def take_action(self, parsed_args): for snapshot in parsed_args.snapshot: try: snapshot_obj = utils.find_resource( - share_client.share_snapshots, - snapshot) + share_client.share_snapshots, snapshot + ) if parsed_args.force: - share_client.share_snapshots.force_delete( - snapshot_obj) + share_client.share_snapshots.force_delete(snapshot_obj) else: - share_client.share_snapshots.delete( - snapshot_obj) + share_client.share_snapshots.delete(snapshot_obj) if parsed_args.wait: if not utils.wait_for_delete( - manager=share_client.share_snapshots, - res_id=snapshot_obj.id): + manager=share_client.share_snapshots, + res_id=snapshot_obj.id, + ): result += 1 except Exception as e: result += 1 - LOG.error(_( - "Failed to delete snapshot with " - "name or ID '%(snapshot)s': %(e)s"), - {'snapshot': snapshot, 'e': e}) + LOG.error( + _( + "Failed to delete snapshot with " + "name or ID '%(snapshot)s': %(e)s" + ), + {'snapshot': snapshot, 'e': e}, + ) if result > 0: total = len(parsed_args.snapshot) - msg = (_("%(result)s of %(total)s snapshots failed " - "to delete.") % {'result': result, 'total': total}) + msg = _("%(result)s of %(total)s snapshots failed to delete.") % { + 'result': result, + 'total': total, + } raise exceptions.CommandError(msg) class ShowShareSnapshot(command.ShowOne): """Display a share snapshot""" - _description = _( - "Show details about a share snapshot") + + _description = _("Show details about a share snapshot") def get_parser(self, prog_name): - parser = super(ShowShareSnapshot, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "snapshot", metavar="", - help=_("Name or ID of the snapshot to display") + help=_("Name or ID of the snapshot to display"), ) return parser @@ -189,12 +197,12 @@ def take_action(self, parsed_args): share_client = self.app.client_manager.share share_snapshot = utils.find_resource( - share_client.share_snapshots, - parsed_args.snapshot) + share_client.share_snapshots, parsed_args.snapshot + ) - export_locations = ( - share_client.share_snapshot_export_locations.list( - share_snapshot)) + export_locations = share_client.share_snapshot_export_locations.list( + share_snapshot + ) locations = [] for location in export_locations: @@ -202,8 +210,7 @@ def take_action(self, parsed_args): locations.append(location._info) if parsed_args.formatter == 'table': - locations = cliutils.convert_dict_list_to_string( - locations) + locations = cliutils.convert_dict_list_to_string(locations) data = share_snapshot._info data['export_locations'] = locations @@ -211,8 +218,9 @@ def take_action(self, parsed_args): # 'metadata' --> 'properties' data.update( { - 'properties': - format_columns.DictColumn(data.pop('metadata', {})), + 'properties': format_columns.DictColumn( + data.pop('metadata', {}) + ), }, ) data.pop('links', None) @@ -222,46 +230,58 @@ def take_action(self, parsed_args): class SetShareSnapshot(command.Command): """Set share snapshot properties.""" + _description = _("Set share snapshot properties") def get_parser(self, prog_name): - parser = super(SetShareSnapshot, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "snapshot", metavar="", - help=_('Name or ID of the snapshot to set a property for') + help=_('Name or ID of the snapshot to set a property for'), ) parser.add_argument( "--name", metavar="", default=None, - help=_("Set a name to the snapshot.") + help=_("Set a name to the snapshot."), ) parser.add_argument( "--description", metavar="", default=None, - help=_("Set a description to the snapshot.") + help=_("Set a description to the snapshot."), ) parser.add_argument( "--status", metavar="", - choices=['available', 'error', 'creating', 'deleting', - 'manage_starting', 'manage_error', - 'unmanage_starting', 'unmanage_error', - 'error_deleting'], - help=_("Assign a status to the snapshot (Admin only). " - "Options include : available, error, creating, " - "deleting, manage_starting, manage_error, " - "unmanage_starting, unmanage_error, error_deleting.") + choices=[ + 'available', + 'error', + 'creating', + 'deleting', + 'manage_starting', + 'manage_error', + 'unmanage_starting', + 'unmanage_error', + 'error_deleting', + ], + help=_( + "Assign a status to the snapshot (Admin only). " + "Options include : available, error, creating, " + "deleting, manage_starting, manage_error, " + "unmanage_starting, unmanage_error, error_deleting." + ), ) parser.add_argument( "--property", metavar="", default={}, action=parseractions.KeyValueAction, - help=_("Set a property to this snapshot " - "(repeat option to set multiple properties)"), + help=_( + "Set a property to this snapshot " + "(repeat option to set multiple properties)" + ), ) return parser @@ -270,8 +290,8 @@ def take_action(self, parsed_args): result = 0 share_snapshot = utils.find_resource( - share_client.share_snapshots, - parsed_args.snapshot) + share_client.share_snapshots, parsed_args.snapshot + ) kwargs = {} @@ -281,54 +301,60 @@ def take_action(self, parsed_args): kwargs['display_description'] = parsed_args.description try: - share_client.share_snapshots.update( - share_snapshot, - **kwargs - ) + share_client.share_snapshots.update(share_snapshot, **kwargs) except Exception as e: result += 1 - LOG.error(_( - "Failed to set share snapshot properties " - "'%(properties)s': %(exception)s"), - {'properties': kwargs, - 'exception': e}) + LOG.error( + _( + "Failed to set share snapshot properties " + "'%(properties)s': %(exception)s" + ), + {'properties': kwargs, 'exception': e}, + ) if parsed_args.status: try: share_client.share_snapshots.reset_state( - share_snapshot, - parsed_args.status + share_snapshot, parsed_args.status ) except Exception as e: result += 1 - LOG.error(_( - "Failed to update snapshot status to " - "'%(status)s': %(e)s"), - {'status': parsed_args.status, 'e': e}) + LOG.error( + _( + "Failed to update snapshot status to " + "'%(status)s': %(e)s" + ), + {'status': parsed_args.status, 'e': e}, + ) if parsed_args.property: try: share_snapshot.set_metadata(parsed_args.property) except Exception as e: - LOG.error(_("Failed to set share snapshot properties " - "'%(properties)s': %(exception)s"), - {'properties': parsed_args.property, - 'exception': e}) + LOG.error( + _( + "Failed to set share snapshot properties " + "'%(properties)s': %(exception)s" + ), + {'properties': parsed_args.property, 'exception': e}, + ) result += 1 if result > 0: - raise exceptions.CommandError(_("One or more of the " - "set operations failed")) + raise exceptions.CommandError( + _("One or more of the set operations failed") + ) class UnsetShareSnapshot(command.Command): """Unset a share snapshot property.""" + _description = _("Unset a share snapshot property") def get_parser(self, prog_name): - parser = super(UnsetShareSnapshot, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "snapshot", metavar="", - help=_("Name or ID of the snapshot to set a property for") + help=_("Name or ID of the snapshot to set a property for"), ) parser.add_argument( "--name", @@ -344,8 +370,10 @@ def get_parser(self, prog_name): '--property', metavar='', action='append', - help=_('Remove a property from snapshot ' - '(repeat option to remove multiple properties)'), + help=_( + 'Remove a property from snapshot ' + '(repeat option to remove multiple properties)' + ), ) return parser @@ -353,8 +381,8 @@ def take_action(self, parsed_args): share_client = self.app.client_manager.share share_snapshot = utils.find_resource( - share_client.share_snapshots, - parsed_args.snapshot) + share_client.share_snapshots, parsed_args.snapshot + ) kwargs = {} if parsed_args.name: @@ -363,68 +391,74 @@ def take_action(self, parsed_args): kwargs['display_description'] = None if kwargs: try: - share_client.share_snapshots.update( - share_snapshot, - **kwargs - ) + share_client.share_snapshots.update(share_snapshot, **kwargs) except Exception as e: - raise exceptions.CommandError(_( - "Failed to unset snapshot display name " - "or display description : %s" % e)) + raise exceptions.CommandError( + _( + "Failed to unset snapshot display name " + f"or display description : {e}" + ) + ) if parsed_args.property: for key in parsed_args.property: try: share_snapshot.delete_metadata([key]) except Exception as e: - raise exceptions.CommandError(_( - "Failed to unset snapshot property " - "'%(key)s': %(e)s"), - {'key': key, 'e': e}) + raise exceptions.CommandError( + _( + "Failed to unset snapshot property " + "'%(key)s': %(e)s" + ), + {'key': key, 'e': e}, + ) class ListShareSnapshot(command.Lister): """List snapshots.""" + _description = _("List snapshots") def get_parser(self, prog_name): - parser = super(ListShareSnapshot, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "--all-projects", action='store_true', default=False, - help=_("Display snapshots from all projects (Admin only).") + help=_("Display snapshots from all projects (Admin only)."), ) parser.add_argument( "--name", metavar="", default=None, - help=_("Filter results by name.") + help=_("Filter results by name."), ) parser.add_argument( '--description', metavar="", default=None, - help=_("Filter results by description. Available only for " - "microversion >= 2.36.") + help=_( + "Filter results by description. Available only for " + "microversion >= 2.36." + ), ) parser.add_argument( '--status', metavar="", default=None, - help=_('Filter results by status') + help=_('Filter results by status'), ) parser.add_argument( '--share', metavar='', default=None, - help=_('Name or ID of a share to filter results by.') + help=_('Name or ID of a share to filter results by.'), ) parser.add_argument( '--usage', metavar='', default=None, choices=['used', 'unused'], - help=_("Option to filter snapshots by usage.") + help=_("Option to filter snapshots by usage."), ) parser.add_argument( "--limit", @@ -432,57 +466,67 @@ def get_parser(self, prog_name): type=int, default=None, action=parseractions.NonNegativeAction, - help=_("Limit the number of snapshots returned") + help=_("Limit the number of snapshots returned"), ) parser.add_argument( "--marker", metavar="", - help=_("The last share ID of the previous page") + help=_("The last share ID of the previous page"), ) parser.add_argument( '--sort', metavar="[:]", default='name:asc', - help=_("Sort output by selected keys and directions(asc or desc) " - "(default: name:asc), multiple keys and directions can be " - "specified separated by comma") + help=_( + "Sort output by selected keys and directions(asc or desc) " + "(default: name:asc), multiple keys and directions can be " + "specified separated by comma" + ), ) parser.add_argument( "--name~", metavar="", default=None, - help=_("Filter results matching a share snapshot name pattern. " - "Available only for microversion >= 2.36.") + help=_( + "Filter results matching a share snapshot name pattern. " + "Available only for microversion >= 2.36." + ), ) parser.add_argument( '--description~', metavar="", default=None, - help=_("Filter results matching a share snapshot description " - "pattern. Available only for microversion >= 2.36.") + help=_( + "Filter results matching a share snapshot description " + "pattern. Available only for microversion >= 2.36." + ), ) parser.add_argument( '--detail', action='store_true', default=False, - help=_("List share snapshots with details") + help=_("List share snapshots with details"), ) parser.add_argument( '--property', metavar='', action=parseractions.KeyValueAction, - help=_('Filter snapshots having a given metadata key=value ' - 'property. (repeat option to filter by multiple ' - 'properties)'), + help=_( + 'Filter snapshots having a given metadata key=value ' + 'property. (repeat option to filter by multiple ' + 'properties)' + ), ) parser.add_argument( '--count', action='store_true', default=False, - help=_("The total count of share snapshots before pagination is " - "applied. This parameter is useful when applying " - "pagination parameters '--limit' and '--offset'. Available " - "only for microversion >= 2.79.") + help=_( + "The total count of share snapshots before pagination is " + "applied. This parameter is useful when applying " + "pagination parameters '--limit' and '--offset'. Available " + "only for microversion >= 2.79." + ), ) return parser @@ -492,8 +536,9 @@ def take_action(self, parsed_args): share_id = None if parsed_args.share: - share_id = utils.find_resource(share_client.shares, - parsed_args.share).id + share_id = utils.find_resource( + share_client.shares, parsed_args.share + ).id columns = ['ID', 'Name'] search_opts = { @@ -505,39 +550,48 @@ def take_action(self, parsed_args): 'share_id': share_id, 'usage': parsed_args.usage, 'metadata': oscutils.extract_key_value_options( - parsed_args.property), + parsed_args.property + ), } if share_client.api_version >= api_versions.APIVersion("2.36"): search_opts['name~'] = getattr(parsed_args, 'name~') search_opts['description~'] = getattr(parsed_args, 'description~') search_opts['description'] = parsed_args.description - elif (parsed_args.description or getattr(parsed_args, 'name~') or - getattr(parsed_args, 'description~')): + elif ( + parsed_args.description + or getattr(parsed_args, 'name~') + or getattr(parsed_args, 'description~') + ): raise exceptions.CommandError( "Pattern based filtering (name~, description~ and description)" - " is only available with manila API version >= 2.36") + " is only available with manila API version >= 2.36" + ) if parsed_args.count: if share_client.api_version < api_versions.APIVersion("2.79"): raise exceptions.CommandError( "Displaying total number of share snapshots is only " - "available with manila API version >= 2.79") + "available with manila API version >= 2.79" + ) if parsed_args.formatter != 'table': raise exceptions.CommandError( - "Count can only be printed when using '--format table'") + "Count can only be printed when using '--format table'" + ) if parsed_args.detail: - columns.extend([ - 'Status', - 'Description', - 'Created At', - 'Size', - 'Share ID', - 'Share Proto', - 'Share Size', - 'User ID' - ]) + columns.extend( + [ + 'Status', + 'Description', + 'Created At', + 'Size', + 'Share ID', + 'Share Proto', + 'Share Size', + 'User ID', + ] + ) if parsed_args.all_projects: columns.append('Project ID') @@ -546,17 +600,21 @@ def take_action(self, parsed_args): if parsed_args.count: search_opts['with_count'] = True snapshots, total_count = share_client.share_snapshots.list( - search_opts=search_opts) + search_opts=search_opts + ) else: snapshots = share_client.share_snapshots.list( - search_opts=search_opts) + search_opts=search_opts + ) snapshots = utils.sort_items(snapshots, parsed_args.sort, str) if parsed_args.count: - print("Total number of snapshots: %s" % total_count) - return (columns, - (utils.get_item_properties(s, columns) for s in snapshots)) + print(f"Total number of snapshots: {total_count}") + return ( + columns, + (utils.get_item_properties(s, columns) for s in snapshots), + ) class AdoptShareSnapshot(command.ShowOne): @@ -565,29 +623,30 @@ class AdoptShareSnapshot(command.ShowOne): _description = _("Adopt a share snapshot") def get_parser(self, prog_name): - parser = super(AdoptShareSnapshot, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "share", metavar="", - help=_("Name or ID of the share that owns the snapshot " - "to be adopted.") + help=_( + "Name or ID of the share that owns the snapshot to be adopted." + ), ) parser.add_argument( "provider_location", metavar="", - help=_("Provider location of the snapshot on the backend.") + help=_("Provider location of the snapshot on the backend."), ) parser.add_argument( "--name", metavar="", default=None, - help=_("Optional snapshot name (Default=None).") + help=_("Optional snapshot name (Default=None)."), ) parser.add_argument( "--description", metavar="", default=None, - help=_("Optional snapshot description (Default=None).") + help=_("Optional snapshot description (Default=None)."), ) parser.add_argument( "--driver-option", @@ -596,27 +655,27 @@ def get_parser(self, prog_name): action=parseractions.KeyValueAction, help=_( "Set driver options as key=value pairs." - "(repeat option to set multiple key=value pairs)") + "(repeat option to set multiple key=value pairs)" + ), ) parser.add_argument( "--wait", action='store_true', - help=_("Wait until share snapshot is adopted") + help=_("Wait until share snapshot is adopted"), ) return parser def take_action(self, parsed_args): share_client = self.app.client_manager.share - share = utils.find_resource(share_client.shares, - parsed_args.share) + share = utils.find_resource(share_client.shares, parsed_args.share) snapshot = share_client.share_snapshots.manage( share=share, provider_location=parsed_args.provider_location, driver_options=parsed_args.driver_option, name=parsed_args.name, - description=parsed_args.description + description=parsed_args.description, ) if parsed_args.wait: @@ -624,12 +683,13 @@ def take_action(self, parsed_args): status_f=share_client.share_snapshots.get, res_id=snapshot.id, success_status=['available'], - error_status=['manage_error', 'error'] + error_status=['manage_error', 'error'], ): LOG.error(_("ERROR: Share snapshot is in error state.")) - snapshot = utils.find_resource(share_client.share_snapshots, - snapshot.id) + snapshot = utils.find_resource( + share_client.share_snapshots, snapshot.id + ) snapshot._info.pop('links', None) @@ -642,17 +702,17 @@ class AbandonShareSnapshot(command.Command): _description = _("Abandon share snapshot(s)") def get_parser(self, prog_name): - parser = super(AbandonShareSnapshot, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "snapshot", metavar="", nargs='+', - help=_("Name or ID of the snapshot(s) to be abandoned.") + help=_("Name or ID of the snapshot(s) to be abandoned."), ) parser.add_argument( "--wait", action='store_true', - help=_("Wait until share snapshot is abandoned") + help=_("Wait until share snapshot is abandoned"), ) return parser @@ -662,26 +722,32 @@ def take_action(self, parsed_args): for snapshot in parsed_args.snapshot: snapshot_obj = utils.find_resource( - share_client.share_snapshots, - snapshot) + share_client.share_snapshots, snapshot + ) try: share_client.share_snapshots.unmanage(snapshot_obj) if parsed_args.wait: if not utils.wait_for_delete( - manager=share_client.share_snapshots, - res_id=snapshot_obj.id): + manager=share_client.share_snapshots, + res_id=snapshot_obj.id, + ): result += 1 except Exception as e: result += 1 - LOG.error(_( - "Failed to abandon share snapshot with " - "name or ID '%(snapshot)s': %(e)s"), - {'snapshot': snapshot, 'e': e}) + LOG.error( + _( + "Failed to abandon share snapshot with " + "name or ID '%(snapshot)s': %(e)s" + ), + {'snapshot': snapshot, 'e': e}, + ) if result > 0: total = len(parsed_args.snapshot) - msg = (_("%(result)s of %(total)s snapshots failed " - "to abandon.") % {'result': result, 'total': total}) + msg = _("%(result)s of %(total)s snapshots failed to abandon.") % { + 'result': result, + 'total': total, + } raise exceptions.CommandError(msg) @@ -691,22 +757,24 @@ class ShareSnapshotAccessAllow(command.ShowOne): _description = _("Allow access to a snapshot") def get_parser(self, prog_name): - parser = super(ShareSnapshotAccessAllow, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "snapshot", metavar="", - help=_("Name or ID of the snapshot") + help=_("Name or ID of the snapshot"), ) parser.add_argument( 'access_type', metavar="", - help=_('Access rule type (only "ip", "user" (user or group), ' - '"cert" or "cephx" are supported).') + help=_( + 'Access rule type (only "ip", "user" (user or group), ' + '"cert" or "cephx" are supported).' + ), ) parser.add_argument( 'access_to', metavar="", - help=_('Value that defines access.') + help=_('Value that defines access.'), ) return parser @@ -714,41 +782,41 @@ def take_action(self, parsed_args): share_client = self.app.client_manager.share snapshot_obj = utils.find_resource( - share_client.share_snapshots, - parsed_args.snapshot) + share_client.share_snapshots, parsed_args.snapshot + ) try: snapshot_access = share_client.share_snapshots.allow( snapshot=snapshot_obj, access_type=parsed_args.access_type, - access_to=parsed_args.access_to + access_to=parsed_args.access_to, ) return self.dict2columns(snapshot_access) except Exception as e: raise exceptions.CommandError( "Failed to create access to share snapshot " - "'%s': %s" % (snapshot_obj, e)) + f"'{snapshot_obj}': {e}" + ) class ShareSnapshotAccessDeny(command.Command): """Delete access to a snapshot""" - _description = _( - "Delete access to a snapshot") + _description = _("Delete access to a snapshot") def get_parser(self, prog_name): - parser = super(ShareSnapshotAccessDeny, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "snapshot", metavar="", - help=_("Name or ID of the share snapshot to deny access to.") + help=_("Name or ID of the share snapshot to deny access to."), ) parser.add_argument( "id", metavar="", nargs="+", - help=_("ID(s) of the access rule(s) to be deleted.") + help=_("ID(s) of the access rule(s) to be deleted."), ) return parser @@ -757,42 +825,46 @@ def take_action(self, parsed_args): result = 0 snapshot_obj = utils.find_resource( - share_client.share_snapshots, - parsed_args.snapshot) + share_client.share_snapshots, parsed_args.snapshot + ) for access_id in parsed_args.id: try: share_client.share_snapshots.deny( - snapshot=snapshot_obj, - id=access_id + snapshot=snapshot_obj, id=access_id ) except Exception as e: result += 1 - LOG.error(_( - "Failed to delete access to share snapshot " - "for an access rule with ID '%(access)s': %(e)s"), - {'access': access_id, 'e': e}) + LOG.error( + _( + "Failed to delete access to share snapshot " + "for an access rule with ID '%(access)s': %(e)s" + ), + {'access': access_id, 'e': e}, + ) if result > 0: total = len(parsed_args.id) - msg = (_("Failed to delete access to a share snapshot for " - "%(result)s out of %(total)s access rule ID's ") - % {'result': result, 'total': total}) + msg = _( + "Failed to delete access to a share snapshot for " + "%(result)s out of %(total)s access rule ID's " + ) % {'result': result, 'total': total} raise exceptions.CommandError(msg) class ShareSnapshotAccessList(command.Lister): """Show access list for a snapshot""" - _description = _( - "Show access list for a snapshot") + _description = _("Show access list for a snapshot") def get_parser(self, prog_name): - parser = super(ShareSnapshotAccessList, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "snapshot", metavar="", - help=_("Name or ID of the share snapshot to show access list for.") + help=_( + "Name or ID of the share snapshot to show access list for." + ), ) return parser @@ -800,36 +872,30 @@ def take_action(self, parsed_args): share_client = self.app.client_manager.share snapshot_obj = utils.find_resource( - share_client.share_snapshots, - parsed_args.snapshot) + share_client.share_snapshots, parsed_args.snapshot + ) - access_rules = share_client.share_snapshots.access_list( - snapshot_obj) + access_rules = share_client.share_snapshots.access_list(snapshot_obj) - columns = [ - "ID", - "Access Type", - "Access To", - "State" - ] + columns = ["ID", "Access Type", "Access To", "State"] - return (columns, - (utils.get_item_properties(s, columns) for s in access_rules)) + return ( + columns, + (utils.get_item_properties(s, columns) for s in access_rules), + ) class ShareSnapshotListExportLocation(command.Lister): """List export locations of a given snapshot""" - _description = _( - "List export locations of a given snapshot") + _description = _("List export locations of a given snapshot") def get_parser(self, prog_name): - parser = super(ShareSnapshotListExportLocation, self).get_parser( - prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "snapshot", metavar="", - help=_("Name or ID of the share snapshot.") + help=_("Name or ID of the share snapshot."), ) return parser @@ -837,37 +903,37 @@ def take_action(self, parsed_args): share_client = self.app.client_manager.share snapshot_obj = utils.find_resource( - share_client.share_snapshots, - parsed_args.snapshot) + share_client.share_snapshots, parsed_args.snapshot + ) export_locations = share_client.share_snapshot_export_locations.list( - snapshot=snapshot_obj) + snapshot=snapshot_obj + ) columns = ["ID", "Path"] return ( columns, - (utils.get_item_properties(s, columns) for s in export_locations)) + (utils.get_item_properties(s, columns) for s in export_locations), + ) class ShareSnapshotShowExportLocation(command.ShowOne): """Show export location of the share snapshot""" - _description = _( - "Show export location of the share snapshot") + _description = _("Show export location of the share snapshot") def get_parser(self, prog_name): - parser = super(ShareSnapshotShowExportLocation, self).get_parser( - prog_name) + parser = super().get_parser(prog_name) parser.add_argument( "snapshot", metavar="", - help=_("Name or ID of the share snapshot.") + help=_("Name or ID of the share snapshot."), ) parser.add_argument( "export_location", metavar="", - help=_("ID of the share snapshot export location.") + help=_("ID of the share snapshot export location."), ) return parser @@ -875,11 +941,11 @@ def take_action(self, parsed_args): share_client = self.app.client_manager.share snapshot_obj = utils.find_resource( - share_client.share_snapshots, - parsed_args.snapshot) + share_client.share_snapshots, parsed_args.snapshot + ) export_location = share_client.share_snapshot_export_locations.get( - export_location=parsed_args.export_location, - snapshot=snapshot_obj) + export_location=parsed_args.export_location, snapshot=snapshot_obj + ) return self.dict2columns(export_location._info) diff --git a/manilaclient/osc/v2/share_transfers.py b/manilaclient/osc/v2/share_transfers.py index 912a4b6a..cb650d18 100644 --- a/manilaclient/osc/v2/share_transfers.py +++ b/manilaclient/osc/v2/share_transfers.py @@ -32,7 +32,7 @@ 'source_project_id', 'destination_project_id', 'accepted', - 'expires_at' + 'expires_at', ] TRANSFER_SUMMARY_ATTRIBUTES = [ @@ -45,27 +45,28 @@ class CreateShareTransfer(command.ShowOne): """Create a new share transfer.""" + _description = _("Create a new share transfer") def get_parser(self, prog_name): - parser = super(CreateShareTransfer, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( - 'share', - metavar='', - help='Name or ID of share to transfer.') + 'share', metavar='', help='Name or ID of share to transfer.' + ) parser.add_argument( '--name', metavar='', default=None, - help='Transfer name. Default=None.') + help='Transfer name. Default=None.', + ) return parser def take_action(self, parsed_args): share_client = self.app.client_manager.share - share = osc_utils.find_resource(share_client.shares, - parsed_args.share) + share = osc_utils.find_resource(share_client.shares, parsed_args.share) transfer = share_client.transfers.create( - share.id, name=parsed_args.name) + share.id, name=parsed_args.name + ) transfer._info.pop('links', None) @@ -74,15 +75,17 @@ def take_action(self, parsed_args): class DeleteShareTransfer(command.Command): """Remove one or more transfers.""" + _description = _("Remove one or more transfers") def get_parser(self, prog_name): - parser = super(DeleteShareTransfer, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'transfer', metavar='', nargs='+', - help='Name(s) or ID(s) of the transfer(s).') + help='Name(s) or ID(s) of the transfer(s).', + ) return parser def take_action(self, parsed_args): @@ -92,86 +95,101 @@ def take_action(self, parsed_args): for transfer in parsed_args.transfer: try: transfer_obj = apiutils.find_resource( - share_client.transfers, - transfer) + share_client.transfers, transfer + ) share_client.transfers.delete(transfer_obj.id) except Exception as e: failure_count += 1 - LOG.error(_( - "Failed to delete %(transfer)s: %(e)s"), - {'transfer': transfer, 'e': e}) + LOG.error( + _("Failed to delete %(transfer)s: %(e)s"), + {'transfer': transfer, 'e': e}, + ) if failure_count > 0: - raise exceptions.CommandError(_( - "Unable to delete some or all of the specified transfers.")) + raise exceptions.CommandError( + _("Unable to delete some or all of the specified transfers.") + ) class ListShareTransfer(command.Lister): """Lists all transfers.""" + _description = _("Lists all transfers") def get_parser(self, prog_name): - parser = super(ListShareTransfer, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( '--all-projects', action='store_true', - help=_("Shows details for all tenants. (Admin only).") + help=_("Shows details for all tenants. (Admin only)."), ) parser.add_argument( '--name', metavar='', default=None, - help='Filter share transfers by name. Default=None.') + help='Filter share transfers by name. Default=None.', + ) parser.add_argument( '--id', metavar='', default=None, - help='Filter share transfers by ID. Default=None.') + help='Filter share transfers by ID. Default=None.', + ) parser.add_argument( - '--resource-type', '--resource_type', + '--resource-type', + '--resource_type', metavar='', default=None, help='Filter share transfers by resource type, ' - 'which can be share. Default=None.') + 'which can be share. Default=None.', + ) parser.add_argument( - '--resource-id', '--resource_id', + '--resource-id', + '--resource_id', metavar='', default=None, - help='Filter share transfers by resource ID. Default=None.') + help='Filter share transfers by resource ID. Default=None.', + ) parser.add_argument( - '--source-project-id', '--source_project_id', + '--source-project-id', + '--source_project_id', metavar='', default=None, help='Filter share transfers by ID of the Project that ' - 'initiated the transfer. Default=None.') + 'initiated the transfer. Default=None.', + ) parser.add_argument( '--limit', metavar='', type=int, default=None, help='Maximum number of transfer records to ' - 'return. (Default=None)') + 'return. (Default=None)', + ) parser.add_argument( '--offset', metavar="", default=None, - help='Start position of transfer records listing.') + help='Start position of transfer records listing.', + ) parser.add_argument( - '--sort-key', '--sort_key', + '--sort-key', + '--sort_key', metavar='', type=str, default=None, - help='Key to be sorted, available keys are %(keys)s. ' - 'Default=None.' - % {'keys': constants.SHARE_TRANSFER_SORT_KEY_VALUES}) + help=f'Key to be sorted, available keys are {constants.SHARE_TRANSFER_SORT_KEY_VALUES}. ' + 'Default=None.', + ) parser.add_argument( - '--sort-dir', '--sort_dir', + '--sort-dir', + '--sort_dir', metavar='', type=str, default=None, - help='Sort direction, available values are %(values)s. ' - 'OPTIONAL: Default=None.' % { - 'values': constants.SORT_DIR_VALUES}) + help=f'Sort direction, available values are {constants.SORT_DIR_VALUES}. ' + 'OPTIONAL: Default=None.', + ) parser.add_argument( '--detailed', dest='detailed', @@ -180,23 +198,25 @@ def get_parser(self, prog_name): type=int, const=1, default=0, - help="Show detailed information about filtered share transfers.") + help="Show detailed information about filtered share transfers.", + ) return parser def take_action(self, parsed_args): share_client = self.app.client_manager.share - columns = [ - 'ID', - 'Name', - 'Resource Type', - 'Resource Id' - ] + columns = ['ID', 'Name', 'Resource Type', 'Resource Id'] if parsed_args.detailed: - columns.extend(['Created At', 'Source Project Id', - 'Destination Project Id', 'Accepted', - 'Expires At']) + columns.extend( + [ + 'Created At', + 'Source Project Id', + 'Destination Project Id', + 'Accepted', + 'Expires At', + ] + ) search_opts = { 'all_tenants': parsed_args.all_projects, @@ -210,50 +230,62 @@ def take_action(self, parsed_args): } transfers = share_client.transfers.list( - detailed=parsed_args.detailed, search_opts=search_opts, - sort_key=parsed_args.sort_key, sort_dir=parsed_args.sort_dir) + detailed=parsed_args.detailed, + search_opts=search_opts, + sort_key=parsed_args.sort_key, + sort_dir=parsed_args.sort_dir, + ) - return (columns, (osc_utils.get_item_properties - (m, columns) for m in transfers)) + return ( + columns, + (osc_utils.get_item_properties(m, columns) for m in transfers), + ) class ShowShareTransfer(command.ShowOne): """Show details about a share transfer.""" + _description = _("Show details about a share transfer") def get_parser(self, prog_name): - parser = super(ShowShareTransfer, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'transfer', metavar='', - help=_('Name or ID of transfer to show.')) + help=_('Name or ID of transfer to show.'), + ) return parser def take_action(self, parsed_args): share_client = self.app.client_manager.share transfer = apiutils.find_resource( - share_client.transfers, - parsed_args.transfer) + share_client.transfers, parsed_args.transfer + ) - return (TRANSFER_DETAIL_ATTRIBUTES, osc_utils.get_dict_properties( - transfer._info, TRANSFER_DETAIL_ATTRIBUTES)) + return ( + TRANSFER_DETAIL_ATTRIBUTES, + osc_utils.get_dict_properties( + transfer._info, TRANSFER_DETAIL_ATTRIBUTES + ), + ) class AcceptShareTransfer(command.Command): """Accepts a share transfer.""" + _description = _("Accepts a share transfer") def get_parser(self, prog_name): - parser = super(AcceptShareTransfer, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( - 'transfer', - metavar='', - help='ID of transfer to accept.') + 'transfer', metavar='', help='ID of transfer to accept.' + ) parser.add_argument( 'auth_key', metavar='', - help='Authentication key of transfer to accept.') + help='Authentication key of transfer to accept.', + ) parser.add_argument( '--clear-rules', '--clear_rules', @@ -261,12 +293,15 @@ def get_parser(self, prog_name): action='store_true', default=False, help="Whether manila should clean up the access rules after the " - "transfer is complete. (Default=False)") + "transfer is complete. (Default=False)", + ) return parser def take_action(self, parsed_args): share_client = self.app.client_manager.share share_client.transfers.accept( - parsed_args.transfer, parsed_args.auth_key, - clear_access_rules=parsed_args.clear_rules) + parsed_args.transfer, + parsed_args.auth_key, + clear_access_rules=parsed_args.clear_rules, + ) diff --git a/manilaclient/osc/v2/share_type_access.py b/manilaclient/osc/v2/share_type_access.py index b22ae13e..e93e6108 100644 --- a/manilaclient/osc/v2/share_type_access.py +++ b/manilaclient/osc/v2/share_type_access.py @@ -20,19 +20,20 @@ class ShareTypeAccessAllow(command.Command): """Add access for share type.""" + _description = _("Add access for share type") def get_parser(self, prog_name): - parser = super(ShareTypeAccessAllow, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'share_type', metavar="", - help=_("Share type name or ID to add access to") + help=_("Share type name or ID to add access to"), ) parser.add_argument( 'project_id', metavar="", - help=_("Project ID to add share type access for") + help=_("Project ID to add share type access for"), ) return parser @@ -40,28 +41,31 @@ def take_action(self, parsed_args): share_client = self.app.client_manager.share share_type = apiutils.find_resource( - share_client.share_types, parsed_args.share_type) + share_client.share_types, parsed_args.share_type + ) try: share_client.share_type_access.add_project_access( - share_type, - parsed_args.project_id) + share_type, parsed_args.project_id + ) except Exception as e: raise exceptions.CommandError( - "Failed to add access to share type : %s" % e) + f"Failed to add access to share type : {e}" + ) class ListShareTypeAccess(command.Lister): """Get access list for share type.""" + _description = _("Get access list for share type") def get_parser(self, prog_name): - parser = super(ListShareTypeAccess, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'share_type', metavar="", - help=_("Share type name or ID to get access list for") + help=_("Share type name or ID to get access list for"), ) return parser @@ -69,11 +73,13 @@ def take_action(self, parsed_args): share_client = self.app.client_manager.share share_type = apiutils.find_resource( - share_client.share_types, parsed_args.share_type) + share_client.share_types, parsed_args.share_type + ) if share_type._info.get('share_type_access:is_public'): raise exceptions.CommandError( - 'Forbidden to get access list for public share type.') + 'Forbidden to get access list for public share type.' + ) data = share_client.share_type_access.list(share_type) @@ -85,19 +91,20 @@ def take_action(self, parsed_args): class ShareTypeAccessDeny(command.Command): """Delete access from share type.""" + _description = _("Delete access from share type") def get_parser(self, prog_name): - parser = super(ShareTypeAccessDeny, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'share_type', metavar="", - help=_("Share type name or ID to delete access from") + help=_("Share type name or ID to delete access from"), ) parser.add_argument( 'project_id', metavar="", - help=_("Project ID to delete share type access for") + help=_("Project ID to delete share type access for"), ) return parser @@ -105,13 +112,15 @@ def take_action(self, parsed_args): share_client = self.app.client_manager.share share_type = apiutils.find_resource( - share_client.share_types, parsed_args.share_type) + share_client.share_types, parsed_args.share_type + ) try: share_client.share_type_access.remove_project_access( - share_type, - parsed_args.project_id) + share_type, parsed_args.project_id + ) except Exception as e: raise exceptions.CommandError( - "Failed to remove access from share type : %s" % e) + f"Failed to remove access from share type : {e}" + ) diff --git a/manilaclient/osc/v2/share_types.py b/manilaclient/osc/v2/share_types.py index daeacd41..d6ba8fbd 100644 --- a/manilaclient/osc/v2/share_types.py +++ b/manilaclient/osc/v2/share_types.py @@ -32,7 +32,7 @@ 'is_default', 'required_extra_specs', 'optional_extra_specs', - 'description' + 'description', ] @@ -53,9 +53,11 @@ def format_share_type(share_type, formatter='table'): { 'visibility': visibility, 'required_extra_specs': utils.format_properties( - share_type.required_extra_specs), + share_type.required_extra_specs + ), 'optional_extra_specs': utils.format_properties( - optional_extra_specs), + optional_extra_specs + ), } ) else: @@ -72,60 +74,69 @@ def format_share_type(share_type, formatter='table'): class CreateShareType(command.ShowOne): """Create new share type.""" - _description = _( - "Create new share type") + + _description = _("Create new share type") def get_parser(self, prog_name): - parser = super(CreateShareType, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( - 'name', - metavar="", - default=None, - help=_('Share type name') + 'name', metavar="", default=None, help=_('Share type name') ) parser.add_argument( 'spec_driver_handles_share_servers', metavar="", default=None, - help=_("Required extra specification. " - "Valid values are 'true' and 'false'") + help=_( + "Required extra specification. " + "Valid values are 'true' and 'false'" + ), ) parser.add_argument( "--description", metavar="", default=None, - help=_("Share type description. " - "Available only for microversion >= 2.41."), + help=_( + "Share type description. " + "Available only for microversion >= 2.41." + ), ) parser.add_argument( "--snapshot-support", metavar="", default=None, - help=_("Boolean extra spec used for filtering of back ends " - "by their capability to create share snapshots."), + help=_( + "Boolean extra spec used for filtering of back ends " + "by their capability to create share snapshots." + ), ) parser.add_argument( "--create-share-from-snapshot-support", metavar="", default=None, - help=_("Boolean extra spec used for filtering of back ends " - "by their capability to create shares from snapshots."), + help=_( + "Boolean extra spec used for filtering of back ends " + "by their capability to create shares from snapshots." + ), ) parser.add_argument( "--revert-to-snapshot-support", metavar="", default=False, - help=_("Boolean extra spec used for filtering of back ends " - "by their capability to revert shares to snapshots. " - "(Default is False)."), + help=_( + "Boolean extra spec used for filtering of back ends " + "by their capability to revert shares to snapshots. " + "(Default is False)." + ), ) parser.add_argument( "--mount-snapshot-support", metavar="", default=False, - help=_("Boolean extra spec used for filtering of back ends " - "by their capability to mount share snapshots. " - "(Default is False)."), + help=_( + "Boolean extra spec used for filtering of back ends " + "by their capability to mount share snapshots. " + "(Default is False)." + ), ) parser.add_argument( "--extra-specs", @@ -133,87 +144,99 @@ def get_parser(self, prog_name): nargs='*', metavar='', default=None, - help=_("Extra specs key and value of share type that will be" - " used for share type creation. OPTIONAL: Default=None." - " example --extra-specs thin_provisioning=' True', " - "replication_type=readable."), + help=_( + "Extra specs key and value of share type that will be" + " used for share type creation. OPTIONAL: Default=None." + " example --extra-specs thin_provisioning=' True', " + "replication_type=readable." + ), ) parser.add_argument( '--public', metavar="", default=True, - help=_('Make type accessible to the public (default true).') + help=_('Make type accessible to the public (default true).'), ) return parser def take_action(self, parsed_args): share_client = self.app.client_manager.share - kwargs = { - 'name': parsed_args.name - } + kwargs = {'name': parsed_args.name} try: kwargs['spec_driver_handles_share_servers'] = ( strutils.bool_from_string( - parsed_args.spec_driver_handles_share_servers, - strict=True)) + parsed_args.spec_driver_handles_share_servers, strict=True + ) + ) except ValueError as e: - msg = ("Argument spec_driver_handles_share_servers " - "argument is not valid: %s" % str(e)) + msg = ( + "Argument spec_driver_handles_share_servers " + f"argument is not valid: {str(e)}" + ) raise exceptions.CommandError(msg) if parsed_args.description: if share_client.api_version.matches( - api_versions.APIVersion("2.41"), - api_versions.APIVersion()): + api_versions.APIVersion("2.41"), api_versions.APIVersion() + ): kwargs['description'] = parsed_args.description else: raise exceptions.CommandError( "Adding description to share type " - "is only available with API microversion >= 2.41") + "is only available with API microversion >= 2.41" + ) if parsed_args.public: kwargs['is_public'] = strutils.bool_from_string( - parsed_args.public, default=True) + parsed_args.public, default=True + ) extra_specs = {} if parsed_args.extra_specs: for item in parsed_args.extra_specs: (key, value) = item.split('=', 1) if key == 'driver_handles_share_servers': - msg = ("'driver_handles_share_servers' " - "is already set via positional argument.") + msg = ( + "'driver_handles_share_servers' " + "is already set via positional argument." + ) raise exceptions.CommandError(msg) else: extra_specs = utils.extract_extra_specs( - extra_specs, [item]) + extra_specs, [item] + ) for key in constants.BOOL_SPECS: value = getattr(parsed_args, key) if value: extra_specs = utils.extract_extra_specs( - extra_specs, [key + '=' + value]) + extra_specs, [key + '=' + value] + ) kwargs['extra_specs'] = extra_specs share_type = share_client.share_types.create(**kwargs) formatted_type = format_share_type(share_type, parsed_args.formatter) - return (ATTRIBUTES, oscutils.get_dict_properties( - formatted_type._info, ATTRIBUTES)) + return ( + ATTRIBUTES, + oscutils.get_dict_properties(formatted_type._info, ATTRIBUTES), + ) class DeleteShareType(command.Command): """Delete a share type.""" + _description = _("Delete a share type") def get_parser(self, prog_name): - parser = super(DeleteShareType, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'share_types', metavar="", nargs="+", - help=_("Name or ID of the share type(s) to delete") + help=_("Name or ID of the share type(s) to delete"), ) return parser @@ -224,34 +247,39 @@ def take_action(self, parsed_args): for share_type in parsed_args.share_types: try: share_type_obj = apiutils.find_resource( - share_client.share_types, - share_type) + share_client.share_types, share_type + ) share_client.share_types.delete(share_type_obj) except Exception as e: result += 1 - LOG.error(_( - "Failed to delete share type with " - "name or ID '%(share_type)s': %(e)s"), - {'share_type': share_type, 'e': e}) + LOG.error( + _( + "Failed to delete share type with " + "name or ID '%(share_type)s': %(e)s" + ), + {'share_type': share_type, 'e': e}, + ) if result > 0: total = len(parsed_args.share_types) - msg = (_("%(result)s of %(total)s share types failed " - "to delete.") % {'result': result, 'total': total}) + msg = _( + "%(result)s of %(total)s share types failed to delete." + ) % {'result': result, 'total': total} raise exceptions.CommandError(msg) class SetShareType(command.Command): """Set share type properties.""" + _description = _("Set share type properties") def get_parser(self, prog_name): - parser = super(SetShareType, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'share_type', metavar="", - help=_("Name or ID of the share type to modify") + help=_("Name or ID of the share type to modify"), ) parser.add_argument( "--extra-specs", @@ -259,33 +287,41 @@ def get_parser(self, prog_name): nargs='*', metavar='', default=None, - help=_("Extra specs key and value of share type that will be" - " used for share type creation. OPTIONAL: Default=None." - " example --extra-specs thin_provisioning=' True', " - "replication_type=readable."), + help=_( + "Extra specs key and value of share type that will be" + " used for share type creation. OPTIONAL: Default=None." + " example --extra-specs thin_provisioning=' True', " + "replication_type=readable." + ), ) parser.add_argument( '--public', metavar="", default=None, - help=_('New visibility of the share type. If set to True, ' - 'share type will be available to all projects ' - 'in the cloud. ' - 'Available only for microversion >= 2.50') + help=_( + 'New visibility of the share type. If set to True, ' + 'share type will be available to all projects ' + 'in the cloud. ' + 'Available only for microversion >= 2.50' + ), ) parser.add_argument( "--description", metavar="", default=None, - help=_("New description of share type. " - "Available only for microversion >= 2.50"), + help=_( + "New description of share type. " + "Available only for microversion >= 2.50" + ), ) parser.add_argument( '--name', metavar="", default=None, - help=_('New name of share type. ' - 'Available only for microversion >= 2.50') + help=_( + 'New name of share type. ' + 'Available only for microversion >= 2.50' + ), ) return parser @@ -293,10 +329,12 @@ def take_action(self, parsed_args): share_client = self.app.client_manager.share share_type = apiutils.find_resource( - share_client.share_types, parsed_args.share_type) + share_client.share_types, parsed_args.share_type + ) - can_update = ( - share_client.api_version >= api_versions.APIVersion('2.50')) + can_update = share_client.api_version >= api_versions.APIVersion( + '2.50' + ) kwargs = {} if parsed_args.name is not None: @@ -305,46 +343,52 @@ def take_action(self, parsed_args): else: raise exceptions.CommandError( "Setting (new) name to share type " - "is only available with API microversion >= 2.50") + "is only available with API microversion >= 2.50" + ) if parsed_args.description is not None: if can_update: kwargs['description'] = parsed_args.description else: raise exceptions.CommandError( "Setting (new) description to share type " - "is only available with API microversion >= 2.50") + "is only available with API microversion >= 2.50" + ) if parsed_args.public is not None: if can_update: kwargs['is_public'] = strutils.bool_from_string( - parsed_args.public, default=True) + parsed_args.public, default=True + ) else: raise exceptions.CommandError( "Setting visibility to share type " - "is only available with API microversion >= 2.50") + "is only available with API microversion >= 2.50" + ) if kwargs: share_type.update(**kwargs) if parsed_args.extra_specs: extra_specs = utils.extract_extra_specs( - extra_specs={}, - specs_to_add=parsed_args.extra_specs) + extra_specs={}, specs_to_add=parsed_args.extra_specs + ) try: share_type.set_keys(extra_specs) except Exception as e: raise exceptions.CommandError( - "Failed to set share type key: %s" % e) + f"Failed to set share type key: {e}" + ) class UnsetShareType(command.Command): """Unset share type extra specs.""" + _description = _("Unset share type extra specs") def get_parser(self, prog_name): - parser = super(UnsetShareType, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'share_type', metavar="", - help=_("Name or ID of the share type to modify") + help=_("Name or ID of the share type to modify"), ) parser.add_argument( 'extra_specs', @@ -358,28 +402,33 @@ def take_action(self, parsed_args): share_client = self.app.client_manager.share share_type = apiutils.find_resource( - share_client.share_types, parsed_args.share_type) + share_client.share_types, parsed_args.share_type + ) if parsed_args.extra_specs: try: share_type.unset_keys(parsed_args.extra_specs) except Exception as e: raise exceptions.CommandError( - "Failed to remove share type extra spec: %s" % e) + f"Failed to remove share type extra spec: {e}" + ) class ListShareType(command.Lister): """List Share Types.""" + _description = _("List share types") def get_parser(self, prog_name): - parser = super(ListShareType, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( '--all', action='store_true', default=False, - help=_('Display all share types whatever public or private. ' - 'Default=False. (Admin only)'), + help=_( + 'Display all share types whatever public or private. ' + 'Default=False. (Admin only)' + ), ) parser.add_argument( '--extra-specs', @@ -387,9 +436,11 @@ def get_parser(self, prog_name): nargs='*', metavar='', default=None, - help=_('Filter share types with extra specs (key=value). ' - 'Available only for API microversion >= 2.43. ' - 'OPTIONAL: Default=None.'), + help=_( + 'Filter share types with extra specs (key=value). ' + 'Available only for API microversion >= 2.43. ' + 'OPTIONAL: Default=None.' + ), ) return parser @@ -401,25 +452,29 @@ def take_action(self, parsed_args): if share_client.api_version < api_versions.APIVersion("2.43"): raise exceptions.CommandError( "Filtering by 'extra_specs' is available only with " - "API microversion '2.43' and above.") + "API microversion '2.43' and above." + ) search_opts = { 'extra_specs': utils.extract_extra_specs( - extra_specs={}, - specs_to_add=parsed_args.extra_specs) + extra_specs={}, specs_to_add=parsed_args.extra_specs + ) } share_types = share_client.share_types.list( - search_opts=search_opts, - show_all=parsed_args.all) + search_opts=search_opts, show_all=parsed_args.all + ) formatted_types = [] for share_type in share_types: - formatted_types.append(format_share_type(share_type, - parsed_args.formatter)) + formatted_types.append( + format_share_type(share_type, parsed_args.formatter) + ) - values = (oscutils.get_dict_properties( - s._info, ATTRIBUTES) for s in formatted_types) + values = ( + oscutils.get_dict_properties(s._info, ATTRIBUTES) + for s in formatted_types + ) columns = utils.format_column_headers(ATTRIBUTES) @@ -428,14 +483,15 @@ def take_action(self, parsed_args): class ShowShareType(command.ShowOne): """Show a share type.""" + _description = _("Display share type details") def get_parser(self, prog_name): - parser = super(ShowShareType, self).get_parser(prog_name) + parser = super().get_parser(prog_name) parser.add_argument( 'share_type', metavar="", - help=_("Share type to display (name or ID)") + help=_("Share type to display (name or ID)"), ) return parser @@ -443,10 +499,12 @@ def take_action(self, parsed_args): share_client = self.app.client_manager.share share_type = apiutils.find_resource( - share_client.share_types, - parsed_args.share_type) + share_client.share_types, parsed_args.share_type + ) formatted_type = format_share_type(share_type, parsed_args.formatter) - return (ATTRIBUTES, oscutils.get_dict_properties( - formatted_type._info, ATTRIBUTES)) + return ( + ATTRIBUTES, + oscutils.get_dict_properties(formatted_type._info, ATTRIBUTES), + ) diff --git a/manilaclient/shell.py b/manilaclient/shell.py index d379f736..926de18f 100644 --- a/manilaclient/shell.py +++ b/manilaclient/shell.py @@ -77,9 +77,8 @@ def __call__(self, parser, namespace, values, option_string=None): class ManilaClientArgumentParser(argparse.ArgumentParser): - def __init__(self, *args, **kwargs): - super(ManilaClientArgumentParser, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) # NOTE(vponomaryov): Register additional action to be used by arguments # with multiple aliases. self.register('action', 'single_alias', AllowOnlyOneAliasAtATimeAction) @@ -94,11 +93,11 @@ def error(self, message): # FIXME(lzyeval): if changes occur in argparse.ArgParser._check_value choose_from = ' (choose from' progparts = self.prog.partition(' ') - self.exit(2, "error: %(errmsg)s\nTry '%(mainp)s help %(subp)s'" - " for more information.\n" % - {'errmsg': message.split(choose_from)[0], - 'mainp': progparts[0], - 'subp': progparts[2]}) + self.exit( + 2, + f"error: {message.split(choose_from)[0]}\nTry '{progparts[0]} help {progparts[2]}'" + " for more information.\n", + ) def _get_option_tuples(self, option_string): """Avoid ambiguity in argument abbreviation. @@ -106,8 +105,7 @@ def _get_option_tuples(self, option_string): Manilaclient uses aliases for command parameters and this method is used for avoiding parameter ambiguity alert. """ - option_tuples = super( - ManilaClientArgumentParser, self)._get_option_tuples(option_string) + option_tuples = super()._get_option_tuples(option_string) if len(option_tuples) > 1: opt_strings_list = [] opts = [] @@ -119,258 +117,298 @@ def _get_option_tuples(self, option_string): return option_tuples -class OpenStackManilaShell(object): - +class OpenStackManilaShell: def get_base_parser(self): parser = ManilaClientArgumentParser( prog='manila', description=__doc__.strip(), - epilog='See "manila help COMMAND" ' - 'for help on a specific command.', + epilog='See "manila help COMMAND" for help on a specific command.', add_help=False, formatter_class=OpenStackHelpFormatter, ) # Global arguments - parser.add_argument('-h', '--help', - action='store_true', - help=argparse.SUPPRESS) - - parser.add_argument('--version', - action='version', - version=manilaclient.__version__) - - parser.add_argument('-d', '--debug', - action='store_true', - default=cliutils.env('manilaclient_DEBUG', - 'MANILACLIENT_DEBUG', - default=False), - help="Print debugging output.") - - parser.add_argument('--os-cache', - default=cliutils.env('OS_CACHE', default=False), - action='store_true', - help='Use the auth token cache. ' - 'Defaults to env[OS_CACHE].') - - parser.add_argument('--os-reset-cache', - default=False, - action='store_true', - help='Delete cached password and auth token.') - - parser.add_argument('--os-user-id', - metavar='', - default=cliutils.env('OS_USER_ID'), - help=('Defaults to env [OS_USER_ID].')) - parser.add_argument('--os_user_id', - help=argparse.SUPPRESS) - - parser.add_argument('--os-username', - metavar='', - default=cliutils.env('OS_USERNAME', - 'MANILA_USERNAME'), - help='Defaults to env[OS_USERNAME].') - parser.add_argument('--os_username', - help=argparse.SUPPRESS) - - parser.add_argument('--os-password', - metavar='', - default=cliutils.env('OS_PASSWORD', - 'MANILA_PASSWORD'), - help='Defaults to env[OS_PASSWORD].') - parser.add_argument('--os_password', - help=argparse.SUPPRESS) - - parser.add_argument('--os-tenant-name', - metavar='', - default=cliutils.env('OS_TENANT_NAME', - 'MANILA_PROJECT_ID'), - help='Defaults to env[OS_TENANT_NAME].') - parser.add_argument('--os_tenant_name', - help=argparse.SUPPRESS) - - parser.add_argument('--os-project-name', - metavar='', - default=cliutils.env('OS_PROJECT_NAME'), - help=('Another way to specify tenant name. ' - 'This option is mutually exclusive with ' - '--os-tenant-name. ' - 'Defaults to env[OS_PROJECT_NAME].')) - parser.add_argument('--os_project_name', - help=argparse.SUPPRESS) - - parser.add_argument('--os-tenant-id', - metavar='', - default=cliutils.env('OS_TENANT_ID', - 'MANILA_TENANT_ID'), - help='Defaults to env[OS_TENANT_ID].') - parser.add_argument('--os_tenant_id', - help=argparse.SUPPRESS) - - parser.add_argument('--os-project-id', - metavar='', - default=cliutils.env('OS_PROJECT_ID'), - help=('Another way to specify tenant ID. ' - 'This option is mutually exclusive with ' - '--os-tenant-id. ' - 'Defaults to env[OS_PROJECT_ID].')) - parser.add_argument('--os_project_id', - help=argparse.SUPPRESS) - - parser.add_argument('--os-user-domain-id', - metavar='', - default=cliutils.env('OS_USER_DOMAIN_ID'), - help=('OpenStack user domain ID. ' - 'Defaults to env[OS_USER_DOMAIN_ID].')) - parser.add_argument('--os_user_domain_id', - help=argparse.SUPPRESS) - - parser.add_argument('--os-user-domain-name', - metavar='', - default=cliutils.env('OS_USER_DOMAIN_NAME'), - help=('OpenStack user domain name. ' - 'Defaults to env[OS_USER_DOMAIN_NAME].')) - parser.add_argument('--os_user_domain_name', - help=argparse.SUPPRESS) - - parser.add_argument('--os-project-domain-id', - metavar='', - default=cliutils.env('OS_PROJECT_DOMAIN_ID'), - help='Defaults to env[OS_PROJECT_DOMAIN_ID].') - parser.add_argument('--os_project_domain_id', - help=argparse.SUPPRESS) - - parser.add_argument('--os-project-domain-name', - metavar='', - default=cliutils.env('OS_PROJECT_DOMAIN_NAME'), - help='Defaults to env[OS_PROJECT_DOMAIN_NAME].') - parser.add_argument('--os_project_domain_name', - help=argparse.SUPPRESS) - - parser.add_argument('--os-auth-url', - metavar='', - default=cliutils.env('OS_AUTH_URL', - 'MANILA_URL'), - help='Defaults to env[OS_AUTH_URL].') - parser.add_argument('--os_auth_url', - help=argparse.SUPPRESS) - - parser.add_argument('--os-region-name', - metavar='', - default=cliutils.env('OS_REGION_NAME', - 'MANILA_REGION_NAME'), - help='Defaults to env[OS_REGION_NAME].') - parser.add_argument('--os_region_name', - help=argparse.SUPPRESS) - - parser.add_argument('--os-token', - metavar='', - default=cliutils.env('OS_TOKEN'), - help='Defaults to env[OS_TOKEN].') - parser.add_argument('--os_token', - help=argparse.SUPPRESS) - - parser.add_argument('--bypass-url', - metavar='', - default=cliutils.env('OS_MANILA_BYPASS_URL', - 'MANILACLIENT_BYPASS_URL'), - help=("Use this API endpoint instead of the " - "Service Catalog. Defaults to " - "env[OS_MANILA_BYPASS_URL].")) - parser.add_argument('--bypass_url', - help=argparse.SUPPRESS) - - parser.add_argument('--service-type', - metavar='', - help='Defaults to compute for most actions.') - parser.add_argument('--service_type', - help=argparse.SUPPRESS) - - parser.add_argument('--service-name', - metavar='', - default=cliutils.env('OS_MANILA_SERVICE_NAME', - 'MANILA_SERVICE_NAME'), - help='Defaults to env[OS_MANILA_SERVICE_NAME].') - parser.add_argument('--service_name', - help=argparse.SUPPRESS) - - parser.add_argument('--share-service-name', - metavar='', - default=cliutils.env( - 'OS_MANILA_SHARE_SERVICE_NAME', - 'MANILA_share_service_name'), - help='Defaults to env' - '[OS_MANILA_SHARE_SERVICE_NAME].') - parser.add_argument('--share_service_name', - help=argparse.SUPPRESS) - - parser.add_argument('--endpoint-type', - metavar='', - default=cliutils.env( - 'OS_MANILA_ENDPOINT_TYPE', - 'MANILA_ENDPOINT_TYPE', - default=DEFAULT_MANILA_ENDPOINT_TYPE), - help='Defaults to env[OS_MANILA_ENDPOINT_TYPE] or ' - + DEFAULT_MANILA_ENDPOINT_TYPE + '.') - parser.add_argument('--endpoint_type', - help=argparse.SUPPRESS) - - parser.add_argument('--os-share-api-version', - metavar='', - default=cliutils.env( - 'OS_SHARE_API_VERSION', - default=DEFAULT_OS_SHARE_API_VERSION), - help='Accepts 1.x to override default ' - 'to env[OS_SHARE_API_VERSION].') - parser.add_argument('--os_share_api_version', - help=argparse.SUPPRESS) - - parser.add_argument('--os-cacert', - metavar='', - default=cliutils.env('OS_CACERT', default=None), - help='Specify a CA bundle file to use in ' - 'verifying a TLS (https) server certificate. ' - 'Defaults to env[OS_CACERT].') - - parser.add_argument('--insecure', - default=cliutils.env('manilaclient_INSECURE', - 'MANILACLIENT_INSECURE', - default=False), - action='store_true', - help=argparse.SUPPRESS) - - parser.add_argument('--retries', - metavar='', - type=int, - default=0, - help='Number of retries.') - - parser.add_argument('--os-cert', - metavar='', - default=cliutils.env('OS_CERT'), - help='Defaults to env[OS_CERT].') - parser.add_argument('--os_cert', - help=argparse.SUPPRESS) - - parser.add_argument('--os-key', - metavar='', - default=cliutils.env('OS_KEY'), - help='Defaults to env[OS_KEY].') - parser.add_argument('--os_key', - help=argparse.SUPPRESS) + parser.add_argument( + '-h', '--help', action='store_true', help=argparse.SUPPRESS + ) + + parser.add_argument( + '--version', action='version', version=manilaclient.__version__ + ) + + parser.add_argument( + '-d', + '--debug', + action='store_true', + default=cliutils.env( + 'manilaclient_DEBUG', 'MANILACLIENT_DEBUG', default=False + ), + help="Print debugging output.", + ) + + parser.add_argument( + '--os-cache', + default=cliutils.env('OS_CACHE', default=False), + action='store_true', + help='Use the auth token cache. Defaults to env[OS_CACHE].', + ) + + parser.add_argument( + '--os-reset-cache', + default=False, + action='store_true', + help='Delete cached password and auth token.', + ) + + parser.add_argument( + '--os-user-id', + metavar='', + default=cliutils.env('OS_USER_ID'), + help=('Defaults to env [OS_USER_ID].'), + ) + parser.add_argument('--os_user_id', help=argparse.SUPPRESS) + + parser.add_argument( + '--os-username', + metavar='', + default=cliutils.env('OS_USERNAME', 'MANILA_USERNAME'), + help='Defaults to env[OS_USERNAME].', + ) + parser.add_argument('--os_username', help=argparse.SUPPRESS) + + parser.add_argument( + '--os-password', + metavar='', + default=cliutils.env('OS_PASSWORD', 'MANILA_PASSWORD'), + help='Defaults to env[OS_PASSWORD].', + ) + parser.add_argument('--os_password', help=argparse.SUPPRESS) + + parser.add_argument( + '--os-tenant-name', + metavar='', + default=cliutils.env('OS_TENANT_NAME', 'MANILA_PROJECT_ID'), + help='Defaults to env[OS_TENANT_NAME].', + ) + parser.add_argument('--os_tenant_name', help=argparse.SUPPRESS) + + parser.add_argument( + '--os-project-name', + metavar='', + default=cliutils.env('OS_PROJECT_NAME'), + help=( + 'Another way to specify tenant name. ' + 'This option is mutually exclusive with ' + '--os-tenant-name. ' + 'Defaults to env[OS_PROJECT_NAME].' + ), + ) + parser.add_argument('--os_project_name', help=argparse.SUPPRESS) + + parser.add_argument( + '--os-tenant-id', + metavar='', + default=cliutils.env('OS_TENANT_ID', 'MANILA_TENANT_ID'), + help='Defaults to env[OS_TENANT_ID].', + ) + parser.add_argument('--os_tenant_id', help=argparse.SUPPRESS) + + parser.add_argument( + '--os-project-id', + metavar='', + default=cliutils.env('OS_PROJECT_ID'), + help=( + 'Another way to specify tenant ID. ' + 'This option is mutually exclusive with ' + '--os-tenant-id. ' + 'Defaults to env[OS_PROJECT_ID].' + ), + ) + parser.add_argument('--os_project_id', help=argparse.SUPPRESS) + + parser.add_argument( + '--os-user-domain-id', + metavar='', + default=cliutils.env('OS_USER_DOMAIN_ID'), + help=( + 'OpenStack user domain ID. Defaults to env[OS_USER_DOMAIN_ID].' + ), + ) + parser.add_argument('--os_user_domain_id', help=argparse.SUPPRESS) + + parser.add_argument( + '--os-user-domain-name', + metavar='', + default=cliutils.env('OS_USER_DOMAIN_NAME'), + help=( + 'OpenStack user domain name. ' + 'Defaults to env[OS_USER_DOMAIN_NAME].' + ), + ) + parser.add_argument('--os_user_domain_name', help=argparse.SUPPRESS) + + parser.add_argument( + '--os-project-domain-id', + metavar='', + default=cliutils.env('OS_PROJECT_DOMAIN_ID'), + help='Defaults to env[OS_PROJECT_DOMAIN_ID].', + ) + parser.add_argument('--os_project_domain_id', help=argparse.SUPPRESS) + + parser.add_argument( + '--os-project-domain-name', + metavar='', + default=cliutils.env('OS_PROJECT_DOMAIN_NAME'), + help='Defaults to env[OS_PROJECT_DOMAIN_NAME].', + ) + parser.add_argument('--os_project_domain_name', help=argparse.SUPPRESS) + + parser.add_argument( + '--os-auth-url', + metavar='', + default=cliutils.env('OS_AUTH_URL', 'MANILA_URL'), + help='Defaults to env[OS_AUTH_URL].', + ) + parser.add_argument('--os_auth_url', help=argparse.SUPPRESS) + + parser.add_argument( + '--os-region-name', + metavar='', + default=cliutils.env('OS_REGION_NAME', 'MANILA_REGION_NAME'), + help='Defaults to env[OS_REGION_NAME].', + ) + parser.add_argument('--os_region_name', help=argparse.SUPPRESS) + + parser.add_argument( + '--os-token', + metavar='', + default=cliutils.env('OS_TOKEN'), + help='Defaults to env[OS_TOKEN].', + ) + parser.add_argument('--os_token', help=argparse.SUPPRESS) + + parser.add_argument( + '--bypass-url', + metavar='', + default=cliutils.env( + 'OS_MANILA_BYPASS_URL', 'MANILACLIENT_BYPASS_URL' + ), + help=( + "Use this API endpoint instead of the " + "Service Catalog. Defaults to " + "env[OS_MANILA_BYPASS_URL]." + ), + ) + parser.add_argument('--bypass_url', help=argparse.SUPPRESS) + + parser.add_argument( + '--service-type', + metavar='', + help='Defaults to compute for most actions.', + ) + parser.add_argument('--service_type', help=argparse.SUPPRESS) + + parser.add_argument( + '--service-name', + metavar='', + default=cliutils.env( + 'OS_MANILA_SERVICE_NAME', 'MANILA_SERVICE_NAME' + ), + help='Defaults to env[OS_MANILA_SERVICE_NAME].', + ) + parser.add_argument('--service_name', help=argparse.SUPPRESS) + + parser.add_argument( + '--share-service-name', + metavar='', + default=cliutils.env( + 'OS_MANILA_SHARE_SERVICE_NAME', 'MANILA_share_service_name' + ), + help='Defaults to env[OS_MANILA_SHARE_SERVICE_NAME].', + ) + parser.add_argument('--share_service_name', help=argparse.SUPPRESS) + + parser.add_argument( + '--endpoint-type', + metavar='', + default=cliutils.env( + 'OS_MANILA_ENDPOINT_TYPE', + 'MANILA_ENDPOINT_TYPE', + default=DEFAULT_MANILA_ENDPOINT_TYPE, + ), + help='Defaults to env[OS_MANILA_ENDPOINT_TYPE] or ' + + DEFAULT_MANILA_ENDPOINT_TYPE + + '.', + ) + parser.add_argument('--endpoint_type', help=argparse.SUPPRESS) + + parser.add_argument( + '--os-share-api-version', + metavar='', + default=cliutils.env( + 'OS_SHARE_API_VERSION', default=DEFAULT_OS_SHARE_API_VERSION + ), + help='Accepts 1.x to override default ' + 'to env[OS_SHARE_API_VERSION].', + ) + parser.add_argument('--os_share_api_version', help=argparse.SUPPRESS) + + parser.add_argument( + '--os-cacert', + metavar='', + default=cliutils.env('OS_CACERT', default=None), + help='Specify a CA bundle file to use in ' + 'verifying a TLS (https) server certificate. ' + 'Defaults to env[OS_CACERT].', + ) + + parser.add_argument( + '--insecure', + default=cliutils.env( + 'manilaclient_INSECURE', 'MANILACLIENT_INSECURE', default=False + ), + action='store_true', + help=argparse.SUPPRESS, + ) + + parser.add_argument( + '--retries', + metavar='', + type=int, + default=0, + help='Number of retries.', + ) + + parser.add_argument( + '--os-cert', + metavar='', + default=cliutils.env('OS_CERT'), + help='Defaults to env[OS_CERT].', + ) + parser.add_argument('--os_cert', help=argparse.SUPPRESS) + + parser.add_argument( + '--os-key', + metavar='', + default=cliutils.env('OS_KEY'), + help='Defaults to env[OS_KEY].', + ) + parser.add_argument('--os_key', help=argparse.SUPPRESS) if osprofiler_profiler: - parser.add_argument('--profile', - metavar='HMAC_KEY', - default=cliutils.env('OS_PROFILE'), - help='HMAC key to use for encrypting ' - 'context data for performance profiling ' - 'of operation. This key needs to match the ' - 'one configured on the manila api server. ' - 'Without key the profiling will not be ' - 'triggered even if osprofiler is enabled ' - 'on server side. Defaults to ' - 'env[OS_PROFILE].') + parser.add_argument( + '--profile', + metavar='HMAC_KEY', + default=cliutils.env('OS_PROFILE'), + help='HMAC key to use for encrypting ' + 'context data for performance profiling ' + 'of operation. This key needs to match the ' + 'one configured on the manila api server. ' + 'Without key the profiling will not be ' + 'triggered even if osprofiler is enabled ' + 'on server side. Defaults to ' + 'env[OS_PROFILE].', + ) parser.set_defaults(func=self.do_help) parser.set_defaults(command='') @@ -403,16 +441,16 @@ def get_subcommand_parser(self, version): def _discover_extensions(self, api_version): extensions = [] for name, module in itertools.chain( - self._discover_via_python_path(), - self._discover_via_contrib_path(api_version)): - + self._discover_via_python_path(), + self._discover_via_contrib_path(api_version), + ): extension = manilaclient.extension.Extension(name, module) extensions.append(extension) return extensions def _discover_via_python_path(self): - for (module_loader, name, ispkg) in pkgutil.iter_modules(): + for module_loader, name, ispkg in pkgutil.iter_modules(): if name.endswith('python_manilaclient_ext'): if not hasattr(module_loader, 'load_module'): # Python 2.6 compat: actually get an ImpImporter obj @@ -422,9 +460,7 @@ def _discover_via_python_path(self): yield name, module def _load_module(self, name, path): - module_spec = importlib_util.spec_from_file_location( - name, path - ) + module_spec = importlib_util.spec_from_file_location(name, path) module = importlib_util.module_from_spec(module_spec) module_spec.loader.exec_module(module) return module @@ -448,7 +484,8 @@ def _add_bash_completion_subparser(self, subparsers): subparser = subparsers.add_parser( 'bash_completion', add_help=False, - formatter_class=OpenStackHelpFormatter) + formatter_class=OpenStackHelpFormatter, + ) self.subcommands['bash_completion'] = subparser subparser.set_defaults(func=self.do_bash_completion) @@ -467,14 +504,18 @@ def _find_actions(self, subparsers, actions_module): help=help, description=desc, add_help=False, - formatter_class=OpenStackHelpFormatter) + formatter_class=OpenStackHelpFormatter, + ) - subparser.add_argument('-h', '--help', - action='help', - help=argparse.SUPPRESS,) + subparser.add_argument( + '-h', + '--help', + action='help', + help=argparse.SUPPRESS, + ) self.subcommands[command] = subparser - for (args, kwargs) in arguments: + for args, kwargs in arguments: subparser.add_argument(*args, **kwargs) subparser.set_defaults(func=callback) @@ -484,20 +525,18 @@ def setup_debugging(self, debug): streamformat = "%(levelname)s (%(module)s:%(lineno)d) %(message)s" logging.basicConfig(level=logging.DEBUG, format=streamformat) - logging.getLogger('requests.packages.urllib3.connectionpool' - ).setLevel(logging.WARNING) + logging.getLogger('requests.packages.urllib3.connectionpool').setLevel( + logging.WARNING + ) logging.getLogger('keystoneauth1.session').setLevel(logging.WARNING) - def _build_subcommands_and_extensions(self, - os_api_version, - argv, - options): - + def _build_subcommands_and_extensions(self, os_api_version, argv, options): self.extensions = self._discover_extensions(os_api_version) self._run_extension_hooks('__pre_parse_args__') self.parser = self.get_subcommand_parser( - os_api_version.get_major_version()) + os_api_version.get_major_version() + ) if argv and len(argv) > 1 and '--help' in argv: argv = [x for x in argv if x != '--help'] @@ -523,9 +562,9 @@ def main(self, argv): os_api_version = self._validate_input_api_version(options) # build available subcommands based on version - args = self._build_subcommands_and_extensions(os_api_version, - argv, - options) + args = self._build_subcommands_and_extensions( + os_api_version, argv, options + ) if not args: return 0 @@ -539,10 +578,12 @@ def main(self, argv): if not options.os_share_api_version: api_version = api_versions.get_api_version( - DEFAULT_MAJOR_OS_SHARE_API_VERSION) + DEFAULT_MAJOR_OS_SHARE_API_VERSION + ) else: api_version = api_versions.get_api_version( - options.os_share_api_version) + options.os_share_api_version + ) major_version_string = str(api_version.ver_major) os_service_type = args.service_type @@ -586,33 +627,40 @@ def main(self, argv): client_args['share_service_name'] = args.share_service_name self._validate_required_options( - args.os_tenant_name, args.os_tenant_id, - args.os_project_name, args.os_project_id, - args.os_token, args.bypass_url, - client_args['auth_url']) + args.os_tenant_name, + args.os_tenant_id, + args.os_project_name, + args.os_project_id, + args.os_token, + args.bypass_url, + client_args['auth_url'], + ) # This client is needed to discover the server api version. - temp_client = client.Client(manilaclient.API_MAX_VERSION, - **client_args) + temp_client = client.Client( + manilaclient.API_MAX_VERSION, **client_args + ) - self.cs, discovered_version = self._discover_client(temp_client, - os_api_version, - os_endpoint_type, - os_service_type, - client_args) + self.cs, discovered_version = self._discover_client( + temp_client, + os_api_version, + os_endpoint_type, + os_service_type, + client_args, + ) - args = self._build_subcommands_and_extensions(discovered_version, - argv, - options) + args = self._build_subcommands_and_extensions( + discovered_version, argv, options + ) profile = osprofiler_profiler and options.profile if profile: osprofiler_profiler.init(options.profile) try: - decoder_path = ( - '%s/%s' % (os.path.dirname(os.path.abspath(__file__)), - 'osc/v2/data/manila.csv') + decoder_path = '{}/{}'.format( + os.path.dirname(os.path.abspath(__file__)), + 'osc/v2/data/manila.csv', ) with open(decoder_path) as f: decoder_data = { @@ -623,16 +671,20 @@ def main(self, argv): # this is fine decoder_data = {} - deprecation_message = ("manila CLI is deprecated and will be removed " - "in the future. Use openstack CLI instead.") + deprecation_message = ( + "manila CLI is deprecated and will be removed " + "in the future. Use openstack CLI instead." + ) cmd = args.func.__name__.lstrip('do_').replace("_", "-") if decoder_data and cmd in decoder_data: - deprecation_message = " ".join([ - deprecation_message, - "The equivalent command is \" openstack", - f"{decoder_data[cmd]}", - "\"" - ]) + deprecation_message = " ".join( + [ + deprecation_message, + "The equivalent command is \" openstack", + f"{decoder_data[cmd]}", + "\"", + ] + ) print(deprecation_message, file=sys.stderr) @@ -640,24 +692,26 @@ def main(self, argv): if profile: trace_id = osprofiler_profiler.get().get_base_id() - print("Profiling trace ID: %s" % trace_id) - print("To display trace use next command:\n" - "osprofiler trace show --html %s " % trace_id) - - def _discover_client(self, - current_client, - os_api_version, - os_endpoint_type, - os_service_type, - client_args): + print(f"Profiling trace ID: {trace_id}") + print( + "To display trace use next command:\n" + f"osprofiler trace show --html {trace_id} " + ) + def _discover_client( + self, + current_client, + os_api_version, + os_endpoint_type, + os_service_type, + client_args, + ): if os_api_version == manilaclient.API_DEPRECATED_VERSION: discovered_version = manilaclient.API_DEPRECATED_VERSION os_service_type = constants.V1_SERVICE_TYPE else: discovered_version = api_versions.discover_version( - current_client, - os_api_version + current_client, os_api_version ) if not os_endpoint_type: @@ -666,15 +720,19 @@ def _discover_client(self, if not os_service_type: os_service_type = self._discover_service_type(discovered_version) - if (discovered_version != manilaclient.API_MAX_VERSION or - os_service_type != constants.V1_SERVICE_TYPE or - os_endpoint_type != DEFAULT_MANILA_ENDPOINT_TYPE): + if ( + discovered_version != manilaclient.API_MAX_VERSION + or os_service_type != constants.V1_SERVICE_TYPE + or os_endpoint_type != DEFAULT_MANILA_ENDPOINT_TYPE + ): client_args['version'] = discovered_version client_args['service_type'] = os_service_type client_args['endpoint_type'] = os_endpoint_type - return (client.Client(discovered_version, **client_args), - discovered_version) + return ( + client.Client(discovered_version, **client_args), + discovered_version, + ) else: return current_client, discovered_version @@ -688,20 +746,30 @@ def _validate_input_api_version(self, options): api_version = manilaclient.API_MAX_VERSION else: api_version = api_versions.get_api_version( - options.os_share_api_version) + options.os_share_api_version + ) return api_version - def _validate_required_options(self, tenant_name, tenant_id, - project_name, project_id, - token, service_catalog_url, auth_url): + def _validate_required_options( + self, + tenant_name, + tenant_id, + project_name, + project_id, + token, + service_catalog_url, + auth_url, + ): if token and not service_catalog_url: raise exc.CommandError( "bypass_url missing: When specifying a token the bypass_url " - "must be set via --bypass-url or env[OS_MANILA_BYPASS_URL]") + "must be set via --bypass-url or env[OS_MANILA_BYPASS_URL]" + ) if service_catalog_url and not token: raise exc.CommandError( "Token missing: When specifying a bypass_url a token must be " - "set via --os-token or env[OS_TOKEN]") + "set via --os-token or env[OS_TOKEN]" + ) if token and service_catalog_url: return @@ -721,7 +789,8 @@ def _validate_required_options(self, tenant_name, tenant_id, if not auth_url: raise exc.CommandError( "You must provide an auth url " - "via either --os-auth-url or env[OS_AUTH_URL]") + "via either --os-auth-url or env[OS_AUTH_URL]" + ) def _run_extension_hooks(self, hook_type, *args, **kwargs): """Run hooks for all registered extensions.""" @@ -745,16 +814,21 @@ def do_bash_completion(self, args): commands.remove('bash_completion') print(' '.join(commands | options)) - @cliutils.arg('command', metavar='', nargs='?', - help='Display help for ') + @cliutils.arg( + 'command', + metavar='', + nargs='?', + help='Display help for ', + ) def do_help(self, args): """Display help about this program or one of its subcommands.""" if args.command: if args.command in self.subcommands: self.subcommands[args.command].print_help() else: - raise exc.CommandError("'%s' is not a valid subcommand" % - args.command) + raise exc.CommandError( + f"'{args.command}' is not a valid subcommand" + ) else: self.parser.print_help() @@ -763,8 +837,8 @@ def do_help(self, args): class OpenStackHelpFormatter(argparse.HelpFormatter): def start_section(self, heading): # Title-case the headings - heading = '%s%s' % (heading[0].upper(), heading[1:]) - super(OpenStackHelpFormatter, self).start_section(heading) + heading = f'{heading[0].upper()}{heading[1:]}' + super().start_section(heading) def main(): @@ -775,7 +849,7 @@ def main(): sys.exit(130) except Exception as e: logger.debug(e, exc_info=1) - print("ERROR: %s" % str(e), file=sys.stderr) + print(f"ERROR: {str(e)}", file=sys.stderr) sys.exit(1) diff --git a/manilaclient/tests/functional/base.py b/manilaclient/tests/functional/base.py index 97709731..c77ee7b1 100644 --- a/manilaclient/tests/functional/base.py +++ b/manilaclient/tests/functional/base.py @@ -30,7 +30,7 @@ LOG = log.getLogger(__name__) -class handle_cleanup_exceptions(object): +class handle_cleanup_exceptions: """Handle exceptions raised with cleanup operations. Always suppress errors when lib_exc.NotFound or lib_exc.Forbidden @@ -52,7 +52,6 @@ def __exit__(self, exc_type, exc_value, exc_traceback): class BaseTestCase(base.ClientTestBase): - # Will be cleaned up after test suite run class_resources = [] @@ -60,12 +59,12 @@ class BaseTestCase(base.ClientTestBase): method_resources = [] def setUp(self): - super(BaseTestCase, self).setUp() + super().setUp() self.addCleanup(self.clear_resources) @classmethod def tearDownClass(cls): - super(BaseTestCase, cls).tearDownClass() + super().tearDownClass() cls.clear_resources(cls.class_resources) @classmethod @@ -106,41 +105,56 @@ def clear_resources(cls, resources=None): # TODO(vponomaryov): add support for other resources if res["type"] == "share_type": client.delete_share_type( - res_id, microversion=res["microversion"]) + res_id, microversion=res["microversion"] + ) client.wait_for_share_type_deletion( - res_id, microversion=res["microversion"]) + res_id, microversion=res["microversion"] + ) elif res["type"] == "share_network": client.delete_share_network( - res_id, microversion=res["microversion"]) + res_id, microversion=res["microversion"] + ) client.wait_for_share_network_deletion( - res_id, microversion=res["microversion"]) + res_id, microversion=res["microversion"] + ) elif res["type"] == "share_network_subnet": client.delete_share_network_subnet( share_network_subnet=res_id, share_network=deletion_params["share_network"], - microversion=res["microversion"]) + microversion=res["microversion"], + ) client.wait_for_share_network_subnet_deletion( share_network_subnet=res_id, share_network=deletion_params["share_network"], - microversion=res["microversion"]) + microversion=res["microversion"], + ) elif res["type"] == "share": client.delete_share( - res_id, microversion=res["microversion"]) + res_id, microversion=res["microversion"] + ) client.wait_for_share_deletion( - res_id, microversion=res["microversion"]) + res_id, microversion=res["microversion"] + ) elif res["type"] == "snapshot": client.delete_snapshot( - res_id, microversion=res["microversion"]) + res_id, microversion=res["microversion"] + ) client.wait_for_snapshot_deletion( - res_id, microversion=res["microversion"]) + res_id, microversion=res["microversion"] + ) elif res["type"] == "share_replica": client.delete_share_replica( - res_id, microversion=res["microversion"]) + res_id, microversion=res["microversion"] + ) client.wait_for_share_replica_deletion( - res_id, microversion=res["microversion"]) + res_id, microversion=res["microversion"] + ) else: - LOG.warning("Provided unsupported resource type for " - "cleanup '%s'. Skipping.", res["type"]) + LOG.warning( + "Provided unsupported resource type for " + "cleanup '%s'. Skipping.", + res["type"], + ) res["deleted"] = True @classmethod @@ -155,7 +169,8 @@ def get_admin_client(cls): user_domain_id=CONF.admin_user_domain_id or None, uri=CONF.admin_auth_url or CONF.auth_url, insecure=CONF.insecure, - cli_dir=CONF.manila_exec_dir) + cli_dir=CONF.manila_exec_dir, + ) # Set specific for admin project share network manilaclient.share_network = CONF.admin_share_network return manilaclient @@ -172,7 +187,8 @@ def get_user_client(cls): user_domain_id=CONF.user_domain_id or None, uri=CONF.auth_url, insecure=CONF.insecure, - cli_dir=CONF.manila_exec_dir) + cli_dir=CONF.manila_exec_dir, + ) # Set specific for user project share network manilaclient.share_network = CONF.share_network return manilaclient @@ -195,16 +211,25 @@ def _get_clients(self): def skip_if_microversion_not_supported(self, microversion): if not utils.is_microversion_supported(microversion): raise self.skipException( - "Microversion '%s' is not supported." % microversion) + f"Microversion '{microversion}' is not supported." + ) @classmethod - def create_share_type(cls, name=None, driver_handles_share_servers=True, - snapshot_support=None, - create_share_from_snapshot=None, - revert_to_snapshot=None, mount_snapshot=None, - is_public=True, client=None, cleanup_in_class=False, - microversion=None, extra_specs=None, - description=None): + def create_share_type( + cls, + name=None, + driver_handles_share_servers=True, + snapshot_support=None, + create_share_from_snapshot=None, + revert_to_snapshot=None, + mount_snapshot=None, + is_public=True, + client=None, + cleanup_in_class=False, + microversion=None, + extra_specs=None, + description=None, + ): if client is None: client = cls.get_admin_client() data = { @@ -234,9 +259,15 @@ def create_share_type(cls, name=None, driver_handles_share_servers=True, return share_type @classmethod - def update_share_type(cls, share_type_id, name=None, - is_public=None, client=None, - microversion=None, description=None): + def update_share_type( + cls, + share_type_id, + name=None, + is_public=None, + client=None, + microversion=None, + description=None, + ): if client is None: client = cls.get_admin_client() data = { @@ -253,11 +284,17 @@ def update_share_type(cls, share_type_id, name=None, return share_type @classmethod - def create_share_network(cls, name=None, description=None, - neutron_net_id=None, - neutron_subnet_id=None, - availability_zone=None, client=None, - cleanup_in_class=False, microversion=None): + def create_share_network( + cls, + name=None, + description=None, + neutron_net_id=None, + neutron_subnet_id=None, + availability_zone=None, + client=None, + cleanup_in_class=False, + microversion=None, + ): if client is None: client = cls.get_admin_client() share_network = client.create_share_network( @@ -281,15 +318,21 @@ def create_share_network(cls, name=None, description=None, return share_network @classmethod - def add_share_network_subnet(cls, share_network, - neutron_net_id=None, neutron_subnet_id=None, - availability_zone=None, client=None, - cleanup_in_class=False, microversion=None): + def add_share_network_subnet( + cls, + share_network, + neutron_net_id=None, + neutron_subnet_id=None, + availability_zone=None, + client=None, + cleanup_in_class=False, + microversion=None, + ): if client is None: client = cls.get_admin_client() share_network_subnet = client.add_share_network_subnet( - share_network, neutron_net_id, neutron_subnet_id, - availability_zone) + share_network, neutron_net_id, neutron_subnet_id, availability_zone + ) resource = { "type": "share_network_subnet", "id": share_network_subnet["id"], @@ -306,12 +349,23 @@ def add_share_network_subnet(cls, share_network, return share_network_subnet @classmethod - def create_share(cls, share_protocol=None, size=None, share_network=None, - share_type=None, name=None, description=None, - public=False, snapshot=None, metadata=None, - client=None, use_wait_option=False, - cleanup_in_class=False, wait_for_creation=True, - microversion=None): + def create_share( + cls, + share_protocol=None, + size=None, + share_network=None, + share_type=None, + name=None, + description=None, + public=False, + snapshot=None, + metadata=None, + client=None, + use_wait_option=False, + cleanup_in_class=False, + wait_for_creation=True, + microversion=None, + ): client = client or cls.get_admin_client() data = { 'share_protocol': share_protocol or client.share_protocol, @@ -327,7 +381,8 @@ def create_share(cls, share_protocol=None, size=None, share_network=None, share_type = share_type or CONF.share_type share_network = share_network or cls._determine_share_network_to_use( - client, share_type, microversion=microversion) + client, share_type, microversion=microversion + ) data['share_type'] = share_type data['share_network'] = share_network @@ -343,41 +398,53 @@ def create_share(cls, share_protocol=None, size=None, share_network=None, else: cls.method_resources.insert(0, resource) if wait_for_creation and not use_wait_option: - client.wait_for_resource_status(share['id'], - constants.STATUS_AVAILABLE) + client.wait_for_resource_status( + share['id'], constants.STATUS_AVAILABLE + ) return share @classmethod - def delete_share(cls, shares_to_delete, share_group_id=None, - wait=False, client=None, microversion=None): + def delete_share( + cls, + shares_to_delete, + share_group_id=None, + wait=False, + client=None, + microversion=None, + ): client = client or cls.get_admin_client() - client.delete_share(shares_to_delete, share_group_id=share_group_id, - wait=wait, microversion=microversion) + client.delete_share( + shares_to_delete, + share_group_id=share_group_id, + wait=wait, + microversion=microversion, + ) @classmethod - def soft_delete_share(cls, shares_to_soft_delete, - client=None, microversion=None): + def soft_delete_share( + cls, shares_to_soft_delete, client=None, microversion=None + ): client = client or cls.get_admin_client() - client.soft_delete_share(shares_to_soft_delete, - microversion=microversion) + client.soft_delete_share( + shares_to_soft_delete, microversion=microversion + ) @classmethod - def restore_share(cls, shares_to_restore, - client=None, microversion=None): + def restore_share(cls, shares_to_restore, client=None, microversion=None): client = client or cls.get_admin_client() - client.restore_share(shares_to_restore, - microversion=microversion) + client.restore_share(shares_to_restore, microversion=microversion) @classmethod - def create_share_transfer(cls, share_id, name=None, - client=None, microversion=None): + def create_share_transfer( + cls, share_id, name=None, client=None, microversion=None + ): client = client or cls.get_admin_client() - return client.create_share_transfer(share_id, name=name, - microversion=microversion) + return client.create_share_transfer( + share_id, name=name, microversion=microversion + ) @classmethod - def delete_share_transfer(cls, transfer, client=None, - microversion=None): + def delete_share_transfer(cls, transfer, client=None, microversion=None): client = client or cls.get_admin_client() client.delete_share_transfer(transfer, microversion=microversion) @@ -392,30 +459,45 @@ def list_share_transfer(cls, client=None, microversion=None): return client.list_share_transfer(microversion=microversion) @classmethod - def accept_share_transfer(cls, transfer, auth_key, - client=None, microversion=None): + def accept_share_transfer( + cls, transfer, auth_key, client=None, microversion=None + ): client = client or cls.get_admin_client() - client.accept_share_transfer(transfer, auth_key, - microversion=microversion) + client.accept_share_transfer( + transfer, auth_key, microversion=microversion + ) @classmethod - def _determine_share_network_to_use(cls, client, share_type, - microversion=None): + def _determine_share_network_to_use( + cls, client, share_type, microversion=None + ): """Determine what share network we need from the share type.""" # Get share type, determine if we need the share network - share_type = client.get_share_type(share_type, - microversion=microversion) + share_type = client.get_share_type( + share_type, microversion=microversion + ) dhss_pattern = re.compile('driver_handles_share_servers : ([a-zA-Z]+)') dhss = dhss_pattern.search(share_type['required_extra_specs']).group(1) return client.share_network if dhss.lower() == 'true' else None @classmethod - def create_security_service(cls, type='ldap', name=None, description=None, - dns_ip=None, ou=None, server=None, domain=None, - user=None, password=None, default_ad_site=None, - client=None, cleanup_in_class=False, - microversion=None): + def create_security_service( + cls, + type='ldap', + name=None, + description=None, + dns_ip=None, + ou=None, + server=None, + domain=None, + user=None, + password=None, + default_ad_site=None, + client=None, + cleanup_in_class=False, + microversion=None, + ): if client is None: client = cls.get_admin_client() data = { @@ -445,9 +527,17 @@ def create_security_service(cls, type='ldap', name=None, description=None, return ss @classmethod - def create_snapshot(cls, share, name=None, description=None, - force=False, client=None, wait_for_creation=True, - cleanup_in_class=False, microversion=None): + def create_snapshot( + cls, + share, + name=None, + description=None, + force=False, + client=None, + wait_for_creation=True, + cleanup_in_class=False, + microversion=None, + ): if client is None: client = cls.get_admin_client() data = { @@ -473,8 +563,13 @@ def create_snapshot(cls, share, name=None, description=None, return snapshot @classmethod - def create_message(cls, client=None, wait_for_creation=True, - cleanup_in_class=False, microversion=None): + def create_message( + cls, + client=None, + wait_for_creation=True, + cleanup_in_class=False, + microversion=None, + ): """Trigger a 'no valid host' situation to generate a message.""" if client is None: client = cls.get_admin_client() @@ -484,15 +579,23 @@ def create_message(cls, client=None, wait_for_creation=True, } share_type_name = data_utils.rand_name("share-type") cls.create_share_type( - name=share_type_name, extra_specs=extra_specs, - driver_handles_share_servers=False, client=client, - cleanup_in_class=cleanup_in_class, microversion=microversion) + name=share_type_name, + extra_specs=extra_specs, + driver_handles_share_servers=False, + client=client, + cleanup_in_class=cleanup_in_class, + microversion=microversion, + ) share_name = data_utils.rand_name("share") share = cls.create_share( - name=share_name, share_type=share_type_name, - cleanup_in_class=cleanup_in_class, microversion=microversion, - wait_for_creation=False, client=client) + name=share_name, + share_type=share_type_name, + cleanup_in_class=cleanup_in_class, + microversion=microversion, + wait_for_creation=False, + client=client, + ) client.wait_for_resource_status(share['id'], constants.STATUS_ERROR) message = client.wait_for_message(share['id']) @@ -510,20 +613,28 @@ def create_message(cls, client=None, wait_for_creation=True, return message @classmethod - def create_share_replica(cls, share_id, client=None, - wait_for_creation=True, cleanup_in_class=False, - availability_zone=None, share_network=None, - microversion=None): + def create_share_replica( + cls, + share_id, + client=None, + wait_for_creation=True, + cleanup_in_class=False, + availability_zone=None, + share_network=None, + microversion=None, + ): client = client or cls.get_user_client() share_replica = client.create_share_replica( share_id, availability_zone=availability_zone, share_network=share_network, - microversion=microversion) + microversion=microversion, + ) if wait_for_creation: share_replica = client.wait_for_share_replica_status( - share_replica['id']) + share_replica['id'] + ) resource = { "type": "share_replica", diff --git a/manilaclient/tests/functional/client.py b/manilaclient/tests/functional/client.py index 7a3f0bfe..c0324365 100644 --- a/manilaclient/tests/functional/client.py +++ b/manilaclient/tests/functional/client.py @@ -41,13 +41,14 @@ def not_found_wrapper(f): - def wrapped_func(self, *args, **kwargs): try: return f(self, *args, **kwargs) except tempest_lib_exc.CommandFailed as e: - for regexp in (r'No (\w+) with a name or ID', - r'not(.*){0,5}found'): + for regexp in ( + r'No (\w+) with a name or ID', + r'not(.*){0,5}found', + ): if re.search(regexp, str(e.stderr)): # Raise appropriate 'NotFound' error raise tempest_lib_exc.NotFound() @@ -57,7 +58,6 @@ def wrapped_func(self, *args, **kwargs): def forbidden_wrapper(f): - def wrapped_func(self, *args, **kwargs): try: return f(self, *args, **kwargs) @@ -71,9 +71,8 @@ def wrapped_func(self, *args, **kwargs): class ManilaCLIClient(base.CLIClient): - def __init__(self, *args, **kwargs): - super(ManilaCLIClient, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) if CONF.enable_protocols: self.share_protocol = CONF.enable_protocols[0] else: @@ -82,9 +81,16 @@ def __init__(self, *args, **kwargs): self.build_interval = CONF.build_interval self.build_timeout = CONF.build_timeout - def manila(self, action, flags='', params='', fail_ok=False, - endpoint_type='publicURL', merge_stderr=False, - microversion=None): + def manila( + self, + action, + flags='', + params='', + fail_ok=False, + endpoint_type='publicURL', + merge_stderr=False, + microversion=None, + ): """Executes manila command for the given action. :param action: the cli command to run using manila @@ -104,7 +110,7 @@ def manila(self, action, flags='', params='', fail_ok=False, :param microversion: API microversion to be used for request :type microversion: str """ - flags += ' --endpoint-type %s' % endpoint_type + flags += f' --endpoint-type {endpoint_type}' if not microversion: # NOTE(vponomaryov): use max API version from config microversion = CONF.max_api_microversion @@ -113,12 +119,20 @@ def manila(self, action, flags='', params='', fail_ok=False, # can contain '--os-share-api-version' key. If it is so and we # reached this part then value of 'microversion' param will be # used and existing one in 'flags' param will be ignored. - flags += ' --os-share-api-version %s' % microversion + flags += f' --os-share-api-version {microversion}' return self.cmd_with_auth( - 'manila', action, flags, params, fail_ok, merge_stderr) + 'manila', action, flags, params, fail_ok, merge_stderr + ) - def wait_for_resource_deletion(self, res_type, res_id, interval=3, - timeout=180, microversion=None, **kwargs): + def wait_for_resource_deletion( + self, + res_type, + res_id, + interval=3, + timeout=180, + microversion=None, + **kwargs, + ): """Resource deletion waiter. :param res_type: text -- type of resource @@ -157,7 +171,8 @@ def wait_for_resource_deletion(self, res_type, res_id, interval=3, if not deleted: raise exceptions.ResourceReleaseFailed( - res_type=res_type, res_id=res_id) + res_type=res_type, res_id=res_id + ) def list_availability_zones(self, columns=None, microversion=None): """List availability zones. @@ -175,12 +190,19 @@ def list_availability_zones(self, columns=None, microversion=None): # Share types - def create_share_type(self, name=None, driver_handles_share_servers=True, - snapshot_support=None, - create_share_from_snapshot=None, - revert_to_snapshot=None, mount_snapshot=None, - is_public=True, microversion=None, extra_specs=None, - description=None): + def create_share_type( + self, + name=None, + driver_handles_share_servers=True, + snapshot_support=None, + create_share_from_snapshot=None, + revert_to_snapshot=None, + mount_snapshot=None, + is_public=True, + microversion=None, + extra_specs=None, + description=None, + ): """Creates share type. :param name: text -- name of share type to use, if not set then @@ -208,8 +230,7 @@ def create_share_type(self, name=None, driver_handles_share_servers=True, if not isinstance(is_public, str): is_public = str(is_public) - cmd = ('type-create %(name)s %(dhss)s --is-public %(is_public)s ') % { - 'name': name, 'dhss': dhss, 'is_public': is_public} + cmd = f'type-create {name} {dhss} --is-public {is_public} ' if description is not None: cmd += " --description " + description @@ -222,34 +243,41 @@ def create_share_type(self, name=None, driver_handles_share_servers=True, if create_share_from_snapshot is not None: if not isinstance(create_share_from_snapshot, str): create_share_from_snapshot = str(create_share_from_snapshot) - cmd += (" --create-share-from-snapshot-support " + - create_share_from_snapshot) + cmd += ( + " --create-share-from-snapshot-support " + + create_share_from_snapshot + ) if revert_to_snapshot is not None: if not isinstance(revert_to_snapshot, str): revert_to_snapshot = str(revert_to_snapshot) - cmd += (" --revert-to-snapshot-support " + revert_to_snapshot) + cmd += " --revert-to-snapshot-support " + revert_to_snapshot if mount_snapshot is not None: if not isinstance(mount_snapshot, str): mount_snapshot = str(mount_snapshot) - cmd += (" --mount-snapshot-support " + mount_snapshot) + cmd += " --mount-snapshot-support " + mount_snapshot if extra_specs is not None: extra_spec_str = '' for k, v in extra_specs.items(): if not isinstance(v, str): extra_specs[k] = str(v) - extra_spec_str += "{}='{}' ".format(k, v) + extra_spec_str += f"{k}='{v}' " cmd += " --extra_specs " + extra_spec_str share_type_raw = self.manila(cmd, microversion=microversion) share_type = utils.details(share_type_raw) return share_type - def update_share_type(self, share_type_id, name=None, - is_public=None, microversion=None, - description=None): + def update_share_type( + self, + share_type_id, + name=None, + is_public=None, + microversion=None, + description=None, + ): """Update share type. :param share_type_id: text -- id of share type. @@ -262,8 +290,7 @@ def update_share_type(self, share_type_id, name=None, type will be available to all tenants in the cloud. """ - cmd = ('type-update %(share_type_id)s ') % { - 'share_type_id': share_type_id} + cmd = f'type-update {share_type_id} ' if is_public is not None: if not isinstance(is_public, str): @@ -286,10 +313,12 @@ def update_share_type(self, share_type_id, name=None, def delete_share_type(self, share_type, microversion=None): """Deletes share type by its Name or ID.""" return self.manila( - 'type-delete %s' % share_type, microversion=microversion) + f'type-delete {share_type}', microversion=microversion + ) - def list_share_types(self, list_all=True, columns=None, search_opts=None, - microversion=None): + def list_share_types( + self, list_all=True, columns=None, search_opts=None, microversion=None + ): """List share types. :param list_all: bool -- whether to list all share types or only public @@ -334,7 +363,8 @@ def is_share_type_deleted(self, share_type, microversion=None): # NOTE(vponomaryov): we use 'list' operation because there is no # 'get/show' operation for share-types available for CLI share_types = self.list_share_types( - list_all=True, microversion=microversion) + list_all=True, microversion=microversion + ) for list_element in share_types: if share_type in (list_element['ID'], list_element['Name']): return False @@ -346,105 +376,117 @@ def wait_for_share_type_deletion(self, share_type, microversion=None): :param share_type: text -- Name or ID of share type """ self.wait_for_resource_deletion( - SHARE_TYPE, res_id=share_type, interval=2, timeout=6, - microversion=microversion) + SHARE_TYPE, + res_id=share_type, + interval=2, + timeout=6, + microversion=microversion, + ) def get_project_id(self, name_or_id): identity_api_version = '3' flags = ( - "--os-username %(username)s " - "--os-project-name %(project_name)s " - "--os-password %(password)s " - "--os-identity-api-version %(identity_api_version)s " - ) % { - "username": CONF.admin_username, - "project_name": CONF.admin_tenant_name, - "password": CONF.admin_password, - "identity_api_version": identity_api_version, - } + f"--os-username {CONF.admin_username} " + f"--os-project-name {CONF.admin_tenant_name} " + f"--os-password {CONF.admin_password} " + f"--os-identity-api-version {identity_api_version} " + ) if identity_api_version == "3": if CONF.admin_project_domain_name: - flags += ( - "--os-project-domain-name %s " % - CONF.admin_project_domain_name) + flags += f"--os-project-domain-name {CONF.admin_project_domain_name} " elif CONF.admin_project_domain_id: flags += ( - "--os-project-domain-id %s " % - CONF.admin_project_domain_id) + f"--os-project-domain-id {CONF.admin_project_domain_id} " + ) if CONF.admin_user_domain_name: flags += ( - "--os-user-domain-name %s " % - CONF.admin_user_domain_name) + f"--os-user-domain-name {CONF.admin_user_domain_name} " + ) elif CONF.admin_user_domain_id: - flags += ( - "--os-user-domain-id %s " % - CONF.admin_user_domain_id) + flags += f"--os-user-domain-id {CONF.admin_user_domain_id} " project_id = self.openstack( - 'project show -f value -c id %s' % name_or_id, flags=flags) + f'project show -f value -c id {name_or_id}', flags=flags + ) return project_id.strip() @not_found_wrapper - def add_share_type_access(self, share_type_name_or_id, project_id, - microversion=None): + def add_share_type_access( + self, share_type_name_or_id, project_id, microversion=None + ): data = dict(st=share_type_name_or_id, project=project_id) - self.manila('type-access-add %(st)s %(project)s' % data, - microversion=microversion) + self.manila( + 'type-access-add {st} {project}'.format(**data), + microversion=microversion, + ) @not_found_wrapper - def remove_share_type_access(self, share_type_name_or_id, project_id, - microversion=None): + def remove_share_type_access( + self, share_type_name_or_id, project_id, microversion=None + ): data = dict(st=share_type_name_or_id, project=project_id) - self.manila('type-access-remove %(st)s %(project)s' % data, - microversion=microversion) + self.manila( + 'type-access-remove {st} {project}'.format(**data), + microversion=microversion, + ) @not_found_wrapper def list_share_type_access(self, share_type_id, microversion=None): projects_raw = self.manila( - 'type-access-list %s' % share_type_id, microversion=microversion) + f'type-access-list {share_type_id}', microversion=microversion + ) projects = output_parser.listing(projects_raw) project_ids = [pr['Project_ID'] for pr in projects] return project_ids @not_found_wrapper - def set_share_type_extra_specs(self, share_type_name_or_id, extra_specs, - microversion=None): + def set_share_type_extra_specs( + self, share_type_name_or_id, extra_specs, microversion=None + ): """Set key-value pair for share type.""" if not (isinstance(extra_specs, dict) and extra_specs): raise exceptions.InvalidData( - message='Provided invalid extra specs - %s' % extra_specs) - cmd = 'type-key %s set ' % share_type_name_or_id + message=f'Provided invalid extra specs - {extra_specs}' + ) + cmd = f'type-key {share_type_name_or_id} set ' for key, value in extra_specs.items(): - cmd += '%(key)s=%(value)s ' % {'key': key, 'value': value} + cmd += f'{key}={value} ' return self.manila(cmd, microversion=microversion) @not_found_wrapper - def unset_share_type_extra_specs(self, share_type_name_or_id, - extra_specs_keys, microversion=None): + def unset_share_type_extra_specs( + self, share_type_name_or_id, extra_specs_keys, microversion=None + ): """Unset key-value pair for share type.""" - if not (isinstance(extra_specs_keys, (list, tuple, set)) and - extra_specs_keys): + if not ( + isinstance(extra_specs_keys, (list, tuple, set)) + and extra_specs_keys + ): raise exceptions.InvalidData( - message='Provided invalid extra specs - %s' % extra_specs_keys) - cmd = 'type-key %s unset ' % share_type_name_or_id + message=f'Provided invalid extra specs - {extra_specs_keys}' + ) + cmd = f'type-key {share_type_name_or_id} unset ' for key in extra_specs_keys: - cmd += '%s ' % key + cmd += f'{key} ' return self.manila(cmd, microversion=microversion) def list_all_share_type_extra_specs(self, microversion=None): """List extra specs for all share types.""" extra_specs_raw = self.manila( - 'extra-specs-list', microversion=microversion) + 'extra-specs-list', microversion=microversion + ) extra_specs = utils.listing(extra_specs_raw) return extra_specs - def list_share_type_extra_specs(self, share_type_name_or_id, - microversion=None): + def list_share_type_extra_specs( + self, share_type_name_or_id, microversion=None + ): """List extra specs for specific share type by its Name or ID.""" all_share_types = self.list_all_share_type_extra_specs( - microversion=microversion) + microversion=microversion + ) for share_type in all_share_types: if share_type_name_or_id in (share_type['ID'], share_type['Name']): return share_type['all_extra_specs'] @@ -452,10 +494,15 @@ def list_share_type_extra_specs(self, share_type_name_or_id, # Share networks - def create_share_network(self, name=None, description=None, - neutron_net_id=None, neutron_subnet_id=None, - availability_zone=None, - microversion=None): + def create_share_network( + self, + name=None, + description=None, + neutron_net_id=None, + neutron_subnet_id=None, + availability_zone=None, + microversion=None, + ): """Creates share network. :param name: text -- desired name of new share network @@ -468,17 +515,22 @@ def create_share_network(self, name=None, description=None, description=description, neutron_net_id=neutron_net_id, neutron_subnet_id=neutron_subnet_id, - availability_zone=availability_zone + availability_zone=availability_zone, ) share_network_raw = self.manila( - 'share-network-create %s' % params, microversion=microversion) + f'share-network-create {params}', microversion=microversion + ) share_network = output_parser.details(share_network_raw) return share_network - def _combine_share_network_data(self, name=None, description=None, - neutron_net_id=None, - neutron_subnet_id=None, - availability_zone=None): + def _combine_share_network_data( + self, + name=None, + description=None, + neutron_net_id=None, + neutron_subnet_id=None, + availability_zone=None, + ): """Combines params for share network operations 'create' and 'update'. :returns: text -- set of CLI parameters @@ -496,21 +548,28 @@ def _combine_share_network_data(self, name=None, description=None, data['--availability_zone'] = availability_zone cmd = '' for key, value in data.items(): - cmd += "%(k)s=%(v)s " % {'k': key, 'v': value} + cmd += f"{key}={value} " return cmd @not_found_wrapper def get_share_network(self, share_network, microversion=None): """Returns share network by its Name or ID.""" share_network_raw = self.manila( - 'share-network-show %s' % share_network, microversion=microversion) + f'share-network-show {share_network}', microversion=microversion + ) share_network = output_parser.details(share_network_raw) return share_network @not_found_wrapper - def update_share_network(self, share_network, name=None, description=None, - neutron_net_id=None, - neutron_subnet_id=None, microversion=None): + def update_share_network( + self, + share_network, + name=None, + description=None, + neutron_net_id=None, + neutron_subnet_id=None, + microversion=None, + ): """Updates share-network by its name or ID. :param name: text -- new name for share network @@ -522,31 +581,37 @@ def update_share_network(self, share_network, name=None, description=None, name=name, description=description, neutron_net_id=neutron_net_id, - neutron_subnet_id=neutron_subnet_id) + neutron_subnet_id=neutron_subnet_id, + ) share_network_raw = self.manila( - 'share-network-update %(sn)s %(params)s' % dict( - sn=share_network, params=sn_params), - microversion=microversion) + 'share-network-update {sn} {params}'.format( + **dict(sn=share_network, params=sn_params) + ), + microversion=microversion, + ) share_network = output_parser.details(share_network_raw) return share_network @not_found_wrapper def delete_share_network(self, share_network, microversion=None): """Deletes share network by its Name or ID.""" - return self.manila('share-network-delete %s' % share_network, - microversion=microversion) + return self.manila( + f'share-network-delete {share_network}', microversion=microversion + ) @staticmethod def _stranslate_to_cli_optional_param(param): if len(param) < 1 or not isinstance(param, str): raise exceptions.InvalidData( - 'Provided wrong parameter for translation.') + 'Provided wrong parameter for translation.' + ) while not param[0:2] == '--': param = '-' + param return param.replace('_', '-') - def list_share_networks(self, all_tenants=False, filters=None, - columns=None, microversion=None): + def list_share_networks( + self, all_tenants=False, filters=None, columns=None, microversion=None + ): """List share networks. :param all_tenants: bool -- whether to list share-networks that belong @@ -568,73 +633,86 @@ def list_share_networks(self, all_tenants=False, filters=None, cmd += ' --all-tenants ' if filters and isinstance(filters, dict): for k, v in filters.items(): - cmd += '%(k)s=%(v)s ' % { - 'k': self._stranslate_to_cli_optional_param(k), 'v': v} + cmd += f'{self._stranslate_to_cli_optional_param(k)}={v} ' share_networks_raw = self.manila(cmd, microversion=microversion) share_networks = utils.listing(share_networks_raw) return share_networks - def share_network_reset_state(self, id=None, state=None, - microversion=None): - cmd = 'share-network-reset-state %s ' % id + def share_network_reset_state( + self, id=None, state=None, microversion=None + ): + cmd = f'share-network-reset-state {id} ' if state: - cmd += '--state %s' % state + cmd += f'--state {state}' share_network_raw = self.manila(cmd, microversion=microversion) share_network = utils.listing(share_network_raw) return share_network def share_network_security_service_add( - self, share_network_id, security_service_id, microversion=None): - cmd = ('share-network-security-service-add %(network_id)s ' - '%(service_id)s' % {'network_id': share_network_id, - 'service_id': security_service_id}) + self, share_network_id, security_service_id, microversion=None + ): + cmd = ( + f'share-network-security-service-add {share_network_id} ' + f'{security_service_id}' + ) self.manila(cmd, microversion=microversion) def share_network_security_service_update( - self, share_network_id, current_security_service_id, - new_security_service_id, microversion=None): + self, + share_network_id, + current_security_service_id, + new_security_service_id, + microversion=None, + ): cmd = ( - 'share-network-security-service-update %(network_id)s ' - '%(current_service_id)s %(new_security_service_id)s' % { - 'network_id': share_network_id, - 'current_service_id': current_security_service_id, - 'new_security_service_id': new_security_service_id}) + f'share-network-security-service-update {share_network_id} ' + f'{current_security_service_id} {new_security_service_id}' + ) self.manila(cmd, microversion=microversion) def share_network_security_service_add_check( - self, share_network_id, security_service_id, - reset=False, microversion=None): + self, + share_network_id, + security_service_id, + reset=False, + microversion=None, + ): cmd = ( - 'share-network-security-service-add-check %(network_id)s ' - '%(security_service_id)s' % { - 'network_id': share_network_id, - 'security_service_id': security_service_id}) + f'share-network-security-service-add-check {share_network_id} ' + f'{security_service_id}' + ) if reset: - cmd += '--reset %s' % reset + cmd += f'--reset {reset}' return output_parser.details( - self.manila(cmd, microversion=microversion)) + self.manila(cmd, microversion=microversion) + ) def share_network_security_service_update_check( - self, share_network_id, current_security_service_id, - new_security_service_id, reset=False, microversion=None): + self, + share_network_id, + current_security_service_id, + new_security_service_id, + reset=False, + microversion=None, + ): cmd = ( - 'share-network-security-service-update-check %(network_id)s ' - '%(current_security_service_id)s %(new_security_service_id)s ' % { - 'network_id': share_network_id, - 'current_security_service_id': current_security_service_id, - 'new_security_service_id': new_security_service_id}) + f'share-network-security-service-update-check {share_network_id} ' + f'{current_security_service_id} {new_security_service_id} ' + ) if reset: - cmd += '--reset %s' % reset + cmd += f'--reset {reset}' return output_parser.details( - self.manila(cmd, microversion=microversion)) + self.manila(cmd, microversion=microversion) + ) def share_network_security_service_list( - self, share_network_id, microversion=None): - cmd = ('share-network-security-service-list %s' % share_network_id) + self, share_network_id, microversion=None + ): + cmd = f'share-network-security-service-list {share_network_id}' share_networks_raw = self.manila(cmd, microversion=microversion) network_services = utils.listing(share_networks_raw) return network_services @@ -650,41 +728,52 @@ def is_share_network_deleted(self, share_network, microversion=None): return False return True - def wait_for_share_network_deletion(self, share_network, - microversion=None): + def wait_for_share_network_deletion( + self, share_network, microversion=None + ): """Wait for share network deletion by its Name or ID. :param share_network: text -- Name or ID of share network """ self.wait_for_resource_deletion( - SHARE_NETWORK, res_id=share_network, interval=2, timeout=6, - microversion=microversion) + SHARE_NETWORK, + res_id=share_network, + interval=2, + timeout=6, + microversion=microversion, + ) def share_network_subnet_create_check( - self, share_network_id, neutron_net_id=None, - neutron_subnet_id=None, availability_zone=None, reset=False, - microversion=None): + self, + share_network_id, + neutron_net_id=None, + neutron_subnet_id=None, + availability_zone=None, + reset=False, + microversion=None, + ): params = self._combine_share_network_subnet_data( neutron_net_id=neutron_net_id, neutron_subnet_id=neutron_subnet_id, - availability_zone=availability_zone) - cmd = ( - 'share-network-subnet-create-check %(network_id)s ' - '%(params)s' % { - 'network_id': share_network_id, - 'params': params}) + availability_zone=availability_zone, + ) + cmd = f'share-network-subnet-create-check {share_network_id} {params}' if reset: - cmd += '--reset %s' % reset + cmd += f'--reset {reset}' return output_parser.details( - self.manila(cmd, microversion=microversion)) + self.manila(cmd, microversion=microversion) + ) # Share Network Subnets - def _combine_share_network_subnet_data(self, neutron_net_id=None, - neutron_subnet_id=None, - availability_zone=None): + def _combine_share_network_subnet_data( + self, + neutron_net_id=None, + neutron_subnet_id=None, + availability_zone=None, + ): """Combines params for share network subnet 'create' operation. :returns: text -- set of CLI parameters @@ -698,38 +787,45 @@ def _combine_share_network_subnet_data(self, neutron_net_id=None, data['--availability_zone'] = availability_zone cmd = '' for key, value in data.items(): - cmd += "%(k)s=%(v)s " % dict(k=key, v=value) + cmd += "{k}={v} ".format(**dict(k=key, v=value)) return cmd - def add_share_network_subnet(self, share_network, - neutron_net_id=None, neutron_subnet_id=None, - availability_zone=None, microversion=None): + def add_share_network_subnet( + self, + share_network, + neutron_net_id=None, + neutron_subnet_id=None, + availability_zone=None, + microversion=None, + ): """Create new share network subnet for the given share network.""" params = self._combine_share_network_subnet_data( neutron_net_id=neutron_net_id, neutron_subnet_id=neutron_subnet_id, - availability_zone=availability_zone) + availability_zone=availability_zone, + ) share_network_subnet_raw = self.manila( - 'share-network-subnet-create %(sn)s %(params)s' % - {'sn': share_network, 'params': params}, microversion=microversion) + f'share-network-subnet-create {share_network} {params}', + microversion=microversion, + ) share_network_subnet = output_parser.details(share_network_subnet_raw) return share_network_subnet - def get_share_network_subnet(self, share_network, share_network_subnet, - microversion=None): + def get_share_network_subnet( + self, share_network, share_network_subnet, microversion=None + ): """Returns share network subnet by share network ID and subnet ID.""" share_network_subnet_raw = self.manila( - 'share-network-subnet-show %(share_net)s %(share_subnet)s' % { - 'share_net': share_network, - 'share_subnet': share_network_subnet, - }) + f'share-network-subnet-show {share_network} {share_network_subnet}' + ) share_network_subnet = output_parser.details(share_network_subnet_raw) return share_network_subnet def get_share_network_subnets(self, share_network, microversion=None): - share_network = self.get_share_network(share_network, - microversion=microversion) + share_network = self.get_share_network( + share_network, microversion=microversion + ) raw_subnets = share_network.get('share_network_subnets') subnets = ast.literal_eval(raw_subnets) # NOTE(lseki): convert literal None to string 'None' @@ -739,17 +835,18 @@ def get_share_network_subnets(self, share_network, microversion=None): return subnets @not_found_wrapper - def delete_share_network_subnet(self, share_network, share_network_subnet, - microversion=None): + def delete_share_network_subnet( + self, share_network, share_network_subnet, microversion=None + ): """Delete a share_network.""" self.manila( - 'share-network-subnet-delete %(share_net)s %(share_subnet)s' % { - 'share_net': share_network, - 'share_subnet': share_network_subnet, - }, microversion=microversion) + f'share-network-subnet-delete {share_network} {share_network_subnet}', + microversion=microversion, + ) - def is_share_network_subnet_deleted(self, share_network_subnet, - share_network, microversion=None): + def is_share_network_subnet_deleted( + self, share_network_subnet, share_network, microversion=None + ): # NOTE(lseki): the parameter share_network_subnet comes before # share_network, because the wrapper method wait_for_resource_deletion # expects the resource id in first place (subnet ID in this case). @@ -760,12 +857,13 @@ def is_share_network_subnet_deleted(self, share_network_subnet, belongs to """ subnets = self.get_share_network_subnets(share_network) - return not any(subnet['id'] == share_network_subnet - for subnet in subnets) + return not any( + subnet['id'] == share_network_subnet for subnet in subnets + ) - def wait_for_share_network_subnet_deletion(self, share_network_subnet, - share_network, - microversion=None): + def wait_for_share_network_subnet_deletion( + self, share_network_subnet, share_network, microversion=None + ): # NOTE(lseki): the parameter share_network_subnet comes before # share_network, because the wrapper method wait_for_resource_deletion # expects the resource id in first place (subnet ID in this case). @@ -777,15 +875,30 @@ def wait_for_share_network_subnet_deletion(self, share_network_subnet, """ args = {'share_network': share_network} self.wait_for_resource_deletion( - SHARE_NETWORK_SUBNET, res_id=share_network_subnet, - interval=2, timeout=6, microversion=microversion, **args) + SHARE_NETWORK_SUBNET, + res_id=share_network_subnet, + interval=2, + timeout=6, + microversion=microversion, + **args, + ) # Shares - def create_share(self, share_protocol, size, share_network=None, - share_type=None, name=None, description=None, - public=False, snapshot=None, metadata=None, wait=False, - microversion=None): + def create_share( + self, + share_protocol, + size, + share_network=None, + share_type=None, + name=None, + description=None, + public=False, + snapshot=None, + metadata=None, + wait=False, + microversion=None, + ): """Creates a share. :param share_protocol: str -- share protocol of a share. @@ -801,28 +914,27 @@ def create_share(self, share_protocol, size, share_network=None, :param wait: bool - the client must wait for "available" state :param microversion: str -- API microversion that should be used. """ - cmd = 'create %(share_protocol)s %(size)s ' % { - 'share_protocol': share_protocol, 'size': size} + cmd = f'create {share_protocol} {size} ' if share_network is not None: - cmd += '--share-network %s ' % share_network + cmd += f'--share-network {share_network} ' if share_type is not None: - cmd += '--share-type %s ' % share_type + cmd += f'--share-type {share_type} ' if name is None: name = data_utils.rand_name('autotest_share_name') - cmd += '--name %s ' % name + cmd += f'--name {name} ' if description is None: description = data_utils.rand_name('autotest_share_description') - cmd += '--description %s ' % description + cmd += f'--description {description} ' if public: cmd += '--public ' if snapshot is not None: - cmd += '--snapshot %s ' % snapshot + cmd += f'--snapshot {snapshot} ' if metadata: metadata_cli = '' for k, v in metadata.items(): - metadata_cli += '%(k)s=%(v)s ' % {'k': k, 'v': v} + metadata_cli += f'{k}={v} ' if metadata_cli: - cmd += '--metadata %s ' % metadata_cli + cmd += f'--metadata {metadata_cli} ' if wait: cmd += '--wait ' share_raw = self.manila(cmd, microversion=microversion) @@ -832,13 +944,19 @@ def create_share(self, share_protocol, size, share_network=None, @not_found_wrapper def get_share(self, share, microversion=None): """Returns a share by its Name or ID.""" - share_raw = self.manila('show %s' % share, microversion=microversion) + share_raw = self.manila(f'show {share}', microversion=microversion) share = output_parser.details(share_raw) return share @not_found_wrapper - def update_share(self, share, name=None, description=None, - is_public=False, microversion=None): + def update_share( + self, + share, + name=None, + description=None, + is_public=False, + microversion=None, + ): """Updates a share. :param share: str -- name or ID of a share that should be updated. @@ -847,20 +965,21 @@ def update_share(self, share, name=None, description=None, :param is_public: bool -- should a share be public or not. Default is False. """ - cmd = 'update %s ' % share + cmd = f'update {share} ' if name: - cmd += '--name %s ' % name + cmd += f'--name {name} ' if description: - cmd += '--description %s ' % description + cmd += f'--description {description} ' is_public = strutils.bool_from_string(is_public, strict=True) - cmd += '--is-public %s ' % is_public + cmd += f'--is-public {is_public} ' return self.manila(cmd, microversion=microversion) @not_found_wrapper @forbidden_wrapper - def delete_share(self, shares, share_group_id=None, wait=False, - microversion=None): + def delete_share( + self, shares, share_group_id=None, wait=False, microversion=None + ): """Deletes share[s] by Names or IDs. :param shares: either str or list of str that can be either Name @@ -873,9 +992,9 @@ def delete_share(self, shares, share_group_id=None, wait=False, shares = [shares] cmd = 'delete ' for share in shares: - cmd += '%s ' % share + cmd += f'{share} ' if share_group_id: - cmd += '--share-group-id %s ' % share_group_id + cmd += f'--share-group-id {share_group_id} ' if wait: cmd += '--wait ' return self.manila(cmd, microversion=microversion) @@ -892,7 +1011,7 @@ def soft_delete_share(self, shares, microversion=None): shares = [shares] cmd = 'soft-delete ' for share in shares: - cmd += '%s ' % share + cmd += f'{share} ' return self.manila(cmd, microversion=microversion) @not_found_wrapper @@ -907,19 +1026,18 @@ def restore_share(self, shares, microversion=None): shares = [shares] cmd = 'restore ' for share in shares: - cmd += '%s ' % share + cmd += f'{share} ' return self.manila(cmd, microversion=microversion) - def create_share_transfer(self, share_id, name=None, - microversion=None): + def create_share_transfer(self, share_id, name=None, microversion=None): """Create a share transfer. :param share_id: ID of share. ":param name: name of transfer. """ - cmd = 'share-transfer-create %s ' % share_id + cmd = f'share-transfer-create {share_id} ' if name: - cmd += '--name %s' % name + cmd += f'--name {name}' transfer_raw = self.manila(cmd, microversion=microversion) transfer = output_parser.details(transfer_raw) return transfer @@ -929,7 +1047,7 @@ def delete_share_transfer(self, transfer, microversion=None): :param transfer: ID or name of share transfer. """ - cmd = 'share-transfer-delete %s ' % transfer + cmd = f'share-transfer-delete {transfer} ' self.manila(cmd, microversion=microversion) def get_share_transfer(self, transfer, microversion=None): @@ -937,7 +1055,7 @@ def get_share_transfer(self, transfer, microversion=None): :param transfer: ID or name of share transfer. """ - cmd = 'share-transfer-show %s ' % transfer + cmd = f'share-transfer-show {transfer} ' transfer_raw = self.manila(cmd, microversion=microversion) transfer = output_parser.details(transfer_raw) return transfer @@ -950,18 +1068,23 @@ def list_share_transfer(self, microversion=None): transfers = utils.listing(transfer_raw) return transfers - def accept_share_transfer(self, transfer, auth_key, - microversion=None): + def accept_share_transfer(self, transfer, auth_key, microversion=None): """Accept a share transfer. :param transfer: ID or name of share transfer. """ - cmd = 'share-transfer-accept %s %s' % (transfer, auth_key) + cmd = f'share-transfer-accept {transfer} {auth_key}' self.manila(cmd, microversion=microversion) - def list_shares(self, all_tenants=False, is_soft_deleted=False, - filters=None, columns=None, is_public=False, - microversion=None): + def list_shares( + self, + all_tenants=False, + is_soft_deleted=False, + filters=None, + columns=None, + is_public=False, + microversion=None, + ): """List shares. :param all_tenants: bool -- whether to list shares that belong @@ -990,16 +1113,16 @@ def list_shares(self, all_tenants=False, is_soft_deleted=False, cmd += '--soft-deleted ' if filters and isinstance(filters, dict): for k, v in filters.items(): - cmd += '%(k)s=%(v)s ' % { - 'k': self._stranslate_to_cli_optional_param(k), 'v': v} + cmd += f'{self._stranslate_to_cli_optional_param(k)}={v} ' if columns is not None: cmd += '--columns ' + columns shares_raw = self.manila(cmd, microversion=microversion) shares = utils.listing(shares_raw) return shares - def list_share_instances(self, share_id=None, filters=None, - microversion=None): + def list_share_instances( + self, share_id=None, filters=None, microversion=None + ): """List share instances. :param share_id: ID of a share to filter by. @@ -1014,11 +1137,10 @@ def list_share_instances(self, share_id=None, filters=None, """ cmd = 'share-instance-list ' if share_id: - cmd += '--share-id %s' % share_id + cmd += f'--share-id {share_id}' if filters and isinstance(filters, dict): for k, v in filters.items(): - cmd += '%(k)s=%(v)s ' % { - 'k': self._stranslate_to_cli_optional_param(k), 'v': v} + cmd += f'{self._stranslate_to_cli_optional_param(k)}={v} ' share_instances_raw = self.manila(cmd, microversion=microversion) share_instances = utils.listing(share_instances_raw) return share_instances @@ -1040,8 +1162,12 @@ def wait_for_share_deletion(self, share, microversion=None): :param share: str -- Name or ID of share """ self.wait_for_resource_deletion( - SHARE, res_id=share, interval=5, timeout=300, - microversion=microversion) + SHARE, + res_id=share, + interval=5, + timeout=300, + microversion=microversion, + ) def is_share_transfer_deleted(self, transfer, microversion=None): """Says whether transfer is deleted or not. @@ -1060,8 +1186,12 @@ def wait_for_transfer_deletion(self, transfer, microversion=None): :param transfer: str -- Name or ID of transfer. """ self.wait_for_resource_deletion( - SHARE, res_id=transfer, interval=5, timeout=300, - microversion=microversion) + SHARE, + res_id=transfer, + interval=5, + timeout=300, + microversion=microversion, + ) def wait_for_share_soft_deletion(self, share_id, microversion=None): body = self.get_share(share_id, microversion=microversion) @@ -1077,10 +1207,10 @@ def wait_for_share_soft_deletion(self, share_id, microversion=None): return if int(time.time()) - start >= self.build_timeout: - message = ("Share %(share_id)s failed to be soft deleted " - "within the required time %(build_timeout)s." % - {"share_id": share_id, - "build_timeout": self.build_timeout}) + message = ( + f"Share {share_id} failed to be soft deleted " + f"within the required time {self.build_timeout}." + ) raise tempest_lib_exc.TimeoutException(message) def wait_for_share_restore(self, share_id, microversion=None): @@ -1097,14 +1227,15 @@ def wait_for_share_restore(self, share_id, microversion=None): return if int(time.time()) - start >= self.build_timeout: - message = ("Share %(share_id)s failed to be restored " - "within the required time %(build_timeout)s." % - {"share_id": share_id, - "build_timeout": self.build_timeout}) + message = ( + f"Share {share_id} failed to be restored " + f"within the required time {self.build_timeout}." + ) raise tempest_lib_exc.TimeoutException(message) - def wait_for_resource_status(self, resource_id, status, microversion=None, - resource_type="share"): + def wait_for_resource_status( + self, resource_id, status, microversion=None, resource_type="share" + ): """Waits for a share to reach a given status.""" get_func = getattr(self, 'get_' + resource_type) body = get_func(resource_id, microversion=microversion) @@ -1122,19 +1253,22 @@ def wait_for_resource_status(self, resource_id, status, microversion=None, raise exceptions.ShareBuildErrorException(share=resource_id) if int(time.time()) - start >= self.build_timeout: - message = ("Resource %(resource_id)s failed to reach " - "%(status)s status within the required time " - "(%(build_timeout)s)." % - {"resource_id": resource_id, "status": status, - "build_timeout": self.build_timeout}) + message = ( + f"Resource {resource_id} failed to reach " + f"{status} status within the required time " + f"({self.build_timeout})." + ) raise tempest_lib_exc.TimeoutException(message) - def wait_for_migration_task_state(self, share_id, dest_host, - task_state_to_wait, microversion=None): + def wait_for_migration_task_state( + self, share_id, dest_host, task_state_to_wait, microversion=None + ): """Waits for a share to migrate to a certain host.""" - statuses = ((task_state_to_wait,) - if not isinstance(task_state_to_wait, (tuple, list, set)) - else task_state_to_wait) + statuses = ( + (task_state_to_wait,) + if not isinstance(task_state_to_wait, (tuple, list, set)) + else task_state_to_wait + ) share = self.get_share(share_id, microversion=microversion) start = int(time.time()) while share['task_state'] not in statuses: @@ -1144,24 +1278,28 @@ def wait_for_migration_task_state(self, share_id, dest_host, break elif share['task_state'] == constants.TASK_STATE_MIGRATION_ERROR: raise exceptions.ShareMigrationException( - share_id=share['id'], src=share['host'], dest=dest_host) + share_id=share['id'], src=share['host'], dest=dest_host + ) elif int(time.time()) - start >= self.build_timeout: - message = ('Share %(share_id)s failed to reach a status in' - '%(status)s when migrating from host %(src)s to ' - 'host %(dest)s within the required time ' - '%(timeout)s.' % { - 'src': share['host'], - 'dest': dest_host, - 'share_id': share['id'], - 'timeout': self.build_timeout, - 'status': str(statuses), - }) + message = ( + 'Share {share_id} failed to reach a status in' + '{status} when migrating from host {src} to ' + 'host {dest} within the required time ' + '{timeout}.'.format( + src=share['host'], + dest=dest_host, + share_id=share['id'], + timeout=self.build_timeout, + status=str(statuses), + ) + ) raise tempest_lib_exc.TimeoutException(message) return share @not_found_wrapper - def _set_share_metadata(self, share, data, update_all=False, - microversion=None): + def _set_share_metadata( + self, share, data, update_all=False, microversion=None + ): """Sets a share metadata. :param share: str -- Name or ID of a share. @@ -1170,26 +1308,29 @@ def _set_share_metadata(self, share, data, update_all=False, will be deleted. """ if not (isinstance(data, dict) and data): - msg = ('Provided invalid data for setting of share metadata - ' - '%s' % data) + msg = ( + f'Provided invalid data for setting of share metadata - {data}' + ) raise exceptions.InvalidData(message=msg) if update_all: - cmd = 'metadata-update-all %s ' % share + cmd = f'metadata-update-all {share} ' else: - cmd = 'metadata %s set ' % share + cmd = f'metadata {share} set ' for k, v in data.items(): - cmd += '%(k)s=%(v)s ' % {'k': k, 'v': v} + cmd += f'{k}={v} ' return self.manila(cmd, microversion=microversion) def update_all_share_metadata(self, share, data, microversion=None): metadata_raw = self._set_share_metadata( - share, data, True, microversion=microversion) + share, data, True, microversion=microversion + ) metadata = output_parser.details(metadata_raw) return metadata def set_share_metadata(self, share, data, microversion=None): return self._set_share_metadata( - share, data, False, microversion=microversion) + share, data, False, microversion=microversion + ) @not_found_wrapper def unset_share_metadata(self, share, keys, microversion=None): @@ -1199,12 +1340,14 @@ def unset_share_metadata(self, share, keys, microversion=None): :param keys: str/list -- key or list of keys to unset. """ if not (isinstance(keys, list) and keys): - msg = ('Provided invalid data for unsetting of share metadata - ' - '%s' % keys) + msg = ( + 'Provided invalid data for unsetting of share metadata - ' + f'{keys}' + ) raise exceptions.InvalidData(message=msg) - cmd = 'metadata %s unset ' % share + cmd = f'metadata {share} unset ' for key in keys: - cmd += '%s ' % key + cmd += f'{key} ' return self.manila(cmd, microversion=microversion) @not_found_wrapper @@ -1214,22 +1357,29 @@ def get_share_metadata(self, share, microversion=None): :param share: str -- Name or ID of a share. """ metadata_raw = self.manila( - 'metadata-show %s' % share, microversion=microversion) + f'metadata-show {share}', microversion=microversion + ) metadata = output_parser.details(metadata_raw) return metadata - def create_snapshot(self, share, name=None, description=None, - force=False, microversion=None): + def create_snapshot( + self, + share, + name=None, + description=None, + force=False, + microversion=None, + ): """Creates a snapshot.""" - cmd = 'snapshot-create %(share)s ' % {'share': share} + cmd = f'snapshot-create {share} ' if name is None: name = data_utils.rand_name('autotest_snapshot_name') - cmd += '--name %s ' % name + cmd += f'--name {name} ' if description is None: description = data_utils.rand_name('autotest_snapshot_description') - cmd += '--description %s ' % description + cmd += f'--description {description} ' if force: - cmd += '--force %s' % force + cmd += f'--force {force}' snapshot_raw = self.manila(cmd, microversion=microversion) snapshot = output_parser.details(snapshot_raw) return snapshot @@ -1237,14 +1387,16 @@ def create_snapshot(self, share, name=None, description=None, @not_found_wrapper def get_snapshot(self, snapshot, microversion=None): """Retrieves a snapshot by its Name or ID.""" - snapshot_raw = self.manila('snapshot-show %s' % snapshot, - microversion=microversion) + snapshot_raw = self.manila( + f'snapshot-show {snapshot}', microversion=microversion + ) snapshot = output_parser.details(snapshot_raw) return snapshot @not_found_wrapper - def list_snapshot_export_locations(self, snapshot, columns=None, - microversion=None): + def list_snapshot_export_locations( + self, snapshot, columns=None, microversion=None + ): """List snapshot export locations. :param snapshot: str -- Name or ID of a snapshot. @@ -1252,7 +1404,7 @@ def list_snapshot_export_locations(self, snapshot, columns=None, Example, "--columns uuid,path". :param microversion: API microversion to be used for request. """ - cmd = "snapshot-export-location-list %s" % snapshot + cmd = f"snapshot-export-location-list {snapshot}" if columns is not None: cmd += " --columns " + columns export_locations_raw = self.manila(cmd, microversion=microversion) @@ -1261,9 +1413,9 @@ def list_snapshot_export_locations(self, snapshot, columns=None, @not_found_wrapper @forbidden_wrapper - def list_snapshot_instance_export_locations(self, snapshot_instance, - columns=None, - microversion=None): + def list_snapshot_instance_export_locations( + self, snapshot_instance, columns=None, microversion=None + ): """List snapshot instance export locations. :param snapshot_instance: str -- Name or ID of a snapshot instance. @@ -1271,7 +1423,7 @@ def list_snapshot_instance_export_locations(self, snapshot_instance, Example, "--columns uuid,path". :param microversion: API microversion to be used for request. """ - cmd = "snapshot-instance-export-location-list %s" % snapshot_instance + cmd = f"snapshot-instance-export-location-list {snapshot_instance}" if columns is not None: cmd += " --columns " + columns export_locations_raw = self.manila(cmd, microversion=microversion) @@ -1283,14 +1435,16 @@ def list_snapshot_instance_export_locations(self, snapshot_instance, def delete_snapshot(self, snapshot, microversion=None): """Deletes snapshot by Names or IDs.""" return self.manila( - "snapshot-delete %s" % snapshot, microversion=microversion) + f"snapshot-delete {snapshot}", microversion=microversion + ) - def list_snapshot_instances(self, snapshot_id=None, columns=None, - detailed=None, microversion=None): + def list_snapshot_instances( + self, snapshot_id=None, columns=None, detailed=None, microversion=None + ): """List snapshot instances.""" cmd = 'snapshot-instance-list ' if snapshot_id: - cmd += '--snapshot %s' % snapshot_id + cmd += f'--snapshot {snapshot_id}' if columns is not None: cmd += ' --columns ' + columns if detailed: @@ -1301,16 +1455,16 @@ def list_snapshot_instances(self, snapshot_id=None, columns=None, def get_snapshot_instance(self, id=None, microversion=None): """Get snapshot instance.""" - cmd = 'snapshot-instance-show %s ' % id + cmd = f'snapshot-instance-show {id} ' snapshot_instance_raw = self.manila(cmd, microversion=microversion) snapshot_instance = output_parser.details(snapshot_instance_raw) return snapshot_instance def reset_snapshot_instance(self, id=None, state=None, microversion=None): """Reset snapshot instance status.""" - cmd = 'snapshot-instance-reset-state %s ' % id + cmd = f'snapshot-instance-reset-state {id} ' if state: - cmd += '--state %s' % state + cmd += f'--state {state}' snapshot_instance_raw = self.manila(cmd, microversion=microversion) snapshot_instance = utils.listing(snapshot_instance_raw) return snapshot_instance @@ -1332,8 +1486,12 @@ def wait_for_snapshot_deletion(self, snapshot, microversion=None): :param snapshot: str -- Name or ID of snapshot """ self.wait_for_resource_deletion( - SNAPSHOT, res_id=snapshot, interval=5, timeout=300, - microversion=microversion) + SNAPSHOT, + res_id=snapshot, + interval=5, + timeout=300, + microversion=microversion, + ) def wait_for_snapshot_status(self, snapshot, status, microversion=None): """Waits for a snapshot to reach a given status.""" @@ -1354,15 +1512,20 @@ def wait_for_snapshot_status(self, snapshot, status, microversion=None): if int(time.time()) - start >= self.build_timeout: message = ( - "Snapshot %(snapshot_name)s failed to reach %(status)s " - "status within the required time (%(timeout)s s)." % { - "snapshot_name": snapshot_name, "status": status, - "timeout": self.build_timeout}) + f"Snapshot {snapshot_name} failed to reach {status} " + f"status within the required time ({self.build_timeout} s)." + ) raise tempest_lib_exc.TimeoutException(message) @not_found_wrapper - def list_access(self, entity_id, columns=None, microversion=None, - is_snapshot=False, metadata=None): + def list_access( + self, + entity_id, + columns=None, + microversion=None, + is_snapshot=False, + metadata=None, + ): """Returns list of access rules for a share. :param entity_id: str -- Name or ID of a share or snapshot. @@ -1372,137 +1535,157 @@ def list_access(self, entity_id, columns=None, microversion=None, access of a share or snapshot. """ if is_snapshot: - cmd = 'snapshot-access-list %s ' % entity_id + cmd = f'snapshot-access-list {entity_id} ' else: - cmd = 'access-list %s ' % entity_id + cmd = f'access-list {entity_id} ' if columns is not None: cmd += ' --columns ' + columns if metadata: metadata_cli = '' for k, v in metadata.items(): - metadata_cli += '%(k)s=%(v)s ' % {'k': k, 'v': v} + metadata_cli += f'{k}={v} ' if metadata_cli: - cmd += ' --metadata %s ' % metadata_cli + cmd += f' --metadata {metadata_cli} ' access_list_raw = self.manila(cmd, microversion=microversion) return output_parser.listing(access_list_raw) @not_found_wrapper - def get_access(self, share_id, access_id, microversion=None, - is_snapshot=False): - for access in self.list_access(share_id, microversion=microversion, - is_snapshot=is_snapshot): + def get_access( + self, share_id, access_id, microversion=None, is_snapshot=False + ): + for access in self.list_access( + share_id, microversion=microversion, is_snapshot=is_snapshot + ): if access['id'] == access_id: return access raise tempest_lib_exc.NotFound() @not_found_wrapper def access_show(self, access_id, microversion=None): - raw_access = self.manila("access-show %s" % access_id, - microversion=microversion) + raw_access = self.manila( + f"access-show {access_id}", microversion=microversion + ) return output_parser.details(raw_access) @not_found_wrapper def access_set_metadata(self, access_id, metadata, microversion=None): if not (isinstance(metadata, dict) and metadata): - msg = ('Provided invalid metadata for setting of access rule' - ' metadata - %s' % metadata) + msg = ( + 'Provided invalid metadata for setting of access rule' + f' metadata - {metadata}' + ) raise exceptions.InvalidData(message=msg) - cmd = "access-metadata %s set " % access_id + cmd = f"access-metadata {access_id} set " for k, v in metadata.items(): - cmd += '%(k)s=%(v)s ' % {'k': k, 'v': v} + cmd += f'{k}={v} ' return self.manila(cmd, microversion=microversion) @not_found_wrapper def access_unset_metadata(self, access_id, keys, microversion=None): if not (isinstance(keys, (list, tuple, set)) and keys): raise exceptions.InvalidData( - message='Provided invalid keys - %s' % keys) - cmd = 'access-metadata %s unset ' % access_id + message=f'Provided invalid keys - {keys}' + ) + cmd = f'access-metadata {access_id} unset ' for key in keys: - cmd += '%s ' % key + cmd += f'{key} ' return self.manila(cmd, microversion=microversion) @not_found_wrapper - def snapshot_access_allow(self, snapshot_id, access_type, access_to, - microversion=None): + def snapshot_access_allow( + self, snapshot_id, access_type, access_to, microversion=None + ): raw_access = self.manila( - 'snapshot-access-allow %(id)s %(type)s %(access_to)s' % { - 'id': snapshot_id, - 'type': access_type, - 'access_to': access_to, - }, - microversion=microversion) + f'snapshot-access-allow {snapshot_id} {access_type} {access_to}', + microversion=microversion, + ) return output_parser.details(raw_access) @not_found_wrapper def snapshot_access_deny(self, snapshot_id, access_id, microversion=None): return self.manila( - 'snapshot-access-deny %(share_id)s %(access_id)s' % { - 'share_id': snapshot_id, - 'access_id': access_id, - }, - microversion=microversion) + f'snapshot-access-deny {snapshot_id} {access_id}', + microversion=microversion, + ) @not_found_wrapper - def access_allow(self, share_id, access_type, access_to, access_level, - metadata=None, microversion=None): - cmd = ('access-allow --access-level %(level)s %(id)s %(type)s ' - '%(access_to)s' % { - 'level': access_level, - 'id': share_id, - 'type': access_type, - 'access_to': access_to}) + def access_allow( + self, + share_id, + access_type, + access_to, + access_level, + metadata=None, + microversion=None, + ): + cmd = ( + f'access-allow --access-level {access_level} {share_id} {access_type} ' + f'{access_to}' + ) if metadata: metadata_cli = '' for k, v in metadata.items(): - metadata_cli += '%(k)s=%(v)s ' % {'k': k, 'v': v} + metadata_cli += f'{k}={v} ' if metadata_cli: - cmd += ' --metadata %s ' % metadata_cli + cmd += f' --metadata {metadata_cli} ' raw_access = self.manila(cmd, microversion=microversion) return output_parser.details(raw_access) @not_found_wrapper def access_deny(self, share_id, access_id, microversion=None): return self.manila( - 'access-deny %(share_id)s %(access_id)s' % { - 'share_id': share_id, - 'access_id': access_id, - }, - microversion=microversion) - - def wait_for_access_rule_status(self, share_id, access_id, state='active', - microversion=None, is_snapshot=False): + f'access-deny {share_id} {access_id}', microversion=microversion + ) + + def wait_for_access_rule_status( + self, + share_id, + access_id, + state='active', + microversion=None, + is_snapshot=False, + ): access = self.get_access( - share_id, access_id, microversion=microversion, - is_snapshot=is_snapshot) + share_id, + access_id, + microversion=microversion, + is_snapshot=is_snapshot, + ) start = int(time.time()) while access['state'] != state: time.sleep(self.build_interval) access = self.get_access( - share_id, access_id, microversion=microversion, - is_snapshot=is_snapshot) + share_id, + access_id, + microversion=microversion, + is_snapshot=is_snapshot, + ) if access['state'] == state: return elif access['state'] == 'error': raise exceptions.AccessRuleCreateErrorException( - access=access_id) + access=access_id + ) if int(time.time()) - start >= self.build_timeout: message = ( - "Access rule %(access)s failed to reach %(state)s state " - "within the required time (%(build_timeout)s s)." % { - "access": access_id, "state": state, - "build_timeout": self.build_timeout}) + f"Access rule {access_id} failed to reach {state} state " + f"within the required time ({self.build_timeout} s)." + ) raise tempest_lib_exc.TimeoutException(message) - def wait_for_access_rule_deletion(self, share_id, access_id, - microversion=None, is_snapshot=False): + def wait_for_access_rule_deletion( + self, share_id, access_id, microversion=None, is_snapshot=False + ): try: access = self.get_access( - share_id, access_id, microversion=microversion, - is_snapshot=is_snapshot) + share_id, + access_id, + microversion=microversion, + is_snapshot=is_snapshot, + ) except tempest_lib_exc.NotFound: return @@ -1511,61 +1694,66 @@ def wait_for_access_rule_deletion(self, share_id, access_id, time.sleep(self.build_interval) try: access = self.get_access( - share_id, access_id, microversion=microversion, - is_snapshot=is_snapshot) + share_id, + access_id, + microversion=microversion, + is_snapshot=is_snapshot, + ) except tempest_lib_exc.NotFound: return if access['state'] == 'error': raise exceptions.AccessRuleDeleteErrorException( - access=access_id) + access=access_id + ) if int(time.time()) - start >= self.build_timeout: message = ( - "Access rule %(access)s failed to reach deleted state " - "within the required time (%(timeout)s s)." % - {"access": access_id, "timeout": self.build_timeout}) + f"Access rule {access_id} failed to reach deleted state " + f"within the required time ({self.build_timeout} s)." + ) raise tempest_lib_exc.TimeoutException(message) def reset_task_state(self, share_id, state, version=None): - state = '--task_state %s' % state if state else '' - return self.manila('reset-task-state %(state)s %(share)s' % { - 'state': state, - 'share': share_id, - }, microversion=version) - - def migration_start(self, share_id, dest_host, writable, nondisruptive, - preserve_metadata, preserve_snapshots, - force_host_assisted_migration, new_share_network=None, - new_share_type=None): - cmd = ('migration-start %(share)s %(host)s ' - '--writable %(writable)s --nondisruptive %(nondisruptive)s ' - '--preserve-metadata %(preserve_metadata)s ' - '--preserve-snapshots %(preserve_snapshots)s') % { - 'share': share_id, - 'host': dest_host, - 'writable': writable, - 'nondisruptive': nondisruptive, - 'preserve_metadata': preserve_metadata, - 'preserve_snapshots': preserve_snapshots, - } + state = f'--task_state {state}' if state else '' + return self.manila( + f'reset-task-state {state} {share_id}', microversion=version + ) + + def migration_start( + self, + share_id, + dest_host, + writable, + nondisruptive, + preserve_metadata, + preserve_snapshots, + force_host_assisted_migration, + new_share_network=None, + new_share_type=None, + ): + cmd = ( + f'migration-start {share_id} {dest_host} ' + f'--writable {writable} --nondisruptive {nondisruptive} ' + f'--preserve-metadata {preserve_metadata} ' + f'--preserve-snapshots {preserve_snapshots}' + ) if force_host_assisted_migration: - cmd += (' --force-host-assisted-migration %s' - % force_host_assisted_migration) + cmd += f' --force-host-assisted-migration {force_host_assisted_migration}' if new_share_network: - cmd += ' --new-share-network %s' % new_share_network + cmd += f' --new-share-network {new_share_network}' if new_share_type: - cmd += ' --new-share-type %s' % new_share_type + cmd += f' --new-share-type {new_share_type}' return self.manila(cmd) def migration_complete(self, share_id): - return self.manila('migration-complete %s' % share_id) + return self.manila(f'migration-complete {share_id}') def migration_cancel(self, share_id): - return self.manila('migration-cancel %s' % share_id) + return self.manila(f'migration-cancel {share_id}') def migration_get_progress(self, share_id): - result = self.manila('migration-get-progress %s' % share_id) + result = self.manila(f'migration-get-progress {share_id}') return output_parser.details(result) def pool_list(self, detail=False): @@ -1575,10 +1763,20 @@ def pool_list(self, detail=False): response = self.manila(cmd) return output_parser.listing(response) - def create_security_service(self, type='ldap', name=None, description=None, - dns_ip=None, ou=None, server=None, domain=None, - user=None, password=None, default_ad_site=None, - microversion=None): + def create_security_service( + self, + type='ldap', + name=None, + description=None, + dns_ip=None, + ou=None, + server=None, + domain=None, + user=None, + password=None, + default_ad_site=None, + microversion=None, + ): """Creates security service. :param type: security service type (ldap, kerberos or active_directory) @@ -1593,8 +1791,8 @@ def create_security_service(self, type='ldap', name=None, description=None, :param default_ad_site: default AD site """ - cmd = 'security-service-create %s ' % type - cmd += self. _combine_security_service_data( + cmd = f'security-service-create {type} ' + cmd += self._combine_security_service_data( name=name, description=description, dns_ip=dns_ip, @@ -1603,20 +1801,30 @@ def create_security_service(self, type='ldap', name=None, description=None, domain=domain, user=user, password=password, - default_ad_site=default_ad_site) + default_ad_site=default_ad_site, + ) ss_raw = self.manila(cmd, microversion=microversion) security_service = output_parser.details(ss_raw) return security_service @not_found_wrapper - def update_security_service(self, security_service, name=None, - description=None, dns_ip=None, ou=None, - server=None, domain=None, user=None, - password=None, default_ad_site=None, - microversion=None): - cmd = 'security-service-update %s ' % security_service - cmd += self. _combine_security_service_data( + def update_security_service( + self, + security_service, + name=None, + description=None, + dns_ip=None, + ou=None, + server=None, + domain=None, + user=None, + password=None, + default_ad_site=None, + microversion=None, + ): + cmd = f'security-service-update {security_service} ' + cmd += self._combine_security_service_data( name=name, description=description, dns_ip=dns_ip, @@ -1625,38 +1833,49 @@ def update_security_service(self, security_service, name=None, domain=domain, user=user, password=password, - default_ad_site=default_ad_site) + default_ad_site=default_ad_site, + ) return output_parser.details( - self.manila(cmd, microversion=microversion)) + self.manila(cmd, microversion=microversion) + ) - def _combine_security_service_data(self, name=None, description=None, - dns_ip=None, ou=None, server=None, - domain=None, user=None, password=None, - default_ad_site=None): + def _combine_security_service_data( + self, + name=None, + description=None, + dns_ip=None, + ou=None, + server=None, + domain=None, + user=None, + password=None, + default_ad_site=None, + ): data = '' if name is not None: - data += '--name %s ' % name + data += f'--name {name} ' if description is not None: - data += '--description %s ' % description + data += f'--description {description} ' if dns_ip is not None: - data += '--dns-ip %s ' % dns_ip + data += f'--dns-ip {dns_ip} ' if ou is not None: - data += '--ou %s ' % ou + data += f'--ou {ou} ' if server is not None: - data += '--server %s ' % server + data += f'--server {server} ' if domain is not None: - data += '--domain %s ' % domain + data += f'--domain {domain} ' if user is not None: - data += '--user %s ' % user + data += f'--user {user} ' if password is not None: - data += '--password %s ' % password + data += f'--password {password} ' if default_ad_site is not None: - data += '--default-ad-site %s ' % default_ad_site + data += f'--default-ad-site {default_ad_site} ' return data @not_found_wrapper - def list_share_export_locations(self, share, columns=None, - microversion=None): + def list_share_export_locations( + self, share, columns=None, microversion=None + ): """List share export locations. :param share: str -- Name or ID of a share. @@ -1664,7 +1883,7 @@ def list_share_export_locations(self, share, columns=None, Example, "--columns uuid,path". :param microversion: API microversion to be used for request. """ - cmd = "share-export-location-list %s" % share + cmd = f"share-export-location-list {share}" if columns is not None: cmd += " --columns " + columns export_locations_raw = self.manila(cmd, microversion=microversion) @@ -1672,8 +1891,9 @@ def list_share_export_locations(self, share, columns=None, return export_locations @not_found_wrapper - def get_snapshot_export_location(self, snapshot, export_location_uuid, - microversion=None): + def get_snapshot_export_location( + self, snapshot, export_location_uuid, microversion=None + ): """Returns an export location by snapshot and its UUID. :param snapshot: str -- Name or ID of a snapshot. @@ -1681,17 +1901,16 @@ def get_snapshot_export_location(self, snapshot, export_location_uuid, :param microversion: API microversion to be used for request. """ snapshot_raw = self.manila( - 'snapshot-export-location-show %(snapshot)s %(el_uuid)s' % { - 'snapshot': snapshot, - 'el_uuid': export_location_uuid, - }, - microversion=microversion) + f'snapshot-export-location-show {snapshot} {export_location_uuid}', + microversion=microversion, + ) snapshot = output_parser.details(snapshot_raw) return snapshot @not_found_wrapper def get_snapshot_instance_export_location( - self, snapshot, export_location_uuid, microversion=None): + self, snapshot, export_location_uuid, microversion=None + ): """Returns an export location by snapshot instance and its UUID. :param snapshot: str -- Name or ID of a snapshot instance. @@ -1699,15 +1918,16 @@ def get_snapshot_instance_export_location( :param microversion: API microversion to be used for request. """ snapshot_raw = self.manila( - 'snapshot-instance-export-location-show %(snapshot)s %(el_uuid)s' - % {'snapshot': snapshot, 'el_uuid': export_location_uuid}, - microversion=microversion) + f'snapshot-instance-export-location-show {snapshot} {export_location_uuid}', + microversion=microversion, + ) snapshot = output_parser.details(snapshot_raw) return snapshot @not_found_wrapper - def get_share_export_location(self, share, export_location_uuid, - microversion=None): + def get_share_export_location( + self, share, export_location_uuid, microversion=None + ): """Returns an export location by share and its UUID. :param share: str -- Name or ID of a share. @@ -1715,18 +1935,17 @@ def get_share_export_location(self, share, export_location_uuid, :param microversion: API microversion to be used for request. """ share_raw = self.manila( - 'share-export-location-show %(share)s %(el_uuid)s' % { - 'share': share, - 'el_uuid': export_location_uuid, - }, - microversion=microversion) + f'share-export-location-show {share} {export_location_uuid}', + microversion=microversion, + ) share = output_parser.details(share_raw) return share @not_found_wrapper @forbidden_wrapper - def list_share_instance_export_locations(self, share_instance, - columns=None, microversion=None): + def list_share_instance_export_locations( + self, share_instance, columns=None, microversion=None + ): """List share instance export locations. :param share_instance: str -- Name or ID of a share instance. @@ -1734,7 +1953,7 @@ def list_share_instance_export_locations(self, share_instance, Example, "--columns uuid,path". :param microversion: API microversion to be used for request. """ - cmd = "share-instance-export-location-list %s" % share_instance + cmd = f"share-instance-export-location-list {share_instance}" if columns is not None: cmd += " --columns " + columns export_locations_raw = self.manila(cmd, microversion=microversion) @@ -1743,9 +1962,9 @@ def list_share_instance_export_locations(self, share_instance, @not_found_wrapper @forbidden_wrapper - def get_share_instance_export_location(self, share_instance, - export_location_uuid, - microversion=None): + def get_share_instance_export_location( + self, share_instance, export_location_uuid, microversion=None + ): """Returns an export location by share instance and its UUID. :param share_instance: str -- Name or ID of a share instance. @@ -1754,11 +1973,9 @@ def get_share_instance_export_location(self, share_instance, """ share_raw = self.manila( 'share-instance-export-location-show ' - '%(share_instance)s %(el_uuid)s' % { - 'share_instance': share_instance, - 'el_uuid': export_location_uuid, - }, - microversion=microversion) + f'{share_instance} {export_location_uuid}', + microversion=microversion, + ) share = output_parser.details(share_raw) return share @@ -1768,12 +1985,14 @@ def get_share_instance_export_location(self, share_instance, def get_share_server(self, share_server, microversion=None): """Returns share server by its Name or ID.""" share_server_raw = self.manila( - 'share-server-show %s' % share_server, microversion=microversion) + f'share-server-show {share_server}', microversion=microversion + ) share_server = output_parser.details(share_server_raw) return share_server - def list_share_servers(self, filters=None, columns=None, - microversion=None): + def list_share_servers( + self, filters=None, columns=None, microversion=None + ): """List share servers. :param filters: dict -- filters for listing of share servers. @@ -1791,8 +2010,7 @@ def list_share_servers(self, filters=None, columns=None, cmd += ' --columns ' + columns if filters and isinstance(filters, dict): for k, v in filters.items(): - cmd += '%(k)s=%(v)s ' % { - 'k': self._stranslate_to_cli_optional_param(k), 'v': v} + cmd += f'{self._stranslate_to_cli_optional_param(k)}={v} ' share_servers_raw = self.manila(cmd, microversion=microversion) share_servers = utils.listing(share_servers_raw) return share_servers @@ -1800,8 +2018,9 @@ def list_share_servers(self, filters=None, columns=None, @not_found_wrapper def delete_share_server(self, share_server, microversion=None): """Deletes share server by its Name or ID.""" - return self.manila('share-server-delete %s' % share_server, - microversion=microversion) + return self.manila( + f'share-server-delete {share_server}', microversion=microversion + ) def is_share_server_deleted(self, share_server_id, microversion=None): """Says whether share server is deleted or not. @@ -1820,110 +2039,125 @@ def wait_for_share_server_deletion(self, share_server, microversion=None): :param share_server: text -- Name or ID of share server """ self.wait_for_resource_deletion( - SHARE_SERVER, res_id=share_server, interval=3, timeout=60, - microversion=microversion) + SHARE_SERVER, + res_id=share_server, + interval=3, + timeout=60, + microversion=microversion, + ) def unmanage_share(self, server_id): - return self.manila('unmanage %s ' % server_id) + return self.manila(f'unmanage {server_id} ') def unmanage_server(self, share_server_id): - return self.manila('share-server-unmanage %s ' % share_server_id) + return self.manila(f'share-server-unmanage {share_server_id} ') - def share_server_manage(self, host, share_network, identifier, - driver_options=None): + def share_server_manage( + self, host, share_network, identifier, driver_options=None + ): if driver_options: - command = ('share-server-manage %s %s %s %s' % - (host, share_network, identifier, driver_options)) + command = f'share-server-manage {host} {share_network} {identifier} {driver_options}' else: - command = ('share-server-manage %s %s %s' % (host, share_network, - identifier)) + command = ( + f'share-server-manage {host} {share_network} {identifier}' + ) managed_share_server_raw = self.manila(command) managed_share_server = output_parser.details(managed_share_server_raw) return managed_share_server['id'] def manage_share(self, host, protocol, export_location, share_server): managed_share_raw = self.manila( - 'manage %s %s %s --share-server-id %s' % (host, protocol, - export_location, - share_server)) + f'manage {host} {protocol} {export_location} --share-server-id {share_server}' + ) managed_share = output_parser.details(managed_share_raw) return managed_share['id'] - def share_server_migration_check(self, server_id, dest_host, writable, - nondisruptive, preserve_snapshots, - new_share_network=None): - cmd = ('share-server-migration-check %(server_id)s %(host)s ' - '--writable %(writable)s --nondisruptive %(nondisruptive)s ' - '--preserve-snapshots %(preserve_snapshots)s') % { - 'server_id': server_id, - 'host': dest_host, - 'writable': writable, - 'nondisruptive': nondisruptive, - 'preserve_snapshots': preserve_snapshots, - } + def share_server_migration_check( + self, + server_id, + dest_host, + writable, + nondisruptive, + preserve_snapshots, + new_share_network=None, + ): + cmd = ( + f'share-server-migration-check {server_id} {dest_host} ' + f'--writable {writable} --nondisruptive {nondisruptive} ' + f'--preserve-snapshots {preserve_snapshots}' + ) if new_share_network: - cmd += ' --new-share-network %s' % new_share_network + cmd += f' --new-share-network {new_share_network}' result = self.manila(cmd) return output_parser.details(result) - def share_server_migration_start(self, server_id, dest_host, - writable=False, nondisruptive=False, - preserve_snapshots=False, - new_share_network=None): - cmd = ('share-server-migration-start %(server_id)s %(host)s ' - '--writable %(writable)s --nondisruptive %(nondisruptive)s ' - '--preserve-snapshots %(preserve_snapshots)s') % { - 'server_id': server_id, - 'host': dest_host, - 'writable': writable, - 'nondisruptive': nondisruptive, - 'preserve_snapshots': preserve_snapshots, - } + def share_server_migration_start( + self, + server_id, + dest_host, + writable=False, + nondisruptive=False, + preserve_snapshots=False, + new_share_network=None, + ): + cmd = ( + f'share-server-migration-start {server_id} {dest_host} ' + f'--writable {writable} --nondisruptive {nondisruptive} ' + f'--preserve-snapshots {preserve_snapshots}' + ) if new_share_network: - cmd += ' --new-share-network %s' % new_share_network + cmd += f' --new-share-network {new_share_network}' return self.manila(cmd) def share_server_migration_complete(self, server_id): - return self.manila('share-server-migration-complete %s' % server_id) + return self.manila(f'share-server-migration-complete {server_id}') def share_server_migration_cancel(self, server_id): - return self.manila('share-server-migration-cancel %s' % server_id) + return self.manila(f'share-server-migration-cancel {server_id}') def share_server_migration_get_progress(self, server_id): - result = self.manila('share-server-migration-get-progress %s' - % server_id) + result = self.manila( + f'share-server-migration-get-progress {server_id}' + ) return output_parser.details(result) - def wait_for_server_migration_task_state(self, share_server_id, dest_host, - task_state_to_wait, - microversion=None): - """Waits for a certain server task state. """ - statuses = ((task_state_to_wait,) - if not isinstance(task_state_to_wait, (tuple, list, set)) - else task_state_to_wait) - server = self.get_share_server(share_server=share_server_id, - microversion=microversion) + def wait_for_server_migration_task_state( + self, share_server_id, dest_host, task_state_to_wait, microversion=None + ): + """Waits for a certain server task state.""" + statuses = ( + (task_state_to_wait,) + if not isinstance(task_state_to_wait, (tuple, list, set)) + else task_state_to_wait + ) + server = self.get_share_server( + share_server=share_server_id, microversion=microversion + ) start = int(time.time()) while server['task_state'] not in statuses: time.sleep(self.build_interval) - server = self.get_share_server(share_server=share_server_id, - microversion=microversion) + server = self.get_share_server( + share_server=share_server_id, microversion=microversion + ) if server['task_state'] in statuses: return server elif server['task_state'] == constants.TASK_STATE_MIGRATION_ERROR: raise exceptions.ShareServerMigrationException( - server_id=server['id']) + server_id=server['id'] + ) elif int(time.time()) - start >= self.build_timeout: - message = ('Server %(share_server_id)s failed to reach the ' - 'status in %(status)s while migrating from host ' - '%(src)s to host %(dest)s within the required time ' - '%(timeout)s.' % { - 'src': server['host'], - 'dest': dest_host, - 'share_server_id': server['id'], - 'timeout': self.build_timeout, - 'status': str(statuses), - }) + message = ( + 'Server {share_server_id} failed to reach the ' + 'status in {status} while migrating from host ' + '{src} to host {dest} within the required time ' + '{timeout}.'.format( + src=server['host'], + dest=dest_host, + share_server_id=server['id'], + timeout=self.build_timeout, + status=str(statuses), + ) + ) raise tempest_lib_exc.TimeoutException(message) # user messages @@ -1940,9 +2174,10 @@ def wait_for_message(self, resource_id): return msg if int(time.time()) - start >= self.build_timeout: - message = ('No message for resource with id %s was created in' - ' the required time (%s s).' % - (resource_id, self.build_timeout)) + message = ( + f'No message for resource with id {resource_id} was created in' + f' the required time ({self.build_timeout} s).' + ) raise tempest_lib_exc.TimeoutException(message) def list_messages(self, columns=None, microversion=None): @@ -1963,15 +2198,17 @@ def list_messages(self, columns=None, microversion=None): def get_message(self, message, microversion=None): """Returns share server by its Name or ID.""" message_raw = self.manila( - 'message-show %s' % message, microversion=microversion) + f'message-show {message}', microversion=microversion + ) message = output_parser.details(message_raw) return message @not_found_wrapper def delete_message(self, message, microversion=None): """Deletes message by its ID.""" - return self.manila('message-delete %s' % message, - microversion=microversion) + return self.manila( + f'message-delete {message}', microversion=microversion + ) def is_message_deleted(self, message, microversion=None): """Indicates whether message is deleted or not. @@ -1990,18 +2227,27 @@ def wait_for_message_deletion(self, message, microversion=None): :param message: text -- ID of message """ self.wait_for_resource_deletion( - MESSAGE, res_id=message, interval=3, timeout=60, - microversion=microversion) + MESSAGE, + res_id=message, + interval=3, + timeout=60, + microversion=microversion, + ) # Share replicas - def create_share_replica(self, share, availability_zone=None, - share_network=None, microversion=None): + def create_share_replica( + self, + share, + availability_zone=None, + share_network=None, + microversion=None, + ): """Create a share replica. :param share: str -- Name or ID of a share to create a replica of """ - cmd = "share-replica-create %s" % share + cmd = f"share-replica-create {share}" if availability_zone is not None: cmd += " --availability_zone " + availability_zone if share_network is not None: @@ -2012,7 +2258,7 @@ def create_share_replica(self, share, availability_zone=None, @not_found_wrapper def get_share_replica(self, replica, microversion=None): - cmd = "share-replica-show %s" % replica + cmd = f"share-replica-show {replica}" replica = self.manila(cmd, microversion=microversion) return output_parser.details(replica) @@ -2021,8 +2267,8 @@ def get_share_replica(self, replica, microversion=None): def delete_share_replica(self, share_replica, microversion=None): """Deletes share replica by ID.""" return self.manila( - "share-replica-delete %s" % share_replica, - microversion=microversion) + f"share-replica-delete {share_replica}", microversion=microversion + ) def is_share_replica_deleted(self, replica, microversion=None): """Indicates whether a share replica is deleted or not. @@ -2041,44 +2287,51 @@ def wait_for_share_replica_deletion(self, replica, microversion=None): :param replica: text -- ID of share replica """ self.wait_for_resource_deletion( - SHARE_REPLICA, res_id=replica, interval=3, timeout=60, - microversion=microversion) + SHARE_REPLICA, + res_id=replica, + interval=3, + timeout=60, + microversion=microversion, + ) - def wait_for_share_replica_status(self, share_replica, - status="available", - microversion=None): + def wait_for_share_replica_status( + self, share_replica, status="available", microversion=None + ): """Waits for a share replica to reach a given status.""" - replica = self.get_share_replica(share_replica, - microversion=microversion) + replica = self.get_share_replica( + share_replica, microversion=microversion + ) share_replica_status = replica['status'] start = int(time.time()) while share_replica_status != status: time.sleep(self.build_interval) - replica = self.get_share_replica(share_replica, - microversion=microversion) + replica = self.get_share_replica( + share_replica, microversion=microversion + ) share_replica_status = replica['status'] if share_replica_status == status: return replica elif 'error' in share_replica_status.lower(): raise exceptions.ShareReplicaBuildErrorException( - replica=share_replica) + replica=share_replica + ) if int(time.time()) - start >= self.build_timeout: message = ( - "Share replica %(id)s failed to reach %(status)s " + f"Share replica {share_replica} failed to reach {status} " "status within the required time " - "(%(build_timeout)s s)." % { - "id": share_replica, "status": status, - "build_timeout": self.build_timeout}) + f"({self.build_timeout} s)." + ) raise tempest_lib_exc.TimeoutException(message) return replica @not_found_wrapper @forbidden_wrapper - def list_share_replica_export_locations(self, share_replica, - columns=None, microversion=None): + def list_share_replica_export_locations( + self, share_replica, columns=None, microversion=None + ): """List share replica export locations. :param share_replica: str -- ID of share replica. @@ -2086,7 +2339,7 @@ def list_share_replica_export_locations(self, share_replica, Example, "--columns id,path". :param microversion: API microversion to be used for request. """ - cmd = "share-replica-export-location-list %s" % share_replica + cmd = f"share-replica-export-location-list {share_replica}" if columns is not None: cmd += " --columns " + columns export_locations_raw = self.manila(cmd, microversion=microversion) @@ -2095,9 +2348,9 @@ def list_share_replica_export_locations(self, share_replica, @not_found_wrapper @forbidden_wrapper - def get_share_replica_export_location(self, share_replica, - export_location_uuid, - microversion=None): + def get_share_replica_export_location( + self, share_replica, export_location_uuid, microversion=None + ): """Returns an export location by share replica and export location ID. :param share_replica: str -- ID of share replica. @@ -2106,10 +2359,8 @@ def get_share_replica_export_location(self, share_replica, """ export_raw = self.manila( 'share-replica-export-location-show ' - '%(share_replica)s %(el_uuid)s' % { - 'share_replica': share_replica, - 'el_uuid': export_location_uuid, - }, - microversion=microversion) + f'{share_replica} {export_location_uuid}', + microversion=microversion, + ) export = output_parser.details(export_raw) return export diff --git a/manilaclient/tests/functional/exceptions.py b/manilaclient/tests/functional/exceptions.py index fd96a4da..e6398f99 100644 --- a/manilaclient/tests/functional/exceptions.py +++ b/manilaclient/tests/functional/exceptions.py @@ -45,8 +45,9 @@ class ShareBuildErrorException(exceptions.TempestException): class ShareReplicaBuildErrorException(exceptions.TempestException): - message = ("Share replica %(replica)s failed to build and is in ERROR " - "status.") + message = ( + "Share replica %(replica)s failed to build and is in ERROR status." + ) class SnapshotBuildErrorException(exceptions.TempestException): @@ -62,9 +63,11 @@ class AccessRuleDeleteErrorException(exceptions.TempestException): class ShareMigrationException(exceptions.TempestException): - message = ("Share %(share_id)s failed to migrate from " - "host %(src)s to host %(dest)s.") + message = ( + "Share %(share_id)s failed to migrate from " + "host %(src)s to host %(dest)s." + ) class ShareServerMigrationException(exceptions.TempestException): - message = ("Share server %(server_id)s failed to migrate.") + message = "Share server %(server_id)s failed to migrate." diff --git a/manilaclient/tests/functional/osc/base.py b/manilaclient/tests/functional/osc/base.py index d396657a..31706fec 100644 --- a/manilaclient/tests/functional/osc/base.py +++ b/manilaclient/tests/functional/osc/base.py @@ -36,7 +36,7 @@ def get_admin_client(cls): project_domain_name=CONF.admin_project_domain_name or None, project_domain_id=CONF.admin_project_domain_id or None, user_domain_name=CONF.admin_user_domain_name or None, - user_domain_id=CONF.admin_user_domain_id or None + user_domain_id=CONF.admin_user_domain_id or None, ) return admin_client @@ -52,7 +52,7 @@ def get_user_client(cls): project_domain_name=CONF.project_domain_name or None, project_domain_id=CONF.project_domain_id or None, user_domain_name=CONF.user_domain_name or None, - user_domain_id=CONF.user_domain_id or None + user_domain_id=CONF.user_domain_id or None, ) return user_client @@ -79,53 +79,79 @@ def _get_property_from_output(self, output): obj[item['Field']] = str(item['Value']) return obj - def _wait_for_object_status(self, object_name, object_id, status, - timeout=CONF.build_timeout, - interval=CONF.build_interval): + def _wait_for_object_status( + self, + object_name, + object_id, + status, + timeout=CONF.build_timeout, + interval=CONF.build_interval, + ): """Waits for a object to reach a given status.""" start_time = time.time() while time.time() - start_time < timeout: - if status == self.openstack( - '%(obj)s show -c status -f value %(id)s' - % {'obj': object_name, - 'id': object_id}).rstrip(): + if ( + status + == self.openstack( + f'{object_name} show -c status -f value {object_id}' + ).rstrip() + ): break time.sleep(interval) else: - self.fail("%s %s did not reach status %s after %d seconds." - % (object_name, object_id, status, timeout)) + self.fail( + "%s %s did not reach status %s after %d seconds." + % (object_name, object_id, status, timeout) + ) - def check_object_deleted(self, object_name, object_id, - timeout=CONF.build_timeout, - interval=CONF.build_interval): + def check_object_deleted( + self, + object_name, + object_id, + timeout=CONF.build_timeout, + interval=CONF.build_interval, + ): """Check that object deleted successfully""" - cmd = '%s list -c ID -f value' % object_name + cmd = f'{object_name} list -c ID -f value' start_time = time.time() while time.time() - start_time < timeout: if object_id not in self.openstack(cmd): break time.sleep(interval) else: - self.fail("%s %s not deleted after %d seconds." - % (object_name, object_id, timeout)) + self.fail( + "%s %s not deleted after %d seconds." + % (object_name, object_id, timeout) + ) - def openstack(self, action, flags='', params='', fail_ok=False, - merge_stderr=False, client=None): + def openstack( + self, + action, + flags='', + params='', + fail_ok=False, + merge_stderr=False, + client=None, + ): """Executes openstack command for given action""" if '--os-share-api-version' not in flags: flags = ( - flags + '--os-share-api-version %s' - % CONF.max_api_microversion) + flags + f'--os-share-api-version {CONF.max_api_microversion}' + ) if client is None: client = self.admin_client - return client.openstack(action, flags=flags, params=params, - fail_ok=fail_ok, - merge_stderr=merge_stderr) + return client.openstack( + action, + flags=flags, + params=params, + fail_ok=fail_ok, + merge_stderr=merge_stderr, + ) def listing_result(self, object_name, command, client=None): """Returns output for the given command as list of dictionaries""" @@ -141,49 +167,61 @@ def dict_result(self, object_name, command, client=None): result_dict = self._get_property_from_output(output) return result_dict - def create_share(self, share_protocol=None, size=None, name=None, - snapshot_id=None, properties=None, share_network=None, - description=None, public=False, share_type=None, - availability_zone=None, share_group=None, - add_cleanup=True, client=None, wait=None, - wait_for_status='available'): - + def create_share( + self, + share_protocol=None, + size=None, + name=None, + snapshot_id=None, + properties=None, + share_network=None, + description=None, + public=False, + share_type=None, + availability_zone=None, + share_group=None, + add_cleanup=True, + client=None, + wait=None, + wait_for_status='available', + ): name = name or data_utils.rand_name('autotest_share_name') # share_type = dhss_false until we have implemented # share network commands for osc share_type = share_type or 'dhss_false' - cmd = ('create ' - '%(protocol)s %(size)s %(name)s %(desc)s %(public)s %(stype)s' - % {'protocol': share_protocol or 'NFS', - 'size': size or '1', - 'name': '--name %s' % name, - 'desc': '--description %s' % description, - 'public': '--public %s' % public, - 'stype': '--share-type %s' % share_type}) + cmd = 'create {protocol} {size} {name} {desc} {public} {stype}'.format( + protocol=share_protocol or 'NFS', + size=size or '1', + name=f'--name {name}', + desc=f'--description {description}', + public=f'--public {public}', + stype=f'--share-type {share_type}', + ) if snapshot_id: - cmd = cmd + ' --snapshot-id %s' % snapshot_id + cmd = cmd + f' --snapshot-id {snapshot_id}' if properties: for key, value in properties.items(): - cmd = (cmd + ' --property %(key)s=%(value)s' - % {'key': key, 'value': value}) + cmd = cmd + f' --property {key}={value}' if share_network: - cmd = cmd + ' --share-network %s' % share_network + cmd = cmd + f' --share-network {share_network}' if availability_zone: - cmd = cmd + ' --availability-zone %s' % availability_zone + cmd = cmd + f' --availability-zone {availability_zone}' if share_group: - cmd = cmd + ' --share-group %s' % share_group + cmd = cmd + f' --share-group {share_group}' if wait: cmd = cmd + ' --wait' share_object = self.dict_result('share', cmd, client=client) self._wait_for_object_status( - 'share', share_object['id'], wait_for_status) + 'share', share_object['id'], wait_for_status + ) if add_cleanup: self.addCleanup( - self.openstack, 'share delete %s --wait' % share_object['id'] + self.openstack, + 'share delete {} --wait'.format(share_object['id']), ) return share_object @@ -203,27 +241,37 @@ def list_pools(self, backend=None, host=None, pool=None, detail=False): return pools - def create_share_type(self, name=None, dhss=False, description=None, - snapshot_support=None, - create_share_from_snapshot_support=None, - revert_to_snapshot_support=False, - mount_snapshot_support=False, extra_specs={}, - public=True, add_cleanup=True, client=None, - formatter=None): - + def create_share_type( + self, + name=None, + dhss=False, + description=None, + snapshot_support=None, + create_share_from_snapshot_support=None, + revert_to_snapshot_support=False, + mount_snapshot_support=False, + extra_specs={}, + public=True, + add_cleanup=True, + client=None, + formatter=None, + ): name = name or data_utils.rand_name('autotest_share_type_name') - cmd = (f'create {name} {dhss} --public {public}') + cmd = f'create {name} {dhss} --public {public}' if description: cmd += f' --description {description}' if snapshot_support: cmd += f' --snapshot-support {snapshot_support}' if create_share_from_snapshot_support: - cmd += (' --create-share-from-snapshot-support ' - f'{create_share_from_snapshot_support}') + cmd += ( + ' --create-share-from-snapshot-support ' + f'{create_share_from_snapshot_support}' + ) if revert_to_snapshot_support: - cmd += (' --revert-to-snapshot-support ' - f' {revert_to_snapshot_support}') + cmd += ( + f' --revert-to-snapshot-support {revert_to_snapshot_support}' + ) if mount_snapshot_support: cmd += f' --mount-snapshot-support {mount_snapshot_support}' if extra_specs: @@ -259,13 +307,19 @@ def list_services(self, host=None, status=None, state=None, zone=None): services = self.listing_result('share', cmd) return services - def create_share_access_rule(self, share, access_type, - access_to, properties=None, - access_level=None, wait=False, - lock_visibility=False, - lock_deletion=False, - lock_reason=None, - add_cleanup=False): + def create_share_access_rule( + self, + share, + access_type, + access_to, + properties=None, + access_level=None, + wait=False, + lock_visibility=False, + lock_deletion=False, + lock_reason=None, + add_cleanup=False, + ): cmd = f'access create {share} {access_type} {access_to} ' if access_level: @@ -286,17 +340,23 @@ def create_share_access_rule(self, share, access_type, return access_rule def get_share_export_locations(self, share): - cmd = (f'export location list {share}') + cmd = f'export location list {share}' export_locations = json.loads(self.openstack(f'share {cmd} -f json')) return export_locations - def create_snapshot(self, share, name=None, - description=None, wait=True, force=None, - add_cleanup=True, client=None): - + def create_snapshot( + self, + share, + name=None, + description=None, + wait=True, + force=None, + add_cleanup=True, + client=None, + ): name = name or data_utils.rand_name('autotest_snapshot_name') - cmd = (f'snapshot create {share} --name {name} ') + cmd = f'snapshot create {share} --name {name} ' if description: cmd += f' --description {description}' @@ -310,24 +370,29 @@ def create_snapshot(self, share, name=None, if add_cleanup: self.addCleanup( self.openstack, - f'share snapshot delete {snapshot_object["id"]} --wait') + f'share snapshot delete {snapshot_object["id"]} --wait', + ) return snapshot_object def create_share_transfer(self, share, name=None, client=None): - name = name or data_utils.rand_name('autotest_share_transfer_name') - cmd = (f'transfer create {share} --name {name} ') + cmd = f'transfer create {share} --name {name} ' transfer_object = self.dict_result('share', cmd, client=client) return transfer_object - def create_share_network(self, neutron_net_id=None, - neutron_subnet_id=None, name=None, - description=None, availability_zone=None, - add_cleanup=True): + def create_share_network( + self, + neutron_net_id=None, + neutron_subnet_id=None, + name=None, + description=None, + availability_zone=None, + add_cleanup=True, + ): name = name or data_utils.rand_name('autotest_share_network_name') - cmd = (f'network create --name {name} --description {description}') + cmd = f'network create --name {name} --description {description}' if neutron_net_id: cmd = cmd + f' --neutron-net-id {neutron_net_id}' if neutron_subnet_id: @@ -337,52 +402,61 @@ def create_share_network(self, neutron_net_id=None, share_network_obj = self.dict_result('share', cmd) self._wait_for_object_status( - 'share network', share_network_obj['id'], 'active') + 'share network', share_network_obj['id'], 'active' + ) if add_cleanup: self.addCleanup( self.openstack, - f'share network delete {share_network_obj["id"]}' + f'share network delete {share_network_obj["id"]}', ) return share_network_obj - def create_share_replica(self, share, availability_zone=None, - share_network=None, wait=None, - add_cleanup=True): - cmd = (f'replica create {share}') + def create_share_replica( + self, + share, + availability_zone=None, + share_network=None, + wait=None, + add_cleanup=True, + ): + cmd = f'replica create {share}' if availability_zone: cmd = cmd + f' --availability-zone {availability_zone}' if wait: cmd = cmd + ' --wait' if share_network: - cmd = cmd + ' --share-network %s' % share_network + cmd = cmd + f' --share-network {share_network}' replica_object = self.dict_result('share', cmd) self._wait_for_object_status( - 'share replica', replica_object['id'], 'available') + 'share replica', replica_object['id'], 'available' + ) if add_cleanup: self.addCleanup( self.openstack, - f'share replica delete {replica_object["id"]} --wait' + f'share replica delete {replica_object["id"]} --wait', ) return replica_object def get_share_replica_export_locations(self, replica): - cmd = (f'replica export location list {replica}') + cmd = f'replica export location list {replica}' export_locations = self.listing_result('share', cmd) return export_locations - def create_share_group_type(self, name=None, share_types=None, - group_specs=None, public=True, - add_cleanup=True): - + def create_share_group_type( + self, + name=None, + share_types=None, + group_specs=None, + public=True, + add_cleanup=True, + ): name = name or data_utils.rand_name('autotest_share_group_types_name') share_types = share_types or 'None' - cmd = (f'group type create ' - f'{name} ' - f'{share_types} ') + cmd = f'group type create {name} {share_types} ' if group_specs: cmd = cmd + f' --group-specs {group_specs} ' @@ -394,27 +468,28 @@ def create_share_group_type(self, name=None, share_types=None, if add_cleanup: self.addCleanup( self.openstack, - 'share group type delete %s' % share_object['id']) + 'share group type delete {}'.format(share_object['id']), + ) return share_object def share_group_type_access_create(self, group_type, project): - cmd = (f'group type access create ' - f'{group_type} ' - f'{project} ') + cmd = f'group type access create {group_type} {project} ' self.dict_result('share', cmd) def share_group_type_access_delete(self, group_type, access_id): - cmd = (f'group type access delete ' - f'{group_type} ' - f'{access_id} ') + cmd = f'group type access delete {group_type} {access_id} ' self.dict_result('share', cmd) - def check_create_network_subnet(self, share_network, neutron_net_id=None, - neutron_subnet_id=None, - availability_zone=None, - restart_check=None): + def check_create_network_subnet( + self, + share_network, + neutron_net_id=None, + neutron_subnet_id=None, + availability_zone=None, + restart_check=None, + ): cmd = f'network subnet create {share_network} --check-only' if neutron_net_id: @@ -429,10 +504,15 @@ def check_create_network_subnet(self, share_network, neutron_net_id=None, check_result = self.dict_result('share', cmd) return check_result - def create_resource_lock(self, resource_id, resource_type='share', - resource_action='delete', lock_reason=None, - add_cleanup=True, client=None): - + def create_resource_lock( + self, + resource_id, + resource_type='share', + resource_action='delete', + lock_reason=None, + add_cleanup=True, + client=None, + ): cmd = f'lock create {resource_id} {resource_type}' cmd += f' --resource-action {resource_action}' @@ -442,17 +522,24 @@ def create_resource_lock(self, resource_id, resource_type='share', lock = self.dict_result('share', cmd, client=client) if add_cleanup: - self.addCleanup(self.openstack, - 'share lock delete %s' % lock['id'], - client=client) + self.addCleanup( + self.openstack, + 'share lock delete {}'.format(lock['id']), + client=client, + ) return lock - def create_backup(self, share_id, name=None, description=None, - backup_options=None, add_cleanup=True): - + def create_backup( + self, + share_id, + name=None, + description=None, + backup_options=None, + add_cleanup=True, + ): name = name or data_utils.rand_name('autotest_backup_name') - cmd = (f'backup create {share_id} ') + cmd = f'backup create {share_id} ' if name: cmd += f' --name {name}' @@ -466,11 +553,13 @@ def create_backup(self, share_id, name=None, description=None, backup_object = self.dict_result('share', cmd) self._wait_for_object_status( - 'share backup', backup_object['id'], 'available') + 'share backup', backup_object['id'], 'available' + ) if add_cleanup: self.addCleanup( self.openstack, - f'share backup delete {backup_object["id"]} --wait') + f'share backup delete {backup_object["id"]} --wait', + ) return backup_object diff --git a/manilaclient/tests/functional/osc/test_availability_zones.py b/manilaclient/tests/functional/osc/test_availability_zones.py index 48717ad5..6c1c3305 100644 --- a/manilaclient/tests/functional/osc/test_availability_zones.py +++ b/manilaclient/tests/functional/osc/test_availability_zones.py @@ -15,13 +15,7 @@ class AvailabilityZonesCLITest(base.OSCClientTestBase): - def test_openstack_share_availability_zones_list(self): azs = self.listing_result('share', 'availability zone list') - self.assertTableStruct(azs, [ - 'Id', - 'Name', - 'Created At', - 'Updated At' - ]) + self.assertTableStruct(azs, ['Id', 'Name', 'Created At', 'Updated At']) self.assertTrue(len(azs) > 0) diff --git a/manilaclient/tests/functional/osc/test_messages.py b/manilaclient/tests/functional/osc/test_messages.py index cb2b8186..f9977991 100644 --- a/manilaclient/tests/functional/osc/test_messages.py +++ b/manilaclient/tests/functional/osc/test_messages.py @@ -17,44 +17,59 @@ class MessagesCLITest(base.OSCClientTestBase): - def setUp(self): - super(MessagesCLITest, self).setUp() + super().setUp() # cause a user message by using an invalid share type for provisioning st = self.create_share_type(extra_specs={'fake_key': 'fake_value'}) - self.share = self.create_share(share_type=st['name'], - wait_for_status='error', - client=self.user_client) + self.share = self.create_share( + share_type=st['name'], + wait_for_status='error', + client=self.user_client, + ) def test_list_and_show_messages(self): # Get all messages messages = self.listing_result( - 'share', 'message list', client=self.user_client) + 'share', 'message list', client=self.user_client + ) # We must have at least one message self.assertTrue(len(messages) > 0) - self.assertTableStruct(messages, [ - 'ID', - 'Resource Type', - 'Resource ID', - 'Action ID', - 'User Message', - 'Detail ID', - 'Created At', - ]) + self.assertTableStruct( + messages, + [ + 'ID', + 'Resource Type', + 'Resource ID', + 'Action ID', + 'User Message', + 'Detail ID', + 'Created At', + ], + ) # grab the message we created - message = [msg for msg in messages - if msg['Resource ID'] == self.share['id']] + message = [ + msg for msg in messages if msg['Resource ID'] == self.share['id'] + ] self.assertEqual(1, len(message)) - show_message = self.dict_result('share', - f'message show {message[0]["ID"]}') - self.addCleanup(self.openstack, - f'share message delete {show_message["id"]}') + show_message = self.dict_result( + 'share', f'message show {message[0]["ID"]}' + ) + self.addCleanup( + self.openstack, f'share message delete {show_message["id"]}' + ) self.assertEqual(message[0]['ID'], show_message['id']) expected_keys = ( - 'id', 'action_id', 'resource_id', 'detail_id', 'resource_type', - 'created_at', 'expires_at', 'message_level', 'user_message', + 'id', + 'action_id', + 'resource_id', + 'detail_id', + 'resource_type', + 'created_at', + 'expires_at', + 'message_level', + 'user_message', 'request_id', ) for key in expected_keys: @@ -66,54 +81,53 @@ def test_list_and_show_messages(self): filtered_messages = self.listing_result( 'share', f'message list --since {since} --before {before}', - client=self.user_client) + client=self.user_client, + ) self.assertTrue(len(filtered_messages) > 0) - self.assertIn(show_message['id'], - [m['ID'] for m in filtered_messages]) + self.assertIn(show_message['id'], [m['ID'] for m in filtered_messages]) # filtering by message level filtered_messages = self.listing_result( 'share', f'message list --message-level {show_message["message_level"]}', - client=self.user_client) + client=self.user_client, + ) self.assertTrue(len(filtered_messages) > 0) - self.assertIn(show_message['id'], - [m['ID'] for m in filtered_messages]) + self.assertIn(show_message['id'], [m['ID'] for m in filtered_messages]) # filtering by Resource ID filtered_messages = self.listing_result( 'share', f'message list --resource-id {self.share["id"]}', - client=self.user_client) + client=self.user_client, + ) self.assertEqual(1, len(filtered_messages)) self.assertEqual(show_message['resource_id'], self.share["id"]) def test_delete_message(self): messages = self.listing_result( - 'share', 'message list', client=self.user_client) - message = [msg for msg in messages - if msg['Resource ID'] == self.share['id']] + 'share', 'message list', client=self.user_client + ) + message = [ + msg for msg in messages if msg['Resource ID'] == self.share['id'] + ] self.assertEqual(1, len(message)) message = message[0] self.openstack(f'share message delete {message["ID"]}') messages = self.listing_result( - 'share', 'message list', client=self.user_client) - messages = [msg for msg in messages - if msg['ID'] == message["ID"]] + 'share', 'message list', client=self.user_client + ) + messages = [msg for msg in messages if msg['ID'] == message["ID"]] self.assertEqual(0, len(messages)) def test_delete_message_invalid_id(self): self.assertRaises( - exceptions.CommandFailed, - self.openstack, - 'share message delete 0' + exceptions.CommandFailed, self.openstack, 'share message delete 0' ) def test_show_message_missing_id(self): self.assertRaises( - exceptions.CommandFailed, - self.openstack, - 'share message show' + exceptions.CommandFailed, self.openstack, 'share message show' ) diff --git a/manilaclient/tests/functional/osc/test_resource_locks.py b/manilaclient/tests/functional/osc/test_resource_locks.py index e7c9cd18..0be7dfa5 100644 --- a/manilaclient/tests/functional/osc/test_resource_locks.py +++ b/manilaclient/tests/functional/osc/test_resource_locks.py @@ -42,25 +42,26 @@ class ResourceLockTests(base.OSCClientTestBase): """Lock CLI test cases""" def setUp(self): - super(ResourceLockTests, self).setUp() + super().setUp() self.share_type = self.create_share_type( - name=data_utils.rand_name('lock_tests_type')) + name=data_utils.rand_name('lock_tests_type') + ) self.share = self.create_share(share_type=self.share_type['id']) def test_lock_create_show_use_delete(self): """Create a deletion lock on share, view it, try it and remove.""" - lock = self.create_resource_lock(self.share['id'], - lock_reason='tigers rule', - client=self.user_client, - add_cleanup=False) + lock = self.create_resource_lock( + self.share['id'], + lock_reason='tigers rule', + client=self.user_client, + add_cleanup=False, + ) client_user_id = self.openstack( - "token issue -c user_id -f value", - client=self.user_client + "token issue -c user_id -f value", client=self.user_client ).strip() client_project_id = self.openstack( - "token issue -c project_id -f value", - client=self.user_client + "token issue -c project_id -f value", client=self.user_client ).strip() self.assertEqual(self.share['id'], lock['resource_id']) @@ -75,60 +76,78 @@ def test_lock_create_show_use_delete(self): self.assertEqual(lock['lock_context'], lock_show['Lock Context']) # When a deletion lock exists, share deletion must fail - self.assertRaises(lib_exc.CommandFailed, - self.openstack, - f"share delete {self.share['id']}") + self.assertRaises( + lib_exc.CommandFailed, + self.openstack, + f"share delete {self.share['id']}", + ) # delete the lock, share will be deleted in cleanup stage - self.openstack(f"share lock delete {lock['id']}", - client=self.user_client) + self.openstack( + f"share lock delete {lock['id']}", client=self.user_client + ) - self.assertRaises(lib_exc.CommandFailed, - self.openstack, - f"share lock show {lock['id']}") + self.assertRaises( + lib_exc.CommandFailed, + self.openstack, + f"share lock show {lock['id']}", + ) def test_lock_list_filter_paginate(self): - lock_1 = self.create_resource_lock(self.share['id'], - lock_reason='tigers rule', - client=self.user_client) - lock_2 = self.create_resource_lock(self.share['id'], - lock_reason='tigers still rule', - client=self.user_client) - lock_3 = self.create_resource_lock(self.share['id'], - lock_reason='admins rule', - client=self.admin_client) - - locks = self.listing_result('share', - f'lock list --resource {self.share["id"]}') + lock_1 = self.create_resource_lock( + self.share['id'], + lock_reason='tigers rule', + client=self.user_client, + ) + lock_2 = self.create_resource_lock( + self.share['id'], + lock_reason='tigers still rule', + client=self.user_client, + ) + lock_3 = self.create_resource_lock( + self.share['id'], + lock_reason='admins rule', + client=self.admin_client, + ) + + locks = self.listing_result( + 'share', f'lock list --resource {self.share["id"]}' + ) self.assertEqual(3, len(locks)) - self.assertEqual(sorted(LOCK_SUMMARY_ATTRIBUTES), - sorted(locks[0].keys())) - - locks = self.listing_result('share', - 'lock list --lock-context user ' - f' --resource {self.share["id"]}') + self.assertEqual( + sorted(LOCK_SUMMARY_ATTRIBUTES), sorted(locks[0].keys()) + ) + + locks = self.listing_result( + 'share', + f'lock list --lock-context user --resource {self.share["id"]}', + ) self.assertEqual(2, len(locks)) self.assertNotIn(lock_3['id'], [lock['ID'] for lock in locks]) - locks = self.listing_result('share', - 'lock list --lock-context user' - f' --resource {self.share["id"]}' - ' --sort-key created_at ' - ' --sort-dir desc ' - ' --limit 1') + locks = self.listing_result( + 'share', + 'lock list --lock-context user' + f' --resource {self.share["id"]}' + ' --sort-key created_at ' + ' --sort-dir desc ' + ' --limit 1', + ) self.assertEqual(1, len(locks)) self.assertIn(lock_2['id'], [lock['ID'] for lock in locks]) self.assertNotIn(lock_1['id'], [lock['ID'] for lock in locks]) self.assertNotIn(lock_3['id'], [lock['ID'] for lock in locks]) def test_lock_set_unset_lock_reason(self): - lock = self.create_resource_lock(self.share['id'], - client=self.user_client) + lock = self.create_resource_lock( + self.share['id'], client=self.user_client + ) self.assertEqual('None', lock['lock_reason']) - self.openstack('share lock set ' - f"--lock-reason 'updated reason' {lock['id']}") + self.openstack( + f'share lock set --lock-reason \'updated reason\' {lock["id"]}' + ) lock_show = self.dict_result("share", f"lock show {lock['id']}") self.assertEqual('updated reason', lock_show['Lock Reason']) @@ -138,30 +157,35 @@ def test_lock_set_unset_lock_reason(self): def test_lock_restrictions(self): """A user can't update or delete a lock created by another user.""" - lock = self.create_resource_lock(self.share['id'], - client=self.admin_client, - add_cleanup=False) + lock = self.create_resource_lock( + self.share['id'], client=self.admin_client, add_cleanup=False + ) self.assertEqual('admin', lock['lock_context']) - self.assertRaises(lib_exc.CommandFailed, - self.openstack, - f"share lock set {lock['id']} " - f"--reason 'i cannot do this'", - client=self.user_client) - self.assertRaises(lib_exc.CommandFailed, - self.openstack, - f"share lock unset {lock['id']} --reason", - client=self.user_client) - self.assertRaises(lib_exc.CommandFailed, - self.openstack, - f"share lock delete {lock['id']} ", - client=self.user_client) - - self.openstack(f'share lock set ' - f'--lock-reason "I can do this" ' - f'{lock["id"]}', - client=self.admin_client) - - self.openstack(f'share lock delete ' - f'{lock["id"]}', - client=self.admin_client) + self.assertRaises( + lib_exc.CommandFailed, + self.openstack, + f"share lock set {lock['id']} --reason 'i cannot do this'", + client=self.user_client, + ) + self.assertRaises( + lib_exc.CommandFailed, + self.openstack, + f"share lock unset {lock['id']} --reason", + client=self.user_client, + ) + self.assertRaises( + lib_exc.CommandFailed, + self.openstack, + f"share lock delete {lock['id']} ", + client=self.user_client, + ) + + self.openstack( + f'share lock set --lock-reason "I can do this" {lock["id"]}', + client=self.admin_client, + ) + + self.openstack( + f'share lock delete {lock["id"]}', client=self.admin_client + ) diff --git a/manilaclient/tests/functional/osc/test_share_access_rules.py b/manilaclient/tests/functional/osc/test_share_access_rules.py index 334cde0b..b90e22ae 100644 --- a/manilaclient/tests/functional/osc/test_share_access_rules.py +++ b/manilaclient/tests/functional/osc/test_share_access_rules.py @@ -18,14 +18,14 @@ @ddt.ddt class ShareAccessAllowTestCase(base.OSCClientTestBase): - def test_share_access_allow(self): share = self.create_share() access_rule = self.create_share_access_rule( share=share['name'], access_type='ip', access_to='0.0.0.0/0', - wait=True) + wait=True, + ) self.assertEqual(access_rule['share_id'], share['id']) self.assertEqual(access_rule['state'], 'active') @@ -36,10 +36,10 @@ def test_share_access_allow(self): self.assertEqual(access_rule['properties'], '') self.assertEqual(access_rule['access_level'], 'rw') - access_rules = self.listing_result('share', - f'access list {share["id"]}') - self.assertIn(access_rule['id'], - [item['ID'] for item in access_rules]) + access_rules = self.listing_result( + 'share', f'access list {share["id"]}' + ) + self.assertIn(access_rule['id'], [item['ID'] for item in access_rules]) # create another access rule with different params access_rule = self.create_share_access_rule( @@ -47,7 +47,8 @@ def test_share_access_allow(self): access_type='ip', access_to='12.34.56.78', access_level='ro', - properties='foo=bar') + properties='foo=bar', + ) self.assertEqual(access_rule['access_type'], 'ip') self.assertEqual(access_rule['access_to'], '12.34.56.78') @@ -55,18 +56,23 @@ def test_share_access_allow(self): self.assertEqual(access_rule['access_level'], 'ro') @ddt.data( - {'lock_visibility': True, 'lock_deletion': True, - 'lock_reason': None}, - {'lock_visibility': False, 'lock_deletion': True, - 'lock_reason': None}, - {'lock_visibility': True, 'lock_deletion': False, - 'lock_reason': 'testing'}, - {'lock_visibility': True, 'lock_deletion': False, - 'lock_reason': 'testing'}, + {'lock_visibility': True, 'lock_deletion': True, 'lock_reason': None}, + {'lock_visibility': False, 'lock_deletion': True, 'lock_reason': None}, + { + 'lock_visibility': True, + 'lock_deletion': False, + 'lock_reason': 'testing', + }, + { + 'lock_visibility': True, + 'lock_deletion': False, + 'lock_reason': 'testing', + }, ) @ddt.unpack - def test_share_access_allow_restrict(self, lock_visibility, - lock_deletion, lock_reason): + def test_share_access_allow_restrict( + self, lock_visibility, lock_deletion, lock_reason + ): share = self.create_share() access_rule = self.create_share_access_rule( share=share['id'], @@ -75,19 +81,21 @@ def test_share_access_allow_restrict(self, lock_visibility, wait=True, lock_visibility=lock_visibility, lock_deletion=lock_deletion, - lock_reason=lock_reason) + lock_reason=lock_reason, + ) if lock_deletion: self.assertRaises( tempest_exc.CommandFailed, self.openstack, 'share', - params=f'access delete {share["id"]} {access_rule["id"]}' + params=f'access delete {share["id"]} {access_rule["id"]}', ) self.openstack( 'share', params=f'access delete {share["id"]} {access_rule["id"]} ' - f'--unrestrict --wait') + f'--unrestrict --wait', + ) @ddt.ddt @@ -100,26 +108,29 @@ def test_share_access_deny(self, lock_deletion): access_type='ip', access_to='0.0.0.0/0', wait=True, - lock_deletion=lock_deletion) + lock_deletion=lock_deletion, + ) - access_rules = self.listing_result('share', - f'access list {share["id"]}') + access_rules = self.listing_result( + 'share', f'access list {share["id"]}' + ) num_access_rules = len(access_rules) delete_params = ( - f'access delete {share["name"]} {access_rule["id"]} --wait') + f'access delete {share["name"]} {access_rule["id"]} --wait' + ) if lock_deletion: delete_params += ' --unrestrict' self.openstack('share', params=delete_params) - access_rules = self.listing_result('share', - f'access list {share["id"]}') + access_rules = self.listing_result( + 'share', f'access list {share["id"]}' + ) self.assertEqual(num_access_rules - 1, len(access_rules)) @ddt.data class ListShareAccessRulesTestCase(base.OSCClientTestBase): - @ddt.data("2.45", "2.33", "2.21") def test_share_access_list(self, microversion): share = self.create_share() @@ -127,25 +138,21 @@ def test_share_access_list(self, microversion): share=share['name'], access_type='ip', access_to='0.0.0.0/0', - wait=True) + wait=True, + ) output = self.openstack( 'share', params=f'access list {share["id"]}', - flags=f'--os-share-api-version {microversion}') + flags=f'--os-share-api-version {microversion}', + ) access_rule_list = self.parser.listing(output) - base_list = [ - 'ID', - 'Access Type', - 'Access To', - 'Access Level', - 'State'] + base_list = ['ID', 'Access Type', 'Access To', 'Access Level', 'State'] if microversion >= '2.33': base_list.append('Access Key') if microversion >= '2.45': - base_list.extend(['Created At', - 'Updated At']) + base_list.extend(['Created At', 'Updated At']) self.assertTableStruct(access_rule_list, base_list) self.assertTrue(len(access_rule_list) > 0) @@ -155,19 +162,21 @@ def test_share_access_list(self, microversion): access_type='ip', access_to='192.168.0.151', wait=True, - properties='foo=bar') + properties='foo=bar', + ) output = self.openstack( 'share', - params=f'access list {share["id"]} ' - f'--properties foo=bar', - flags=f'--os-share-api-version {microversion}') + params=f'access list {share["id"]} --properties foo=bar', + flags=f'--os-share-api-version {microversion}', + ) access_rule_properties = self.parser.listing(output) self.assertEqual(1, len(access_rule_properties)) - self.assertEqual(access_rule_properties['id'], - access_rule_properties[0]['ID']) + self.assertEqual( + access_rule_properties['id'], access_rule_properties[0]['ID'] + ) def test_share_access_list_with_filters(self): share = self.create_share() @@ -176,17 +185,20 @@ def test_share_access_list_with_filters(self): share=share['name'], access_type='ip', access_to='0.0.0.0/0', - wait=True) + wait=True, + ) self.create_share_access_rule( share=share['name'], access_type='ip', access_to=access_to_filter, - wait=True) + wait=True, + ) output = self.openstack( 'share', params=f'access list {share["id"]} --access-to {access_to_filter}', - flags='--os-share-api-version 2.82') + flags='--os-share-api-version 2.82', + ) access_rule_list = self.parser.listing(output) self.assertTrue(len(access_rule_list) == 1) @@ -199,11 +211,12 @@ def test_share_access_show(self): share=share['name'], access_type='ip', access_to='0.0.0.0/0', - wait=True) + wait=True, + ) access_rule_show = self.dict_result( - 'share', - f'access show {access_rule["id"]}') + 'share', f'access show {access_rule["id"]}' + ) self.assertEqual(access_rule_show['id'], access_rule['id']) self.assertEqual(access_rule_show['share_id'], share['id']) self.assertEqual(access_rule_show['access_level'], 'rw') @@ -211,8 +224,9 @@ def test_share_access_show(self): self.assertEqual(access_rule_show['access_type'], 'ip') self.assertEqual(access_rule_show['state'], 'active') self.assertEqual(access_rule_show['access_key'], 'None') - self.assertEqual(access_rule_show['created_at'], - access_rule['created_at']) + self.assertEqual( + access_rule_show['created_at'], access_rule['created_at'] + ) self.assertEqual(access_rule_show['properties'], '') self.assertIn('updated_at', access_rule_show) @@ -224,17 +238,19 @@ def test_set_share_access_metadata(self): share=share['name'], access_type='ip', access_to='0.0.0.0/0', - wait=True) + wait=True, + ) self.assertEqual(access_rule['properties'], '') - self.openstack('share', - params=f'access set {access_rule["id"]} ' - f'--property foo=bar') + self.openstack( + 'share', + params=f'access set {access_rule["id"]} --property foo=bar', + ) access_rule = self.dict_result( - 'share', - f'access show {access_rule["id"]}') + 'share', f'access show {access_rule["id"]}' + ) self.assertEqual(access_rule['properties'], 'foo : bar') def test_set_share_access_level(self): @@ -243,16 +259,17 @@ def test_set_share_access_level(self): share=share['name'], access_type='ip', access_to='0.0.0.0/0', - wait=True) + wait=True, + ) self.assertEqual(access_rule['access_level'], 'rw') - self.openstack('share', - params=f'access set {access_rule["id"]} ' - f'--access-level ro') + self.openstack( + 'share', params=f'access set {access_rule["id"]} --access-level ro' + ) access_rule = self.dict_result( - 'share', - f'access show {access_rule["id"]}') + 'share', f'access show {access_rule["id"]}' + ) self.assertEqual(access_rule['access_level'], 'ro') @@ -264,13 +281,14 @@ def test_unset_share_access(self): access_type='ip', access_to='192.168.0.101', wait=True, - properties='foo=bar') + properties='foo=bar', + ) - self.openstack('share', - params=f'access unset ' - f'--property foo {access_rule["id"]}') + self.openstack( + 'share', params=f'access unset --property foo {access_rule["id"]}' + ) access_rule_unset = self.dict_result( - 'share', - f'access show {access_rule["id"]}') + 'share', f'access show {access_rule["id"]}' + ) self.assertEqual(access_rule_unset['properties'], '') diff --git a/manilaclient/tests/functional/osc/test_share_backups.py b/manilaclient/tests/functional/osc/test_share_backups.py index 978c617c..bccfe4b8 100644 --- a/manilaclient/tests/functional/osc/test_share_backups.py +++ b/manilaclient/tests/functional/osc/test_share_backups.py @@ -25,11 +25,13 @@ def test_share_backup_create(self): share_id=share['id'], name='test_backup_create', description='Description', - backup_options={'dummy': True}) + backup_options={'dummy': True}, + ) # fetch latest after periodic callback updates status - backup = json.loads(self.openstack( - f'share backup show -f json {backup["id"]}')) + backup = json.loads( + self.openstack(f'share backup show -f json {backup["id"]}') + ) self.assertEqual(share["id"], backup["share_id"]) self.assertEqual('test_backup_create', backup["name"]) @@ -37,8 +39,7 @@ def test_share_backup_create(self): self.assertEqual('available', backup["status"]) backups_list = self.listing_result('share backup', 'list') - self.assertIn(backup['id'], - [item['ID'] for item in backups_list]) + self.assertIn(backup['id'], [item['ID'] for item in backups_list]) def test_share_backup_delete(self): share = self.create_share() @@ -46,10 +47,10 @@ def test_share_backup_delete(self): backup = self.create_backup( share_id=share['id'], backup_options={'dummy': True}, - add_cleanup=False) + add_cleanup=False, + ) - self.openstack( - f'share backup delete {backup["id"]} --wait') + self.openstack(f'share backup delete {backup["id"]} --wait') self.check_object_deleted('share backup', backup["id"]) @@ -60,10 +61,10 @@ def test_share_backup_show(self): share_id=share['id'], name='test_backup_show', description='Description', - backup_options={'dummy': True}) + backup_options={'dummy': True}, + ) - show_result = self.dict_result( - 'share backup', f'show {backup["id"]}') + show_result = self.dict_result('share backup', f'show {backup["id"]}') self.assertEqual(backup["id"], show_result["id"]) self.assertEqual('test_backup_show', show_result["name"]) @@ -73,16 +74,15 @@ def test_share_backup_restore(self): share = self.create_share() backup = self.create_backup( - share_id=share['id'], - backup_options={'dummy': True}) + share_id=share['id'], backup_options={'dummy': True} + ) - self.openstack( - f'share backup restore {backup["id"]} --wait') + self.openstack(f'share backup restore {backup["id"]} --wait') - backup = json.loads(self.openstack( - f'share backup show -f json {backup["id"]}')) - share = json.loads(self.openstack( - f'share show -f json {share["id"]}')) + backup = json.loads( + self.openstack(f'share backup show -f json {backup["id"]}') + ) + share = json.loads(self.openstack(f'share show -f json {share["id"]}')) self.assertEqual('available', backup['status']) self.assertEqual('available', share['status']) @@ -90,15 +90,16 @@ def test_share_backup_restore(self): def test_share_backup_set(self): share = self.create_share() - backup = self.create_backup(share_id=share['id'], - backup_options={'dummy': True}) + backup = self.create_backup( + share_id=share['id'], backup_options={'dummy': True} + ) self.openstack( f'share backup set {backup["id"]} ' - f'--name test_backup_set --description Description') + f'--name test_backup_set --description Description' + ) - show_result = self.dict_result( - 'share backup ', f'show {backup["id"]}') + show_result = self.dict_result('share backup ', f'show {backup["id"]}') self.assertEqual(backup['id'], show_result["id"]) self.assertEqual('test_backup_set', show_result["name"]) @@ -111,13 +112,16 @@ def test_share_backup_unset(self): share_id=share['id'], name='test_backup_unset', description='Description', - backup_options={'dummy': True}) + backup_options={'dummy': True}, + ) self.openstack( - f'share backup unset {backup["id"]} --name --description') + f'share backup unset {backup["id"]} --name --description' + ) - show_result = json.loads(self.openstack( - f'share backup show -f json {backup["id"]}')) + show_result = json.loads( + self.openstack(f'share backup show -f json {backup["id"]}') + ) self.assertEqual(backup['id'], show_result["id"]) self.assertIsNone(show_result["name"]) @@ -127,44 +131,44 @@ def test_share_backup_list(self): share_1 = self.create_share() share_2 = self.create_share() - backup_1 = self.create_backup(share_id=share_1['id'], - backup_options={'dummy': True}) - backup_2 = self.create_backup(share_id=share_2['id'], - backup_options={'dummy': True}) + backup_1 = self.create_backup( + share_id=share_1['id'], backup_options={'dummy': True} + ) + backup_2 = self.create_backup( + share_id=share_2['id'], backup_options={'dummy': True} + ) backups_list = self.listing_result( 'share backup', f'list --name {backup_2["name"]} ' ) - self.assertTableStruct(backups_list, [ - 'ID', - 'Name', - 'Share ID', - 'Status' - ]) + self.assertTableStruct( + backups_list, ['ID', 'Name', 'Share ID', 'Status'] + ) self.assertEqual(1, len(backups_list)) - self.assertIn(backup_2['id'], - [item['ID'] for item in backups_list]) + self.assertIn(backup_2['id'], [item['ID'] for item in backups_list]) backups_list = self.listing_result( 'share backup', f'list --share {share_1["id"]} --detail' ) - self.assertTableStruct(backups_list, [ - 'ID', - 'Name', - 'Share ID', - 'Status', - 'Description', - 'Availability Zone', - 'Created At', - 'Updated At', - 'Size', - 'Progress', - 'Restore Progress', - 'Host', - 'Topic', - ]) + self.assertTableStruct( + backups_list, + [ + 'ID', + 'Name', + 'Share ID', + 'Status', + 'Description', + 'Availability Zone', + 'Created At', + 'Updated At', + 'Size', + 'Progress', + 'Restore Progress', + 'Host', + 'Topic', + ], + ) self.assertEqual(1, len(backups_list)) - self.assertIn(backup_1['id'], - [item['ID'] for item in backups_list]) + self.assertIn(backup_1['id'], [item['ID'] for item in backups_list]) diff --git a/manilaclient/tests/functional/osc/test_share_group_type_access.py b/manilaclient/tests/functional/osc/test_share_group_type_access.py index 2ea865e0..5537b61a 100644 --- a/manilaclient/tests/functional/osc/test_share_group_type_access.py +++ b/manilaclient/tests/functional/osc/test_share_group_type_access.py @@ -17,32 +17,37 @@ class SharesGroupTypeAccessCLITest(base.OSCClientTestBase): - def test_share_group_type_access_create(self): share_group_type_name = self.create_share_group_type( - share_types='dhss_false', public=False)['name'] + share_types='dhss_false', public=False + )['name'] access_list = self.listing_result( - 'share', f'group type access list {share_group_type_name}') + 'share', f'group type access list {share_group_type_name}' + ) self.assertEqual(0, len(access_list)) cmd_output = jsonutils.loads(self.openstack('token issue -f json ')) auth_project_id = cmd_output['project_id'] self.share_group_type_access_create( - share_group_type_name, auth_project_id) + share_group_type_name, auth_project_id + ) share_group_type_access_list = self.listing_result( - 'share', f'group type access list {share_group_type_name}') + 'share', f'group type access list {share_group_type_name}' + ) self.assertEqual(1, len(share_group_type_access_list)) def test_share_group_type_access_delete(self): share_group_type_name = self.create_share_group_type( - share_types='dhss_false', public=False)['name'] + share_types='dhss_false', public=False + )['name'] access_list = self.listing_result( - 'share', f'group type access list {share_group_type_name}') + 'share', f'group type access list {share_group_type_name}' + ) self.assertEqual(0, len(access_list)) cmd_output = jsonutils.loads(self.openstack('token issue -f json ')) @@ -51,38 +56,47 @@ def test_share_group_type_access_delete(self): # Create using name to ensure that we are "translating" the # name into the actual ID in the CLI self.share_group_type_access_create( - share_group_type_name, auth_project_id) + share_group_type_name, auth_project_id + ) share_group_type_access_list = self.listing_result( - 'share', f'group type access list {share_group_type_name}') + 'share', f'group type access list {share_group_type_name}' + ) self.assertEqual(1, len(share_group_type_access_list)) self.assertEqual( - share_group_type_access_list[0]['Project ID'], auth_project_id) + share_group_type_access_list[0]['Project ID'], auth_project_id + ) self.share_group_type_access_delete( - share_group_type_name, auth_project_id) + share_group_type_name, auth_project_id + ) access_list = self.listing_result( - 'share', f'group type access list {share_group_type_name}') + 'share', f'group type access list {share_group_type_name}' + ) self.assertEqual(0, len(access_list)) def test_share_group_type_access_list(self): share_group_type_name = self.create_share_group_type( - share_types='dhss_false', public=False)['name'] + share_types='dhss_false', public=False + )['name'] access_list = self.listing_result( - 'share', f'group type access list {share_group_type_name}') + 'share', f'group type access list {share_group_type_name}' + ) self.assertEqual(0, len(access_list)) cmd_output = jsonutils.loads(self.openstack('token issue -f json ')) auth_project_id = cmd_output['project_id'] self.share_group_type_access_create( - share_group_type_name, auth_project_id) + share_group_type_name, auth_project_id + ) share_group_type_access_list = self.listing_result( - 'share', f'group type access list {share_group_type_name}') + 'share', f'group type access list {share_group_type_name}' + ) self.assertEqual(1, len(share_group_type_access_list)) self.assertTableStruct(access_list, ['Project ID']) diff --git a/manilaclient/tests/functional/osc/test_share_limits.py b/manilaclient/tests/functional/osc/test_share_limits.py index 4176abe4..82d922ec 100644 --- a/manilaclient/tests/functional/osc/test_share_limits.py +++ b/manilaclient/tests/functional/osc/test_share_limits.py @@ -17,27 +17,25 @@ class ListSharePoolsTestCase(base.OSCClientTestBase): - def test_limits_show_absolute(self): - limits = self.listing_result('share', ' limits show --absolute') - self.assertTableStruct(limits, [ - 'Name', - 'Value' - ]) + self.assertTableStruct(limits, ['Name', 'Value']) def test_limits_show_rate(self): - - limits = self.listing_result('share', - ' limits show --rate --print-empty') - - self.assertTableStruct(limits, [ - 'Verb', - 'Regex', - 'URI', - 'Value', - 'Remaining', - 'Unit', - 'Next Available' - ]) + limits = self.listing_result( + 'share', ' limits show --rate --print-empty' + ) + + self.assertTableStruct( + limits, + [ + 'Verb', + 'Regex', + 'URI', + 'Value', + 'Remaining', + 'Unit', + 'Next Available', + ], + ) diff --git a/manilaclient/tests/functional/osc/test_share_network_subnets.py b/manilaclient/tests/functional/osc/test_share_network_subnets.py index 7f00c449..e9b77e2a 100644 --- a/manilaclient/tests/functional/osc/test_share_network_subnets.py +++ b/manilaclient/tests/functional/osc/test_share_network_subnets.py @@ -17,12 +17,10 @@ class ShareNetworkSubnetsCLITest(base.OSCClientTestBase): - def test_openstack_share_network_create_check(self): share_network = self.create_share_network() - check_result = self.check_create_network_subnet( - share_network['id']) + check_result = self.check_create_network_subnet(share_network['id']) self.assertEqual('True', check_result['compatible']) self.assertEqual('', check_result['hosts_check_result']) @@ -31,7 +29,8 @@ def test_openstack_share_network_create_check_restart(self): share_network = self.create_share_network() check_result = self.check_create_network_subnet( - share_network['id'], restart_check=True) + share_network['id'], restart_check=True + ) self.assertEqual('True', check_result['compatible']) self.assertEqual('', check_result['hosts_check_result']) diff --git a/manilaclient/tests/functional/osc/test_share_networks.py b/manilaclient/tests/functional/osc/test_share_networks.py index 7739078b..67c053c1 100644 --- a/manilaclient/tests/functional/osc/test_share_networks.py +++ b/manilaclient/tests/functional/osc/test_share_networks.py @@ -14,7 +14,6 @@ class ShareNetworksCLITest(base.OSCClientTestBase): - def test_openstack_share_network_create(self): share_network_name = 'test_create_share_network' share_network = self.create_share_network(name=share_network_name) @@ -22,68 +21,82 @@ def test_openstack_share_network_create(self): self.assertEqual(share_network['name'], share_network_name) share_network_list = self.listing_result('share network', 'list') - self.assertIn(share_network['id'], - [item['ID'] for item in share_network_list]) + self.assertIn( + share_network['id'], [item['ID'] for item in share_network_list] + ) def test_openstack_share_network_list(self): share_network = self.create_share_network() share_network_list = self.listing_result('share network', 'list') - self.assertTableStruct(share_network_list, [ - 'ID', - 'Name', - ]) - self.assertIn(share_network['id'], - [item['ID'] for item in share_network_list]) + self.assertTableStruct( + share_network_list, + [ + 'ID', + 'Name', + ], + ) + self.assertIn( + share_network['id'], [item['ID'] for item in share_network_list] + ) def test_openstack_share_network_show(self): share_network = self.create_share_network() - result = self.dict_result('share network', - 'show %s' % share_network['id']) + result = self.dict_result( + 'share network', 'show {}'.format(share_network['id']) + ) self.assertEqual(share_network['id'], result['id']) - listing_result = self.listing_result('share network', - 'show %s' % share_network['id']) - self.assertTableStruct(listing_result, [ - 'Field', - 'Value' - ]) + listing_result = self.listing_result( + 'share network', 'show {}'.format(share_network['id']) + ) + self.assertTableStruct(listing_result, ['Field', 'Value']) def test_openstack_share_network_delete(self): share_network = self.create_share_network(add_cleanup=False) share_network_list = self.listing_result('share network', 'list') - self.assertIn(share_network['id'], - [item['ID'] for item in share_network_list]) + self.assertIn( + share_network['id'], [item['ID'] for item in share_network_list] + ) - self.openstack('share network delete %s' % share_network['id']) + self.openstack('share network delete {}'.format(share_network['id'])) self.check_object_deleted('share network', share_network['id']) - share_network_list_after_delete = self.listing_result('share network', - 'list') + share_network_list_after_delete = self.listing_result( + 'share network', 'list' + ) self.assertNotIn( share_network['id'], - [item['ID'] for item in share_network_list_after_delete]) + [item['ID'] for item in share_network_list_after_delete], + ) def test_openstack_share_network_set(self): share_network = self.create_share_network() - self.openstack('share network set %s --name %s' - % (share_network['id'], 'new_name')) - result = self.dict_result('share network', 'show %s' % - share_network['id']) + self.openstack( + 'share network set {} --name {}'.format( + share_network['id'], 'new_name' + ) + ) + result = self.dict_result( + 'share network', 'show {}'.format(share_network['id']) + ) self.assertEqual(share_network['id'], result['id']) self.assertEqual('new_name', result['name']) def test_openstack_share_network_unset(self): share_network = self.create_share_network(name='test_name') - result1 = self.dict_result('share network', 'show %s' % - share_network['id']) + result1 = self.dict_result( + 'share network', 'show {}'.format(share_network['id']) + ) self.assertEqual(share_network['id'], result1['id']) self.assertEqual(share_network['name'], result1['name']) - self.openstack('share network unset %s --name' - % (share_network['id'])) - result2 = self.dict_result('share network', 'show %s' % - share_network['id']) + self.openstack( + 'share network unset {} --name'.format(share_network['id']) + ) + result2 = self.dict_result( + 'share network', 'show {}'.format(share_network['id']) + ) self.assertEqual(share_network['id'], result2['id']) self.assertEqual('None', result2['name']) diff --git a/manilaclient/tests/functional/osc/test_share_pools.py b/manilaclient/tests/functional/osc/test_share_pools.py index f086e5e4..1f1c638c 100644 --- a/manilaclient/tests/functional/osc/test_share_pools.py +++ b/manilaclient/tests/functional/osc/test_share_pools.py @@ -14,33 +14,25 @@ class ListSharePoolsTestCase(base.OSCClientTestBase): - def test_pool_list(self): pools = self.list_pools() - self.assertTableStruct(pools, [ - 'Name', - 'Host', - 'Backend', - 'Pool' - ]) + self.assertTableStruct(pools, ['Name', 'Host', 'Backend', 'Pool']) self.assertTrue(len(pools) > 0) # Filter results first_pool = pools[0] - pools = self.list_pools(backend=first_pool['Backend'], - host=first_pool['Host'], - pool=first_pool['Pool']) + pools = self.list_pools( + backend=first_pool['Backend'], + host=first_pool['Host'], + pool=first_pool['Pool'], + ) self.assertEqual(1, len(pools)) self.assertEqual(first_pool['Name'], pools[0]['Name']) def test_pool_list_detail(self): pools = self.list_pools(detail=True) - self.assertTableStruct(pools, [ - 'Name', - 'Host', - 'Backend', - 'Pool', - 'Capabilities' - ]) + self.assertTableStruct( + pools, ['Name', 'Host', 'Backend', 'Pool', 'Capabilities'] + ) self.assertTrue(len(pools) > 0) diff --git a/manilaclient/tests/functional/osc/test_share_replica_export_locations.py b/manilaclient/tests/functional/osc/test_share_replica_export_locations.py index 7e6f6a40..586275cb 100644 --- a/manilaclient/tests/functional/osc/test_share_replica_export_locations.py +++ b/manilaclient/tests/functional/osc/test_share_replica_export_locations.py @@ -16,44 +16,51 @@ class ShareReplicaExportLocationsCLITest(base.OSCClientTestBase): - def test_openstack_share_replica_export_location_list(self): slug = 'replica-supported' share_type = self.create_share_type( - data_utils.rand_name(slug), 'False', extra_specs={ - 'replication_type': 'readable'}) + data_utils.rand_name(slug), + 'False', + extra_specs={'replication_type': 'readable'}, + ) share = self.create_share(share_type=share_type['name']) replica = self.create_share_replica(share['id'], wait=True) rep_exp_loc_list = self.listing_result( - 'share replica export location', f'list {replica["id"]}') - self.assertTableStruct(rep_exp_loc_list, [ - 'ID', - 'Availability Zone', - 'Replica State', - 'Preferred', - 'Path' - ]) + 'share replica export location', f'list {replica["id"]}' + ) + self.assertTableStruct( + rep_exp_loc_list, + ['ID', 'Availability Zone', 'Replica State', 'Preferred', 'Path'], + ) exp_loc_list = self.openstack( - f'share replica show {replica["id"]} -f json') + f'share replica show {replica["id"]} -f json' + ) exp_loc_list = json.loads(exp_loc_list) - self.assertIn(exp_loc_list.get('export_locations')[0]['id'], - [item['ID'] for item in rep_exp_loc_list]) + self.assertIn( + exp_loc_list.get('export_locations')[0]['id'], + [item['ID'] for item in rep_exp_loc_list], + ) def test_openstack_share_replica_export_location_show(self): slug = 'replica-supported' share_type = self.create_share_type( - data_utils.rand_name(slug), 'False', extra_specs={ - 'replication_type': 'readable'}) + data_utils.rand_name(slug), + 'False', + extra_specs={'replication_type': 'readable'}, + ) share = self.create_share(share_type=share_type['name']) replica = self.create_share_replica(share['id'], wait=True) rep_exp_loc_obj = self.get_share_replica_export_locations( - replica['id'])[0] + replica['id'] + )[0] exp_loc_list = self.openstack( - f'share replica show {replica["id"]} -f json') + f'share replica show {replica["id"]} -f json' + ) exp_loc_list = json.loads(exp_loc_list) result = self.dict_result( 'share replica export location', - f'show {replica["id"]} {rep_exp_loc_obj["ID"]}') + f'show {replica["id"]} {rep_exp_loc_obj["ID"]}', + ) export_location = exp_loc_list['export_locations'][0] self.assertEqual(result['id'], export_location['id']) diff --git a/manilaclient/tests/functional/osc/test_share_replicas.py b/manilaclient/tests/functional/osc/test_share_replicas.py index 0658ccdd..4eb84604 100644 --- a/manilaclient/tests/functional/osc/test_share_replicas.py +++ b/manilaclient/tests/functional/osc/test_share_replicas.py @@ -18,36 +18,41 @@ class ShareReplicasCLITest(base.OSCClientTestBase): - def _create_share_and_replica(self, add_cleanup=True): replication_type = CONF.replication_type share_type = self.create_share_type( data_utils.rand_name('test_share_type'), dhss=True, - extra_specs={'replication_type': replication_type}) + extra_specs={'replication_type': replication_type}, + ) share_network = self.create_share_network(name='test_share_network') - share = self.create_share(share_type=share_type['name'], - share_network=share_network['id']) - replica = self.create_share_replica(share['id'], - share_network=share_network['id'], - wait=True, - add_cleanup=add_cleanup) + share = self.create_share( + share_type=share_type['name'], share_network=share_network['id'] + ) + replica = self.create_share_replica( + share['id'], + share_network=share_network['id'], + wait=True, + add_cleanup=add_cleanup, + ) return replica def test_share_replica_create(self): share_replica = self._create_share_and_replica() share_replica_list = self.listing_result('share replica', 'list') - self.assertTableStruct(share_replica_list, [ - 'ID', - 'Status', - 'Share ID', - ]) - self.assertIn(share_replica['id'], - [item['ID'] for item in share_replica_list]) + self.assertTableStruct( + share_replica_list, + [ + 'ID', + 'Status', + 'Share ID', + ], + ) + self.assertIn( + share_replica['id'], [item['ID'] for item in share_replica_list] + ) def test_share_replica_delete(self): share_replica = self._create_share_and_replica(add_cleanup=False) - self.openstack( - f'share replica delete {share_replica["id"]}' - ) + self.openstack(f'share replica delete {share_replica["id"]}') self.check_object_deleted('share replica', share_replica["id"]) diff --git a/manilaclient/tests/functional/osc/test_share_services.py b/manilaclient/tests/functional/osc/test_share_services.py index cd5286e6..a44fd7a8 100644 --- a/manilaclient/tests/functional/osc/test_share_services.py +++ b/manilaclient/tests/functional/osc/test_share_services.py @@ -14,45 +14,47 @@ class ShareServicesTestCase(base.OSCClientTestBase): - def test_services_list(self): services = self.list_services() - self.assertTableStruct(services, [ - 'ID', - 'Binary', - 'Host', - 'Zone', - 'Status', - 'State', - 'Updated At' - ]) + self.assertTableStruct( + services, + ['ID', 'Binary', 'Host', 'Zone', 'Status', 'State', 'Updated At'], + ) self.assertTrue(len(services) > 0) # Filter results first_service = services[0] - services = self.list_services(host=first_service['Host'], - status=first_service['Status'], - state=first_service['State']) + services = self.list_services( + host=first_service['Host'], + status=first_service['Status'], + state=first_service['State'], + ) self.assertEqual(1, len(services)) for attr in ('ID', 'Binary', 'Host', 'State', 'Status', 'Zone'): self.assertEqual(first_service[attr], services[0][attr]) def test_services_set(self): services = self.list_services() - service = [service for service in services if - service["Binary"] == "manila-data"] + service = [ + service + for service in services + if service["Binary"] == "manila-data" + ] first_service = service[0] - self.openstack(f'share service set {first_service["Host"]} ' - f'{first_service["Binary"]} ' - '--disable --disable-reason test') - result = self.listing_result('share service', - 'list --status disabled') + self.openstack( + f'share service set {first_service["Host"]} ' + f'{first_service["Binary"]} ' + '--disable --disable-reason test' + ) + result = self.listing_result('share service', 'list --status disabled') self.assertEqual(first_service['ID'], result[0]['ID']) self.assertEqual('disabled', result[0]['Status']) self.assertEqual('test', result[0]['Disabled Reason']) # enable the share service again - self.openstack(f'share service set {first_service["Host"]} ' - f'{first_service["Binary"]} ' - '--enable') + self.openstack( + f'share service set {first_service["Host"]} ' + f'{first_service["Binary"]} ' + '--enable' + ) diff --git a/manilaclient/tests/functional/osc/test_share_snapshot_instances.py b/manilaclient/tests/functional/osc/test_share_snapshot_instances.py index 1fa91811..39b63605 100644 --- a/manilaclient/tests/functional/osc/test_share_snapshot_instances.py +++ b/manilaclient/tests/functional/osc/test_share_snapshot_instances.py @@ -14,62 +14,75 @@ class ShareSnapshotInstancesCLITest(base.OSCClientTestBase): - def test_openstack_share_snapshot_instance_list(self): share = self.create_share() snapshot = self.create_snapshot(share['id']) share_snapshot_instances_list = self.listing_result( - 'share snapshot instance', 'list --detailed') - self.assertTableStruct(share_snapshot_instances_list, [ - 'ID', - 'Snapshot ID', - 'Status', - 'Created At', - 'Updated At', - 'Share ID', - 'Share Instance ID', - 'Progress', - 'Provider Location' - ]) - self.assertIn(snapshot['id'], - [item['Snapshot ID'] for item in ( - share_snapshot_instances_list)]) + 'share snapshot instance', 'list --detailed' + ) + self.assertTableStruct( + share_snapshot_instances_list, + [ + 'ID', + 'Snapshot ID', + 'Status', + 'Created At', + 'Updated At', + 'Share ID', + 'Share Instance ID', + 'Progress', + 'Provider Location', + ], + ) + self.assertIn( + snapshot['id'], + [item['Snapshot ID'] for item in (share_snapshot_instances_list)], + ) def test_openstack_share_snapshot_instance_show(self): share = self.create_share() snapshot = self.create_snapshot(share['id'], wait=True) share_snapshot_instance = self.listing_result( - "share snapshot instance", f'list --snapshot {snapshot["id"]}') - result = self.dict_result('share snapshot instance', - f'show {share_snapshot_instance[0]["ID"]}') + "share snapshot instance", f'list --snapshot {snapshot["id"]}' + ) + result = self.dict_result( + 'share snapshot instance', + f'show {share_snapshot_instance[0]["ID"]}', + ) self.assertEqual(share_snapshot_instance[0]['ID'], result['id']) - self.assertEqual(share_snapshot_instance[0]['Snapshot ID'], - result['snapshot_id']) + self.assertEqual( + share_snapshot_instance[0]['Snapshot ID'], result['snapshot_id'] + ) listing_result = self.listing_result( - 'share snapshot instance', f'show ' - f'{share_snapshot_instance[0]["ID"]}') - self.assertTableStruct(listing_result, [ - 'Field', - 'Value' - ]) + 'share snapshot instance', + f'show {share_snapshot_instance[0]["ID"]}', + ) + self.assertTableStruct(listing_result, ['Field', 'Value']) def test_openstack_share_snapshot_instance_set(self): share = self.create_share() snapshot = self.create_snapshot(share['id'], wait=True) share_snapshot_instance = self.listing_result( - "share snapshot instance", f'list --snapshot {snapshot["id"]}') - result1 = self.dict_result('share snapshot instance', - f'show {share_snapshot_instance[0]["ID"]}') + "share snapshot instance", f'list --snapshot {snapshot["id"]}' + ) + result1 = self.dict_result( + 'share snapshot instance', + f'show {share_snapshot_instance[0]["ID"]}', + ) self.assertEqual(share_snapshot_instance[0]['ID'], result1['id']) self.assertEqual(snapshot['id'], result1['snapshot_id']) self.assertEqual('available', result1['status']) - self.openstack('share snapshot instance set ' - f'{share_snapshot_instance[0]["ID"]} --status error') - result2 = self.dict_result('share snapshot instance', - f'show {share_snapshot_instance[0]["ID"]}') + self.openstack( + 'share snapshot instance set ' + f'{share_snapshot_instance[0]["ID"]} --status error' + ) + result2 = self.dict_result( + 'share snapshot instance', + f'show {share_snapshot_instance[0]["ID"]}', + ) self.assertEqual(share_snapshot_instance[0]["ID"], result2['id']) self.assertEqual('error', result2['status']) diff --git a/manilaclient/tests/functional/osc/test_share_snapshots.py b/manilaclient/tests/functional/osc/test_share_snapshots.py index 127ae648..4af5cc6b 100644 --- a/manilaclient/tests/functional/osc/test_share_snapshots.py +++ b/manilaclient/tests/functional/osc/test_share_snapshots.py @@ -22,9 +22,8 @@ def test_share_snapshot_create(self): share = self.create_share() snapshot = self.create_snapshot( - share=share['id'], - name='Snap', - description='Description') + share=share['id'], name='Snap', description='Description' + ) self.assertEqual(share["id"], snapshot["share_id"]) self.assertEqual('Snap', snapshot["name"]) @@ -32,33 +31,31 @@ def test_share_snapshot_create(self): self.assertEqual('available', snapshot["status"]) snapshots_list = self.listing_result('share snapshot', 'list') - self.assertIn(snapshot['id'], - [item['ID'] for item in snapshots_list]) + self.assertIn(snapshot['id'], [item['ID'] for item in snapshots_list]) def test_share_snapshot_delete(self): share = self.create_share() - snapshot_1 = self.create_snapshot( - share=share['id'], add_cleanup=False) - snapshot_2 = self.create_snapshot( - share=share['id'], add_cleanup=False) + snapshot_1 = self.create_snapshot(share=share['id'], add_cleanup=False) + snapshot_2 = self.create_snapshot(share=share['id'], add_cleanup=False) self.openstack( f'share snapshot delete {snapshot_1["id"]} {snapshot_2["id"]} ' - '--wait') + '--wait' + ) self.check_object_deleted('share snapshot', snapshot_1["id"]) self.check_object_deleted('share snapshot', snapshot_2["id"]) - snapshot_3 = self.create_snapshot( - share=share['id'], add_cleanup=False) + snapshot_3 = self.create_snapshot(share=share['id'], add_cleanup=False) self.openstack( - f'share snapshot set {snapshot_3["id"]} ' - '--status creating') + f'share snapshot set {snapshot_3["id"]} --status creating' + ) self.openstack( - f'share snapshot delete {snapshot_3["id"]} --wait --force') + f'share snapshot delete {snapshot_3["id"]} --wait --force' + ) self.check_object_deleted('share snapshot', snapshot_3["id"]) @@ -66,12 +63,12 @@ def test_share_snapshot_show(self): share = self.create_share() snapshot = self.create_snapshot( - share=share['id'], - name='Snap', - description='Description') + share=share['id'], name='Snap', description='Description' + ) show_result = self.dict_result( - 'share snapshot', f'show {snapshot["id"]}') + 'share snapshot', f'show {snapshot["id"]}' + ) self.assertEqual(snapshot["id"], show_result["id"]) self.assertEqual('Snap', show_result["name"]) @@ -84,10 +81,12 @@ def test_share_snapshot_set(self): self.openstack( f'share snapshot set {snapshot["id"]} ' - f'--name Snap --description Description') + f'--name Snap --description Description' + ) show_result = self.dict_result( - 'share snapshot ', f'show {snapshot["id"]}') + 'share snapshot ', f'show {snapshot["id"]}' + ) self.assertEqual(snapshot['id'], show_result["id"]) self.assertEqual('Snap', show_result["name"]) @@ -97,15 +96,16 @@ def test_share_snapshot_unset(self): share = self.create_share() snapshot = self.create_snapshot( - share=share['id'], - name='Snap', - description='Description') + share=share['id'], name='Snap', description='Description' + ) self.openstack( - f'share snapshot unset {snapshot["id"]} --name --description') + f'share snapshot unset {snapshot["id"]} --name --description' + ) - show_result = json.loads(self.openstack( - f'share snapshot show -f json {snapshot["id"]}')) + show_result = json.loads( + self.openstack(f'share snapshot show -f json {snapshot["id"]}') + ) self.assertEqual(snapshot['id'], show_result["id"]) self.assertIsNone(show_result["name"]) @@ -116,31 +116,27 @@ def test_share_snapshot_list(self): snapshot_1 = self.create_snapshot(share=share['id']) snapshot_2 = self.create_snapshot( - share=share['id'], - description='Description') + share=share['id'], description='Description' + ) snapshots_list = self.listing_result( - 'share snapshot', f'list --name {snapshot_2["name"]} ' - f'--description {snapshot_2["description"]} --all-projects' + 'share snapshot', + f'list --name {snapshot_2["name"]} ' + f'--description {snapshot_2["description"]} --all-projects', ) - self.assertTableStruct(snapshots_list, [ - 'ID', - 'Name', - 'Project ID' - ]) + self.assertTableStruct(snapshots_list, ['ID', 'Name', 'Project ID']) - self.assertIn(snapshot_2["name"], - [snap["Name"] for snap in snapshots_list]) + self.assertIn( + snapshot_2["name"], [snap["Name"] for snap in snapshots_list] + ) self.assertEqual(1, len(snapshots_list)) snapshots_list = self.listing_result( - 'share snapshot', f'list --share {share["name"]}') + 'share snapshot', f'list --share {share["name"]}' + ) - self.assertTableStruct(snapshots_list, [ - 'ID', - 'Name' - ]) + self.assertTableStruct(snapshots_list, ['ID', 'Name']) id_list = [snap["ID"] for snap in snapshots_list] self.assertIn(snapshot_1["id"], id_list) @@ -149,25 +145,31 @@ def test_share_snapshot_list(self): snapshots_list = self.listing_result( 'share snapshot', f'list --name~ {snapshot_2["name"][-3:]} ' - '--description~ Des --detail') - - self.assertTableStruct(snapshots_list, [ - 'ID', - 'Name', - 'Status', - 'Description', - 'Created At', - 'Size', - 'Share ID', - 'Share Proto', - 'Share Size', - 'User ID' - ]) - - self.assertIn(snapshot_2["name"], - [snap["Name"] for snap in snapshots_list]) + '--description~ Des --detail', + ) + + self.assertTableStruct( + snapshots_list, + [ + 'ID', + 'Name', + 'Status', + 'Description', + 'Created At', + 'Size', + 'Share ID', + 'Share Proto', + 'Share Size', + 'User ID', + ], + ) + + self.assertIn( + snapshot_2["name"], [snap["Name"] for snap in snapshots_list] + ) self.assertEqual( - snapshot_2["description"], snapshots_list[0]['Description']) + snapshot_2["description"], snapshots_list[0]['Description'] + ) self.assertEqual(1, len(snapshots_list)) def test_share_snapshot_export_location_list(self): @@ -176,12 +178,10 @@ def test_share_snapshot_export_location_list(self): snapshot = self.create_snapshot(share=share['id']) export_location_list = self.listing_result( - 'share snapshot export location', f' list {snapshot["id"]}') + 'share snapshot export location', f' list {snapshot["id"]}' + ) - self.assertTableStruct(export_location_list, [ - 'ID', - 'Path' - ]) + self.assertTableStruct(export_location_list, ['ID', 'Path']) def test_share_snapshot_export_location_show(self): share = self.create_share() @@ -189,11 +189,13 @@ def test_share_snapshot_export_location_show(self): snapshot = self.create_snapshot(share=share['id']) export_location_list = self.listing_result( - 'share snapshot export location', f'list {snapshot["id"]}') + 'share snapshot export location', f'list {snapshot["id"]}' + ) export_location = self.dict_result( 'share snapshot export location', - f'show {snapshot["id"]} {export_location_list[0]["ID"]}') + f'show {snapshot["id"]} {export_location_list[0]["ID"]}', + ) self.assertIn('id', export_location) self.assertIn('created_at', export_location) @@ -205,25 +207,25 @@ def test_share_snapshot_export_location_show(self): def test_share_snapshot_abandon_adopt(self): share = self.create_share() - snapshot = self.create_snapshot( - share=share['id'], add_cleanup=False) + snapshot = self.create_snapshot(share=share['id'], add_cleanup=False) - self.openstack( - f'share snapshot abandon {snapshot["id"]} --wait') + self.openstack(f'share snapshot abandon {snapshot["id"]} --wait') snapshots_list = self.listing_result('share snapshot', 'list') - self.assertNotIn(snapshot['id'], - [item['ID'] for item in snapshots_list]) + self.assertNotIn( + snapshot['id'], [item['ID'] for item in snapshots_list] + ) snapshot = self.dict_result( 'share snapshot', f'adopt {share["id"]} 10.0.0.1:/foo/path ' - f'--name Snap --description Zorilla --wait') + f'--name Snap --description Zorilla --wait', + ) snapshots_list = self.listing_result('share snapshot', 'list') - self.assertIn(snapshot['id'], - [item['ID'] for item in snapshots_list]) + self.assertIn(snapshot['id'], [item['ID'] for item in snapshots_list]) self.addCleanup( self.openstack, - f'share snapshot delete {snapshot["id"]} --force --wait') + f'share snapshot delete {snapshot["id"]} --force --wait', + ) diff --git a/manilaclient/tests/functional/osc/test_share_transfers.py b/manilaclient/tests/functional/osc/test_share_transfers.py index 41bfb0e3..bdfa2a4b 100644 --- a/manilaclient/tests/functional/osc/test_share_transfers.py +++ b/manilaclient/tests/functional/osc/test_share_transfers.py @@ -17,42 +17,57 @@ class TransfersCLITest(base.OSCClientTestBase): - def setUp(self): - super(TransfersCLITest, self).setUp() + super().setUp() self.share_type = self.create_share_type() def test_transfer_create_list_show_delete(self): - share = self.create_share(share_type=self.share_type['name'], - wait_for_status='available', - client=self.user_client) + share = self.create_share( + share_type=self.share_type['name'], + wait_for_status='available', + client=self.user_client, + ) # create share transfer self.create_share_transfer(share['id'], name='transfer_test') self._wait_for_object_status('share', share['id'], 'awaiting_transfer') # Get all transfers transfers = self.listing_result( - 'share', 'transfer list', client=self.user_client) + 'share', 'transfer list', client=self.user_client + ) # We must have at least one transfer self.assertTrue(len(transfers) > 0) - self.assertTableStruct(transfers, [ - 'ID', - 'Name', - 'Resource Type', - 'Resource Id', - ]) + self.assertTableStruct( + transfers, + [ + 'ID', + 'Name', + 'Resource Type', + 'Resource Id', + ], + ) # grab the transfer we created - transfer = [transfer for transfer in transfers - if transfer['Resource Id'] == share['id']] + transfer = [ + transfer + for transfer in transfers + if transfer['Resource Id'] == share['id'] + ] self.assertEqual(1, len(transfer)) - show_transfer = self.dict_result('share', - f'transfer show {transfer[0]["ID"]}') + show_transfer = self.dict_result( + 'share', f'transfer show {transfer[0]["ID"]}' + ) self.assertEqual(transfer[0]['ID'], show_transfer['id']) expected_keys = ( - 'id', 'created_at', 'name', 'resource_type', 'resource_id', - 'source_project_id', 'destination_project_id', 'accepted', + 'id', + 'created_at', + 'name', + 'resource_type', + 'resource_id', + 'source_project_id', + 'destination_project_id', + 'accepted', 'expires_at', ) for key in expected_keys: @@ -62,7 +77,8 @@ def test_transfer_create_list_show_delete(self): filtered_transfers = self.listing_result( 'share', f'transfer list --resource-id {share["id"]}', - client=self.user_client) + client=self.user_client, + ) self.assertEqual(1, len(filtered_transfers)) self.assertEqual(show_transfer['resource_id'], share["id"]) @@ -71,15 +87,19 @@ def test_transfer_create_list_show_delete(self): self._wait_for_object_status('share', share['id'], 'available') def test_transfer_accept(self): - share = self.create_share(share_type=self.share_type['name'], - wait_for_status='available', - client=self.user_client) + share = self.create_share( + share_type=self.share_type['name'], + wait_for_status='available', + client=self.user_client, + ) # create share transfer - transfer = self.create_share_transfer(share['id'], - name='transfer_test') + transfer = self.create_share_transfer( + share['id'], name='transfer_test' + ) self._wait_for_object_status('share', share['id'], 'awaiting_transfer') # accept share transfer self.openstack( - f'share transfer accept {transfer["id"]} {transfer["auth_key"]}') + f'share transfer accept {transfer["id"]} {transfer["auth_key"]}' + ) self._wait_for_object_status('share', share['id'], 'available') diff --git a/manilaclient/tests/functional/osc/test_share_types.py b/manilaclient/tests/functional/osc/test_share_types.py index 010c07cc..abd3a530 100644 --- a/manilaclient/tests/functional/osc/test_share_types.py +++ b/manilaclient/tests/functional/osc/test_share_types.py @@ -15,12 +15,10 @@ class ShareTypesCLITest(base.OSCClientTestBase): - def test_share_type_create(self): name = 'test_share_type' description = 'Description' - share_type = self.create_share_type( - name=name, description=description) + share_type = self.create_share_type(name=name, description=description) self.assertEqual(name, share_type["name"]) self.assertEqual(description, share_type["description"]) @@ -28,7 +26,8 @@ def test_share_type_create(self): share_types_list = self.listing_result('share type', 'list') self.assertIn( - share_type["id"], [item['ID'] for item in share_types_list]) + share_type["id"], [item['ID'] for item in share_types_list] + ) def test_share_type_create_specs(self): share_type = self.create_share_type( @@ -36,22 +35,19 @@ def test_share_type_create_specs(self): create_share_from_snapshot_support=True, revert_to_snapshot_support=True, mount_snapshot_support=True, - extra_specs={ - "foo": "bar", - "manila": "zorilla" - }, - formatter='json') + extra_specs={"foo": "bar", "manila": "zorilla"}, + formatter='json', + ) required_specs = share_type["required_extra_specs"] optional_specs = share_type["optional_extra_specs"] - self.assertEqual( - False, required_specs["driver_handles_share_servers"]) + self.assertEqual(False, required_specs["driver_handles_share_servers"]) self.assertEqual('True', optional_specs["snapshot_support"]) self.assertEqual( - 'True', optional_specs["create_share_from_snapshot_support"]) - self.assertEqual( - 'True', optional_specs["revert_to_snapshot_support"]) + 'True', optional_specs["create_share_from_snapshot_support"] + ) + self.assertEqual('True', optional_specs["revert_to_snapshot_support"]) self.assertEqual('True', optional_specs["mount_snapshot_support"]) self.assertEqual("bar", optional_specs["foo"]) self.assertEqual("zorilla", optional_specs["manila"]) @@ -75,72 +71,73 @@ def test_share_type_set(self): ' --name Name --public false --extra-specs foo=bar' ) - share_type = json.loads(self.openstack( - f'share type show {share_type["id"]} -f json' - )) + share_type = json.loads( + self.openstack(f'share type show {share_type["id"]} -f json') + ) self.assertEqual('Description', share_type["description"]) self.assertEqual('Name', share_type["name"]) self.assertEqual('private', share_type["visibility"]) - self.assertEqual( - 'bar', share_type["optional_extra_specs"]["foo"]) + self.assertEqual('bar', share_type["optional_extra_specs"]["foo"]) def test_share_type_unset(self): share_type = self.create_share_type( - snapshot_support=True, - extra_specs={'foo': 'bar'}) + snapshot_support=True, extra_specs={'foo': 'bar'} + ) self.openstack( - f'share type unset {share_type["id"]} ' - 'snapshot_support foo') + f'share type unset {share_type["id"]} snapshot_support foo' + ) - share_type = json.loads(self.openstack( - f'share type show {share_type["id"]} -f json' - )) + share_type = json.loads( + self.openstack(f'share type show {share_type["id"]} -f json') + ) self.assertNotIn('foo', share_type["optional_extra_specs"]) self.assertNotIn( - 'snapshot_support', share_type["optional_extra_specs"]) + 'snapshot_support', share_type["optional_extra_specs"] + ) def test_share_type_list(self): share_type_1 = self.create_share_type(public=False) - share_type_2 = self.create_share_type( - extra_specs={'foo': 'bar'}) + share_type_2 = self.create_share_type(extra_specs={'foo': 'bar'}) types_list = self.listing_result( - 'share type', 'list --all', client=self.admin_client) - - self.assertTableStruct(types_list, [ - 'ID', - 'Name', - 'Visibility', - 'Is Default', - 'Required Extra Specs', - 'Optional Extra Specs', - 'Description' - ]) + 'share type', 'list --all', client=self.admin_client + ) + + self.assertTableStruct( + types_list, + [ + 'ID', + 'Name', + 'Visibility', + 'Is Default', + 'Required Extra Specs', + 'Optional Extra Specs', + 'Description', + ], + ) id_list = [item['ID'] for item in types_list] self.assertIn(share_type_1['id'], id_list) self.assertIn(share_type_2['id'], id_list) types_list = self.listing_result( - 'share type', 'list --extra-specs foo=bar') + 'share type', 'list --extra-specs foo=bar' + ) id_list = [item['ID'] for item in types_list] self.assertNotIn(share_type_1['id'], id_list) self.assertIn(share_type_2['id'], id_list) def test_share_type_show(self): - share_type = self.create_share_type( - extra_specs={'foo': 'bar'}) + share_type = self.create_share_type(extra_specs={'foo': 'bar'}) - result = json.loads(self.openstack( - f'share type show {share_type["id"]} -f json')) + result = json.loads( + self.openstack(f'share type show {share_type["id"]} -f json') + ) self.assertEqual(share_type["name"], result["name"]) - self.assertEqual( - share_type["visibility"], result["visibility"]) - self.assertEqual( - share_type["is_default"], str(result["is_default"])) - self.assertEqual( - 'bar', result["optional_extra_specs"]["foo"]) + self.assertEqual(share_type["visibility"], result["visibility"]) + self.assertEqual(share_type["is_default"], str(result["is_default"])) + self.assertEqual('bar', result["optional_extra_specs"]["foo"]) diff --git a/manilaclient/tests/functional/osc/test_shares.py b/manilaclient/tests/functional/osc/test_shares.py index 524fbeb4..69fcff4e 100644 --- a/manilaclient/tests/functional/osc/test_shares.py +++ b/manilaclient/tests/functional/osc/test_shares.py @@ -15,7 +15,6 @@ class SharesCLITest(base.OSCClientTestBase): - def test_openstack_share_create(self): share_name = 'test_create_share' share = self.create_share(name=share_name) @@ -30,30 +29,32 @@ def test_openstack_share_create(self): def test_openstack_share_list(self): share = self.create_share() shares_list = self.listing_result('share', 'list') - self.assertTableStruct(shares_list, [ - 'ID', - 'Name', - 'Size', - 'Share Proto', - 'Status', - 'Is Public', - 'Share Type Name', - 'Host', - 'Availability Zone' - ]) + self.assertTableStruct( + shares_list, + [ + 'ID', + 'Name', + 'Size', + 'Share Proto', + 'Status', + 'Is Public', + 'Share Type Name', + 'Host', + 'Availability Zone', + ], + ) self.assertIn(share['id'], [item['ID'] for item in shares_list]) def test_openstack_share_show(self): share = self.create_share() - result = self.dict_result('share', 'show %s' % share['id']) + result = self.dict_result('share', 'show {}'.format(share['id'])) self.assertEqual(share['id'], result['id']) - listing_result = self.listing_result('share', 'show %s' % share['id']) - self.assertTableStruct(listing_result, [ - 'Field', - 'Value' - ]) + listing_result = self.listing_result( + 'share', 'show {}'.format(share['id']) + ) + self.assertTableStruct(listing_result, ['Field', 'Value']) def test_openstack_share_delete(self): share = self.create_share(add_cleanup=False) @@ -61,30 +62,35 @@ def test_openstack_share_delete(self): self.assertIn(share['id'], [item['ID'] for item in shares_list]) - self.openstack('share delete %s' % share['id']) + self.openstack('share delete {}'.format(share['id'])) self.check_object_deleted('share', share['id']) shares_list_after_delete = self.listing_result('share', 'list') self.assertNotIn( - share['id'], [item['ID'] for item in shares_list_after_delete]) + share['id'], [item['ID'] for item in shares_list_after_delete] + ) def test_openstack_share_set(self): share = self.create_share() - self.openstack(f'share set {share["id"]} --name new_name ' - f'--property key=value') + self.openstack( + f'share set {share["id"]} --name new_name --property key=value' + ) result = self.dict_result('share', f'show {share["id"]}') self.assertEqual(share['id'], result['id']) self.assertEqual('new_name', result['name']) self.assertEqual("key='value'", result['properties']) def test_openstack_share_unset(self): - share = self.create_share(name='test_name', properties={ - 'foo': 'bar', 'test_key': 'test_value'}) + share = self.create_share( + name='test_name', + properties={'foo': 'bar', 'test_key': 'test_value'}, + ) result1 = self.dict_result('share', f'show {share["id"]}') self.assertEqual(share['id'], result1['id']) self.assertEqual(share['name'], result1['name']) - self.assertEqual("foo='bar', test_key='test_value'", - result1['properties']) + self.assertEqual( + "foo='bar', test_key='test_value'", result1['properties'] + ) self.openstack(f'share unset {share["id"]} --name --property test_key') result2 = self.dict_result('share', f'show {share["id"]}') @@ -100,10 +106,12 @@ def test_openstack_share_soft_delete(self): self.openstack(f'share delete {share["id"]} --soft') self.check_object_deleted('share', share['id']) - shares_list_after_delete = self.listing_result('share', 'list ' - '--soft-deleted') + shares_list_after_delete = self.listing_result( + 'share', 'list --soft-deleted' + ) self.assertIn( - share['id'], [item['ID'] for item in shares_list_after_delete]) + share['id'], [item['ID'] for item in shares_list_after_delete] + ) def test_openstack_share_resize(self): share = self.create_share() @@ -116,7 +124,8 @@ def test_openstack_share_revert(self): share_type = self.create_share_type( name=data_utils.rand_name(slug), snapshot_support=True, - revert_to_snapshot_support=True) + revert_to_snapshot_support=True, + ) share = self.create_share(share_type=share_type['id'], size=10) snapshot = self.create_snapshot(share['id'], wait=True) self.assertEqual(snapshot['size'], share['size']) @@ -146,11 +155,14 @@ def test_openstack_share_abandon_adopt(self): self.check_object_deleted('share', share['id']) shares_list_after_delete = self.listing_result('share', 'list') self.assertNotIn( - share['id'], [item['ID'] for item in shares_list_after_delete]) + share['id'], [item['ID'] for item in shares_list_after_delete] + ) result = self.dict_result( - 'share', f'adopt {host} {protocol} {export_location} ' - f'--share-type {share_type} --wait') + 'share', + f'adopt {host} {protocol} {export_location} ' + f'--share-type {share_type} --wait', + ) # verify adopted self.assertEqual(host, result['host']) @@ -161,24 +173,26 @@ def test_openstack_share_export_location_show(self): share = self.create_share() share_export_locations = self.get_share_export_locations(share["id"]) result_export_locations = self.listing_result( - 'share', f'export location list {share["id"]}') + 'share', f'export location list {share["id"]}' + ) for share_export in share_export_locations: export_location = self.dict_result( - 'share', f'export location show {share["id"]} ' - f'{share_export["ID"]}') - self.assertIn(export_location["id"], [item["ID"] for item in - result_export_locations]) + 'share', + f'export location show {share["id"]} {share_export["ID"]}', + ) + self.assertIn( + export_location["id"], + [item["ID"] for item in result_export_locations], + ) def test_openstack_share_export_location_list(self): share = self.create_share() share_export_locations = self.get_share_export_locations(share["id"]) result_export_locations = self.listing_result( - 'share', f'export location list {share["id"]}') + 'share', f'export location list {share["id"]}' + ) - self.assertTableStruct(result_export_locations, [ - 'ID', - 'Path' - ]) + self.assertTableStruct(result_export_locations, ['ID', 'Path']) export_location_ids = [el['ID'] for el in share_export_locations] for share_export in result_export_locations: self.assertIn(share_export["ID"], export_location_ids) @@ -193,10 +207,12 @@ def test_openstack_share_restore(self): self.check_object_deleted('share', share['id']) shares_list_after_delete = self.listing_result('share', 'list') self.assertNotIn( - share['id'], [item['ID'] for item in shares_list_after_delete]) + share['id'], [item['ID'] for item in shares_list_after_delete] + ) self.openstack(f'share restore {share["id"]} ') shares_list_after_restore = self.listing_result('share', 'list') self.assertIn( - share['id'], [item['ID'] for item in shares_list_after_restore]) + share['id'], [item['ID'] for item in shares_list_after_restore] + ) diff --git a/manilaclient/tests/functional/osc/test_shares_group_type.py b/manilaclient/tests/functional/osc/test_shares_group_type.py index 2268253a..062423bf 100644 --- a/manilaclient/tests/functional/osc/test_shares_group_type.py +++ b/manilaclient/tests/functional/osc/test_shares_group_type.py @@ -18,52 +18,65 @@ class SharesGroupTypesCLITest(base.OSCClientTestBase): - def test_share_group_type_create(self): share_group_type_name = 'test_share_group_type_create' share_group_type = self.create_share_group_type( - name=share_group_type_name, share_types='dhss_false') + name=share_group_type_name, share_types='dhss_false' + ) self.assertEqual(share_group_type['name'], share_group_type_name) self.assertIsNotNone(share_group_type['share_types']) shares_group_type_list = self.listing_result( - 'share', 'group type list') + 'share', 'group type list' + ) self.assertIn( share_group_type['id'], - [item['ID'] for item in shares_group_type_list]) + [item['ID'] for item in shares_group_type_list], + ) def test_openstack_share_group_type_list(self): share_group_type_name = data_utils.rand_name( - 'test_share_group_type_create') + 'test_share_group_type_create' + ) share_group_type = self.create_share_group_type( - name=share_group_type_name, share_types='dhss_false') + name=share_group_type_name, share_types='dhss_false' + ) shares_group_type_list = self.listing_result( - 'share', 'group type list') - self.assertTableStruct(shares_group_type_list, [ - 'ID', - 'Name', - 'Share Types', - 'Visibility', - 'Is Default', - 'Group Specs' - ]) + 'share', 'group type list' + ) + self.assertTableStruct( + shares_group_type_list, + [ + 'ID', + 'Name', + 'Share Types', + 'Visibility', + 'Is Default', + 'Group Specs', + ], + ) self.assertIn( share_group_type['id'], - [item['ID'] for item in shares_group_type_list]) + [item['ID'] for item in shares_group_type_list], + ) def test_openstack_share_group_type_show(self): share_group_type_name = data_utils.rand_name( - 'test_share_group_type_create') + 'test_share_group_type_create' + ) share_type_name = 'dhss_false' share_group_type = self.create_share_group_type( - name=share_group_type_name, share_types=share_type_name) + name=share_group_type_name, share_types=share_type_name + ) shares_group_type_show = self.dict_result( - 'share', f'group type show {share_group_type_name}') + 'share', f'group type show {share_group_type_name}' + ) share_type_id = self.dict_result( - 'share', f'type show {share_type_name}')['id'] + 'share', f'type show {share_type_name}' + )['id'] expected_sgt_values = { 'id': share_group_type['id'], @@ -71,7 +84,7 @@ def test_openstack_share_group_type_show(self): 'share_types': share_type_id, 'visibility': 'public', 'is_default': 'False', - 'group_specs': '' + 'group_specs': '', } for k, v in shares_group_type_show.items(): @@ -79,22 +92,21 @@ def test_openstack_share_group_type_show(self): def test_openstack_share_group_type_set(self): share_group_type_name = data_utils.rand_name( - 'test_share_group_type_create') + 'test_share_group_type_create' + ) share_type_name = 'dhss_false' share_group_type = self.create_share_group_type( - name=share_group_type_name, share_types=share_type_name) + name=share_group_type_name, share_types=share_type_name + ) shares_group_type_show = self.openstack( - f'share group type show {share_group_type_name} -f json') + f'share group type show {share_group_type_name} -f json' + ) shares_group_type_show = jsonutils.loads(shares_group_type_show) - expected_sgt_values = { - 'id': share_group_type['id'], - 'group_specs': {} - } + expected_sgt_values = {'id': share_group_type['id'], 'group_specs': {}} for k, v in expected_sgt_values.items(): - self.assertEqual(expected_sgt_values[k], shares_group_type_show[k] - ) + self.assertEqual(expected_sgt_values[k], shares_group_type_show[k]) group_snap_key = 'snapshot_support' group_snap_value = 'False' @@ -103,17 +115,17 @@ def test_openstack_share_group_type_set(self): self.dict_result( 'share', f'group type set {share_group_type_name} ' - f'--group-specs {group_specs}') + f'--group-specs {group_specs}', + ) shares_group_type_show = self.openstack( - f'share group type show {share_group_type_name} -f json') + f'share group type show {share_group_type_name} -f json' + ) shares_group_type_show = jsonutils.loads(shares_group_type_show) expected_sgt_values = { 'id': share_group_type['id'], - 'group_specs': { - group_snap_key: group_snap_value - } + 'group_specs': {group_snap_key: group_snap_value}, } for k, v in expected_sgt_values.items(): @@ -121,41 +133,40 @@ def test_openstack_share_group_type_set(self): def test_openstack_share_group_type_unset(self): share_group_type_name = data_utils.rand_name( - 'test_share_group_type_create') + 'test_share_group_type_create' + ) group_snap_key = 'snapshot_support' group_snap_value = 'False' group_specs = f"{group_snap_key}={group_snap_value}" share_group_type = self.create_share_group_type( - name=share_group_type_name, share_types='dhss_false', - group_specs=group_specs) + name=share_group_type_name, + share_types='dhss_false', + group_specs=group_specs, + ) shares_group_type_show = self.openstack( - f'share group type show {share_group_type_name} -f json') + f'share group type show {share_group_type_name} -f json' + ) shares_group_type_show = jsonutils.loads(shares_group_type_show) expected_sgt_values = { 'id': share_group_type['id'], - 'group_specs': { - group_snap_key: group_snap_value - } + 'group_specs': {group_snap_key: group_snap_value}, } for k, v in expected_sgt_values.items(): - self.assertEqual(expected_sgt_values[k], shares_group_type_show[k] - ) + self.assertEqual(expected_sgt_values[k], shares_group_type_show[k]) self.dict_result( 'share', - f'group type unset {share_group_type_name} ' - f'{group_snap_key}') + f'group type unset {share_group_type_name} {group_snap_key}', + ) shares_group_type_show = self.openstack( - f'share group type show {share_group_type_name} -f json') + f'share group type show {share_group_type_name} -f json' + ) shares_group_type_show = jsonutils.loads(shares_group_type_show) - expected_sgt_values = { - 'id': share_group_type['id'], - 'group_specs': {} - } + expected_sgt_values = {'id': share_group_type['id'], 'group_specs': {}} for k, v in expected_sgt_values.items(): self.assertEqual(expected_sgt_values[k], shares_group_type_show[k]) diff --git a/manilaclient/tests/functional/test_availability_zones.py b/manilaclient/tests/functional/test_availability_zones.py index 190774bd..425c0afc 100644 --- a/manilaclient/tests/functional/test_availability_zones.py +++ b/manilaclient/tests/functional/test_availability_zones.py @@ -21,13 +21,13 @@ @ddt.ddt class ManilaClientTestAvailabilityZonesReadOnly(base.BaseTestCase): - @ddt.data("2.6", "2.7", "2.22") def test_availability_zone_list(self, microversion): self.skip_if_microversion_not_supported(microversion) azs = self.user_client.list_availability_zones( - microversion=microversion) + microversion=microversion + ) for az in azs: self.assertEqual(4, len(az)) diff --git a/manilaclient/tests/functional/test_common.py b/manilaclient/tests/functional/test_common.py index 06fa77f3..0c6cb98a 100644 --- a/manilaclient/tests/functional/test_common.py +++ b/manilaclient/tests/functional/test_common.py @@ -22,7 +22,6 @@ @ddt.ddt class ManilaClientTestCommonReadOnly(base.BaseTestCase): - @ddt.data('admin', 'user') def test_manila_version(self, role): self.clients[role].manila('', flags='--version') @@ -46,10 +45,20 @@ def test_help(self, role): if match: commands.append(match.group(1)) commands = set(commands) - wanted_commands = set(( - 'absolute-limits', 'list', 'help', 'quota-show', 'access-list', - 'snapshot-list', 'access-allow', 'access-deny', - 'share-network-list', 'security-service-list')) + wanted_commands = set( + ( + 'absolute-limits', + 'list', + 'help', + 'quota-show', + 'access-list', + 'snapshot-list', + 'access-allow', + 'access-deny', + 'share-network-list', + 'security-service-list', + ) + ) self.assertFalse(wanted_commands - commands) @ddt.data('admin', 'user') @@ -59,7 +68,8 @@ def test_credentials(self, role): @ddt.data('admin', 'user') def test_list_extensions(self, role): roles = self.parser.listing( - self.clients[role].manila('list-extensions')) + self.clients[role].manila('list-extensions') + ) self.assertTableStruct(roles, ['Name', 'Summary', 'Alias', 'Updated']) @ddt.data('admin', 'user') diff --git a/manilaclient/tests/functional/test_export_locations.py b/manilaclient/tests/functional/test_export_locations.py index 374322e8..0bf6e0ae 100644 --- a/manilaclient/tests/functional/test_export_locations.py +++ b/manilaclient/tests/functional/test_export_locations.py @@ -21,19 +21,16 @@ @ddt.ddt class ExportLocationReadWriteTest(base.BaseTestCase): - def setUp(self): - super(ExportLocationReadWriteTest, self).setUp() - self.share = self.create_share( - client=self.get_user_client()) + super().setUp() + self.share = self.create_share(client=self.get_user_client()) @ddt.data('admin', 'user') def test_list_share_export_locations(self, role): self.skip_if_microversion_not_supported('2.14') client = self.admin_client if role == 'admin' else self.user_client - export_locations = client.list_share_export_locations( - self.share['id']) + export_locations = client.list_share_export_locations(self.share['id']) self.assertGreater(len(export_locations), 0) expected_keys = ('ID', 'Path', 'Preferred') @@ -49,7 +46,8 @@ def test_list_share_export_locations_with_columns(self, role): client = self.admin_client if role == 'admin' else self.user_client export_locations = client.list_share_export_locations( - self.share['id'], columns='id,path') + self.share['id'], columns='id,path' + ) self.assertGreater(len(export_locations), 0) expected_keys = ('Id', 'Path') @@ -66,11 +64,11 @@ def test_get_share_export_location(self, role): self.skip_if_microversion_not_supported('2.14') client = self.admin_client if role == 'admin' else self.user_client - export_locations = client.list_share_export_locations( - self.share['id']) + export_locations = client.list_share_export_locations(self.share['id']) el = client.get_share_export_location( - self.share['id'], export_locations[0]['ID']) + self.share['id'], export_locations[0]['ID'] + ) expected_keys = ['path', 'updated_at', 'created_at', 'id', 'preferred'] if role == 'admin': @@ -83,9 +81,11 @@ def test_get_share_export_location(self, role): self.assertTrue(uuidutils.is_uuid_like(el['id'])) self.assertIn(el['preferred'], ('True', 'False')) for list_k, get_k in ( - ('ID', 'id'), ('Path', 'path'), ('Preferred', 'preferred')): - self.assertEqual( - export_locations[0][list_k], el[get_k]) + ('ID', 'id'), + ('Path', 'path'), + ('Preferred', 'preferred'), + ): + self.assertEqual(export_locations[0][list_k], el[get_k]) def test_list_share_instance_export_locations(self): self.skip_if_microversion_not_supported('2.14') @@ -98,7 +98,8 @@ def test_list_share_instance_export_locations(self): share_instance_id = share_instances[0]['ID'] export_locations = client.list_share_instance_export_locations( - share_instance_id) + share_instance_id + ) self.assertGreater(len(export_locations), 0) expected_keys = ('ID', 'Path', 'Is Admin only', 'Preferred') @@ -118,7 +119,8 @@ def test_list_share_instance_export_locations_with_columns(self): share_instance_id = share_instances[0]['ID'] export_locations = client.list_share_instance_export_locations( - share_instance_id, columns='id,path') + share_instance_id, columns='id,path' + ) self.assertGreater(len(export_locations), 0) expected_keys = ('Id', 'Path') @@ -141,14 +143,21 @@ def test_get_share_instance_export_location(self): share_instance_id = share_instances[0]['ID'] export_locations = client.list_share_instance_export_locations( - share_instance_id) + share_instance_id + ) el = client.get_share_instance_export_location( - share_instance_id, export_locations[0]['ID']) + share_instance_id, export_locations[0]['ID'] + ) expected_keys = ( - 'path', 'updated_at', 'created_at', 'id', 'preferred', - 'is_admin_only', 'share_instance_id', + 'path', + 'updated_at', + 'created_at', + 'id', + 'preferred', + 'is_admin_only', + 'share_instance_id', ) for key in expected_keys: self.assertIn(key, el) @@ -156,7 +165,9 @@ def test_get_share_instance_export_location(self): self.assertIn(el['preferred'], ('True', 'False')) self.assertTrue(uuidutils.is_uuid_like(el['id'])) for list_k, get_k in ( - ('ID', 'id'), ('Path', 'path'), ('Preferred', 'preferred'), - ('Is Admin only', 'is_admin_only')): - self.assertEqual( - export_locations[0][list_k], el[get_k]) + ('ID', 'id'), + ('Path', 'path'), + ('Preferred', 'preferred'), + ('Is Admin only', 'is_admin_only'), + ): + self.assertEqual(export_locations[0][list_k], el[get_k]) diff --git a/manilaclient/tests/functional/test_limits.py b/manilaclient/tests/functional/test_limits.py index 8308b8a4..8d79cb6b 100644 --- a/manilaclient/tests/functional/test_limits.py +++ b/manilaclient/tests/functional/test_limits.py @@ -20,7 +20,6 @@ @ddt.ddt class ManilaClientTestLimitsReadOnly(base.BaseTestCase): - @ddt.data('admin', 'user') def test_rate_limits(self, role): self.clients[role].manila('rate-limits') diff --git a/manilaclient/tests/functional/test_messages.py b/manilaclient/tests/functional/test_messages.py index e7a8380c..dd06c524 100644 --- a/manilaclient/tests/functional/test_messages.py +++ b/manilaclient/tests/functional/test_messages.py @@ -17,7 +17,6 @@ @ddt.ddt class MessagesReadOnlyTest(base.BaseTestCase): - @ddt.data( ("admin", "2.37"), ("user", "2.37"), @@ -30,9 +29,8 @@ def test_message_list(self, role, microversion): @ddt.ddt class MessagesReadWriteTest(base.BaseTestCase): - def setUp(self): - super(MessagesReadWriteTest, self).setUp() + super().setUp() self.message = self.create_message() def test_list_messages(self): @@ -46,8 +44,14 @@ def test_list_messages(self): self.assertTrue(any(m['Resource Type'] is not None for m in messages)) @ddt.data( - 'id', 'action_id', 'resource_id', 'action_id', 'detail_id', - 'resource_type', 'created_at', 'action_id,detail_id,resource_id', + 'id', + 'action_id', + 'resource_id', + 'action_id', + 'detail_id', + 'resource_type', + 'created_at', + 'action_id,detail_id,resource_id', ) def test_list_share_type_select_column(self, columns): self.skip_if_microversion_not_supported('2.37') @@ -57,8 +61,14 @@ def test_get_message(self): self.skip_if_microversion_not_supported('2.37') message = self.admin_client.get_message(self.message['ID']) expected_keys = ( - 'id', 'action_id', 'resource_id', 'action_id', 'detail_id', - 'resource_type', 'created_at', 'created_at', + 'id', + 'action_id', + 'resource_id', + 'action_id', + 'detail_id', + 'resource_type', + 'created_at', + 'created_at', ) for key in expected_keys: self.assertIn(key, message) diff --git a/manilaclient/tests/functional/test_quotas.py b/manilaclient/tests/functional/test_quotas.py index 9e5cf736..dd6efb04 100644 --- a/manilaclient/tests/functional/test_quotas.py +++ b/manilaclient/tests/functional/test_quotas.py @@ -40,62 +40,75 @@ def _get_share_type_quota_values(project_quota_value): @ddt.ddt @utils.skip_if_microversion_not_supported("2.39") class QuotasReadWriteTest(base.BaseTestCase): - def setUp(self): super(self.__class__, self).setUp() self.microversion = "2.39" self.project_id = self.admin_client.get_project_id( - self.admin_client.tenant_name) + self.admin_client.tenant_name + ) # Create share type self.share_type = self.create_share_type( name=data_utils.rand_name("manilaclient_functional_test"), driver_handles_share_servers=False, is_public=True, - microversion=self.microversion + microversion=self.microversion, ) self.st_id = self.share_type["ID"] def _verify_current_st_quotas_equal_to(self, quotas, microversion): # Read share type quotas - cmd = 'quota-show --tenant-id %s --share-type %s' % ( - self.project_id, self.st_id) + cmd = f'quota-show --tenant-id {self.project_id} --share-type {self.st_id}' st_quotas_raw = self.admin_client.manila( - cmd, microversion=microversion) + cmd, microversion=microversion + ) st_quotas = output_parser.details(st_quotas_raw) # Verify that quotas self.assertGreater(len(st_quotas), 3) for key, value in st_quotas.items(): - if key not in ('shares', 'gigabytes', 'snapshots', - 'snapshot_gigabytes'): + if key not in ( + 'shares', + 'gigabytes', + 'snapshots', + 'snapshot_gigabytes', + ): continue self.assertIn(key, quotas) self.assertEqual(int(quotas[key]), int(value)) def _verify_current_quotas_equal_to(self, quotas, microversion): # Read quotas - cmd = 'quota-show --tenant-id %s' % self.project_id - quotas_raw = self.admin_client.manila( - cmd, microversion=microversion) + cmd = f'quota-show --tenant-id {self.project_id}' + quotas_raw = self.admin_client.manila(cmd, microversion=microversion) quotas = output_parser.details(quotas_raw) # Verify that quotas self.assertGreater(len(quotas), 3) for key, value in quotas.items(): - if key not in ('shares', 'gigabytes', 'snapshots', - 'snapshot_gigabytes', - 'share_groups', 'share_group_snapshots'): + if key not in ( + 'shares', + 'gigabytes', + 'snapshots', + 'snapshot_gigabytes', + 'share_groups', + 'share_group_snapshots', + ): continue self.assertIn(key, quotas) self.assertEqual(int(quotas[key]), int(value)) - @ddt.data(*set([ - "2.40", api_versions.MAX_VERSION, - ])) + @ddt.data( + *set( + [ + "2.40", + api_versions.MAX_VERSION, + ] + ) + ) def test_update_quotas_for_share_groups(self, microversion): if not utils.is_microversion_supported(microversion): - msg = "Microversion '%s' not supported." % microversion + msg = f"Microversion '{microversion}' not supported." raise self.skipException(msg) # Get default quotas @@ -104,20 +117,22 @@ def test_update_quotas_for_share_groups(self, microversion): default_quotas = output_parser.details(quotas_raw) # Get project quotas - cmd = 'quota-show --tenant-id %s ' % self.project_id + cmd = f'quota-show --tenant-id {self.project_id} ' quotas_raw = self.admin_client.manila(cmd, microversion=microversion) p_quotas = output_parser.details(quotas_raw) # Define custom share group quotas for project p_custom_quotas = { 'share_groups': -1 if int(p_quotas['share_groups']) != -1 else 999, - 'share_group_snapshots': -1 if int( - p_quotas['share_group_snapshots']) != -1 else 999, + 'share_group_snapshots': -1 + if int(p_quotas['share_group_snapshots']) != -1 + else 999, } # Update share group quotas for project - cmd = ('quota-update %s --share-groups %s ' - '--share-group-snapshots %s') % ( + cmd = ( + 'quota-update {} --share-groups {} --share-group-snapshots {}' + ).format( self.project_id, p_custom_quotas['share_groups'], p_custom_quotas['share_group_snapshots'], @@ -128,18 +143,20 @@ def test_update_quotas_for_share_groups(self, microversion): self._verify_current_quotas_equal_to(p_custom_quotas, microversion) # Reset quotas - cmd = 'quota-delete --tenant-id %s --share-type %s' % ( - self.project_id, self.st_id) + cmd = f'quota-delete --tenant-id {self.project_id} --share-type {self.st_id}' self.admin_client.manila(cmd, microversion=microversion) # Verify quotas after reset self._verify_current_quotas_equal_to(default_quotas, microversion) # Return project quotas back - cmd = ('quota-update %s --share-groups %s ' - '--share-group-snapshots %s') % ( + cmd = ( + 'quota-update {} --share-groups {} --share-group-snapshots {}' + ).format( self.project_id, - p_quotas['share_groups'], p_quotas['share_group_snapshots']) + p_quotas['share_groups'], + p_quotas['share_group_snapshots'], + ) self.admin_client.manila(cmd, microversion=microversion) # Verify quotas after reset @@ -147,44 +164,58 @@ def test_update_quotas_for_share_groups(self, microversion): @ddt.data('--share-groups', '--share-group-snapshots') @utils.skip_if_microversion_not_supported("2.39") - def test_update_quotas_for_share_groups_using_too_old_microversion(self, - arg): - cmd = 'quota-update %s %s 13' % (self.project_id, arg) + def test_update_quotas_for_share_groups_using_too_old_microversion( + self, arg + ): + cmd = f'quota-update {self.project_id} {arg} 13' self.assertRaises( exceptions.CommandFailed, self.admin_client.manila, - cmd, microversion='2.39') + cmd, + microversion='2.39', + ) @ddt.data('--share-replicas', '--replica-gigabytes') @utils.skip_if_microversion_not_supported("2.52") - def test_update_quotas_for_share_replicas_using_too_old_microversion(self, - arg): - cmd = 'quota-update %s %s 10' % (self.project_id, arg) + def test_update_quotas_for_share_replicas_using_too_old_microversion( + self, arg + ): + cmd = f'quota-update {self.project_id} {arg} 10' self.assertRaises( exceptions.CommandFailed, self.admin_client.manila, - cmd, microversion='2.52') + cmd, + microversion='2.52', + ) @ddt.data('--share-groups', '--share-group-snapshots') @utils.skip_if_microversion_not_supported("2.40") def test_update_share_type_quotas_for_share_groups(self, arg): - cmd = 'quota-update %s --share-type %s %s 13' % ( - self.project_id, self.st_id, arg) + cmd = f'quota-update {self.project_id} --share-type {self.st_id} {arg} 13' self.assertRaises( exceptions.CommandFailed, self.admin_client.manila, - cmd, microversion='2.40') + cmd, + microversion='2.40', + ) - @ddt.data(*set([ - "2.39", "2.40", REPLICA_QUOTAS_MICROVERSION, api_versions.MAX_VERSION, - ])) + @ddt.data( + *set( + [ + "2.39", + "2.40", + REPLICA_QUOTAS_MICROVERSION, + api_versions.MAX_VERSION, + ] + ) + ) def test_update_share_type_quotas_positive(self, microversion): if not utils.is_microversion_supported(microversion): - msg = "Microversion '%s' not supported." % microversion + msg = f"Microversion '{microversion}' not supported." raise self.skipException(msg) # Get project quotas - cmd = 'quota-show --tenant-id %s ' % self.project_id + cmd = f'quota-show --tenant-id {self.project_id} ' quotas_raw = self.admin_client.manila(cmd, microversion=microversion) p_quotas = output_parser.details(quotas_raw) @@ -194,32 +225,40 @@ def test_update_share_type_quotas_positive(self, microversion): 'snapshots': _get_share_type_quota_values(p_quotas['snapshots']), 'gigabytes': _get_share_type_quota_values(p_quotas['gigabytes']), 'snapshot_gigabytes': _get_share_type_quota_values( - p_quotas['snapshot_gigabytes']), + p_quotas['snapshot_gigabytes'] + ), } - supports_share_replica_quotas = ( - api_versions.APIVersion(microversion) >= api_versions.APIVersion( - REPLICA_QUOTAS_MICROVERSION)) + supports_share_replica_quotas = api_versions.APIVersion( + microversion + ) >= api_versions.APIVersion(REPLICA_QUOTAS_MICROVERSION) if supports_share_replica_quotas: st_custom_quotas['share_replicas'] = _get_share_type_quota_values( p_quotas['share_replicas'] ) st_custom_quotas['replica_gigabytes'] = ( - _get_share_type_quota_values(p_quotas['replica_gigabytes'])) - replica_params = (' --share-replicas %s ' - '--replica-gigabytes %s') % ( + _get_share_type_quota_values(p_quotas['replica_gigabytes']) + ) + replica_params = ( + ' --share-replicas {} --replica-gigabytes {}' + ).format( st_custom_quotas['share_replicas'], - st_custom_quotas['replica_gigabytes']) + st_custom_quotas['replica_gigabytes'], + ) # Update quotas for share type - cmd = ('quota-update %s --share-type %s ' - '--shares %s --gigabytes %s --snapshots %s ' - '--snapshot-gigabytes %s') % ( - self.project_id, self.st_id, - st_custom_quotas['shares'], - st_custom_quotas['gigabytes'], - st_custom_quotas['snapshots'], - st_custom_quotas['snapshot_gigabytes']) + cmd = ( + 'quota-update {} --share-type {} ' + '--shares {} --gigabytes {} --snapshots {} ' + '--snapshot-gigabytes {}' + ).format( + self.project_id, + self.st_id, + st_custom_quotas['shares'], + st_custom_quotas['gigabytes'], + st_custom_quotas['snapshots'], + st_custom_quotas['snapshot_gigabytes'], + ) if supports_share_replica_quotas: cmd += replica_params @@ -229,8 +268,7 @@ def test_update_share_type_quotas_positive(self, microversion): self._verify_current_st_quotas_equal_to(st_custom_quotas, microversion) # Reset share type quotas - cmd = 'quota-delete --tenant-id %s --share-type %s' % ( - self.project_id, self.st_id) + cmd = f'quota-delete --tenant-id {self.project_id} --share-type {self.st_id}' self.admin_client.manila(cmd, microversion=microversion) # Verify share type quotas after reset @@ -238,38 +276,43 @@ def test_update_share_type_quotas_positive(self, microversion): @utils.skip_if_microversion_not_supported("2.38") def test_read_share_type_quotas_with_too_old_microversion(self): - cmd = 'quota-show --tenant-id %s --share-type %s' % ( - self.project_id, self.st_id) + cmd = f'quota-show --tenant-id {self.project_id} --share-type {self.st_id}' self.assertRaises( exceptions.CommandFailed, self.admin_client.manila, - cmd, microversion='2.38') + cmd, + microversion='2.38', + ) @utils.skip_if_microversion_not_supported("2.38") def test_update_share_type_quotas_with_too_old_microversion(self): - cmd = 'quota-update --tenant-id %s --share-type %s --shares %s' % ( - self.project_id, self.st_id, '0') + cmd = 'quota-update --tenant-id {} --share-type {} --shares {}'.format( + self.project_id, self.st_id, '0' + ) self.assertRaises( exceptions.CommandFailed, self.admin_client.manila, - cmd, microversion='2.38') + cmd, + microversion='2.38', + ) @utils.skip_if_microversion_not_supported("2.38") def test_delete_share_type_quotas_with_too_old_microversion(self): - cmd = 'quota-delete --tenant-id %s --share-type %s' % ( - self.project_id, self.st_id) + cmd = f'quota-delete --tenant-id {self.project_id} --share-type {self.st_id}' self.assertRaises( exceptions.CommandFailed, self.admin_client.manila, - cmd, microversion='2.38') + cmd, + microversion='2.38', + ) @ddt.ddt class ManilaClientTestQuotasReadOnly(base.BaseTestCase): - def test_quota_class_show_by_admin(self): roles = self.parser.listing( - self.clients['admin'].manila('quota-class-show', params='abc')) + self.clients['admin'].manila('quota-class-show', params='abc') + ) self.assertTableStruct(roles, ('Property', 'Value')) def test_quota_class_show_by_user(self): @@ -277,11 +320,15 @@ def test_quota_class_show_by_user(self): exceptions.CommandFailed, self.clients['user'].manila, 'quota-class-show', - params='abc') + params='abc', + ) def _get_quotas(self, role, operation, microversion): - roles = self.parser.listing(self.clients[role].manila( - 'quota-%s' % operation, microversion=microversion)) + roles = self.parser.listing( + self.clients[role].manila( + f'quota-{operation}', microversion=microversion + ) + ) self.assertTableStruct(roles, ('Property', 'Value')) @ddt.data('admin', 'user') diff --git a/manilaclient/tests/functional/test_scheduler_stats.py b/manilaclient/tests/functional/test_scheduler_stats.py index 6c78e718..117795db 100644 --- a/manilaclient/tests/functional/test_scheduler_stats.py +++ b/manilaclient/tests/functional/test_scheduler_stats.py @@ -19,7 +19,6 @@ class ManilaClientTestSchedulerStatsReadOnly(base.BaseTestCase): - def test_pools_list(self): self.clients['admin'].manila('pool-list') @@ -34,16 +33,17 @@ def test_pools_list_with_share_type_filter(self): name=data_utils.rand_name('manilaclient_functional_test'), snapshot_support=True, ) - self.clients['admin'].manila('pool-list', - params='--share_type ' + - share_type['ID']) + self.clients['admin'].manila( + 'pool-list', params='--share_type ' + share_type['ID'] + ) def test_pools_list_with_filters(self): self.clients['admin'].manila( 'pool-list', - params='--host myhost --backend mybackend --pool mypool') + params='--host myhost --backend mybackend --pool mypool', + ) def test_pools_list_by_user(self): - self.assertRaises(exceptions.CommandFailed, - self.clients['user'].manila, - 'pool-list') + self.assertRaises( + exceptions.CommandFailed, self.clients['user'].manila, 'pool-list' + ) diff --git a/manilaclient/tests/functional/test_security_services.py b/manilaclient/tests/functional/test_security_services.py index ab68dfba..e8a819b3 100644 --- a/manilaclient/tests/functional/test_security_services.py +++ b/manilaclient/tests/functional/test_security_services.py @@ -21,9 +21,8 @@ @ddt.ddt class SecurityServiceReadWriteTest(base.BaseTestCase): - def setUp(self): - super(SecurityServiceReadWriteTest, self).setUp() + super().setUp() self.name = data_utils.rand_name('autotest') self.description = 'fake_description' self.user = 'fake_user' diff --git a/manilaclient/tests/functional/test_services.py b/manilaclient/tests/functional/test_services.py index 1d02765a..bdf424db 100644 --- a/manilaclient/tests/functional/test_services.py +++ b/manilaclient/tests/functional/test_services.py @@ -20,7 +20,6 @@ @ddt.ddt class ManilaClientTestServicesReadOnly(base.BaseTestCase): - @ddt.data("1.0", "2.0", "2.6", "2.7") def test_services_list(self, microversion): self.skip_if_microversion_not_supported(microversion) diff --git a/manilaclient/tests/functional/test_share_access.py b/manilaclient/tests/functional/test_share_access.py index 1d3bd387..772d2330 100644 --- a/manilaclient/tests/functional/test_share_access.py +++ b/manilaclient/tests/functional/test_share_access.py @@ -31,25 +31,29 @@ class ShareAccessReadWriteBase(base.BaseTestCase): access_level = None def setUp(self): - super(ShareAccessReadWriteBase, self).setUp() + super().setUp() if self.protocol not in CONF.enable_protocols: - message = "%s tests are disabled." % self.protocol + message = f"{self.protocol} tests are disabled." raise self.skipException(message) if self.access_level not in CONF.access_levels_mapping.get( - self.protocol, '').split(' '): - raise self.skipException("%(level)s tests for %(protocol)s share " - "access are disabled." % { - 'level': self.access_level, - 'protocol': self.protocol - }) + self.protocol, '' + ).split(' '): + raise self.skipException( + f"{self.access_level} tests for {self.protocol} share " + "access are disabled." + ) self.access_types = CONF.access_types_mapping.get( - self.protocol, '').split(' ') + self.protocol, '' + ).split(' ') if not self.access_types: - raise self.skipException("No access levels were provided for %s " - "share access tests." % self.protocol) + raise self.skipException( + f"No access levels were provided for {self.protocol} " + "share access tests." + ) - self.share = self.create_share(share_protocol=self.protocol, - public=True) + self.share = self.create_share( + share_protocol=self.protocol, public=True + ) self.share_id = self.share['id'] # NOTE(vponomaryov): increase following int range when significant @@ -69,86 +73,120 @@ def setUp(self): } def _test_create_list_access_rule_for_share( - self, microversion, metadata=None): + self, microversion, metadata=None + ): access_type = self.access_types[0] access = self.user_client.access_allow( - self.share['id'], access_type, self.access_to[access_type].pop(), - self.access_level, metadata=metadata, microversion=microversion) + self.share['id'], + access_type, + self.access_to[access_type].pop(), + self.access_level, + metadata=metadata, + microversion=microversion, + ) return access - @ddt.data(*set([ - "1.0", "2.0", "2.6", "2.7", "2.21", "2.33", "2.44", "2.45", - api_versions.MAX_VERSION])) + @ddt.data( + *set( + [ + "1.0", + "2.0", + "2.6", + "2.7", + "2.21", + "2.33", + "2.44", + "2.45", + api_versions.MAX_VERSION, + ] + ) + ) def test_create_list_access_rule_for_share(self, microversion): self.skip_if_microversion_not_supported(microversion) access = self._test_create_list_access_rule_for_share( - microversion=microversion) - access_list = self.user_client.list_access( - self.share['id'], microversion=microversion ) - self.assertTrue(any( - [item for item in access_list if access['id'] == item['id']])) + access_list = self.user_client.list_access( + self.share['id'], microversion=microversion + ) + self.assertTrue( + any([item for item in access_list if access['id'] == item['id']]) + ) self.assertTrue(any(a['access_type'] is not None for a in access_list)) self.assertTrue(any(a['access_to'] is not None for a in access_list)) - self.assertTrue(any(a['access_level'] is not None - for a in access_list)) - if (api_versions.APIVersion(microversion) >= - api_versions.APIVersion("2.33")): + self.assertTrue( + any(a['access_level'] is not None for a in access_list) + ) + if api_versions.APIVersion(microversion) >= api_versions.APIVersion( + "2.33" + ): self.assertTrue( - all(all(key in access for key in ( - 'access_key', 'created_at', 'updated_at')) - for access in access_list)) - elif (api_versions.APIVersion(microversion) >= - api_versions.APIVersion("2.21")): + all( + all( + key in access + for key in ('access_key', 'created_at', 'updated_at') + ) + for access in access_list + ) + ) + elif api_versions.APIVersion(microversion) >= api_versions.APIVersion( + "2.21" + ): self.assertTrue(all('access_key' in a for a in access_list)) else: self.assertTrue(all('access_key' not in a for a in access_list)) @ddt.data("1.0", "2.0", "2.6", "2.7") def test_create_list_access_rule_for_share_select_column( - self, - microversion): + self, microversion + ): self.skip_if_microversion_not_supported(microversion) - self._test_create_list_access_rule_for_share( - microversion=microversion) + self._test_create_list_access_rule_for_share(microversion=microversion) access_list = self.user_client.list_access( self.share['id'], columns="access_type,access_to", - microversion=microversion + microversion=microversion, ) self.assertTrue(any(a['Access_Type'] is not None for a in access_list)) self.assertTrue(any(a['Access_To'] is not None for a in access_list)) self.assertTrue(all('Access_Level' not in a for a in access_list)) self.assertTrue(all('access_level' not in a for a in access_list)) - def _create_delete_access_rule(self, share_id, access_type, access_to, - microversion=None): + def _create_delete_access_rule( + self, share_id, access_type, access_to, microversion=None + ): self.skip_if_microversion_not_supported(microversion) if access_type not in self.access_types: raise self.skipException( - "'%(access_type)s' access rules is disabled for protocol " - "'%(protocol)s'." % {"access_type": access_type, - "protocol": self.protocol}) + f"'{access_type}' access rules is disabled for protocol " + f"'{self.protocol}'." + ) access = self.user_client.access_allow( - share_id, access_type, access_to, self.access_level, - microversion=microversion) + share_id, + access_type, + access_to, + self.access_level, + microversion=microversion, + ) self.assertEqual(share_id, access.get('share_id')) self.assertEqual(access_type, access.get('access_type')) - self.assertEqual(access_to.replace('\\\\', '\\'), - access.get('access_to')) + self.assertEqual( + access_to.replace('\\\\', '\\'), access.get('access_to') + ) self.assertEqual(self.access_level, access.get('access_level')) - if (api_versions.APIVersion(microversion) >= - api_versions.APIVersion("2.33")): + if api_versions.APIVersion(microversion) >= api_versions.APIVersion( + "2.33" + ): self.assertIn('access_key', access) self.assertIn('created_at', access) self.assertIn('updated_at', access) - elif (api_versions.APIVersion(microversion) >= - api_versions.APIVersion("2.21")): + elif api_versions.APIVersion(microversion) >= api_versions.APIVersion( + "2.21" + ): self.assertIn('access_key', access) else: self.assertNotIn('access_key', access) @@ -157,8 +195,12 @@ def _create_delete_access_rule(self, share_id, access_type, access_to, self.user_client.access_deny(share_id, access['id']) self.user_client.wait_for_access_rule_deletion(share_id, access['id']) - self.assertRaises(tempest_lib_exc.NotFound, - self.user_client.get_access, share_id, access['id']) + self.assertRaises( + tempest_lib_exc.NotFound, + self.user_client.get_access, + share_id, + access['id'], + ) @ddt.data(*set(["2.45", api_versions.MAX_VERSION])) def test_create_list_access_rule_with_metadata(self, microversion): @@ -167,16 +209,21 @@ def test_create_list_access_rule_with_metadata(self, microversion): md1 = {"key1": "value1", "key2": "value2"} md2 = {"key3": "value3", "key4": "value4"} self._test_create_list_access_rule_for_share( - metadata=md1, microversion=microversion) + metadata=md1, microversion=microversion + ) access = self._test_create_list_access_rule_for_share( - metadata=md2, microversion=microversion) + metadata=md2, microversion=microversion + ) access_list = self.user_client.list_access( - self.share['id'], metadata={"key4": "value4"}, - microversion=microversion) + self.share['id'], + metadata={"key4": "value4"}, + microversion=microversion, + ) self.assertEqual(1, len(access_list)) # Verify share metadata get_access = self.user_client.access_show( - access_list[0]['id'], microversion=microversion) + access_list[0]['id'], microversion=microversion + ) metadata = ast.literal_eval(get_access['metadata']) self.assertEqual(2, len(metadata)) self.assertIn('key3', metadata) @@ -186,8 +233,9 @@ def test_create_list_access_rule_with_metadata(self, microversion): self.assertEqual(access['id'], access_list[0]['id']) self.user_client.access_deny(access['share_id'], access['id']) - self.user_client.wait_for_access_rule_deletion(access['share_id'], - access['id']) + self.user_client.wait_for_access_rule_deletion( + access['share_id'], access['id'] + ) @ddt.data(*set(["2.45", api_versions.MAX_VERSION])) def test_create_update_show_access_rule_with_metadata(self, microversion): @@ -197,24 +245,29 @@ def test_create_update_show_access_rule_with_metadata(self, microversion): md2 = {"key3": "value3", "key2": "value4"} # create a access rule with metadata access = self._test_create_list_access_rule_for_share( - metadata=md1, microversion=microversion) + metadata=md1, microversion=microversion + ) # get the access rule get_access = self.user_client.access_show( - access['id'], microversion=microversion) + access['id'], microversion=microversion + ) # verify access rule self.assertEqual(access['id'], get_access['id']) self.assertEqual(md1, ast.literal_eval(get_access['metadata'])) # update access rule metadata self.user_client.access_set_metadata( - access['id'], metadata=md2, microversion=microversion) + access['id'], metadata=md2, microversion=microversion + ) get_access = self.user_client.access_show( - access['id'], microversion=microversion) + access['id'], microversion=microversion + ) # verify access rule after update access rule metadata self.assertEqual( {"key1": "value1", "key2": "value4", "key3": "value3"}, - ast.literal_eval(get_access['metadata'])) + ast.literal_eval(get_access['metadata']), + ) self.assertEqual(access['id'], get_access['id']) @ddt.data(*set(["2.45", api_versions.MAX_VERSION])) @@ -224,10 +277,12 @@ def test_delete_access_rule_metadata(self, microversion): md = {"key1": "value1", "key2": "value2"} # create a access rule with metadata access = self._test_create_list_access_rule_for_share( - metadata=md, microversion=microversion) + metadata=md, microversion=microversion + ) # get the access rule get_access = self.user_client.access_show( - access['id'], microversion=microversion) + access['id'], microversion=microversion + ) # verify access rule self.assertEqual(access['id'], get_access['id']) @@ -235,9 +290,11 @@ def test_delete_access_rule_metadata(self, microversion): # delete access rule metadata self.user_client.access_unset_metadata( - access['id'], keys=["key1", "key2"], microversion=microversion) + access['id'], keys=["key1", "key2"], microversion=microversion + ) get_access = self.user_client.access_show( - access['id'], microversion=microversion) + access['id'], microversion=microversion + ) # verify access rule after delete access rule metadata self.assertEqual({}, ast.literal_eval(get_access['metadata'])) @@ -246,22 +303,26 @@ def test_delete_access_rule_metadata(self, microversion): @ddt.data("1.0", "2.0", "2.6", "2.7", "2.21", "2.33") def test_create_delete_ip_access_rule(self, microversion): self._create_delete_access_rule( - self.share_id, 'ip', self.access_to['ip'].pop(), microversion) + self.share_id, 'ip', self.access_to['ip'].pop(), microversion + ) @ddt.data("1.0", "2.0", "2.6", "2.7", "2.21", "2.33") def test_create_delete_user_access_rule(self, microversion): self._create_delete_access_rule( - self.share_id, 'user', CONF.username_for_user_rules, microversion) + self.share_id, 'user', CONF.username_for_user_rules, microversion + ) @ddt.data("1.0", "2.0", "2.6", "2.7", "2.21", "2.33") def test_create_delete_cert_access_rule(self, microversion): self._create_delete_access_rule( - self.share_id, 'cert', self.access_to['cert'].pop(), microversion) + self.share_id, 'cert', self.access_to['cert'].pop(), microversion + ) @ddt.data("2.38", api_versions.MAX_VERSION) def test_create_delete_ipv6_access_rule(self, microversion): self._create_delete_access_rule( - self.share_id, 'ip', self.access_to['ipv6'].pop(), microversion) + self.share_id, 'ip', self.access_to['ipv6'].pop(), microversion + ) class NFSShareRWAccessReadWriteTest(ShareAccessReadWriteBase): diff --git a/manilaclient/tests/functional/test_share_network_subnets.py b/manilaclient/tests/functional/test_share_network_subnets.py index 49c790fd..26c43330 100644 --- a/manilaclient/tests/functional/test_share_network_subnets.py +++ b/manilaclient/tests/functional/test_share_network_subnets.py @@ -23,9 +23,8 @@ @ddt.ddt @utils.skip_if_microversion_not_supported('2.51') class ShareNetworkSubnetsReadWriteTest(base.BaseTestCase): - def setUp(self): - super(ShareNetworkSubnetsReadWriteTest, self).setUp() + super().setUp() self.name = data_utils.rand_name('autotest') self.description = 'fake_description' self.neutron_net_id = 'fake_neutron_net_id' @@ -39,11 +38,13 @@ def setUp(self): ) def test_get_share_network_subnet(self): - default_subnet = utils.get_default_subnet(self.user_client, - self.sn['id']) + default_subnet = utils.get_default_subnet( + self.user_client, self.sn['id'] + ) subnet = self.user_client.get_share_network_subnet( - self.sn['id'], default_subnet['id']) + self.sn['id'], default_subnet['id'] + ) self.assertEqual(self.neutron_net_id, subnet['neutron_net_id']) self.assertEqual(self.neutron_subnet_id, subnet['neutron_subnet_id']) @@ -52,7 +53,9 @@ def test_get_invalid_share_network_subnet(self): self.assertRaises( exceptions.CommandFailed, self.user_client.get_share_network_subnet, - self.sn['id'], 'invalid_subnet_id') + self.sn['id'], + 'invalid_subnet_id', + ) def _get_availability_zone(self): availability_zones = self.user_client.list_availability_zones() @@ -65,9 +68,11 @@ def test_add_share_network_subnet_to_share_network(self): subnet = self.add_share_network_subnet( self.sn['id'], - neutron_net_id, neutron_subnet_id, + neutron_net_id, + neutron_subnet_id, availability_zone, - cleanup_in_class=False) + cleanup_in_class=False, + ) self.assertEqual(neutron_net_id, subnet['neutron_net_id']) self.assertEqual(neutron_subnet_id, subnet['neutron_subnet_id']) @@ -83,7 +88,8 @@ def test_add_invalid_share_network_subnet_to_share_network(self, params): exceptions.CommandFailed, self.add_share_network_subnet, self.sn['id'], - **params) + **params, + ) def test_add_share_network_subnet_to_invalid_share_network(self): self.assertRaises( @@ -91,7 +97,8 @@ def test_add_share_network_subnet_to_invalid_share_network(self): self.add_share_network_subnet, 'invalid_share_network', self.neutron_net_id, - self.neutron_subnet_id) + self.neutron_subnet_id, + ) def test_add_delete_share_network_subnet_from_share_network(self): neutron_net_id = 'new_neutron_net_id' @@ -100,20 +107,23 @@ def test_add_delete_share_network_subnet_from_share_network(self): subnet = self.add_share_network_subnet( self.sn['id'], - neutron_net_id, neutron_subnet_id, + neutron_net_id, + neutron_subnet_id, availability_zone, - cleanup_in_class=False) + cleanup_in_class=False, + ) self.user_client.delete_share_network_subnet( - share_network_subnet=subnet['id'], - share_network=self.sn['id']) + share_network_subnet=subnet['id'], share_network=self.sn['id'] + ) self.user_client.wait_for_share_network_subnet_deletion( - share_network_subnet=subnet['id'], - share_network=self.sn['id']) + share_network_subnet=subnet['id'], share_network=self.sn['id'] + ) def test_delete_invalid_share_network_subnet(self): self.assertRaises( exceptions.NotFound, self.user_client.delete_share_network_subnet, share_network_subnet='invalid_subnet_id', - share_network=self.sn['id']) + share_network=self.sn['id'], + ) diff --git a/manilaclient/tests/functional/test_share_networks.py b/manilaclient/tests/functional/test_share_networks.py index 49d49277..3a3dacb8 100644 --- a/manilaclient/tests/functional/test_share_networks.py +++ b/manilaclient/tests/functional/test_share_networks.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2015 Mirantis Inc. # All Rights Reserved. # @@ -31,9 +30,8 @@ @ddt.ddt class ShareNetworksReadWriteTest(base.BaseTestCase): - def setUp(self): - super(ShareNetworksReadWriteTest, self).setUp() + super().setUp() self.name = data_utils.rand_name('autotest') self.description = 'fake_description' self.neutron_net_id = 'fake_neutron_net_id' @@ -49,18 +47,24 @@ def setUp(self): @ddt.data( {'name': data_utils.rand_name('autotest_share_network_name')}, {'description': 'fake_description'}, - {'neutron_net_id': 'fake_neutron_net_id', - 'neutron_subnet_id': 'fake_neutron_subnet_id'}, + { + 'neutron_net_id': 'fake_neutron_net_id', + 'neutron_subnet_id': 'fake_neutron_subnet_id', + }, ) def test_create_delete_share_network(self, net_data): share_subnet_support = utils.share_network_subnets_are_supported() share_subnet_fields = ( ['neutron_net_id', 'neutron_subnet_id', 'availability_zone'] - if share_subnet_support else []) + if share_subnet_support + else [] + ) sn = self.create_share_network(cleanup_in_class=False, **net_data) - default_subnet = (utils.get_default_subnet(self.user_client, sn['id']) - if share_subnet_support - else None) + default_subnet = ( + utils.get_default_subnet(self.user_client, sn['id']) + if share_subnet_support + else None + ) expected_data = { 'name': 'None', @@ -70,11 +74,15 @@ def test_create_delete_share_network(self, net_data): } expected_data.update(net_data) share_network_expected_data = [ - (k, v) for k, v in expected_data.items() - if k not in share_subnet_fields] + (k, v) + for k, v in expected_data.items() + if k not in share_subnet_fields + ] share_subnet_expected_data = [ - (k, v) for k, v in expected_data.items() - if k in share_subnet_fields] + (k, v) + for k, v in expected_data.items() + if k in share_subnet_fields + ] for k, v in share_network_expected_data: self.assertEqual(v, sn[k]) @@ -86,17 +94,21 @@ def test_create_delete_share_network(self, net_data): @utils.skip_if_microversion_not_supported('2.51') def test_create_delete_share_network_with_az(self): - share_subnet_fields = ( - ['neutron_net_id', 'neutron_subnet_id', 'availability_zone']) + share_subnet_fields = [ + 'neutron_net_id', + 'neutron_subnet_id', + 'availability_zone', + ] az = self.user_client.list_availability_zones()[0] net_data = { 'neutron_net_id': 'fake_neutron_net_id', 'neutron_subnet_id': 'fake_neutron_subnet_id', - 'availability_zone': az['Name'] + 'availability_zone': az['Name'], } sn = self.create_share_network(cleanup_in_class=False, **net_data) default_subnet = utils.get_subnet_by_availability_zone_name( - self.user_client, sn['id'], az['Name']) + self.user_client, sn['id'], az['Name'] + ) expected_data = { 'name': 'None', @@ -107,11 +119,15 @@ def test_create_delete_share_network_with_az(self): } expected_data.update(net_data) share_network_expected_data = [ - (k, v) for k, v in expected_data.items() - if k not in share_subnet_fields] + (k, v) + for k, v in expected_data.items() + if k not in share_subnet_fields + ] share_subnet_expected_data = [ - (k, v) for k, v in expected_data.items() - if k in share_subnet_fields] + (k, v) + for k, v in expected_data.items() + if k in share_subnet_fields + ] for k, v in share_network_expected_data: self.assertEqual(v, sn[k]) @@ -135,40 +151,61 @@ def _get_expected_update_data(self, net_data, net_creation_data): # from string to literal structures in order to process the content of # 'share_network_subnets' field. default_return_value = ( - None if utils.share_network_subnets_are_supported() else 'None') + None if utils.share_network_subnets_are_supported() else 'None' + ) expected_nn_id = ( default_return_value if net_data.get('neutron_net_id') - else net_creation_data.get('neutron_net_id', default_return_value)) + else net_creation_data.get('neutron_net_id', default_return_value) + ) expected_nsn_id = ( default_return_value if net_data.get('neutron_subnet_id') - else net_creation_data.get('neutron_subnet_id', - default_return_value)) + else net_creation_data.get( + 'neutron_subnet_id', default_return_value + ) + ) return expected_nn_id, expected_nsn_id @ddt.data( ({'name': data_utils.rand_name('autotest_share_network_name')}, {}), ({'description': 'fake_description'}, {}), - ({'neutron_net_id': 'fake_neutron_net_id', - 'neutron_subnet_id': 'fake_neutron_subnet_id'}, {}), + ( + { + 'neutron_net_id': 'fake_neutron_net_id', + 'neutron_subnet_id': 'fake_neutron_subnet_id', + }, + {}, + ), ({'name': '""'}, {}), ({'description': '""'}, {}), - ({'neutron_net_id': '""'}, - {'neutron_net_id': 'fake_nn_id', 'neutron_subnet_id': 'fake_nsn_id'}), - ({'neutron_subnet_id': '""'}, - {'neutron_net_id': 'fake_nn_id', 'neutron_subnet_id': 'fake_nsn_id'}) + ( + {'neutron_net_id': '""'}, + { + 'neutron_net_id': 'fake_nn_id', + 'neutron_subnet_id': 'fake_nsn_id', + }, + ), + ( + {'neutron_subnet_id': '""'}, + { + 'neutron_net_id': 'fake_nn_id', + 'neutron_subnet_id': 'fake_nsn_id', + }, + ), ) @ddt.unpack def test_create_update_share_network(self, net_data, net_creation_data): sn = self.create_share_network( - cleanup_in_class=False, **net_creation_data) + cleanup_in_class=False, **net_creation_data + ) update = self.admin_client.update_share_network(sn['id'], **net_data) expected_nn_id, expected_nsn_id = self._get_expected_update_data( - net_data, net_creation_data) + net_data, net_creation_data + ) expected_data = { 'name': 'None', @@ -181,8 +218,9 @@ def test_create_update_share_network(self, net_data, net_creation_data): subnet_keys = ['neutron_net_id', 'neutron_subnet_id'] subnet = ast.literal_eval(update['share_network_subnets']) - update_values = dict([(k, v) for k, v in net_data.items() - if v != '""']) + update_values = dict( + [(k, v) for k, v in net_data.items() if v != '""'] + ) expected_data.update(update_values) for k, v in expected_data.items(): @@ -199,7 +237,8 @@ def test_list_share_networks(self, all_tenants): share_networks = self.admin_client.list_share_networks(all_tenants) self.assertTrue( - any(self.sn['id'] == sn['id'] for sn in share_networks)) + any(self.sn['id'] == sn['id'] for sn in share_networks) + ) for sn in share_networks: self.assertEqual(2, len(sn)) self.assertIn('id', sn) @@ -213,25 +252,31 @@ def test_list_share_networks_select_column(self): def _list_share_networks_with_filters(self, filters): assert_subnet_fields = utils.share_network_subnets_are_supported() - share_subnet_fields = (['neutron_subnet_id', 'neutron_net_id'] - if assert_subnet_fields - else []) - share_network_filters = [(k, v) for k, v in filters.items() - if k not in share_subnet_fields] - share_network_subnet_filters = [(k, v) for k, v in filters.items() - if k in share_subnet_fields] + share_subnet_fields = ( + ['neutron_subnet_id', 'neutron_net_id'] + if assert_subnet_fields + else [] + ) + share_network_filters = [ + (k, v) for k, v in filters.items() if k not in share_subnet_fields + ] + share_network_subnet_filters = [ + (k, v) for k, v in filters.items() if k in share_subnet_fields + ] share_networks = self.admin_client.list_share_networks(filters=filters) self.assertGreater(len(share_networks), 0) self.assertTrue( - any(self.sn['id'] == sn['id'] for sn in share_networks)) + any(self.sn['id'] == sn['id'] for sn in share_networks) + ) for sn in share_networks: try: share_network = self.admin_client.get_share_network(sn['id']) default_subnet = ( utils.get_default_subnet(self.user_client, sn['id']) if assert_subnet_fields - else None) + else None + ) except tempest_lib_exc.NotFound: # NOTE(vponomaryov): Case when some share network was deleted # between our 'list' and 'get' requests. Skip such case. @@ -245,7 +290,8 @@ def _list_share_networks_with_filters(self, filters): def test_list_share_networks_filter_by_project_id(self): project_id = self.admin_client.get_project_id( - self.admin_client.tenant_name) + self.admin_client.tenant_name + ) filters = {'project_id': project_id} self._list_share_networks_with_filters(filters) @@ -275,28 +321,25 @@ def test_list_share_networks_filter_by_inexact(self, option): ) filters = {option + '~': 'inexact'} - share_networks = self.admin_client.list_share_networks( - filters=filters) + share_networks = self.admin_client.list_share_networks(filters=filters) self.assertGreater(len(share_networks), 0) def test_list_share_networks_by_inexact_unicode_option(self): self.create_share_network( - name=u'网络名称', - description=u'网络描述', + name='网络名称', + description='网络描述', neutron_net_id='fake_neutron_net_id', neutron_subnet_id='fake_neutron_subnet_id', ) - filters = {'name~': u'名称'} - share_networks = self.admin_client.list_share_networks( - filters=filters) + filters = {'name~': '名称'} + share_networks = self.admin_client.list_share_networks(filters=filters) self.assertGreater(len(share_networks), 0) - filters = {'description~': u'描述'} - share_networks = self.admin_client.list_share_networks( - filters=filters) + filters = {'description~': '描述'} + share_networks = self.admin_client.list_share_networks(filters=filters) self.assertGreater(len(share_networks), 0) @@ -311,13 +354,17 @@ def test_share_network_reset_status(self): # Admin operation self.admin_client.share_network_reset_state( - share_network['id'], 'error', - microversion=SECURITY_SERVICE_UPDATE_VERSION) + share_network['id'], + 'error', + microversion=SECURITY_SERVICE_UPDATE_VERSION, + ) self.user_client.wait_for_resource_status( - share_network['id'], 'error', + share_network['id'], + 'error', microversion=SECURITY_SERVICE_UPDATE_VERSION, - resource_type="share_network") + resource_type="share_network", + ) def test_share_network_security_service_add(self): share_network = self.create_share_network( @@ -328,25 +375,30 @@ def test_share_network_security_service_add(self): neutron_subnet_id='fake_neutron_subnet_id', ) new_security_service = self.create_security_service( - client=self.user_client) + client=self.user_client + ) check_result = ( self.user_client.share_network_security_service_add_check( share_network['id'], - security_service_id=new_security_service['id'])) + security_service_id=new_security_service['id'], + ) + ) self.assertEqual(check_result['compatible'], 'True') self.user_client.share_network_security_service_add( - share_network['id'], new_security_service['id']) + share_network['id'], new_security_service['id'] + ) network_services = ( self.user_client.share_network_security_service_list( - share_network['id'])) + share_network['id'] + ) + ) self.assertEqual(len(network_services), 1) - self.assertEqual( - network_services[0]['id'], new_security_service['id']) + self.assertEqual(network_services[0]['id'], new_security_service['id']) def test_share_network_security_service_update(self): share_network = self.create_share_network( @@ -359,40 +411,54 @@ def test_share_network_security_service_update(self): current_name = 'current' new_name = 'new' current_security_service = self.create_security_service( - client=self.user_client, name=current_name) + client=self.user_client, name=current_name + ) new_security_service = self.create_security_service( - client=self.user_client, name=new_name) + client=self.user_client, name=new_name + ) check_result = ( self.user_client.share_network_security_service_add_check( - share_network['id'], current_security_service['id'])) + share_network['id'], current_security_service['id'] + ) + ) self.assertEqual(check_result['compatible'], 'True') self.user_client.share_network_security_service_add( - share_network['id'], current_security_service['id']) + share_network['id'], current_security_service['id'] + ) network_services = ( self.user_client.share_network_security_service_list( - share_network['id'])) + share_network['id'] + ) + ) self.assertEqual(len(network_services), 1) self.assertEqual(network_services[0]['name'], current_name) check_result = ( self.user_client.share_network_security_service_update_check( - share_network['id'], current_security_service['id'], - new_security_service['id'])) + share_network['id'], + current_security_service['id'], + new_security_service['id'], + ) + ) self.assertEqual(check_result['compatible'], 'True') self.user_client.share_network_security_service_update( - share_network['id'], current_security_service['id'], - new_security_service['id']) + share_network['id'], + current_security_service['id'], + new_security_service['id'], + ) network_services = ( self.user_client.share_network_security_service_list( - share_network['id'])) + share_network['id'] + ) + ) self.assertEqual(len(network_services), 1) self.assertEqual(network_services[0]['name'], new_name) @@ -403,10 +469,11 @@ def test_share_network_subnet_create_check(self): description='fakedescription', ) - check_result = ( - self.user_client.share_network_subnet_create_check( - share_network['id'], neutron_net_id='fake_neutron_net_id', - neutron_subnet_id='fake_neutron_subnet_id')) + check_result = self.user_client.share_network_subnet_create_check( + share_network['id'], + neutron_net_id='fake_neutron_net_id', + neutron_subnet_id='fake_neutron_subnet_id', + ) self.assertEqual(check_result['compatible'], 'True') @@ -420,7 +487,8 @@ def test_check_add_share_network_subnet_with_invalid_params(self, params): tempest_lib_exc.CommandFailed, self.user_client.share_network_subnet_create_check, self.sn['id'], - **params) + **params, + ) def test_check_add_share_network_subnet_to_invalid_share_network(self): self.assertRaises( @@ -428,16 +496,17 @@ def test_check_add_share_network_subnet_to_invalid_share_network(self): self.user_client.share_network_subnet_create_check, 'invalid_share_network', self.neutron_net_id, - self.neutron_subnet_id) + self.neutron_subnet_id, + ) class ShareNetworkSecurityServiceCheckReadWriteTests(base.BaseTestCase): protocol = None def setUp(self): - super(ShareNetworkSecurityServiceCheckReadWriteTests, self).setUp() + super().setUp() if self.protocol not in CONF.enable_protocols: - message = "%s tests are disabled." % self.protocol + message = f"{self.protocol} tests are disabled." raise self.skipException(message) self.client = self.get_user_client() if not self.client.share_network: @@ -445,8 +514,11 @@ def setUp(self): raise self.skipException(message) def _wait_for_update_security_service_compatible_result( - self, share_network, current_security_service, - new_security_service=None): + self, + share_network, + current_security_service, + new_security_service=None, + ): compatible_expected_result = 'True' check_is_compatible = 'None' tentatives = 0 @@ -458,24 +530,28 @@ def _wait_for_update_security_service_compatible_result( if not new_security_service: check_is_compatible = ( self.user_client.share_network_security_service_add_check( - share_network['id'], - current_security_service['id']))['compatible'] + share_network['id'], current_security_service['id'] + ) + )['compatible'] else: check_is_compatible = ( - (self.user_client. - share_network_security_service_update_check( - share_network['id'], - current_security_service['id'], - new_security_service['id'])))['compatible'] + self.user_client.share_network_security_service_update_check( + share_network['id'], + current_security_service['id'], + new_security_service['id'], + ) + )['compatible'] if tentatives > 3: timeout_message = ( "Share network security service add/update check did not " - "reach 'compatible=True' within 15 seconds.") + "reach 'compatible=True' within 15 seconds." + ) raise exceptions.TimeoutException(message=timeout_message) time.sleep(5) def test_check_if_security_service_can_be_added_to_share_network_in_use( - self): + self, + ): share_network = self.create_share_network( client=self.user_client, description='fakedescription', @@ -485,24 +561,30 @@ def test_check_if_security_service_can_be_added_to_share_network_in_use( # Create a share so we can be sure that a share server will exist and # the check will be performed in the backends self.create_share( - self.protocol, client=self.user_client, - share_network=share_network['id']) + self.protocol, + client=self.user_client, + share_network=share_network['id'], + ) current_security_service = self.create_security_service( - client=self.user_client) + client=self.user_client + ) check_result = ( self.user_client.share_network_security_service_add_check( - share_network['id'], - current_security_service['id'])) + share_network['id'], current_security_service['id'] + ) + ) self.assertEqual(check_result['compatible'], 'None') self._wait_for_update_security_service_compatible_result( - share_network, current_security_service) + share_network, current_security_service + ) def test_add_and_update_security_service_when_share_network_is_in_use( - self): + self, + ): share_network = self.create_share_network( client=self.user_client, name='cool_net_name', @@ -514,66 +596,92 @@ def test_add_and_update_security_service_when_share_network_is_in_use( # Create a share so we can be sure that a share server will exist and # the check will be performed in the backends self.create_share( - self.protocol, name='fake_share_name', - share_network=share_network['id'], client=self.user_client) + self.protocol, + name='fake_share_name', + share_network=share_network['id'], + client=self.user_client, + ) current_security_service = self.create_security_service( - client=self.user_client, name='current_security_service') + client=self.user_client, name='current_security_service' + ) new_security_service = self.create_security_service( - client=self.user_client, name='new_security_service') + client=self.user_client, name='new_security_service' + ) check_result = ( self.user_client.share_network_security_service_add_check( - share_network['id'], current_security_service['id'])) + share_network['id'], current_security_service['id'] + ) + ) self.assertEqual(check_result['compatible'], 'None') self._wait_for_update_security_service_compatible_result( - share_network, current_security_service) + share_network, current_security_service + ) self.user_client.share_network_security_service_add( - share_network['id'], current_security_service['id']) + share_network['id'], current_security_service['id'] + ) network_services = ( self.user_client.share_network_security_service_list( - share_network['id'])) + share_network['id'] + ) + ) self.assertEqual(len(network_services), 1) self.assertEqual( - network_services[0]['name'], current_security_service['name']) + network_services[0]['name'], current_security_service['name'] + ) self.user_client.wait_for_resource_status( - share_network['id'], 'active', + share_network['id'], + 'active', microversion=SECURITY_SERVICE_UPDATE_VERSION, - resource_type="share_network") + resource_type="share_network", + ) check_result = ( self.user_client.share_network_security_service_update_check( - share_network['id'], current_security_service['id'], - new_security_service['id'])) + share_network['id'], + current_security_service['id'], + new_security_service['id'], + ) + ) self.assertEqual(check_result['compatible'], 'None') self._wait_for_update_security_service_compatible_result( - share_network, current_security_service, - new_security_service=new_security_service) + share_network, + current_security_service, + new_security_service=new_security_service, + ) self.user_client.share_network_security_service_update( - share_network['id'], current_security_service['id'], - new_security_service['id']) + share_network['id'], + current_security_service['id'], + new_security_service['id'], + ) network_services = ( self.user_client.share_network_security_service_list( - share_network['id'])) + share_network['id'] + ) + ) self.assertEqual(len(network_services), 1) self.assertEqual( - network_services[0]['name'], new_security_service['name']) + network_services[0]['name'], new_security_service['name'] + ) self.user_client.wait_for_resource_status( - share_network['id'], 'active', + share_network['id'], + 'active', microversion=SECURITY_SERVICE_UPDATE_VERSION, - resource_type="share_network") + resource_type="share_network", + ) base_security_service_check = ShareNetworkSecurityServiceCheckReadWriteTests diff --git a/manilaclient/tests/functional/test_share_replica_export_locations.py b/manilaclient/tests/functional/test_share_replica_export_locations.py index 3f35364e..219a9200 100644 --- a/manilaclient/tests/functional/test_share_replica_export_locations.py +++ b/manilaclient/tests/functional/test_share_replica_export_locations.py @@ -24,18 +24,20 @@ @ddt.ddt -@testtools.skipUnless(CONF.run_replication_tests, - "Replication tests are disabled.") +@testtools.skipUnless( + CONF.run_replication_tests, "Replication tests are disabled." +) @utils.skip_if_microversion_not_supported('2.47') class ShareReplicaExportLocationsTest(base.BaseTestCase): - def _create_share_and_replica(self): replication_type = CONF.replication_type share_type = self.create_share_type( driver_handles_share_servers=False, - extra_specs={'replication_type': replication_type}) - share = self.create_share(share_type=share_type['ID'], - client=self.get_user_client()) + extra_specs={'replication_type': replication_type}, + ) + share = self.create_share( + share_type=share_type['ID'], client=self.get_user_client() + ) share_replica = self.create_share_replica(share['id']) return share, share_replica @@ -44,11 +46,17 @@ def test_list_share_export_locations(self, role): share, share_replica = self._create_share_and_replica() client = self.admin_client if role == 'admin' else self.user_client export_locations = client.list_share_replica_export_locations( - share_replica['id']) + share_replica['id'] + ) self.assertGreater(len(export_locations), 0) - expected_keys = ['ID', 'Path', 'Preferred', 'Replica State', - 'Availability Zone'] + expected_keys = [ + 'ID', + 'Path', + 'Preferred', + 'Replica State', + 'Availability Zone', + ] for el in export_locations: for key in expected_keys: @@ -61,7 +69,8 @@ def test_list_share_export_locations_with_columns(self, role): share, share_replica = self._create_share_and_replica() client = self.admin_client if role == 'admin' else self.user_client export_locations = client.list_share_replica_export_locations( - share_replica['id'], columns='id,path') + share_replica['id'], columns='id,path' + ) self.assertGreater(len(export_locations), 0) expected_keys = ('Id', 'Path') @@ -78,13 +87,22 @@ def test_get_share_replica_export_location(self, role): share, share_replica = self._create_share_and_replica() client = self.admin_client if role == 'admin' else self.user_client export_locations = client.list_share_replica_export_locations( - share_replica['id']) + share_replica['id'] + ) el = client.get_share_replica_export_location( - share_replica['id'], export_locations[0]['ID']) + share_replica['id'], export_locations[0]['ID'] + ) - expected_keys = ['path', 'updated_at', 'created_at', 'id', - 'preferred', 'replica_state', 'availability_zone'] + expected_keys = [ + 'path', + 'updated_at', + 'created_at', + 'id', + 'preferred', + 'replica_state', + 'availability_zone', + ] if role == 'admin': expected_keys.extend(['is_admin_only', 'share_instance_id']) for key in expected_keys: @@ -95,8 +113,10 @@ def test_get_share_replica_export_location(self, role): self.assertTrue(uuidutils.is_uuid_like(el['id'])) self.assertIn(el['preferred'], ('True', 'False')) for list_k, get_k in ( - ('ID', 'id'), ('Path', 'path'), ('Preferred', 'preferred'), - ('Replica State', 'replica_state'), - ('Availability Zone', 'availability_zone')): - self.assertEqual( - export_locations[0][list_k], el[get_k]) + ('ID', 'id'), + ('Path', 'path'), + ('Preferred', 'preferred'), + ('Replica State', 'replica_state'), + ('Availability Zone', 'availability_zone'), + ): + self.assertEqual(export_locations[0][list_k], el[get_k]) diff --git a/manilaclient/tests/functional/test_share_replicas.py b/manilaclient/tests/functional/test_share_replicas.py index 96e42cfd..f7465688 100644 --- a/manilaclient/tests/functional/test_share_replicas.py +++ b/manilaclient/tests/functional/test_share_replicas.py @@ -21,22 +21,24 @@ @utils.skip_if_microversion_not_supported('2.72') class ShareReplicasTest(base.BaseTestCase): - def _create_share_and_replica(self): replication_type = CONF.replication_type share_type = self.create_share_type( driver_handles_share_servers=True, - extra_specs={'replication_type': replication_type}) + extra_specs={'replication_type': replication_type}, + ) share_network = self.create_share_network() share = self.create_share( share_type=share_type['ID'], share_network=share_network['id'], - client=self.get_user_client()) + client=self.get_user_client(), + ) share_replica = self.create_share_replica( share['id'], share_network=share_network['id'], wait_for_creation=True, - client=self.get_user_client()) + client=self.get_user_client(), + ) return share, share_replica def test_share_replica_create(self): diff --git a/manilaclient/tests/functional/test_share_servers.py b/manilaclient/tests/functional/test_share_servers.py index e71ac00d..63e4c19c 100644 --- a/manilaclient/tests/functional/test_share_servers.py +++ b/manilaclient/tests/functional/test_share_servers.py @@ -30,9 +30,8 @@ @ddt.ddt class ShareServersReadOnlyTest(base.BaseTestCase): - def setUp(self): - super(ShareServersReadOnlyTest, self).setUp() + super().setUp() self.client = self.get_admin_client() def test_share_server_list(self): @@ -49,10 +48,14 @@ def test_share_server_list_with_share_network_param(self): def test_share_server_list_with_project_id_param(self): self.client.list_share_servers( - filters={'project_id': 'fake_project_id'}) + filters={'project_id': 'fake_project_id'} + ) @ddt.data( - 'host', 'status', 'project_id', 'share_network', + 'host', + 'status', + 'project_id', + 'share_network', 'host,status,project_id,share_network', ) def test_share_server_list_with_specified_columns(self, columns): @@ -60,21 +63,21 @@ def test_share_server_list_with_specified_columns(self, columns): def test_share_server_list_by_user(self): self.assertRaises( - exceptions.CommandFailed, self.user_client.list_share_servers) + exceptions.CommandFailed, self.user_client.list_share_servers + ) @ddt.ddt class ShareServersReadWriteBase(base.BaseTestCase): - protocol = None def setUp(self): - super(ShareServersReadWriteBase, self).setUp() + super().setUp() if not CONF.run_share_servers_tests: message = "share-server tests are disabled." raise self.skipException(message) if self.protocol not in CONF.enable_protocols: - message = "%s tests are disabled." % self.protocol + message = f"{self.protocol} tests are disabled." raise self.skipException(message) self.client = self.get_admin_client() if not self.client.share_network: @@ -86,20 +89,25 @@ def _create_share_and_share_network(self): description = data_utils.rand_name('autotest_share_description') common_share_network = self.client.get_share_network( - self.client.share_network) + self.client.share_network + ) share_net_info = ( - utils.get_default_subnet(self.user_client, - common_share_network['id']) + utils.get_default_subnet( + self.user_client, common_share_network['id'] + ) if utils.share_network_subnets_are_supported() - else common_share_network) + else common_share_network + ) neutron_net_id = ( share_net_info['neutron_net_id'] if 'none' not in share_net_info['neutron_net_id'].lower() - else None) + else None + ) neutron_subnet_id = ( share_net_info['neutron_subnet_id'] if 'none' not in share_net_info['neutron_subnet_id'].lower() - else None) + else None + ) share_network = self.client.create_share_network( neutron_net_id=neutron_net_id, neutron_subnet_id=neutron_subnet_id, @@ -112,7 +120,7 @@ def _create_share_and_share_network(self): description=description, share_network=share_network['id'], client=self.client, - wait_for_creation=True + wait_for_creation=True, ) self.share = self.client.get_share(self.share['id']) return self.share, share_network @@ -128,14 +136,21 @@ def _delete_share_and_share_server(self, share_id, share_server_id): def test_get_and_delete_share_server(self): self.share, share_network = self._create_share_and_share_network() - share_server_id = self.client.get_share( - self.share['id'])['share_server_id'] + share_server_id = self.client.get_share(self.share['id'])[ + 'share_server_id' + ] # Get share server server = self.client.get_share_server(share_server_id) expected_keys = ( - 'id', 'host', 'status', 'created_at', 'updated_at', - 'share_network_id', 'share_network_name', 'project_id', + 'id', + 'host', + 'status', + 'created_at', + 'updated_at', + 'share_network_id', + 'share_network_name', + 'project_id', ) if utils.is_microversion_supported('2.49'): @@ -148,16 +163,19 @@ def test_get_and_delete_share_server(self): self.client.delete_share_network(share_network['id']) @testtools.skipUnless( - CONF.run_manage_tests, 'Share Manage/Unmanage tests are disabled.') + CONF.run_manage_tests, 'Share Manage/Unmanage tests are disabled.' + ) @utils.skip_if_microversion_not_supported('2.49') def test_manage_and_unmanage_share_server(self): share, share_network = self._create_share_and_share_network() - share_server_id = self.client.get_share( - self.share['id'])['share_server_id'] + share_server_id = self.client.get_share(self.share['id'])[ + 'share_server_id' + ] server = self.client.get_share_server(share_server_id) server_host = server['host'] export_location = self.client.list_share_export_locations( - self.share['id'])[0]['Path'] + self.share['id'] + )[0]['Path'] share_host = share['host'] identifier = server['identifier'] @@ -176,23 +194,28 @@ def test_manage_and_unmanage_share_server(self): # Manage share server managed_share_server_id = self.client.share_server_manage( - server_host, share_network['id'], identifier) + server_host, share_network['id'], identifier + ) self.client.wait_for_resource_status( - managed_share_server_id, constants.STATUS_ACTIVE, - resource_type='share_server') + managed_share_server_id, + constants.STATUS_ACTIVE, + resource_type='share_server', + ) managed_server = self.client.get_share_server(managed_share_server_id) self.assertEqual('False', managed_server['is_auto_deletable']) # Manage share managed_share_id = self.client.manage_share( - share_host, self.protocol, export_location, - managed_share_server_id) - self.client.wait_for_resource_status(managed_share_id, - constants.STATUS_AVAILABLE) + share_host, self.protocol, export_location, managed_share_server_id + ) + self.client.wait_for_resource_status( + managed_share_id, constants.STATUS_AVAILABLE + ) - self._delete_share_and_share_server(managed_share_id, - managed_share_server_id) + self._delete_share_and_share_server( + managed_share_id, managed_share_server_id + ) self.client.delete_share_network(share_network['id']) @@ -207,16 +230,15 @@ class ShareServersReadWriteCIFSTest(ShareServersReadWriteBase): @ddt.ddt @utils.skip_if_microversion_not_supported('2.57') class ShareServersMigrationBase(base.BaseTestCase): - protocol = None def setUp(self): - super(ShareServersMigrationBase, self).setUp() + super().setUp() if not CONF.run_share_servers_tests: message = "Share-server tests are disabled." raise self.skipException(message) if self.protocol not in CONF.enable_protocols: - message = "%s tests are disabled." % self.protocol + message = f"{self.protocol} tests are disabled." raise self.skipException(message) self.client = self.get_admin_client() if not self.client.share_network: @@ -231,25 +253,30 @@ def _create_share_and_share_network(self): description = data_utils.rand_name('autotest_share_description') common_share_network = self.client.get_share_network( - self.client.share_network) - share_net_info = utils.get_default_subnet(self.client, - common_share_network['id']) + self.client.share_network + ) + share_net_info = utils.get_default_subnet( + self.client, common_share_network['id'] + ) neutron_net_id = ( share_net_info['neutron_net_id'] if 'none' not in share_net_info['neutron_net_id'].lower() - else None) + else None + ) neutron_subnet_id = ( share_net_info['neutron_subnet_id'] if 'none' not in share_net_info['neutron_subnet_id'].lower() - else None) + else None + ) share_network = self.client.create_share_network( neutron_net_id=neutron_net_id, neutron_subnet_id=neutron_subnet_id, ) share_type = self.create_share_type( data_utils.rand_name('test_share_type'), - driver_handles_share_servers=True) + driver_handles_share_servers=True, + ) share = self.create_share( share_protocol=self.protocol, @@ -259,14 +286,13 @@ def _create_share_and_share_network(self): share_type=share_type['ID'], share_network=share_network['id'], client=self.client, - wait_for_creation=True + wait_for_creation=True, ) share = self.client.get_share(share['id']) return share, share_network @ddt.data('cancel', 'complete') def test_share_server_migration(self, operation): - # Create a share and share network to be used in the tests. share, share_network = self._create_share_and_share_network() share_server_id = share['share_server_id'] @@ -278,36 +304,46 @@ def test_share_server_migration(self, operation): # than the source host. for hosts in pools: host_name = hosts['Name'].split('#')[0] - if (ast.literal_eval(hosts['Capabilities']).get( - 'driver_handles_share_servers') and - host_name != src_host): + if ( + ast.literal_eval(hosts['Capabilities']).get( + 'driver_handles_share_servers' + ) + and host_name != src_host + ): host_list.append(host_name) host_list = list(set(host_list)) # If not found any host we need skip the test. if len(host_list) == 0: - raise self.skipException("No hosts available for " - "share server migration.") + raise self.skipException( + "No hosts available for share server migration." + ) dest_backend = None # If found at least one host, we still need to verify the # share server migration compatibility with the destination host. for host in host_list: compatibility = self.admin_client.share_server_migration_check( - server_id=share_server_id, dest_host=host, - writable=False, nondisruptive=False, preserve_snapshots=False, - new_share_network=None) + server_id=share_server_id, + dest_host=host, + writable=False, + nondisruptive=False, + preserve_snapshots=False, + new_share_network=None, + ) # If found at least one compatible host, we will use it. if compatibility['compatible']: dest_host = host # If not found, we need skip the test. if dest_backend is not None: - raise self.skipException("No hosts compatible to perform a " - "share server migration.") + raise self.skipException( + "No hosts compatible to perform a share server migration." + ) # Start the share server migration self.admin_client.share_server_migration_start( - share_server_id, dest_host) + share_server_id, dest_host + ) server = self.admin_client.get_share_server(share_server_id) share = self.admin_client.get_share(share['id']) @@ -316,21 +352,25 @@ def test_share_server_migration(self, operation): # Wait for the share server migration driver phase 1 done. task_state = constants.TASK_STATE_MIGRATION_DRIVER_PHASE1_DONE server = self.admin_client.wait_for_server_migration_task_state( - share_server_id, dest_host, task_state) + share_server_id, dest_host, task_state + ) migration_progress = ( self.admin_client.share_server_migration_get_progress( - share_server_id)) + share_server_id + ) + ) dest_share_server_id = migration_progress.get( - 'destination_share_server_id') + 'destination_share_server_id' + ) # Call share server migration complete or cancel operations # according the ddt. if operation == 'complete': task_state = constants.TASK_STATE_MIGRATION_SUCCESS - self.admin_client.share_server_migration_complete( - share_server_id) + self.admin_client.share_server_migration_complete(share_server_id) server = self.admin_client.wait_for_server_migration_task_state( - dest_share_server_id, dest_host, task_state) + dest_share_server_id, dest_host, task_state + ) self.admin_client.wait_for_share_server_deletion(share_server_id) else: @@ -338,7 +378,8 @@ def test_share_server_migration(self, operation): task_state = constants.TASK_STATE_MIGRATION_CANCELLED # Wait for the respectives task state for each operation above. server = self.admin_client.wait_for_server_migration_task_state( - server['id'], dest_host, task_state) + server['id'], dest_host, task_state + ) # Check if the share is available again. share = self.admin_client.get_share(share['id']) diff --git a/manilaclient/tests/functional/test_share_transfers.py b/manilaclient/tests/functional/test_share_transfers.py index 84621398..75ca4420 100644 --- a/manilaclient/tests/functional/test_share_transfers.py +++ b/manilaclient/tests/functional/test_share_transfers.py @@ -22,10 +22,11 @@ class ShareTransferTests(base.BaseTestCase): """Check of base share transfers command""" def setUp(self): - super(ShareTransferTests, self).setUp() + super().setUp() self.share_type = self.create_share_type( name=data_utils.rand_name('test_share_type'), - driver_handles_share_servers=False) + driver_handles_share_servers=False, + ) def test_transfer_create_list_show_delete(self): """Create, list, show and delete a share transfer""" @@ -36,11 +37,13 @@ def test_transfer_create_list_show_delete(self): name=data_utils.rand_name('autotest_share_name'), client=self.user_client, share_type=self.share_type['ID'], - use_wait_option=True) + use_wait_option=True, + ) self.assertEqual("available", share['status']) # create share transfer - transfer = self.create_share_transfer(share['id'], - name='test_share_transfer') + transfer = self.create_share_transfer( + share['id'], name='test_share_transfer' + ) self.assertIn('auth_key', transfer) # list share transfers @@ -71,11 +74,13 @@ def test_transfer_accept(self): name=data_utils.rand_name('autotest_share_name'), client=self.user_client, share_type=self.share_type['ID'], - use_wait_option=True) + use_wait_option=True, + ) self.assertEqual("available", share['status']) # create share transfer - transfer = self.create_share_transfer(share['id'], - name='test_share_transfer') + transfer = self.create_share_transfer( + share['id'], name='test_share_transfer' + ) share = self.user_client.get_share(share['id']) transfer_id = transfer['id'] auth_key = transfer['auth_key'] diff --git a/manilaclient/tests/functional/test_share_types.py b/manilaclient/tests/functional/test_share_types.py index f268aaad..eaa9f668 100644 --- a/manilaclient/tests/functional/test_share_types.py +++ b/manilaclient/tests/functional/test_share_types.py @@ -23,7 +23,6 @@ @ddt.ddt class ShareTypesReadOnlyTest(base.BaseTestCase): - @ddt.data( ("admin", "1.0"), ("admin", "2.0"), @@ -47,80 +46,139 @@ def test_extra_specs_list(self, microversion): @ddt.ddt class ShareTypesReadWriteTest(base.BaseTestCase): - create_keys = ( - 'ID', 'Name', 'Visibility', 'is_default', 'required_extra_specs', - 'optional_extra_specs') + 'ID', + 'Name', + 'Visibility', + 'is_default', + 'required_extra_specs', + 'optional_extra_specs', + ) - def _share_type_listed_by(self, share_type_id, by_admin=False, - list_all=False, microversion=None): + def _share_type_listed_by( + self, share_type_id, by_admin=False, list_all=False, microversion=None + ): client = self.admin_client if by_admin else self.user_client share_types = client.list_share_types( - list_all=list_all, microversion=microversion) + list_all=list_all, microversion=microversion + ) return any(share_type_id == st['ID'] for st in share_types) def _verify_access(self, share_type_id, is_public, microversion=None): if is_public: # Verify that it is listed with common 'type-list' operation. share_types = self.admin_client.list_share_types( - list_all=False, microversion=microversion) + list_all=False, microversion=microversion + ) self.assertTrue( - any(share_type_id == st['ID'] for st in share_types)) + any(share_type_id == st['ID'] for st in share_types) + ) else: # Verify that it is not listed for user - self.assertFalse(self._share_type_listed_by( - share_type_id=share_type_id, by_admin=False, list_all=True, - microversion=microversion)) + self.assertFalse( + self._share_type_listed_by( + share_type_id=share_type_id, + by_admin=False, + list_all=True, + microversion=microversion, + ) + ) # Verify it is listed for admin - self.assertTrue(self._share_type_listed_by( - share_type_id=share_type_id, by_admin=True, list_all=True, - microversion=microversion)) + self.assertTrue( + self._share_type_listed_by( + share_type_id=share_type_id, + by_admin=True, + list_all=True, + microversion=microversion, + ) + ) # Verify it is not listed by default - self.assertFalse(self._share_type_listed_by( - share_type_id=share_type_id, by_admin=True, list_all=False, - microversion=microversion)) + self.assertFalse( + self._share_type_listed_by( + share_type_id=share_type_id, + by_admin=True, + list_all=False, + microversion=microversion, + ) + ) @ddt.data(*unit_test_types.get_valid_type_create_data_2_0()) @ddt.unpack def test_create_delete_share_type( - self, is_public, dhss, spec_snapshot_support, extra_specs): - + self, is_public, dhss, spec_snapshot_support, extra_specs + ): self.skip_if_microversion_not_supported('2.0') self._test_create_delete_share_type( - '2.0', is_public, dhss, spec_snapshot_support, - None, None, None, extra_specs) + '2.0', + is_public, + dhss, + spec_snapshot_support, + None, + None, + None, + extra_specs, + ) @ddt.data(*unit_test_types.get_valid_type_create_data_2_24()) @ddt.unpack def test_create_delete_share_type_2_24( - self, is_public, dhss, spec_snapshot_support, - spec_create_share_from_snapshot, extra_specs): - + self, + is_public, + dhss, + spec_snapshot_support, + spec_create_share_from_snapshot, + extra_specs, + ): self.skip_if_microversion_not_supported('2.24') self._test_create_delete_share_type( - '2.24', is_public, dhss, spec_snapshot_support, - spec_create_share_from_snapshot, None, None, extra_specs) + '2.24', + is_public, + dhss, + spec_snapshot_support, + spec_create_share_from_snapshot, + None, + None, + extra_specs, + ) @ddt.data(*unit_test_types.get_valid_type_create_data_2_27()) @ddt.unpack def test_create_delete_share_type_2_27( - self, is_public, dhss, spec_snapshot_support, - spec_create_share_from_snapshot, spec_revert_to_snapshot_support, - extra_specs): - + self, + is_public, + dhss, + spec_snapshot_support, + spec_create_share_from_snapshot, + spec_revert_to_snapshot_support, + extra_specs, + ): self.skip_if_microversion_not_supported('2.27') self._test_create_delete_share_type( - '2.27', is_public, dhss, spec_snapshot_support, - spec_create_share_from_snapshot, spec_revert_to_snapshot_support, - None, extra_specs) + '2.27', + is_public, + dhss, + spec_snapshot_support, + spec_create_share_from_snapshot, + spec_revert_to_snapshot_support, + None, + extra_specs, + ) def test_create_delete_share_type_with_description(self): self.skip_if_microversion_not_supported('2.41') self._test_create_delete_share_type( - '2.41', True, False, None, None, None, None, None, - description=data_utils.rand_name('test_share_type_description')) + '2.41', + True, + False, + None, + None, + None, + None, + None, + description=data_utils.rand_name('test_share_type_description'), + ) @ddt.data( ('name_updated_1', 'description_updated', True), @@ -131,9 +189,9 @@ def test_create_delete_share_type_with_description(self): (None, None, False), ) @ddt.unpack - def test_create_update_delete_share_type_2_50(self, new_name, - new_description, - new_is_public): + def test_create_update_delete_share_type_2_50( + self, new_name, new_description, new_is_public + ): self.skip_if_microversion_not_supported('2.50') microversion = '2.50' share_type_name = data_utils.rand_name('share_type_update_test') @@ -149,15 +207,19 @@ def test_create_update_delete_share_type_2_50(self, new_name, is_public=True, microversion=microversion, extra_specs={}, - description="share_type_description") + description="share_type_description", + ) st_id = share_type['ID'] # Update share type - st_updated = self.update_share_type(st_id, name=new_name, - description=new_description, - is_public=new_is_public, - microversion=microversion) + st_updated = self.update_share_type( + st_id, + name=new_name, + description=new_description, + is_public=new_is_public, + microversion=microversion, + ) # Verify type name if new_name: self.assertEqual(new_name, st_updated['Name']) @@ -168,19 +230,23 @@ def test_create_update_delete_share_type_2_50(self, new_name, # Verify public if new_is_public is not None: - self.assertEqual('public' if new_is_public else 'private', - st_updated['Visibility'].lower()) + self.assertEqual( + 'public' if new_is_public else 'private', + st_updated['Visibility'].lower(), + ) # Delete share type self.admin_client.delete_share_type(st_id, microversion=microversion) # Wait for share type deletion self.admin_client.wait_for_share_type_deletion( - st_id, microversion=microversion) + st_id, microversion=microversion + ) # Verify that it is not listed with common 'type-list' operation. share_types = self.admin_client.list_share_types( - list_all=False, microversion=microversion) + list_all=False, microversion=microversion + ) self.assertFalse(any(st_id == st['ID'] for st in share_types)) def test_unset_share_type_description_2_50(self): @@ -199,15 +265,16 @@ def test_unset_share_type_description_2_50(self): is_public=True, microversion=microversion, extra_specs={}, - description="share_type_description") + description="share_type_description", + ) st_id = share_type['ID'] # Update share type new_description = "" - st_updated = self.update_share_type(st_id, - description=new_description, - microversion=microversion) + st_updated = self.update_share_type( + st_id, description=new_description, microversion=microversion + ) # Verify type description self.assertEqual('None', st_updated['Description']) @@ -217,21 +284,27 @@ def test_unset_share_type_description_2_50(self): # Wait for share type deletion self.admin_client.wait_for_share_type_deletion( - st_id, microversion=microversion) + st_id, microversion=microversion + ) # Verify that it is not listed with common 'type-list' operation. share_types = self.admin_client.list_share_types( - list_all=False, microversion=microversion) + list_all=False, microversion=microversion + ) self.assertFalse(any(st_id == st['ID'] for st in share_types)) - def _test_create_delete_share_type(self, microversion, is_public, dhss, - spec_snapshot_support, - spec_create_share_from_snapshot, - spec_revert_to_snapshot_support, - spec_mount_snapshot_support, - extra_specs, - description=None): - + def _test_create_delete_share_type( + self, + microversion, + is_public, + dhss, + spec_snapshot_support, + spec_create_share_from_snapshot, + spec_revert_to_snapshot_support, + spec_mount_snapshot_support, + extra_specs, + description=None, + ): share_type_name = data_utils.rand_name('manilaclient_functional_test') if extra_specs is None: @@ -248,7 +321,8 @@ def _test_create_delete_share_type(self, microversion, is_public, dhss, is_public=is_public, microversion=microversion, extra_specs=extra_specs, - description=description) + description=description, + ) # Verify response body for key in self.create_keys: @@ -258,55 +332,75 @@ def _test_create_delete_share_type(self, microversion, is_public, dhss, self.assertEqual(share_type_name, share_type['Name']) # Verify type description - if (api_versions.APIVersion(microversion) >= - api_versions.APIVersion('2.41')): + if api_versions.APIVersion(microversion) >= api_versions.APIVersion( + '2.41' + ): self.assertEqual(description, share_type['Description']) else: self.assertNotIn('description', share_type) # Verify required DHSS extra spec - dhss_expected = 'driver_handles_share_servers : %s' % dhss + dhss_expected = f'driver_handles_share_servers : {dhss}' self.assertEqual(dhss_expected, share_type['required_extra_specs']) # Determine expected extra specs. Note that prior to 2.24, # the standard 'snapshot_support' extra spec was required. expected_extra_specs = [] for key, val in extra_specs.items(): - expected_extra_specs.append(('{} : {}'.format(key, val)).strip()) + expected_extra_specs.append((f'{key} : {val}').strip()) - if (api_versions.APIVersion(microversion) < - api_versions.APIVersion('2.24')): + if api_versions.APIVersion(microversion) < api_versions.APIVersion( + '2.24' + ): if 'snapshot_support' not in extra_specs: if spec_snapshot_support is None: expected_extra_specs.append( - ('{} : {}'.format('snapshot_support', True)).strip()) + ('{} : {}'.format('snapshot_support', True)).strip() + ) else: expected_extra_specs.append( - ('{} : {}'.format( - 'snapshot_support', - spec_snapshot_support)).strip()) + ( + '{} : {}'.format( + 'snapshot_support', spec_snapshot_support + ) + ).strip() + ) else: if spec_snapshot_support is not None: expected_extra_specs.append( - ('{} : {}'.format( - 'snapshot_support', - spec_snapshot_support)).strip()) + ( + '{} : {}'.format( + 'snapshot_support', spec_snapshot_support + ) + ).strip() + ) if spec_create_share_from_snapshot is not None: expected_extra_specs.append( - ('{} : {}'.format( - 'create_share_from_snapshot_support', - spec_create_share_from_snapshot)).strip()) + ( + '{} : {}'.format( + 'create_share_from_snapshot_support', + spec_create_share_from_snapshot, + ) + ).strip() + ) if spec_revert_to_snapshot_support is not None: expected_extra_specs.append( - ('{} : {}'.format( - 'revert_to_snapshot_support', - spec_revert_to_snapshot_support)).strip()) + ( + '{} : {}'.format( + 'revert_to_snapshot_support', + spec_revert_to_snapshot_support, + ) + ).strip() + ) if spec_mount_snapshot_support is not None: expected_extra_specs.append( - ('{} : {}'.format( - 'mount_snapshot_support', - spec_mount_snapshot_support)).strip()) + ( + '{} : {}'.format( + 'mount_snapshot_support', spec_mount_snapshot_support + ) + ).strip() + ) # Verify optional extra specs optional_extra_specs = share_type['optional_extra_specs'] @@ -320,26 +414,30 @@ def _test_create_delete_share_type(self, microversion, is_public, dhss, self.assertIn(e.strip(), expected_extra_specs) # Verify public & default attributes - self.assertEqual('public' if is_public else 'private', - share_type['Visibility'].lower()) + self.assertEqual( + 'public' if is_public else 'private', + share_type['Visibility'].lower(), + ) self.assertEqual('-', share_type['is_default']) # Verify its access st_id = share_type['ID'] - self._verify_access(share_type_id=st_id, - is_public=is_public, - microversion=microversion) + self._verify_access( + share_type_id=st_id, is_public=is_public, microversion=microversion + ) # Delete share type self.admin_client.delete_share_type(st_id, microversion=microversion) # Wait for share type deletion self.admin_client.wait_for_share_type_deletion( - st_id, microversion=microversion) + st_id, microversion=microversion + ) # Verify that it is not listed with common 'type-list' operation. share_types = self.admin_client.list_share_types( - list_all=False, microversion=microversion) + list_all=False, microversion=microversion + ) self.assertFalse(any(st_id == st['ID'] for st in share_types)) @ddt.data("2.6", "2.7") @@ -359,7 +457,8 @@ def test_add_remove_access_to_private_share_type(self, microversion): st_id = share_type['ID'] user_project_id = self.admin_client.get_project_id( - self.user_client.tenant_name) + self.user_client.tenant_name + ) self._verify_access( share_type_id=st_id, @@ -369,27 +468,37 @@ def test_add_remove_access_to_private_share_type(self, microversion): # Project ID is in access list - false st_access_list = self.admin_client.list_share_type_access( - st_id, microversion=microversion) + st_id, microversion=microversion + ) self.assertNotIn(user_project_id, st_access_list) # Add access for project of user self.admin_client.add_share_type_access( - st_id, user_project_id, microversion=microversion) + st_id, user_project_id, microversion=microversion + ) # Verify it is listed for user as well as for admin - self.assertTrue(self._share_type_listed_by( - share_type_id=st_id, by_admin=False, list_all=True)) - self.assertTrue(self._share_type_listed_by( - share_type_id=st_id, by_admin=True, list_all=True)) + self.assertTrue( + self._share_type_listed_by( + share_type_id=st_id, by_admin=False, list_all=True + ) + ) + self.assertTrue( + self._share_type_listed_by( + share_type_id=st_id, by_admin=True, list_all=True + ) + ) # Project ID is in access list - true st_access_list = self.admin_client.list_share_type_access( - st_id, microversion=microversion) + st_id, microversion=microversion + ) self.assertIn(user_project_id, st_access_list) # Remove access self.admin_client.remove_share_type_access( - st_id, user_project_id, microversion=microversion) + st_id, user_project_id, microversion=microversion + ) self._verify_access( share_type_id=st_id, @@ -399,7 +508,8 @@ def test_add_remove_access_to_private_share_type(self, microversion): # Project ID is in access list - false st_access_list = self.admin_client.list_share_type_access( - st_id, microversion=microversion) + st_id, microversion=microversion + ) self.assertNotIn(user_project_id, st_access_list) @ddt.data("2.6", "2.7") @@ -408,11 +518,10 @@ def test_list_share_type(self, microversion): # Create share type self.create_share_type( - name=share_type_name, - driver_handles_share_servers='False') + name=share_type_name, driver_handles_share_servers='False' + ) share_types = self.admin_client.list_share_types( - list_all=True, - microversion=microversion + list_all=True, microversion=microversion ) self.assertTrue(any(s['ID'] is not None for s in share_types)) self.assertTrue(any(s['Name'] is not None for s in share_types)) @@ -424,12 +533,10 @@ def test_list_share_type_select_column(self, microversion): # Create share type self.create_share_type( - name=share_type_name, - driver_handles_share_servers='False') + name=share_type_name, driver_handles_share_servers='False' + ) share_types = self.admin_client.list_share_types( - list_all=True, - columns="id,name", - microversion=microversion + list_all=True, columns="id,name", microversion=microversion ) self.assertTrue(any(s['id'] is not None for s in share_types)) self.assertTrue(any(s['name'] is not None for s in share_types)) @@ -442,22 +549,21 @@ def test_list_share_type_filter_search(self): # Create share type name1 = data_utils.rand_name('manilaclient_functional_test1') self.create_share_type( - name=name1, - driver_handles_share_servers='False') + name=name1, driver_handles_share_servers='False' + ) # Create share type name2 = data_utils.rand_name('manilaclient_functional_test2') self.create_share_type( name=name2, extra_specs=extra_specs, - driver_handles_share_servers='True') + driver_handles_share_servers='True', + ) # List type by extra_specs list_all = False search_opts = {'extra_specs': extra_specs} share_types = self.admin_client.list_share_types( - list_all=list_all, - search_opts=search_opts, - microversion='2.43' + list_all=list_all, search_opts=search_opts, microversion='2.43' ) self.assertTrue(share_types is not None) @@ -465,13 +571,13 @@ def test_list_share_type_filter_search(self): self.assertTrue(len(share_types) == 1) self.assertTrue(all('optional_extra_specs' in s for s in share_types)) self.assertTrue(all(s['Name'] == name2 for s in share_types)) - self.assertTrue(all(s['optional_extra_specs'] == - expect for s in share_types)) + self.assertTrue( + all(s['optional_extra_specs'] == expect for s in share_types) + ) @ddt.ddt class ShareTypeExtraSpecsReadWriteTest(base.BaseTestCase): - @ddt.data( (True, False), (True, True), @@ -481,34 +587,41 @@ class ShareTypeExtraSpecsReadWriteTest(base.BaseTestCase): (False, False, "2.7"), ) @ddt.unpack - def test_share_type_extra_specs_life_cycle(self, is_public, dhss, - microversion=None): + def test_share_type_extra_specs_life_cycle( + self, is_public, dhss, microversion=None + ): if microversion: self.skip_if_microversion_not_supported(microversion) # Create share type st = self.create_share_type( - driver_handles_share_servers=dhss, is_public=is_public, - microversion=microversion) + driver_handles_share_servers=dhss, + is_public=is_public, + microversion=microversion, + ) # Add extra specs to share type st_extra_specs = dict(foo_key='foo_value', bar_key='bar_value') self.admin_client.set_share_type_extra_specs( - st['ID'], st_extra_specs, microversion=microversion) + st['ID'], st_extra_specs, microversion=microversion + ) # View list of extra specs extra_specs = self.admin_client.list_share_type_extra_specs( - st['ID'], microversion=microversion) + st['ID'], microversion=microversion + ) for k, v in st_extra_specs.items(): - self.assertIn('%s : %s' % (k, v), extra_specs) + self.assertIn(f'{k} : {v}', extra_specs) # Remove one extra spec self.admin_client.unset_share_type_extra_specs( - st['ID'], ('foo_key', ), microversion=microversion) + st['ID'], ('foo_key',), microversion=microversion + ) # Verify that removed extra spec is absent extra_specs = self.admin_client.list_share_type_extra_specs( - st['ID'], microversion=microversion) + st['ID'], microversion=microversion + ) self.assertNotIn('foo_key : foo_value', extra_specs) self.assertIn('bar_key : bar_value', extra_specs) - self.assertIn('driver_handles_share_servers : %s' % dhss, extra_specs) + self.assertIn(f'driver_handles_share_servers : {dhss}', extra_specs) diff --git a/manilaclient/tests/functional/test_shares.py b/manilaclient/tests/functional/test_shares.py index f0849a8d..7b589612 100644 --- a/manilaclient/tests/functional/test_shares.py +++ b/manilaclient/tests/functional/test_shares.py @@ -32,9 +32,9 @@ class SharesReadWriteBase(base.BaseTestCase): protocol = None def setUp(self): - super(SharesReadWriteBase, self).setUp() + super().setUp() if self.protocol not in CONF.enable_protocols: - message = "%s tests are disabled" % self.protocol + message = f"{self.protocol} tests are disabled" raise self.skipException(message) self.name = data_utils.rand_name('autotest_share_name') self.description = data_utils.rand_name('autotest_share_description') @@ -46,13 +46,15 @@ def setUp(self): size=1, name=self.name, description=self.description, - client=self.get_user_client()) + client=self.get_user_client(), + ) def test_create_delete_share(self): name = data_utils.rand_name('autotest_share_name') create = self.create_share( - self.protocol, name=name, client=self.user_client) + self.protocol, name=name, client=self.user_client + ) self.assertEqual("creating", create['status']) self.assertEqual(name, create['name']) @@ -70,15 +72,19 @@ def test_create_update_share(self): new_description = 'new_' + description create = self.create_share( - self.protocol, name=name, description=description, - client=self.user_client) + self.protocol, + name=name, + description=description, + client=self.user_client, + ) self.assertEqual(name, create['name']) self.assertEqual(description, create['description']) self.assertEqual('False', create['is_public']) self.user_client.update_share( - create['id'], name=new_name, description=new_description) + create['id'], name=new_name, description=new_description + ) get = self.user_client.get_share(create['id']) self.assertEqual(new_name, get['name']) @@ -106,57 +112,66 @@ def test_create_delete_with_wait(self): description = data_utils.rand_name('we-wait-until-share-is-ready') share_1, share_2 = ( - self.create_share(self.protocol, name=(name % num), - description=description, - use_wait_option=True, - client=self.user_client) + self.create_share( + self.protocol, + name=(name % num), + description=description, + use_wait_option=True, + client=self.user_client, + ) for num in range(0, 2) ) self.assertEqual("available", share_1['status']) self.assertEqual("available", share_2['status']) - self.delete_share([share_1['id'], share_2['id']], - wait=True, - client=self.user_client) + self.delete_share( + [share_1['id'], share_2['id']], wait=True, client=self.user_client + ) for share in (share_1, share_2): - self.assertRaises(exceptions.NotFound, - self.user_client.get_share, - share['id']) + self.assertRaises( + exceptions.NotFound, self.user_client.get_share, share['id'] + ) def test_create_soft_delete_and_restore_share(self): self.skip_if_microversion_not_supported('2.69') microversion = '2.69' description = data_utils.rand_name('we-wait-until-share-is-ready') - share = self.create_share(self.protocol, - name='share_name', - description=description, - use_wait_option=True, - client=self.user_client) + share = self.create_share( + self.protocol, + name='share_name', + description=description, + use_wait_option=True, + client=self.user_client, + ) self.assertEqual("available", share['status']) # soft delete the share to recycle bin - self.soft_delete_share([share['id']], client=self.user_client, - microversion=microversion) + self.soft_delete_share( + [share['id']], client=self.user_client, microversion=microversion + ) self.user_client.wait_for_share_soft_deletion(share['id']) # get shares list in recycle bin - result = self.user_client.list_shares(is_soft_deleted=True, - microversion=microversion) + result = self.user_client.list_shares( + is_soft_deleted=True, microversion=microversion + ) share_ids = [sh['ID'] for sh in result] # check share is in recycle bin self.assertIn(share['id'], share_ids) # restore the share from recycle bin - self.restore_share([share['id']], client=self.user_client, - microversion=microversion) + self.restore_share( + [share['id']], client=self.user_client, microversion=microversion + ) self.user_client.wait_for_share_restore(share['id']) - result1 = self.user_client.list_shares(is_soft_deleted=True, - microversion=microversion) + result1 = self.user_client.list_shares( + is_soft_deleted=True, microversion=microversion + ) share_ids1 = [sh['ID'] for sh in result1] # check share not in recycle bin self.assertNotIn(share['id'], share_ids1) @@ -164,36 +179,41 @@ def test_create_soft_delete_and_restore_share(self): @ddt.ddt class SharesTestMigration(base.BaseTestCase): - def setUp(self): - super(SharesTestMigration, self).setUp() + super().setUp() self.old_type = self.create_share_type( data_utils.rand_name('test_share_type'), - driver_handles_share_servers=True) + driver_handles_share_servers=True, + ) self.new_type = self.create_share_type( data_utils.rand_name('test_share_type'), - driver_handles_share_servers=True) + driver_handles_share_servers=True, + ) self.error_type = self.create_share_type( data_utils.rand_name('test_share_type'), driver_handles_share_servers=True, - extra_specs={'cause_error': 'no_valid_host'}) + extra_specs={'cause_error': 'no_valid_host'}, + ) self.old_share_net = self.get_user_client().get_share_network( - self.get_user_client().share_network) + self.get_user_client().share_network + ) share_net_info = ( - utils.get_default_subnet(self.get_user_client(), - self.old_share_net['id']) + utils.get_default_subnet( + self.get_user_client(), self.old_share_net['id'] + ) if utils.share_network_subnets_are_supported() - else self.old_share_net) + else self.old_share_net + ) self.new_share_net = self.create_share_network( neutron_net_id=share_net_info['neutron_net_id'], - neutron_subnet_id=share_net_info['neutron_subnet_id']) + neutron_subnet_id=share_net_info['neutron_subnet_id'], + ) @utils.skip_if_microversion_not_supported('2.22') @ddt.data('migration_error', 'migration_success', 'None') def test_reset_task_state(self, state): - share = self.create_share( share_protocol='nfs', size=1, @@ -201,7 +221,8 @@ def test_reset_task_state(self, state): client=self.get_user_client(), share_type=self.old_type['ID'], share_network=self.old_share_net['id'], - wait_for_creation=True) + wait_for_creation=True, + ) share = self.user_client.get_share(share['id']) self.admin_client.reset_task_state(share['id'], state) @@ -210,7 +231,8 @@ def test_reset_task_state(self, state): @utils.skip_if_microversion_not_supported('2.29') @testtools.skipUnless( - CONF.run_migration_tests, 'Share migration tests are disabled.') + CONF.run_migration_tests, 'Share migration tests are disabled.' + ) @ddt.data('cancel', 'success', 'error') def test_full_migration(self, test_type): # We are testing with DHSS=True only because it allows us to specify @@ -223,13 +245,13 @@ def test_full_migration(self, test_type): client=self.get_user_client(), share_type=self.old_type['ID'], share_network=self.old_share_net['id'], - wait_for_creation=True) + wait_for_creation=True, + ) share = self.admin_client.get_share(share['id']) pools = self.admin_client.pool_list(detail=True) - dest_pool = utils.choose_matching_backend( - share, pools, self.new_type) + dest_pool = utils.choose_matching_backend(share, pools, self.new_type) self.assertIsNotNone(dest_pool) @@ -240,18 +262,26 @@ def test_full_migration(self, test_type): statuses = constants.TASK_STATE_MIGRATION_ERROR new_type = self.error_type else: - statuses = (constants.TASK_STATE_MIGRATION_DRIVER_PHASE1_DONE, - constants.TASK_STATE_DATA_COPYING_COMPLETED) + statuses = ( + constants.TASK_STATE_MIGRATION_DRIVER_PHASE1_DONE, + constants.TASK_STATE_DATA_COPYING_COMPLETED, + ) self.admin_client.migration_start( - share['id'], dest_pool, writable=True, nondisruptive=False, - preserve_metadata=True, preserve_snapshots=True, + share['id'], + dest_pool, + writable=True, + nondisruptive=False, + preserve_metadata=True, + preserve_snapshots=True, force_host_assisted_migration=False, new_share_network=self.new_share_net['id'], - new_share_type=new_type['ID']) + new_share_type=new_type['ID'], + ) share = self.admin_client.wait_for_migration_task_state( - share['id'], dest_pool, statuses) + share['id'], dest_pool, statuses + ) progress = self.admin_client.migration_get_progress(share['id']) self.assertEqual('100', progress['total_progress']) @@ -271,19 +301,22 @@ def test_full_migration(self, test_type): statuses = constants.TASK_STATE_MIGRATION_CANCELLED share = self.admin_client.wait_for_migration_task_state( - share['id'], dest_pool, statuses) + share['id'], dest_pool, statuses + ) progress = self.admin_client.migration_get_progress(share['id']) self.assertEqual(statuses, progress['task_state']) if test_type == 'success': self.assertEqual(dest_pool, share['host']) self.assertEqual(new_type['ID'], share['share_type']) - self.assertEqual(self.new_share_net['id'], - share['share_network_id']) + self.assertEqual( + self.new_share_net['id'], share['share_network_id'] + ) else: self.assertEqual(source_pool, share['host']) self.assertEqual(self.old_type['ID'], share['share_type']) - self.assertEqual(self.old_share_net['id'], - share['share_network_id']) + self.assertEqual( + self.old_share_net['id'], share['share_network_id'] + ) class NFSSharesReadWriteTest(SharesReadWriteBase): diff --git a/manilaclient/tests/functional/test_shares_listing.py b/manilaclient/tests/functional/test_shares_listing.py index 83cdf228..12f97313 100644 --- a/manilaclient/tests/functional/test_shares_listing.py +++ b/manilaclient/tests/functional/test_shares_listing.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2015 Mirantis Inc. # All Rights Reserved. # @@ -28,7 +27,6 @@ @ddt.ddt class SharesListReadOnlyTest(base.BaseTestCase): - @ddt.data('admin', 'user') def test_shares_list(self, role): self.clients[role].manila('list') @@ -69,7 +67,8 @@ def test_shares_list_filter_by_share_server_as_user(self): exceptions.CommandFailed, self.clients['user'].manila, 'list', - params='--share-server fake') + params='--share-server fake', + ) @ddt.data('admin', 'user') def test_shares_list_filter_by_project_id(self, role): @@ -86,11 +85,13 @@ def test_shares_list_with_limit_and_offset(self, role): {'role': 'admin', 'direction': 'asc'}, {'role': 'admin', 'direction': 'desc'}, {'role': 'user', 'direction': 'asc'}, - {'role': 'user', 'direction': 'desc'}) + {'role': 'user', 'direction': 'desc'}, + ) @ddt.unpack def test_shares_list_with_sorting(self, role, direction): self.clients[role].manila( - 'list', params='--sort-key host --sort-dir ' + direction) + 'list', params='--sort-key host --sort-dir ' + direction + ) @ddt.data('admin', 'user') def test_snapshot_list(self, role): @@ -111,20 +112,23 @@ def test_snapshot_list_filter_by_status(self, role): @ddt.ddt class SharesListReadWriteTest(base.BaseTestCase): - def setUp(self): - super(SharesListReadWriteTest, self).setUp() + super().setUp() self.private_name = data_utils.rand_name('autotest_share_name') self.private_description = data_utils.rand_name( - 'autotest_share_description') + 'autotest_share_description' + ) self.public_name = data_utils.rand_name('autotest_public_share_name') self.public_description = data_utils.rand_name( - 'autotest_public_share_description') + 'autotest_public_share_description' + ) self.admin_private_name = data_utils.rand_name( - 'autotest_admin_private_share_name') + 'autotest_admin_private_share_name' + ) self.admin_private_description = data_utils.rand_name( - 'autotest_admin_private_share_description') + 'autotest_admin_private_share_description' + ) self.soft_name = data_utils.rand_name('soft_delete_share_name') @@ -133,39 +137,48 @@ def setUp(self): description=self.admin_private_description, public=False, client=None, - wait_for_creation=False) + wait_for_creation=False, + ) self.private_share = self.create_share( name=self.private_name, description=self.private_description, public=False, client=self.get_user_client(), - wait_for_creation=False) + wait_for_creation=False, + ) self.public_share = self.create_share( name=self.public_name, description=self.public_description, public=True, - client=self.admin_client) + client=self.admin_client, + ) self.wait_soft_delete_share = self.create_share( name=self.soft_name, public=False, client=self.get_user_client(), - wait_for_creation=False) + wait_for_creation=False, + ) - self.shares_created = (self.private_share['id'], - self.public_share['id'], - self.admin_private_share['id'], - self.wait_soft_delete_share['id']) + self.shares_created = ( + self.private_share['id'], + self.public_share['id'], + self.admin_private_share['id'], + self.wait_soft_delete_share['id'], + ) for share_id in self.shares_created: self.admin_client.wait_for_resource_status( - share_id, constants.STATUS_AVAILABLE) + share_id, constants.STATUS_AVAILABLE + ) - self.soft_delete_share([self.wait_soft_delete_share['id']], - client=self.get_user_client(), - microversion='2.69') + self.soft_delete_share( + [self.wait_soft_delete_share['id']], + client=self.get_user_client(), + microversion='2.69', + ) def _list_shares(self, filters=None): filters = filters or dict() @@ -195,12 +208,15 @@ def _list_shares(self, filters=None): # elapsed between the 'list' and 'get' requests. # If this isn't one of the shares created in # this class, don't worry about such mismatches - self.assertNotIn(share_get['id'], - self.shares_created) + self.assertNotIn( + share_get['id'], self.shares_created + ) continue - if (expected_value != 'deleting' and - share_get[filter_key] == 'deleting'): + if ( + expected_value != 'deleting' + and share_get[filter_key] == 'deleting' + ): continue self.assertEqual(expected_value, share_get[filter_key]) @@ -214,17 +230,25 @@ def test_list_shares_for_all_tenants(self, all_tenants): if all_tenants: self.assertTrue(all('Project ID' in s for s in shares)) - for s_id in (self.private_share['id'], self.public_share['id'], - self.admin_private_share['id']): + for s_id in ( + self.private_share['id'], + self.public_share['id'], + self.admin_private_share['id'], + ): self.assertTrue(any(s_id == s['ID'] for s in shares)) else: self.assertTrue(all('Project ID' not in s for s in shares)) - self.assertTrue(any(self.admin_private_share['id'] == s['ID'] - for s in shares)) - if self.private_share['project_id'] != ( - self.admin_private_share['project_id']): + self.assertTrue( + any(self.admin_private_share['id'] == s['ID'] for s in shares) + ) + if ( + self.private_share['project_id'] + != (self.admin_private_share['project_id']) + ): for s_id in ( - self.private_share['id'], self.public_share['id']): + self.private_share['id'], + self.public_share['id'], + ): self.assertFalse(any(s_id == s['ID'] for s in shares)) @ddt.data(True, False) @@ -238,18 +262,21 @@ def test_list_shares_with_public(self, public): def test_list_shares_by_name(self): shares = self.user_client.list_shares( - filters={'name': self.private_name}) + filters={'name': self.private_name} + ) self.assertEqual(1, len(shares)) self.assertTrue( - any(self.private_share['id'] == s['ID'] for s in shares)) + any(self.private_share['id'] == s['ID'] for s in shares) + ) for share in shares: get = self.user_client.get_share(share['ID']) self.assertEqual(self.private_name, get['name']) def test_list_shares_by_share_type(self): share_type_id = self.user_client.get_share_type( - self.private_share['share_type'])['ID'] + self.private_share['share_type'] + )['ID'] # NOTE(vponomaryov): this is API 2.6+ specific self._list_shares({'share_type': share_type_id}) @@ -258,14 +285,17 @@ def test_list_shares_by_status(self): def test_list_shares_by_project_id(self): project_id = self.user_client.get_project_id( - self.user_client.tenant_name) + self.user_client.tenant_name + ) self._list_shares({'project_id': project_id}) @testtools.skipUnless( - CONF.share_network, "Usage of Share networks is disabled") + CONF.share_network, "Usage of Share networks is disabled" + ) def test_list_shares_by_share_network(self): share_network_id = self.user_client.get_share_network( - CONF.share_network)['id'] + CONF.share_network + )['id'] self._list_shares({'share_network': share_network_id}) @ddt.data( @@ -287,13 +317,16 @@ def test_list_share_select_column(self): @ddt.data('ID', 'Path') def test_list_shares_by_export_location(self, option): export_locations = self.admin_client.list_share_export_locations( - self.public_share['id']) + self.public_share['id'] + ) shares = self.admin_client.list_shares( - filters={'export_location': export_locations[0][option]}) + filters={'export_location': export_locations[0][option]} + ) self.assertEqual(1, len(shares)) self.assertTrue( - any(self.public_share['id'] == s['ID'] for s in shares)) + any(self.public_share['id'] == s['ID'] for s in shares) + ) for share in shares: get = self.admin_client.get_share(share['ID']) self.assertEqual(self.public_name, get['name']) @@ -301,70 +334,81 @@ def test_list_shares_by_export_location(self, option): @ddt.data('ID', 'Path') def test_list_share_instances_by_export_location(self, option): export_locations = self.admin_client.list_share_export_locations( - self.public_share['id']) + self.public_share['id'] + ) share_instances = self.admin_client.list_share_instances( - filters={'export_location': export_locations[0][option]}) + filters={'export_location': export_locations[0][option]} + ) self.assertEqual(1, len(share_instances)) share_instance_id = share_instances[0]['ID'] except_export_locations = ( self.admin_client.list_share_instance_export_locations( - share_instance_id)) + share_instance_id + ) + ) self.assertGreater(len(except_export_locations), 0) self.assertTrue( - any(export_locations[0][option] == e[option] for e in - except_export_locations)) + any( + export_locations[0][option] == e[option] + for e in except_export_locations + ) + ) def test_list_share_by_export_location_with_invalid_version(self): self.assertRaises( exceptions.CommandFailed, self.admin_client.list_shares, filters={'export_location': 'fake'}, - microversion='2.34') + microversion='2.34', + ) def test_list_share_instance_by_export_location_invalid_version(self): self.assertRaises( exceptions.CommandFailed, self.admin_client.list_share_instances, filters={'export_location': 'fake'}, - microversion='2.34') + microversion='2.34', + ) @ddt.data('name', 'description') def test_list_shares_by_inexact_option(self, option): - shares = self.user_client.list_shares( - filters={option + '~': option}) + shares = self.user_client.list_shares(filters={option + '~': option}) # We know we have to have atleast three shares. # Due to test concurrency, there can be # more than three shares (some created by other tests). self.assertGreaterEqual(len(shares), 3) self.assertTrue( - any(self.private_share['id'] == s['ID'] for s in shares)) + any(self.private_share['id'] == s['ID'] for s in shares) + ) def test_list_shares_by_inexact_unicode_option(self): self.create_share( - name=u'共享名称', - description=u'共享描述', - client=self.user_client) - filters = {'name~': u'名称'} + name='共享名称', description='共享描述', client=self.user_client + ) + filters = {'name~': '名称'} shares = self.user_client.list_shares(filters=filters) self.assertGreater(len(shares), 0) - filters = {'description~': u'描述'} + filters = {'description~': '描述'} shares = self.user_client.list_shares(filters=filters) self.assertGreater(len(shares), 0) def test_list_shares_by_description(self): shares = self.user_client.list_shares( - filters={'description': self.private_description}) + filters={'description': self.private_description} + ) self.assertEqual(1, len(shares)) self.assertTrue( - any(self.private_share['id'] == s['ID'] for s in shares)) + any(self.private_share['id'] == s['ID'] for s in shares) + ) def test_list_shares_in_recycle_bin(self): shares = self.user_client.list_shares(is_soft_deleted=True) self.assertTrue( - any(self.wait_soft_delete_share['id'] == s['ID'] for s in shares)) + any(self.wait_soft_delete_share['id'] == s['ID'] for s in shares) + ) diff --git a/manilaclient/tests/functional/test_shares_metadata.py b/manilaclient/tests/functional/test_shares_metadata.py index e9cf356a..5d642d0a 100644 --- a/manilaclient/tests/functional/test_shares_metadata.py +++ b/manilaclient/tests/functional/test_shares_metadata.py @@ -20,9 +20,8 @@ @ddt.ddt class SharesMetadataReadWriteTest(base.BaseTestCase): - def setUp(self): - super(SharesMetadataReadWriteTest, self).setUp() + super().setUp() self.share = self.create_share(client=self.get_user_client()) def test_set_metadata_in_share_creation(self): @@ -44,7 +43,8 @@ def test_set_metadata_in_share_creation(self): def test_set_and_get_metadata(self): # Create share share = self.create_share( - cleanup_in_class=False, client=self.get_user_client()) + cleanup_in_class=False, client=self.get_user_client() + ) # Set share metadata md = {"key3": "value3", "key4": "value4"} @@ -63,7 +63,8 @@ def test_set_and_get_metadata(self): def test_set_and_delete_metadata(self): # Create share share = self.create_share( - cleanup_in_class=False, client=self.get_user_client()) + cleanup_in_class=False, client=self.get_user_client() + ) # Set share metadata md = {"key3": "value3", "key4": "value4"} @@ -81,7 +82,8 @@ def test_set_and_add_metadata(self): # Create share with metadata share = self.create_share( - metadata=md, cleanup_in_class=False, client=self.get_user_client()) + metadata=md, cleanup_in_class=False, client=self.get_user_client() + ) # Set share metadata self.user_client.set_share_metadata(share["id"], {'key6': 'value6'}) @@ -93,23 +95,25 @@ def test_set_and_add_metadata(self): # Verify share metadata self.assertEqual(3, len(metadata)) for i in (5, 6, 7): - key = 'key%s' % i + key = f'key{i}' self.assertIn(key, metadata) - self.assertEqual('value%s' % i, metadata[key]) + self.assertEqual(f'value{i}', metadata[key]) def test_set_and_replace_metadata(self): md = {'key8': 'value8'} # Create share with metadata share = self.create_share( - metadata=md, cleanup_in_class=False, client=self.get_user_client()) + metadata=md, cleanup_in_class=False, client=self.get_user_client() + ) # Set share metadata self.user_client.set_share_metadata(share["id"], {'key9': 'value9'}) # Replace all existing share metadata self.user_client.update_all_share_metadata( - share["id"], {'key10': 'value10'}) + share["id"], {'key10': 'value10'} + ) # Read share metadata metadata = self.user_client.get_share_metadata(share["id"]) @@ -120,10 +124,8 @@ def test_set_and_replace_metadata(self): self.assertEqual('value10', metadata['key10']) @ddt.data( - {"k": "value"}, - {"k" * 255: "value"}, - {"key": "v"}, - {"key": "v" * 1023}) + {"k": "value"}, {"k" * 255: "value"}, {"key": "v"}, {"key": "v" * 1023} + ) def test_set_metadata_min_max_sizes_of_keys_and_values(self, metadata): # Set share metadata self.user_client.set_share_metadata(self.share["id"], metadata) @@ -137,10 +139,8 @@ def test_set_metadata_min_max_sizes_of_keys_and_values(self, metadata): self.assertEqual(metadata[key], get[key]) @ddt.data( - {"k": "value"}, - {"k" * 255: "value"}, - {"key": "v"}, - {"key": "v" * 1023}) + {"k": "value"}, {"k" * 255: "value"}, {"key": "v"}, {"key": "v" * 1023} + ) def test_update_metadata_min_max_sizes_of_keys_and_values(self, metadata): # Update share metadata self.user_client.update_all_share_metadata(self.share["id"], metadata) diff --git a/manilaclient/tests/functional/test_snapshot_access.py b/manilaclient/tests/functional/test_snapshot_access.py index ec297dee..fee71473 100644 --- a/manilaclient/tests/functional/test_snapshot_access.py +++ b/manilaclient/tests/functional/test_snapshot_access.py @@ -27,18 +27,22 @@ class SnapshotAccessReadBase(base.BaseTestCase): protocol = None def setUp(self): - super(SnapshotAccessReadBase, self).setUp() + super().setUp() if self.protocol not in CONF.enable_protocols: - message = "%s tests are disabled." % self.protocol + message = f"{self.protocol} tests are disabled." raise self.skipException(message) self.access_types = CONF.access_types_mapping.get( - self.protocol, '').split(' ') + self.protocol, '' + ).split(' ') if not self.access_types: - raise self.skipException("No access types were provided for %s " - "snapshot access tests." % self.protocol) + raise self.skipException( + f"No access types were provided for {self.protocol} " + "snapshot access tests." + ) - self.share = self.create_share(share_protocol=self.protocol, - client=self.get_user_client()) + self.share = self.create_share( + share_protocol=self.protocol, client=self.get_user_client() + ) int_range = range(0, 10) self.access_to = { @@ -53,124 +57,157 @@ def _test_create_list_access_rule_for_snapshot(self, snapshot_id): for i in range(5): access_ = self.user_client.snapshot_access_allow( - snapshot_id, access_type, - self.access_to[access_type][i]) + snapshot_id, access_type, self.access_to[access_type][i] + ) access.append(access_) return access def test_create_list_access_rule_for_snapshot(self): - snapshot = self.create_snapshot(share=self.share['id'], - client=self.get_user_client(), - cleanup_in_class=False) + snapshot = self.create_snapshot( + share=self.share['id'], + client=self.get_user_client(), + cleanup_in_class=False, + ) access = self._test_create_list_access_rule_for_snapshot( - snapshot['id']) + snapshot['id'] + ) access_list = self.user_client.list_access( - snapshot['id'], is_snapshot=True) + snapshot['id'], is_snapshot=True + ) for i in range(5): - self.assertIn(access[i]['id'], - [access_list[j]['id'] for j in range(5)]) - self.assertIn(access[i]['access_type'], - [access_list[j]['access_type'] for j in range(5)]) - self.assertIn(access[i]['access_to'], - [access_list[j]['access_to'] for j in range(5)]) + self.assertIn( + access[i]['id'], [access_list[j]['id'] for j in range(5)] + ) + self.assertIn( + access[i]['access_type'], + [access_list[j]['access_type'] for j in range(5)], + ) + self.assertIn( + access[i]['access_to'], + [access_list[j]['access_to'] for j in range(5)], + ) self.assertIsNotNone(access_list[i]['access_type']) self.assertIsNotNone(access_list[i]['access_to']) def test_create_list_access_rule_for_snapshot_select_column(self): - snapshot = self.create_snapshot(share=self.share['id'], - client=self.get_user_client(), - cleanup_in_class=False) + snapshot = self.create_snapshot( + share=self.share['id'], + client=self.get_user_client(), + cleanup_in_class=False, + ) self._test_create_list_access_rule_for_snapshot(snapshot['id']) access_list = self.user_client.list_access( - snapshot['id'], columns="access_type,access_to", is_snapshot=True) + snapshot['id'], columns="access_type,access_to", is_snapshot=True + ) self.assertTrue(any(x['Access_Type'] is not None for x in access_list)) self.assertTrue(any(x['Access_To'] is not None for x in access_list)) def _create_delete_access_rule(self, snapshot_id, access_type, access_to): - if access_type not in self.access_types: raise self.skipException( - "'%(access_type)s' access rules is disabled for protocol " - "'%(protocol)s'." % {"access_type": access_type, - "protocol": self.protocol}) + f"'{access_type}' access rules is disabled for protocol " + f"'{self.protocol}'." + ) access = self.user_client.snapshot_access_allow( - snapshot_id, access_type, access_to) + snapshot_id, access_type, access_to + ) self.assertEqual(access_type, access.get('access_type')) - self.assertEqual(access_to.replace('\\\\', '\\'), - access.get('access_to')) + self.assertEqual( + access_to.replace('\\\\', '\\'), access.get('access_to') + ) self.user_client.wait_for_access_rule_status( - snapshot_id, access['id'], is_snapshot=True) + snapshot_id, access['id'], is_snapshot=True + ) self.user_client.snapshot_access_deny(snapshot_id, access['id']) self.user_client.wait_for_access_rule_deletion( - snapshot_id, access['id'], is_snapshot=True) + snapshot_id, access['id'], is_snapshot=True + ) - self.assertRaises(tempest_lib_exc.NotFound, - self.user_client.get_access, snapshot_id, - access['id'], is_snapshot=True) + self.assertRaises( + tempest_lib_exc.NotFound, + self.user_client.get_access, + snapshot_id, + access['id'], + is_snapshot=True, + ) def test_create_delete_snapshot_ip_access_rule(self): - snapshot = self.create_snapshot(share=self.share['id'], - client=self.get_user_client(), - cleanup_in_class=False) + snapshot = self.create_snapshot( + share=self.share['id'], + client=self.get_user_client(), + cleanup_in_class=False, + ) self._create_delete_access_rule( - snapshot['id'], 'ip', self.access_to['ip'][0]) + snapshot['id'], 'ip', self.access_to['ip'][0] + ) def test_create_delete_snapshot_user_access_rule(self): - snapshot = self.create_snapshot(share=self.share['id'], - client=self.get_user_client(), - cleanup_in_class=False) + snapshot = self.create_snapshot( + share=self.share['id'], + client=self.get_user_client(), + cleanup_in_class=False, + ) self._create_delete_access_rule( - snapshot['id'], 'user', CONF.username_for_user_rules) + snapshot['id'], 'user', CONF.username_for_user_rules + ) def test_create_delete_snapshot_cert_access_rule(self): - snapshot = self.create_snapshot(share=self.share['id'], - client=self.get_user_client(), - cleanup_in_class=False) + snapshot = self.create_snapshot( + share=self.share['id'], + client=self.get_user_client(), + cleanup_in_class=False, + ) self._create_delete_access_rule( - snapshot['id'], 'cert', self.access_to['cert'][0]) + snapshot['id'], 'cert', self.access_to['cert'][0] + ) -@testtools.skipUnless(CONF.run_snapshot_tests and - CONF.run_mount_snapshot_tests, - "Snapshots or mountable snapshots tests are disabled.") +@testtools.skipUnless( + CONF.run_snapshot_tests and CONF.run_mount_snapshot_tests, + "Snapshots or mountable snapshots tests are disabled.", +) class NFSSnapshotAccessTest(SnapshotAccessReadBase): protocol = 'nfs' -@testtools.skipUnless(CONF.run_snapshot_tests and - CONF.run_mount_snapshot_tests, - "Snapshots or mountable snapshots tests are disabled.") +@testtools.skipUnless( + CONF.run_snapshot_tests and CONF.run_mount_snapshot_tests, + "Snapshots or mountable snapshots tests are disabled.", +) class CIFSSnapshotAccessTest(SnapshotAccessReadBase): protocol = 'cifs' -@testtools.skipUnless(CONF.run_snapshot_tests and - CONF.run_mount_snapshot_tests, - "Snapshots or mountable snapshots tests are disabled.") +@testtools.skipUnless( + CONF.run_snapshot_tests and CONF.run_mount_snapshot_tests, + "Snapshots or mountable snapshots tests are disabled.", +) class GlusterFSSnapshotAccessTest(SnapshotAccessReadBase): protocol = 'glusterfs' -@testtools.skipUnless(CONF.run_snapshot_tests and - CONF.run_mount_snapshot_tests, - "Snapshots or mountable snapshots tests are disabled.") +@testtools.skipUnless( + CONF.run_snapshot_tests and CONF.run_mount_snapshot_tests, + "Snapshots or mountable snapshots tests are disabled.", +) class HDFSSnapshotAccessTest(SnapshotAccessReadBase): protocol = 'hdfs' -@testtools.skipUnless(CONF.run_snapshot_tests and - CONF.run_mount_snapshot_tests, - "Snapshots or mountable snapshots tests are disabled.") +@testtools.skipUnless( + CONF.run_snapshot_tests and CONF.run_mount_snapshot_tests, + "Snapshots or mountable snapshots tests are disabled.", +) class MAPRFSSnapshotAccessTest(SnapshotAccessReadBase): protocol = 'maprfs' diff --git a/manilaclient/tests/functional/test_snapshot_instances.py b/manilaclient/tests/functional/test_snapshot_instances.py index d5c9c14b..d0ee9b60 100644 --- a/manilaclient/tests/functional/test_snapshot_instances.py +++ b/manilaclient/tests/functional/test_snapshot_instances.py @@ -25,17 +25,15 @@ @ddt.ddt -@testtools.skipUnless(CONF.run_snapshot_tests, - 'Snapshot tests disabled.') +@testtools.skipUnless(CONF.run_snapshot_tests, 'Snapshot tests disabled.') @utils.skip_if_microversion_not_supported('2.19') class SnapshotInstancesTest(base.BaseTestCase): - def setUp(self): - super(SnapshotInstancesTest, self).setUp() - self.share = self.create_share( - client=self.get_user_client()) - self.snapshot = self.create_snapshot(share=self.share['id'], - client=self.get_user_client()) + super().setUp() + self.share = self.create_share(client=self.get_user_client()) + self.snapshot = self.create_snapshot( + share=self.share['id'], client=self.get_user_client() + ) def test_list_all_snapshot_instances(self): snapshot_instances = self.admin_client.list_snapshot_instances() @@ -50,22 +48,31 @@ def test_list_all_snapshot_instances(self): def test_list_all_snapshot_instances_details(self): snapshot_instances = self.admin_client.list_snapshot_instances( - detailed=True) + detailed=True + ) self.assertGreater(len(snapshot_instances), 0) - expected_keys = ('ID', 'Snapshot ID', 'Status', 'Created_at', - 'Updated_at', 'Share_id', 'Share_instance_id', - 'Progress', 'Provider_location') + expected_keys = ( + 'ID', + 'Snapshot ID', + 'Status', + 'Created_at', + 'Updated_at', + 'Share_id', + 'Share_instance_id', + 'Progress', + 'Provider_location', + ) for si in snapshot_instances: for key in expected_keys: self.assertIn(key, si) for key in ('ID', 'Snapshot ID', 'Share_id', 'Share_instance_id'): - self.assertTrue( - uuidutils.is_uuid_like(si[key])) + self.assertTrue(uuidutils.is_uuid_like(si[key])) def test_list_snapshot_instance_with_snapshot(self): snapshot_instances = self.admin_client.list_snapshot_instances( - snapshot_id=self.snapshot['id']) + snapshot_id=self.snapshot['id'] + ) self.assertEqual(1, len(snapshot_instances)) expected_keys = ('ID', 'Snapshot ID', 'Status') @@ -77,11 +84,12 @@ def test_list_snapshot_instance_with_snapshot(self): def test_list_snapshot_instance_with_columns(self): snapshot_instances = self.admin_client.list_snapshot_instances( - self.snapshot['id'], columns='id,status') + self.snapshot['id'], columns='id,status' + ) self.assertGreater(len(snapshot_instances), 0) expected_keys = ('Id', 'Status') - unexpected_keys = ('Snapshot ID', ) + unexpected_keys = ('Snapshot ID',) for si in snapshot_instances: for key in expected_keys: self.assertIn(key, si) @@ -91,29 +99,42 @@ def test_list_snapshot_instance_with_columns(self): def test_get_snapshot_instance(self): snapshot_instances = self.admin_client.list_snapshot_instances( - self.snapshot['id']) + self.snapshot['id'] + ) snapshot_instance = self.admin_client.get_snapshot_instance( - snapshot_instances[0]['ID']) + snapshot_instances[0]['ID'] + ) self.assertGreater(len(snapshot_instance), 0) - expected_keys = ('id', 'snapshot_id', 'status', 'created_at', - 'updated_at', 'share_id', 'share_instance_id', - 'progress', 'provider_location') + expected_keys = ( + 'id', + 'snapshot_id', + 'status', + 'created_at', + 'updated_at', + 'share_id', + 'share_instance_id', + 'progress', + 'provider_location', + ) for key in expected_keys: self.assertIn(key, snapshot_instance) for key in ('id', 'snapshot_id', 'share_id', 'share_instance_id'): - self.assertTrue( - uuidutils.is_uuid_like(snapshot_instance[key])) + self.assertTrue(uuidutils.is_uuid_like(snapshot_instance[key])) def test_snapshot_instance_reset_state(self): snapshot_instances = self.admin_client.list_snapshot_instances( - self.snapshot['id']) + self.snapshot['id'] + ) self.admin_client.reset_snapshot_instance( - snapshot_instances[0]['ID'], 'error') + snapshot_instances[0]['ID'], 'error' + ) snapshot_instance = self.admin_client.get_snapshot_instance( - snapshot_instances[0]['ID']) + snapshot_instances[0]['ID'] + ) self.assertEqual('error', snapshot_instance['status']) - self.admin_client.reset_snapshot_instance(snapshot_instance['id'], - 'available') + self.admin_client.reset_snapshot_instance( + snapshot_instance['id'], 'available' + ) diff --git a/manilaclient/tests/functional/test_snapshot_instances_export_locations.py b/manilaclient/tests/functional/test_snapshot_instances_export_locations.py index 704cd9ee..92931f2d 100644 --- a/manilaclient/tests/functional/test_snapshot_instances_export_locations.py +++ b/manilaclient/tests/functional/test_snapshot_instances_export_locations.py @@ -25,55 +25,66 @@ @ddt.ddt -@testtools.skipUnless(CONF.run_snapshot_tests and - CONF.run_mount_snapshot_tests, - "Snapshots or mountable snapshots tests are disabled.") +@testtools.skipUnless( + CONF.run_snapshot_tests and CONF.run_mount_snapshot_tests, + "Snapshots or mountable snapshots tests are disabled.", +) @utils.skip_if_microversion_not_supported('2.32') class SnapshotInstanceExportLocationReadWriteTest(base.BaseTestCase): - def setUp(self): - super(SnapshotInstanceExportLocationReadWriteTest, self).setUp() - self.share = self.create_share( - client=self.get_user_client()) - self.snapshot = self.create_snapshot(share=self.share['id'], - client=self.get_user_client()) + super().setUp() + self.share = self.create_share(client=self.get_user_client()) + self.snapshot = self.create_snapshot( + share=self.share['id'], client=self.get_user_client() + ) def test_get_snapshot_instance_export_location(self): client = self.admin_client snapshot_instances = client.list_snapshot_instances( - self.snapshot['id']) + self.snapshot['id'] + ) self.assertGreater(len(snapshot_instances), 0) self.assertIn('ID', snapshot_instances[0]) - self.assertTrue(uuidutils.is_uuid_like( - snapshot_instances[0]['ID'])) + self.assertTrue(uuidutils.is_uuid_like(snapshot_instances[0]['ID'])) snapshot_instance_id = snapshot_instances[0]['ID'] export_locations = client.list_snapshot_instance_export_locations( - snapshot_instance_id) + snapshot_instance_id + ) el = client.get_snapshot_instance_export_location( - snapshot_instance_id, export_locations[0]['ID']) - expected_keys = ['path', 'id', 'is_admin_only', - 'share_snapshot_instance_id', 'updated_at', - 'created_at'] + snapshot_instance_id, export_locations[0]['ID'] + ) + expected_keys = [ + 'path', + 'id', + 'is_admin_only', + 'share_snapshot_instance_id', + 'updated_at', + 'created_at', + ] for key in expected_keys: self.assertIn(key, el) for key, key_el in ( - ('ID', 'id'), ('Path', 'path'), - ('Is Admin only', 'is_admin_only')): + ('ID', 'id'), + ('Path', 'path'), + ('Is Admin only', 'is_admin_only'), + ): self.assertEqual(export_locations[0][key], el[key_el]) - self.assertTrue(uuidutils.is_uuid_like( - el['share_snapshot_instance_id'])) + self.assertTrue( + uuidutils.is_uuid_like(el['share_snapshot_instance_id']) + ) self.assertTrue(uuidutils.is_uuid_like(el['id'])) self.assertIn(el['is_admin_only'], ('True', 'False')) def test_list_snapshot_instance_export_locations(self): client = self.admin_client snapshot_instances = client.list_snapshot_instances( - self.snapshot['id']) + self.snapshot['id'] + ) self.assertGreater(len(snapshot_instances), 0) self.assertIn('ID', snapshot_instances[0]) @@ -82,7 +93,8 @@ def test_list_snapshot_instance_export_locations(self): snapshot_instance_id = snapshot_instances[0]['ID'] export_locations = client.list_snapshot_instance_export_locations( - snapshot_instance_id) + snapshot_instance_id + ) self.assertGreater(len(export_locations), 0) @@ -95,7 +107,8 @@ def test_list_snapshot_instance_export_locations(self): def test_list_snapshot_instance_export_locations_with_columns(self): client = self.admin_client snapshot_instances = client.list_snapshot_instances( - self.snapshot['id']) + self.snapshot['id'] + ) self.assertGreater(len(snapshot_instances), 0) self.assertIn('ID', snapshot_instances[0]) @@ -103,7 +116,8 @@ def test_list_snapshot_instance_export_locations_with_columns(self): snapshot_instance_id = snapshot_instances[0]['ID'] export_locations = client.list_snapshot_instance_export_locations( - snapshot_instance_id, columns='id,path') + snapshot_instance_id, columns='id,path' + ) self.assertGreater(len(export_locations), 0) expected_keys = ('Id', 'Path') diff --git a/manilaclient/tests/functional/test_snapshots_export_locations.py b/manilaclient/tests/functional/test_snapshots_export_locations.py index 547ad241..3059467c 100644 --- a/manilaclient/tests/functional/test_snapshots_export_locations.py +++ b/manilaclient/tests/functional/test_snapshots_export_locations.py @@ -25,35 +25,39 @@ @ddt.ddt -@testtools.skipUnless(CONF.run_snapshot_tests and - CONF.run_mount_snapshot_tests, - "Snapshots or mountable snapshots tests are disabled.") +@testtools.skipUnless( + CONF.run_snapshot_tests and CONF.run_mount_snapshot_tests, + "Snapshots or mountable snapshots tests are disabled.", +) @utils.skip_if_microversion_not_supported('2.32') class SnapshotExportLocationReadWriteTest(base.BaseTestCase): - def setUp(self): - super(SnapshotExportLocationReadWriteTest, self).setUp() - self.share = self.create_share( - client=self.get_user_client()) - self.snapshot = self.create_snapshot(share=self.share['id'], - client=self.get_user_client()) + super().setUp() + self.share = self.create_share(client=self.get_user_client()) + self.snapshot = self.create_snapshot( + share=self.share['id'], client=self.get_user_client() + ) @ddt.data('admin', 'user') def test_get_snapshot_export_location(self, role): client = self.admin_client if role == 'admin' else self.user_client export_locations = client.list_snapshot_export_locations( - self.snapshot['id']) + self.snapshot['id'] + ) el = client.get_snapshot_export_location( - self.snapshot['id'], export_locations[0]['ID']) + self.snapshot['id'], export_locations[0]['ID'] + ) expected_keys = ['path', 'id', 'updated_at', 'created_at'] if role == 'admin': - expected_keys.extend(['is_admin_only', - 'share_snapshot_instance_id']) - self.assertTrue(uuidutils.is_uuid_like( - el['share_snapshot_instance_id'])) + expected_keys.extend( + ['is_admin_only', 'share_snapshot_instance_id'] + ) + self.assertTrue( + uuidutils.is_uuid_like(el['share_snapshot_instance_id']) + ) self.assertIn(el['is_admin_only'], ('True', 'False')) self.assertTrue(uuidutils.is_uuid_like(el['id'])) for key in expected_keys: @@ -63,7 +67,8 @@ def test_get_snapshot_export_location(self, role): def test_list_snapshot_export_locations(self, role): client = self.admin_client if role == 'admin' else self.user_client export_locations = client.list_snapshot_export_locations( - self.snapshot['id']) + self.snapshot['id'] + ) self.assertGreater(len(export_locations), 0) expected_keys = ('ID', 'Path') @@ -77,7 +82,8 @@ def test_list_snapshot_export_locations(self, role): def test_list_snapshot_export_locations_with_columns(self, role): client = self.admin_client if role == 'admin' else self.user_client export_locations = client.list_snapshot_export_locations( - self.snapshot['id'], columns='id,path') + self.snapshot['id'], columns='id,path' + ) self.assertGreater(len(export_locations), 0) expected_keys = ('Id', 'Path') diff --git a/manilaclient/tests/functional/utils.py b/manilaclient/tests/functional/utils.py index 4c37c5d0..9ebea8ce 100644 --- a/manilaclient/tests/functional/utils.py +++ b/manilaclient/tests/functional/utils.py @@ -32,21 +32,24 @@ def multi_line_row_table(output_lines, group_by_column_index=0): def get_column_index(column_name, headers, default): return next( (i for i, h in enumerate(headers) if h.lower() == column_name), - default + default, ) if group_by_column_index is None: group_by_column_index = get_column_index( - 'id', parsed_table['headers'], 0) + 'id', parsed_table['headers'], 0 + ) def is_embedded_table(parsed_rows): def is_table_border(t): return str(t).startswith('+') - return (isinstance(parsed_rows, list) - and len(parsed_rows) > 3 - and is_table_border(parsed_rows[0]) - and is_table_border(parsed_rows[-1])) + return ( + isinstance(parsed_rows, list) + and len(parsed_rows) > 3 + and is_table_border(parsed_rows[0]) + and is_table_border(parsed_rows[-1]) + ) def merge_cells(master_cell, value_cell): if value_cell: @@ -71,9 +74,9 @@ def is_empty_row(row): line_with_value = row_index > 0 and row[group_by_column_index] == '' if line_with_value and not is_empty_row(row): - rows[row_index - 1] = list(map(merge_cells, - rows[row_index - 1], - rows.pop(row_index))) + rows[row_index - 1] = list( + map(merge_cells, rows[row_index - 1], rows.pop(row_index)) + ) else: row_index += 1 @@ -104,17 +107,19 @@ def details(output_lines): def is_microversion_supported(microversion): return ( - api_versions.APIVersion(CONF.min_api_microversion) <= - api_versions.APIVersion(microversion) <= - api_versions.APIVersion(CONF.max_api_microversion) + api_versions.APIVersion(CONF.min_api_microversion) + <= api_versions.APIVersion(microversion) + <= api_versions.APIVersion(CONF.max_api_microversion) ) def skip_if_microversion_not_supported(microversion): """Decorator for tests that are microversion-specific.""" if not is_microversion_supported(microversion): - reason = ("Skipped. Test requires microversion %s that is not " - "allowed to be used by configuration." % microversion) + reason = ( + f"Skipped. Test requires microversion {microversion} that is not " + "allowed to be used by configuration." + ) return testtools.skip(reason) return lambda f: f @@ -125,16 +130,29 @@ def choose_matching_backend(share, pools, share_type): # convert extra-specs in provided type to dict format pair = [x.strip() for x in share_type['required_extra_specs'].split(':')] if len(pair) == 2: - value = (True if str(pair[1]).lower() == 'true' - else False if str(pair[1]).lower() == 'false' - else pair[1]) + value = ( + True + if str(pair[1]).lower() == 'true' + else False + if str(pair[1]).lower() == 'false' + else pair[1] + ) extra_specs[pair[0]] = value selected_pool = next( - (x for x in pools if (x['Name'] != share['host'] and all( - y in ast.literal_eval(x['Capabilities']).items() for y in - extra_specs.items()))), - None) + ( + x + for x in pools + if ( + x['Name'] != share['host'] + and all( + y in ast.literal_eval(x['Capabilities']).items() + for y in extra_specs.items() + ) + ) + ), + None, + ) return selected_pool['Name'] @@ -145,10 +163,17 @@ def share_network_subnets_are_supported(): def get_subnet_by_availability_zone_name(client, share_network_id, az_name): subnets = client.get_share_network_subnets(share_network_id) - return next((subnet for subnet in subnets - if subnet['availability_zone'] == az_name), None) + return next( + ( + subnet + for subnet in subnets + if subnet['availability_zone'] == az_name + ), + None, + ) def get_default_subnet(client, share_network_id): - return get_subnet_by_availability_zone_name(client, share_network_id, - 'None') + return get_subnet_by_availability_zone_name( + client, share_network_id, 'None' + ) diff --git a/manilaclient/tests/unit/common/test_httpclient.py b/manilaclient/tests/unit/common/test_httpclient.py index c03e2f47..474f22ca 100644 --- a/manilaclient/tests/unit/common/test_httpclient.py +++ b/manilaclient/tests/unit/common/test_httpclient.py @@ -23,69 +23,85 @@ fake_user_agent = "fake" -fake_response = utils.TestResponse({ - "status_code": 200, - "text": '{"hi": "there"}', -}) +fake_response = utils.TestResponse( + { + "status_code": 200, + "text": '{"hi": "there"}', + } +) mock_request = mock.Mock(return_value=(fake_response)) -bad_400_response = utils.TestResponse({ - "status_code": 400, - "text": '{"error": {"message": "n/a", "details": "Terrible!"}}', -}) +bad_400_response = utils.TestResponse( + { + "status_code": 400, + "text": '{"error": {"message": "n/a", "details": "Terrible!"}}', + } +) bad_400_request = mock.Mock(return_value=(bad_400_response)) -bad_401_response = utils.TestResponse({ - "status_code": 401, - "text": '{"error": {"message": "FAILED!", "details": "DETAILS!"}}', -}) +bad_401_response = utils.TestResponse( + { + "status_code": 401, + "text": '{"error": {"message": "FAILED!", "details": "DETAILS!"}}', + } +) bad_401_request = mock.Mock(return_value=(bad_401_response)) -bad_500_response = utils.TestResponse({ - "status_code": 500, - "text": '{"error": {"message": "FAILED!", "details": "DETAILS!"}}', -}) +bad_500_response = utils.TestResponse( + { + "status_code": 500, + "text": '{"error": {"message": "FAILED!", "details": "DETAILS!"}}', + } +) bad_500_request = mock.Mock(return_value=(bad_500_response)) -retry_after_response = utils.TestResponse({ - "status_code": 413, - "text": '', - "headers": { - "retry-after": "5" - }, -}) +retry_after_response = utils.TestResponse( + { + "status_code": 413, + "text": '', + "headers": {"retry-after": "5"}, + } +) retry_after_mock_request = mock.Mock(return_value=retry_after_response) -retry_after_no_headers_response = utils.TestResponse({ - "status_code": 413, - "text": '', -}) +retry_after_no_headers_response = utils.TestResponse( + { + "status_code": 413, + "text": '', + } +) retry_after_no_headers_mock_request = mock.Mock( - return_value=retry_after_no_headers_response) - -retry_after_non_supporting_response = utils.TestResponse({ - "status_code": 403, - "text": '', - "headers": { - "retry-after": "5" - }, -}) + return_value=retry_after_no_headers_response +) + +retry_after_non_supporting_response = utils.TestResponse( + { + "status_code": 403, + "text": '', + "headers": {"retry-after": "5"}, + } +) retry_after_non_supporting_mock_request = mock.Mock( - return_value=retry_after_non_supporting_response) + return_value=retry_after_non_supporting_response +) def get_authed_client(endpoint_url="http://example.com", retries=0): - cl = httpclient.HTTPClient(endpoint_url, "token", fake_user_agent, - retries=retries, http_log_debug=True, - api_version=manilaclient.API_MAX_VERSION) + cl = httpclient.HTTPClient( + endpoint_url, + "token", + fake_user_agent, + retries=retries, + http_log_debug=True, + api_version=manilaclient.API_MAX_VERSION, + ) return cl @ddt.ddt class ClientTest(utils.TestCase): - def setUp(self): - super(ClientTest, self).setUp() + super().setUp() self.max_version = manilaclient.API_MAX_VERSION self.max_version_str = self.max_version.get_string() @@ -99,7 +115,8 @@ def setUp(self): "http://10.10.10.10:3366/v2/b2d18606-2673-4965-885a-4f5a8b955b9b", "http://manila.example.com:3366/v1.1/", "http://manila.example.com:3366/v2/" - "b2d18606-2673-4965-885a-4f5a8b955b9b") + "b2d18606-2673-4965-885a-4f5a8b955b9b", + ) def test_get(self, endpoint_url): cl = get_authed_client(endpoint_url) @@ -117,11 +134,14 @@ def test_get_call(): "GET", endpoint_url + "/hi", headers=headers, - **self.TEST_REQUEST_BASE) + **self.TEST_REQUEST_BASE, + ) # Automatic JSON parsing self.assertEqual(body, {"hi": "there"}) - self.assertEqual(re.split(r'/v[0-9]+[\.0-9]*', - endpoint_url)[0] + "/", cl.base_url) + self.assertEqual( + re.split(r'/v[0-9]+[\.0-9]*', endpoint_url)[0] + "/", + cl.base_url, + ) test_get_call() @@ -212,7 +232,8 @@ def test_get_call(): "http://10.10.10.10:3366/v2/b2d18606-2673-4965-885a-4f5a8b955b9b", "http://manila.example.com:3366/v2.22/", "http://manila.example.com:3366/v1/" - "b2d18606-2673-4965-885a-4f5a8b955b9b") + "b2d18606-2673-4965-885a-4f5a8b955b9b", + ) def test_post(self, endpoint_url): cl = get_authed_client(endpoint_url) @@ -224,15 +245,18 @@ def test_post_call(): "Content-Type": "application/json", 'Accept': 'application/json', "X-Openstack-Manila-Api-Version": self.max_version_str, - "User-Agent": fake_user_agent + "User-Agent": fake_user_agent, } mock_request.assert_called_with( "POST", endpoint_url + "/hi", headers=headers, data='[1, 2, 3]', - **self.TEST_REQUEST_BASE) - self.assertEqual(re.split(r'/v[0-9]+[\.0-9]*', - endpoint_url)[0] + "/", cl.base_url) + **self.TEST_REQUEST_BASE, + ) + self.assertEqual( + re.split(r'/v[0-9]+[\.0-9]*', endpoint_url)[0] + "/", + cl.base_url, + ) test_post_call() diff --git a/manilaclient/tests/unit/fakes.py b/manilaclient/tests/unit/fakes.py index 01c29972..8576c9a8 100644 --- a/manilaclient/tests/unit/fakes.py +++ b/manilaclient/tests/unit/fakes.py @@ -29,34 +29,36 @@ def assert_has_keys(dictonary, required=None, optional=None): assert k in dictonary except AssertionError: extra_keys = set(dictonary).difference(set(required + optional)) - raise AssertionError("found unexpected keys: %s" % - list(extra_keys)) + raise AssertionError(f"found unexpected keys: {list(extra_keys)}") -class FakeClient(object): - +class FakeClient: def assert_called(self, method, url, body=None, pos=-1, **kwargs): """Assert than an API method was just called.""" expected = (method, url) called = self.client.callstack[pos][0:2] - assert self.client.callstack, ("Expected %s %s but no calls " - "were made." % expected) + assert self.client.callstack, ( + "Expected {} {} but no calls were made.".format(*expected) + ) assert expected == called, 'Expected %s %s; got %s %s' % ( - expected + called) + expected + called + ) if body is not None: actual = self.client.callstack[pos][2] - assert actual == body, "Expected %s; got %s" % (body, actual) + assert actual == body, f"Expected {body}; got {actual}" - def assert_called_anytime(self, method, url, body=None, - clear_callstack=True): + def assert_called_anytime( + self, method, url, body=None, clear_callstack=True + ): """Assert than an API method was called anytime in the test.""" expected = (method, url) - assert self.client.callstack, ("Expected %s %s but no calls " - "were made." % expected) + assert self.client.callstack, ( + "Expected {} {} but no calls were made.".format(*expected) + ) found = False for entry in self.client.callstack: @@ -64,8 +66,9 @@ def assert_called_anytime(self, method, url, body=None, found = True break - assert found, 'Expected %s %s; got %s' % ( - expected[0], expected[1], self.client.callstack) + assert found, ( + f'Expected {expected[0]} {expected[1]}; got {self.client.callstack}' + ) if body is not None: try: diff --git a/manilaclient/tests/unit/osc/osc_fakes.py b/manilaclient/tests/unit/osc/osc_fakes.py index 07beb4af..1b90708a 100644 --- a/manilaclient/tests/unit/osc/osc_fakes.py +++ b/manilaclient/tests/unit/osc/osc_fakes.py @@ -27,8 +27,7 @@ INTERFACE = "catchy" VERSION = "3" -TEST_RESPONSE_DICT = fixture.V2Token(token_id=AUTH_TOKEN, - user_name=USERNAME) +TEST_RESPONSE_DICT = fixture.V2Token(token_id=AUTH_TOKEN, user_name=USERNAME) _s = TEST_RESPONSE_DICT.add_service('identity', name='keystone') _s.add_endpoint(AUTH_URL + ':5000/v2.0') _s = TEST_RESPONSE_DICT.add_service('network', name='neutron') @@ -46,8 +45,7 @@ TEST_VERSIONS = fixture.DiscoveryList(href=AUTH_URL) -class FakeStdout(object): - +class FakeStdout: def __init__(self): self.content = [] @@ -61,8 +59,7 @@ def make_string(self): return result -class FakeLog(object): - +class FakeLog: def __init__(self): self.messages = {} @@ -82,8 +79,7 @@ def critical(self, msg): self.messages['critical'] = msg -class FakeApp(object): - +class FakeApp: def __init__(self, _stdout, _log): self.stdout = _stdout self.client_manager = None @@ -93,19 +89,18 @@ def __init__(self, _stdout, _log): self.log = _log -class FakeOptions(object): +class FakeOptions: def __init__(self, **kwargs): self.os_beta_command = False -class FakeClient(object): - +class FakeClient: def __init__(self, **kwargs): self.endpoint = kwargs['endpoint'] self.token = kwargs['token'] -class FakeClientManager(object): +class FakeClientManager: _api_version = { 'image': '2', } @@ -137,8 +132,7 @@ def is_network_endpoint_enabled(self): return self.network_endpoint_enabled -class FakeResource(object): - +class FakeResource: def __init__(self, manager=None, info=None, loaded=False, methods=None): """Set attributes and methods for a resource. @@ -162,7 +156,7 @@ def __init__(self, manager=None, info=None, loaded=False, methods=None): self._loaded = loaded def _add_details(self, info): - for (k, v) in info.items(): + for k, v in info.items(): setattr(self, k, v) def _add_methods(self, methods): @@ -173,15 +167,16 @@ def _add_methods(self, methods): @value. When users access the attribute with (), @value will be returned, which looks like a function call. """ - for (name, ret) in methods.items(): + for name, ret in methods.items(): method = mock.Mock(return_value=ret) setattr(self, name, method) def __repr__(self): - reprkeys = sorted(k for k in self.__dict__.keys() if k[0] != '_' and - k != 'manager') - info = ", ".join("%s=%s" % (k, getattr(self, k)) for k in reprkeys) - return "<%s %s>" % (self.__class__.__name__, info) + reprkeys = sorted( + k for k in self.__dict__.keys() if k[0] != '_' and k != 'manager' + ) + info = ", ".join(f"{k}={getattr(self, k)}" for k in reprkeys) + return f"<{self.__class__.__name__} {info}>" def keys(self): return self._info.keys() @@ -201,15 +196,15 @@ def get(self, item, default=None): class FakeLimitsResource(FakeResource): - class AbsoluteLimit: def __init__(self, name, value): self.name = name self.value = value class RateLimit: - def __init__(self, verb, uri, regex, value, remaining, - unit, next_available): + def __init__( + self, verb, uri, regex, value, remaining, unit, next_available + ): self.verb = verb self.uri = uri self.regex = regex @@ -236,5 +231,6 @@ def rate(self): rate['value'], rate['remaining'], rate['unit'], - rate['next-available']) + rate['next-available'], + ) ] diff --git a/manilaclient/tests/unit/osc/osc_utils.py b/manilaclient/tests/unit/osc/osc_utils.py index 3c5c8683..c7a75b6b 100644 --- a/manilaclient/tests/unit/osc/osc_utils.py +++ b/manilaclient/tests/unit/osc/osc_utils.py @@ -26,17 +26,20 @@ class ParserException(Exception): class TestCase(testtools.TestCase): - def setUp(self): testtools.TestCase.setUp(self) - if (os.environ.get("OS_STDOUT_CAPTURE") == "True" or - os.environ.get("OS_STDOUT_CAPTURE") == "1"): + if ( + os.environ.get("OS_STDOUT_CAPTURE") == "True" + or os.environ.get("OS_STDOUT_CAPTURE") == "1" + ): stdout = self.useFixture(fixtures.StringStream("stdout")).stream self.useFixture(fixtures.MonkeyPatch("sys.stdout", stdout)) - if (os.environ.get("OS_STDERR_CAPTURE") == "True" or - os.environ.get("OS_STDERR_CAPTURE") == "1"): + if ( + os.environ.get("OS_STDERR_CAPTURE") == "True" + or os.environ.get("OS_STDERR_CAPTURE") == "1" + ): stderr = self.useFixture(fixtures.StringStream("stderr")).stream self.useFixture(fixtures.MonkeyPatch("sys.stderr", stderr)) @@ -45,7 +48,7 @@ def assertNotCalled(self, m, msg=None): if m.called: if not msg: - msg = 'method %s should not have been called' % m + msg = f'method {m} should not have been called' self.fail(msg) @@ -53,7 +56,7 @@ class TestCommand(TestCase): """Test cliff command classes""" def setUp(self): - super(TestCommand, self).setUp() + super().setUp() # Build up a fake app self.fake_stdout = fakes.FakeStdout() self.fake_log = fakes.FakeLog() diff --git a/manilaclient/tests/unit/osc/v2/fakes.py b/manilaclient/tests/unit/osc/v2/fakes.py index d574eb08..62328d8c 100644 --- a/manilaclient/tests/unit/osc/v2/fakes.py +++ b/manilaclient/tests/unit/osc/v2/fakes.py @@ -23,10 +23,9 @@ from manilaclient.tests.unit.osc import osc_utils -class FakeShareClient(object): - +class FakeShareClient: def __init__(self, **kwargs): - super(FakeShareClient, self).__init__() + super().__init__() self.auth_token = kwargs['token'] self.management_url = kwargs['endpoint'] self.shares = mock.Mock() @@ -51,8 +50,9 @@ def __init__(self, **kwargs): self.share_instance_export_locations = mock.Mock() self.share_export_locations = mock.Mock() self.share_snapshot_instance_export_locations = mock.Mock() - self.share_export_locations.resource_class = ( - osc_fakes.FakeResource(None, {})) + self.share_export_locations.resource_class = osc_fakes.FakeResource( + None, {} + ) self.messages = mock.Mock() self.availability_zones = mock.Mock() self.services = mock.Mock() @@ -77,22 +77,19 @@ def __str__(self): class TestShare(osc_utils.TestCommand): - def setUp(self): - super(TestShare, self).setUp() + super().setUp() self.app.client_manager.share = FakeShareClient( - endpoint=osc_fakes.AUTH_URL, - token=osc_fakes.AUTH_TOKEN + endpoint=osc_fakes.AUTH_URL, token=osc_fakes.AUTH_TOKEN ) self.app.client_manager.identity = identity_fakes.FakeIdentityv3Client( - endpoint=osc_fakes.AUTH_URL, - token=osc_fakes.AUTH_TOKEN + endpoint=osc_fakes.AUTH_URL, token=osc_fakes.AUTH_TOKEN ) -class FakeShare(object): +class FakeShare: """Fake one or more shares.""" @staticmethod @@ -146,9 +143,9 @@ def create_one_share(attrs=None, methods=None): # Overwrite default attributes. share_info.update(attrs) - share = osc_fakes.FakeResource(info=copy.deepcopy(share_info), - methods=methods, - loaded=True) + share = osc_fakes.FakeResource( + info=copy.deepcopy(share_info), methods=methods, loaded=True + ) return share @staticmethod @@ -220,13 +217,14 @@ def get_share_data(share=None): if x == 'tags': # The 'tags' should be format_list data_list.append( - format_columns.ListColumn(share.info.get(x))) + format_columns.ListColumn(share.info.get(x)) + ) else: data_list.append(share.info.get(x)) return tuple(data_list) -class FakeShareType(object): +class FakeShareType: """Fake one or more share types""" @staticmethod @@ -243,9 +241,7 @@ def create_one_sharetype(attrs=None, methods=None): methods = methods or {} share_type_info = { - "required_extra_specs": { - "driver_handles_share_servers": True - }, + "required_extra_specs": {"driver_handles_share_servers": True}, "share_type_access:is_public": True, "extra_specs": { "replication_type": "readable", @@ -253,19 +249,18 @@ def create_one_sharetype(attrs=None, methods=None): "mount_snapshot_support": False, "revert_to_snapshot_support": False, "create_share_from_snapshot_support": True, - "snapshot_support": True + "snapshot_support": True, }, "id": 'share-type-id-' + uuid.uuid4().hex, "name": 'share-type-name-' + uuid.uuid4().hex, "is_default": False, - "description": 'share-type-description-' + uuid.uuid4().hex + "description": 'share-type-description-' + uuid.uuid4().hex, } share_type_info.update(attrs) - share_type = osc_fakes.FakeResource(info=copy.deepcopy( - share_type_info), - methods=methods, - loaded=True) + share_type = osc_fakes.FakeResource( + info=copy.deepcopy(share_type_info), methods=methods, loaded=True + ) return share_type @staticmethod @@ -308,7 +303,7 @@ def get_share_types(share_types=None, count=2): return mock.Mock(side_effect=share_types) -class FakeShareExportLocation(object): +class FakeShareExportLocation: """Fake one or more export locations""" @staticmethod @@ -336,9 +331,9 @@ def create_one_export_location(attrs=None): } share_export_location_info.update(attrs) - share_export_location = osc_fakes.FakeResource(info=copy.deepcopy( - share_export_location_info), - loaded=True) + share_export_location = osc_fakes.FakeResource( + info=copy.deepcopy(share_export_location_info), loaded=True + ) return share_export_location @staticmethod @@ -358,12 +353,12 @@ def create_share_export_locations(attrs=None, count=2): share_export_locations = [] for n in range(0, count): share_export_locations.append( - FakeShareExportLocation. - create_one_export_location(attrs)) + FakeShareExportLocation.create_one_export_location(attrs) + ) return share_export_locations -class FakeShareAccessRule(object): +class FakeShareAccessRule: """Fake one or more share access rules""" @staticmethod @@ -386,17 +381,17 @@ def create_one_access_rule(attrs=None): 'access_key': None, 'created_at': datetime.datetime.now().isoformat(), 'updated_at': None, - 'properties': {} + 'properties': {}, } share_access_rule.update(attrs) - share_access_rule = osc_fakes.FakeResource(info=copy.deepcopy( - share_access_rule), - loaded=True) + share_access_rule = osc_fakes.FakeResource( + info=copy.deepcopy(share_access_rule), loaded=True + ) return share_access_rule -class FakeQuotaSet(object): +class FakeQuotaSet: """Fake quota set""" @staticmethod @@ -425,13 +420,13 @@ def create_fake_quotas(attrs=None): } quotas_info.update(attrs) - quotas = osc_fakes.FakeResource(info=copy.deepcopy( - quotas_info), - loaded=True) + quotas = osc_fakes.FakeResource( + info=copy.deepcopy(quotas_info), loaded=True + ) return quotas -class FakeShareSnapshotIntances(object): +class FakeShareSnapshotIntances: """Fake a share snapshot instance""" @staticmethod @@ -455,14 +450,15 @@ def create_one_snapshot_instance(attrs=None, methods=None): 'share_id': 'share-id-' + uuid.uuid4().hex, 'share_instance_id': 'share-instance-id-' + uuid.uuid4().hex, 'progress': None, - 'provider_location': None + 'provider_location': None, } share_snapshot_instance.update(attrs) - share_snapshot_instance = osc_fakes.FakeResource(info=copy.deepcopy( - share_snapshot_instance), + share_snapshot_instance = osc_fakes.FakeResource( + info=copy.deepcopy(share_snapshot_instance), methods=methods, - loaded=True) + loaded=True, + ) return share_snapshot_instance @staticmethod @@ -480,12 +476,13 @@ def create_share_snapshot_instances(attrs=None, count=2): share_snapshot_instances = [] for n in range(0, count): share_snapshot_instances.append( - FakeShareSnapshot.create_one_snapshot(attrs)) + FakeShareSnapshot.create_one_snapshot(attrs) + ) return share_snapshot_instances -class FakeShareSnapshotInstancesExportLocations(object): +class FakeShareSnapshotInstancesExportLocations: """Fake a share snapshot instance Export Locations""" @staticmethod @@ -508,10 +505,10 @@ def create_one_snapshot_instance(attrs=None, methods=None): share_snapshot_instance_export_location.update(attrs) share_snapshot_instance_export_location = osc_fakes.FakeResource( - info=copy.deepcopy( - share_snapshot_instance_export_location), + info=copy.deepcopy(share_snapshot_instance_export_location), methods=methods, - loaded=True) + loaded=True, + ) return share_snapshot_instance_export_location @staticmethod @@ -529,12 +526,13 @@ def create_share_snapshot_instances(attrs=None, count=2): share_snapshot_instances = [] for n in range(0, count): share_snapshot_instances.append( - FakeShareSnapshot.create_one_snapshot(attrs)) + FakeShareSnapshot.create_one_snapshot(attrs) + ) return share_snapshot_instances -class FakeShareSnapshot(object): +class FakeShareSnapshot: """Fake a share snapshot""" @staticmethod @@ -562,14 +560,13 @@ def create_one_snapshot(attrs=None, methods=None): 'share_size': 1, 'size': 1, 'status': None, - 'user_id': 'user-id-' + uuid.uuid4().hex + 'user_id': 'user-id-' + uuid.uuid4().hex, } share_snapshot.update(attrs) - share_snapshot = osc_fakes.FakeResource(info=copy.deepcopy( - share_snapshot), - methods=methods, - loaded=True) + share_snapshot = osc_fakes.FakeResource( + info=copy.deepcopy(share_snapshot), methods=methods, loaded=True + ) return share_snapshot @staticmethod @@ -587,12 +584,13 @@ def create_share_snapshots(attrs=None, count=2): share_snapshots = [] for n in range(0, count): share_snapshots.append( - FakeShareSnapshot.create_one_snapshot(attrs)) + FakeShareSnapshot.create_one_snapshot(attrs) + ) return share_snapshots -class FakeShareTransfer(object): +class FakeShareTransfer: """Fake a share transfer""" @staticmethod @@ -620,14 +618,13 @@ def create_one_transfer(attrs=None, methods=None): 'name': 'name-' + uuid.uuid4().hex, 'resource_id': 'resource-id-' + uuid.uuid4().hex, 'resource_type': 'share', - 'source_project_id': 'source-project-id-' + uuid.uuid4().hex + 'source_project_id': 'source-project-id-' + uuid.uuid4().hex, } share_transfer.update(attrs) - share_transfer = osc_fakes.FakeResource(info=copy.deepcopy( - share_transfer), - methods=methods, - loaded=True) + share_transfer = osc_fakes.FakeResource( + info=copy.deepcopy(share_transfer), methods=methods, loaded=True + ) return share_transfer @staticmethod @@ -645,12 +642,13 @@ def create_share_transfers(attrs=None, count=2): share_transfers = [] for n in range(0, count): share_transfers.append( - FakeShareSnapshot.create_one_snapshot(attrs)) + FakeShareSnapshot.create_one_snapshot(attrs) + ) return share_transfers -class FakeSnapshotAccessRule(object): +class FakeSnapshotAccessRule: """Fake one or more snapshot access rules""" @staticmethod @@ -667,13 +665,13 @@ def create_one_access_rule(attrs={}): 'access_to': 'demo', 'access_type': 'user', 'id': 'access_rule-id-' + uuid.uuid4().hex, - 'state': 'queued_to_apply' + 'state': 'queued_to_apply', } snapshot_access_rule.update(attrs) - snapshot_access_rule = osc_fakes.FakeResource(info=copy.deepcopy( - snapshot_access_rule), - loaded=True) + snapshot_access_rule = osc_fakes.FakeResource( + info=copy.deepcopy(snapshot_access_rule), loaded=True + ) return snapshot_access_rule @staticmethod @@ -691,12 +689,13 @@ def create_access_rules(attrs={}, count=2): access_rules = [] for n in range(0, count): access_rules.append( - FakeSnapshotAccessRule.create_one_access_rule(attrs)) + FakeSnapshotAccessRule.create_one_access_rule(attrs) + ) return access_rules -class FakeSnapshotExportLocation(object): +class FakeSnapshotExportLocation: """Fake one or more export locations""" @staticmethod @@ -722,9 +721,9 @@ def create_one_export_location(attrs=None): } snapshot_export_location_info.update(attrs) - snapshot_export_location = osc_fakes.FakeResource(info=copy.deepcopy( - snapshot_export_location_info), - loaded=True) + snapshot_export_location = osc_fakes.FakeResource( + info=copy.deepcopy(snapshot_export_location_info), loaded=True + ) return snapshot_export_location @staticmethod @@ -742,13 +741,13 @@ def create_export_locations(attrs={}, count=2): export_locations = [] for n in range(0, count): export_locations.append( - FakeSnapshotExportLocation.create_one_export_location( - attrs)) + FakeSnapshotExportLocation.create_one_export_location(attrs) + ) return export_locations -class FakeMessage(object): +class FakeMessage: """Fake message""" @staticmethod @@ -779,9 +778,9 @@ def create_one_message(attrs=None): } message.update(attrs) - message = osc_fakes.FakeResource(info=copy.deepcopy( - message), - loaded=True) + message = osc_fakes.FakeResource( + info=copy.deepcopy(message), loaded=True + ) return message @staticmethod @@ -798,13 +797,12 @@ def create_messages(attrs={}, count=2): messages = [] for n in range(0, count): - messages.append( - FakeMessage.create_one_message(attrs)) + messages.append(FakeMessage.create_one_message(attrs)) return messages -class FakeShareReplica(object): +class FakeShareReplica: """Fake a share replica""" @staticmethod @@ -831,14 +829,13 @@ def create_one_replica(attrs=None, methods=None): 'share_network_id': None, 'share_server_id': None, 'status': None, - 'updated_at': None + 'updated_at': None, } share_replica.update(attrs) - share_replica = osc_fakes.FakeResource(info=copy.deepcopy( - share_replica), - methods=methods, - loaded=True) + share_replica = osc_fakes.FakeResource( + info=copy.deepcopy(share_replica), methods=methods, loaded=True + ) return share_replica @staticmethod @@ -855,12 +852,11 @@ def create_share_replicas(attrs=None, count=2): share_replicas = [] for n in range(0, count): - share_replicas.append( - FakeShareReplica.create_one_replica(attrs)) + share_replicas.append(FakeShareReplica.create_one_replica(attrs)) return share_replicas -class FakeShareAvailabilityZones(object): +class FakeShareAvailabilityZones: """Fake one or more availability zones""" @staticmethod @@ -883,14 +879,13 @@ def create_one_availability_zone(attrs=None): } availability_zone.update(attrs) - availability_zone = osc_fakes.FakeResource(info=copy.deepcopy( - availability_zone), - loaded=True) + availability_zone = osc_fakes.FakeResource( + info=copy.deepcopy(availability_zone), loaded=True + ) return availability_zone @staticmethod def create_share_availability_zones(attrs=None, count=2): - """Create multiple availability zones. :param Dictionary attrs: @@ -904,11 +899,12 @@ def create_share_availability_zones(attrs=None, count=2): availability_zones = [] for n in range(0, count): availability_zones.append( - FakeShareAvailabilityZones.create_one_availability_zone(attrs)) + FakeShareAvailabilityZones.create_one_availability_zone(attrs) + ) return availability_zones -class FakeShareService(object): +class FakeShareService: """Fake one or more share service""" @staticmethod @@ -930,13 +926,13 @@ def create_fake_service(attrs=None): "status": "enabled", "state": "up", "updated_at": 'time-' + uuid.uuid4().hex, - "zone": "fake_zone" + "zone": "fake_zone", } share_service_info.update(attrs) - share_service = osc_fakes.FakeResource(info=copy.deepcopy( - share_service_info), - loaded=True) + share_service = osc_fakes.FakeResource( + info=copy.deepcopy(share_service_info), loaded=True + ) return share_service @staticmethod @@ -953,12 +949,11 @@ def create_fake_services(attrs=None, count=2): services = [] for n in range(count): - services.append( - FakeShareService.create_fake_service(attrs)) + services.append(FakeShareService.create_fake_service(attrs)) return services -class FakeShareSecurityService(object): +class FakeShareSecurityService: """Fake one or more share security service""" @staticmethod @@ -993,10 +988,11 @@ def create_fake_security_service(attrs=None, methods=None): } share_security_service_info.update(attrs) - share_security_service = osc_fakes.FakeResource(info=copy.deepcopy( - share_security_service_info), + share_security_service = osc_fakes.FakeResource( + info=copy.deepcopy(share_security_service_info), methods=methods, - loaded=True) + loaded=True, + ) return share_security_service @staticmethod @@ -1014,11 +1010,12 @@ def create_fake_security_services(attrs=None, count=2): security_services = [] for n in range(count): security_services.append( - FakeShareSecurityService.create_fake_security_service(attrs)) + FakeShareSecurityService.create_fake_security_service(attrs) + ) return security_services -class FakeSharePools(object): +class FakeSharePools: """Fake one or more share pool""" @staticmethod @@ -1038,13 +1035,13 @@ def create_one_share_pool(attrs=None): "host": 'fake_host_' + uuid.uuid4().hex, "backend": 'fake_backend_' + uuid.uuid4().hex, "pool": 'fake_pool_' + uuid.uuid4().hex, - "capabilities": {'fake_capability': uuid.uuid4().hex} + "capabilities": {'fake_capability': uuid.uuid4().hex}, } share_pool.update(attrs) - share_pool = osc_fakes.FakeResource(info=copy.deepcopy( - share_pool), - loaded=True) + share_pool = osc_fakes.FakeResource( + info=copy.deepcopy(share_pool), loaded=True + ) return share_pool @staticmethod @@ -1061,12 +1058,11 @@ def create_share_pools(attrs=None, count=2): share_pools = [] for n in range(count): - share_pools.append( - FakeSharePools.create_one_share_pool(attrs)) + share_pools.append(FakeSharePools.create_one_share_pool(attrs)) return share_pools -class FakeShareInstance(object): +class FakeShareInstance: """Fake a share instance""" @staticmethod @@ -1093,14 +1089,13 @@ def create_one_share_instance(attrs=None, methods=None): 'share_server_id': 'ss-id-' + uuid.uuid4().hex, 'host': None, 'access_rules_status': None, - 'id': 'instance-id-' + uuid.uuid4().hex + 'id': 'instance-id-' + uuid.uuid4().hex, } share_instance.update(attrs) - share_instance = osc_fakes.FakeResource(info=copy.deepcopy( - share_instance), - methods=methods, - loaded=True) + share_instance = osc_fakes.FakeResource( + info=copy.deepcopy(share_instance), methods=methods, loaded=True + ) return share_instance @staticmethod @@ -1117,22 +1112,23 @@ def create_share_instances(attrs=None, count=2): share_instances = [] for n in range(count): share_instances.append( - FakeShareInstance.create_one_share_instance(attrs)) + FakeShareInstance.create_one_share_instance(attrs) + ) return share_instances -class FakeShareLimits(object): +class FakeShareLimits: """Fake one or more share limits""" @staticmethod def create_one_share_limit(attrs=None): """Create a fake share limit dict - :param Dictionary attrs: - A dictionary with all attributes - :return: - A FakeLimitsResource object, with share limits. - """ + :param Dictionary attrs: + A dictionary with all attributes + :return: + A FakeLimitsResource object, with share limits. + """ attrs = attrs or {} @@ -1148,16 +1144,17 @@ def create_one_share_limit(attrs=None): "unit": "MINUTE", "value": "3", "remaining": "1", - } + }, } share_limits.update(attrs) share_limits = osc_fakes.FakeLimitsResource( - info=copy.deepcopy(share_limits), loaded=True) + info=copy.deepcopy(share_limits), loaded=True + ) return share_limits -class FakeShareNetwork(object): +class FakeShareNetwork: """Fake a share network""" @staticmethod @@ -1194,16 +1191,15 @@ def create_one_share_network(attrs=None, methods=None): "cidr": "10.0.0.0/24", "network_type": "vlan", "mtu": "1500", - "gateway": "10.0.0.1" + "gateway": "10.0.0.1", }, ], } share_network.update(attrs) - share_network = osc_fakes.FakeResource(info=copy.deepcopy( - share_network), - methods=methods, - loaded=True) + share_network = osc_fakes.FakeResource( + info=copy.deepcopy(share_network), methods=methods, loaded=True + ) return share_network @staticmethod @@ -1222,12 +1218,13 @@ def create_share_networks(attrs=None, count=2): share_networks = [] for n in range(count): share_networks.append( - FakeShareNetwork.create_one_share_network(attrs)) + FakeShareNetwork.create_one_share_network(attrs) + ) return share_networks -class FakeShareNetworkSubnet(object): +class FakeShareNetworkSubnet: """Fake a share network subnet""" @staticmethod @@ -1261,9 +1258,9 @@ def create_one_share_subnet(attrs=None): } share_network_subnet.update(attrs) - share_network_subnet = osc_fakes.FakeResource(info=copy.deepcopy( - share_network_subnet), - loaded=True) + share_network_subnet = osc_fakes.FakeResource( + info=copy.deepcopy(share_network_subnet), loaded=True + ) return share_network_subnet @staticmethod @@ -1281,12 +1278,13 @@ def create_share_network_subnets(attrs=None, count=2): share_network_subnets = [] for n in range(count): share_network_subnets.append( - FakeShareNetworkSubnet.create_one_share_subnet(attrs)) + FakeShareNetworkSubnet.create_one_share_subnet(attrs) + ) return share_network_subnets -class FakeShareGroup(object): +class FakeShareGroup: """Fake a share group""" @staticmethod @@ -1316,14 +1314,13 @@ def create_one_share_group(attrs=None, methods=None): 'share_network_id': None, 'share_server_id': None, 'share_types': ['share-types-id-' + uuid.uuid4().hex], - 'consistent_snapshot_support': None + 'consistent_snapshot_support': None, } share_group.update(attrs) - share_group = osc_fakes.FakeResource(info=copy.deepcopy( - share_group), - methods=methods, - loaded=True) + share_group = osc_fakes.FakeResource( + info=copy.deepcopy(share_group), methods=methods, loaded=True + ) return share_group @staticmethod @@ -1340,12 +1337,11 @@ def create_share_groups(attrs=None, count=2): share_groups = [] for n in range(0, count): - share_groups.append( - FakeShareGroup.create_one_share_group(attrs)) + share_groups.append(FakeShareGroup.create_one_share_group(attrs)) return share_groups -class FakeShareGroupType(object): +class FakeShareGroupType: """Fake one or more share group types""" @staticmethod @@ -1363,20 +1359,19 @@ def create_one_share_group_type(attrs=None, methods=None): share_group_type_info = { "is_public": True, - "group_specs": { - "snapshot_support": True - }, + "group_specs": {"snapshot_support": True}, "share_types": ['share-types-id-' + uuid.uuid4().hex], "id": 'share-group-type-id-' + uuid.uuid4().hex, "name": 'share-group-type-name-' + uuid.uuid4().hex, - "is_default": False + "is_default": False, } share_group_type_info.update(attrs) - share_group_type = osc_fakes.FakeResource(info=copy.deepcopy( - share_group_type_info), - methods=methods, - loaded=True) + share_group_type = osc_fakes.FakeResource( + info=copy.deepcopy(share_group_type_info), + methods=methods, + loaded=True, + ) return share_group_type @staticmethod @@ -1394,7 +1389,8 @@ def create_share_group_types(attrs=None, count=2): share_group_types = [] for n in range(0, count): share_group_types.append( - FakeShareGroupType.create_one_share_group_type(attrs)) + FakeShareGroupType.create_one_share_group_type(attrs) + ) return share_group_types @@ -1420,7 +1416,7 @@ def get_share_group_types(share_group_types=None, count=2): return mock.Mock(side_effect=share_group_types) -class FakeShareGroupSnapshot(object): +class FakeShareGroupSnapshot: """Fake a share group snapshot""" @staticmethod @@ -1443,14 +1439,15 @@ def create_one_share_group_snapshot(attrs=None, methods=None): 'created_at': datetime.datetime.now().isoformat(), "project_id": 'project-id-' + uuid.uuid4().hex, 'id': 'share-group-snapshot-id-' + uuid.uuid4().hex, - 'description': None + 'description': None, } share_group_snapshot.update(attrs) - share_group_snapshot = osc_fakes.FakeResource(info=copy.deepcopy( - share_group_snapshot), + share_group_snapshot = osc_fakes.FakeResource( + info=copy.deepcopy(share_group_snapshot), methods=methods, - loaded=True) + loaded=True, + ) return share_group_snapshot @staticmethod @@ -1468,11 +1465,12 @@ def create_share_group_snapshots(attrs=None, count=2): share_group_snapshots = [] for n in range(0, count): share_group_snapshots.append( - FakeShareGroupSnapshot.create_one_share_group_snapshot(attrs)) + FakeShareGroupSnapshot.create_one_share_group_snapshot(attrs) + ) return share_group_snapshots -class FakeShareServer(object): +class FakeShareServer: """Fake a share server""" @staticmethod @@ -1501,14 +1499,13 @@ def create_one_server(attrs=None, methods=None): 'source_share_server_id': str(uuid.uuid4()), 'created_at': datetime.datetime.now().isoformat(), 'is_auto_deletable': False, - 'identifier': str(uuid.uuid4()) + 'identifier': str(uuid.uuid4()), } share_server.update(attrs) - share_server = osc_fakes.FakeResource(info=copy.deepcopy( - share_server), - methods=methods, - loaded=True) + share_server = osc_fakes.FakeResource( + info=copy.deepcopy(share_server), methods=methods, loaded=True + ) return share_server @staticmethod @@ -1525,12 +1522,11 @@ def create_share_servers(attrs=None, count=2): attrs = attrs or {} share_servers = [] for n in range(count): - share_servers.append( - FakeShareServer.create_one_server(attrs)) + share_servers.append(FakeShareServer.create_one_server(attrs)) return share_servers -class FakeResourceLock(object): +class FakeResourceLock: """Fake a resource lock""" @staticmethod @@ -1562,10 +1558,9 @@ def create_one_lock(attrs=None, methods=None): } lock.update(attrs) - lock = osc_fakes.FakeResource(info=copy.deepcopy( - lock), - methods=methods, - loaded=True) + lock = osc_fakes.FakeResource( + info=copy.deepcopy(lock), methods=methods, loaded=True + ) return lock @staticmethod @@ -1582,13 +1577,12 @@ def create_locks(attrs=None, count=2): resource_locks = [] for n in range(0, count): - resource_locks.append( - FakeResourceLock.create_one_lock(attrs)) + resource_locks.append(FakeResourceLock.create_one_lock(attrs)) return resource_locks -class FakeShareBackup(object): +class FakeShareBackup: """Fake a share Backup""" @staticmethod @@ -1621,10 +1615,9 @@ def create_one_backup(attrs=None, methods=None): } share_backup.update(attrs) - share_backup = osc_fakes.FakeResource(info=copy.deepcopy( - share_backup), - methods=methods, - loaded=True) + share_backup = osc_fakes.FakeResource( + info=copy.deepcopy(share_backup), methods=methods, loaded=True + ) return share_backup @staticmethod @@ -1641,6 +1634,5 @@ def create_share_backups(attrs=None, count=2): share_backups = [] for n in range(0, count): - share_backups.append( - FakeShareBackup.create_one_backup(attrs)) + share_backups.append(FakeShareBackup.create_one_backup(attrs)) return share_backups diff --git a/manilaclient/tests/unit/osc/v2/test_availability_zones.py b/manilaclient/tests/unit/osc/v2/test_availability_zones.py index 02b5cebf..741523fe 100644 --- a/manilaclient/tests/unit/osc/v2/test_availability_zones.py +++ b/manilaclient/tests/unit/osc/v2/test_availability_zones.py @@ -18,31 +18,31 @@ class TestAvailabilityZones(manila_fakes.TestShare): - def setUp(self): - super(TestAvailabilityZones, self).setUp() + super().setUp() self.zones_mock = self.app.client_manager.share.availability_zones self.zones_mock.reset_mock() class TestShareAvailabilityZoneList(TestAvailabilityZones): - - availability_zones = manila_fakes.FakeShareAvailabilityZones.\ - create_share_availability_zones() + availability_zones = manila_fakes.FakeShareAvailabilityZones.create_share_availability_zones() COLUMNS = ("Id", "Name", "Created At", "Updated At") def setUp(self): - super(TestShareAvailabilityZoneList, self).setUp() + super().setUp() self.zones_mock.list.return_value = self.availability_zones # Get the command object to test self.cmd = osc_availability_zones.ShareAvailabilityZoneList( - self.app, None) + self.app, None + ) - self.values = (oscutils.get_dict_properties( - s._info, self.COLUMNS) for s in self.availability_zones) + self.values = ( + oscutils.get_dict_properties(s._info, self.COLUMNS) + for s in self.availability_zones + ) def test_share_list_availability_zone(self): arglist = [] diff --git a/manilaclient/tests/unit/osc/v2/test_messages.py b/manilaclient/tests/unit/osc/v2/test_messages.py index dbfef9bd..855cd93d 100644 --- a/manilaclient/tests/unit/osc/v2/test_messages.py +++ b/manilaclient/tests/unit/osc/v2/test_messages.py @@ -31,24 +31,22 @@ class TestMessage(manila_fakes.TestShare): - def setUp(self): - super(TestMessage, self).setUp() + super().setUp() self.messages_mock = self.app.client_manager.share.messages self.messages_mock.reset_mock() self.app.client_manager.share.api_version = api_versions.APIVersion( - api_versions.MAX_VERSION) + api_versions.MAX_VERSION + ) class TestMessageDelete(TestMessage): - def setUp(self): - super(TestMessageDelete, self).setUp() + super().setUp() - self.message = ( - manila_fakes.FakeMessage.create_one_message()) + self.message = manila_fakes.FakeMessage.create_one_message() self.messages_mock.get.return_value = self.message @@ -58,16 +56,17 @@ def test_message_delete_missing_args(self): arglist = [] verifylist = [] - self.assertRaises(osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_message_delete(self): - arglist = [ - self.message.id - ] - verifylist = [ - ('message', [self.message.id]) - ] + arglist = [self.message.id] + verifylist = [('message', [self.message.id])] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -77,47 +76,33 @@ def test_message_delete(self): self.assertIsNone(result) def test_message_delete_multiple(self): - messages = ( - manila_fakes.FakeMessage.create_messages( - count=2)) - arglist = [ - messages[0].id, - messages[1].id - ] - verifylist = [ - ('message', [messages[0].id, messages[1].id]) - ] + messages = manila_fakes.FakeMessage.create_messages(count=2) + arglist = [messages[0].id, messages[1].id] + verifylist = [('message', [messages[0].id, messages[1].id])] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - self.assertEqual(self.messages_mock.delete.call_count, - len(messages)) + self.assertEqual(self.messages_mock.delete.call_count, len(messages)) self.assertIsNone(result) def test_message_delete_exception(self): - arglist = [ - self.message.id - ] - verifylist = [ - ('message', [self.message.id]) - ] + arglist = [self.message.id] + verifylist = [('message', [self.message.id])] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.messages_mock.delete.side_effect = exceptions.CommandError() - self.assertRaises(exceptions.CommandError, - self.cmd.take_action, - parsed_args) + self.assertRaises( + exceptions.CommandError, self.cmd.take_action, parsed_args + ) class TestMessageShow(TestMessage): - def setUp(self): - super(TestMessageShow, self).setUp() + super().setUp() - self.message = ( - manila_fakes.FakeMessage.create_one_message()) + self.message = manila_fakes.FakeMessage.create_one_message() self.messages_mock.get.return_value = self.message self.cmd = osc_messages.ShowMessage(self.app, None) @@ -129,16 +114,17 @@ def test_message_show_missing_args(self): arglist = [] verifylist = [] - self.assertRaises(osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_message_show(self): - arglist = [ - self.message.id - ] - verifylist = [ - ('message', self.message.id) - ] + arglist = [self.message.id] + verifylist = [('message', self.message.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) @@ -148,18 +134,17 @@ def test_message_show(self): class TestMessageList(TestMessage): - def setUp(self): - super(TestMessageList, self).setUp() + super().setUp() - self.messages = ( - manila_fakes.FakeMessage.create_messages( - count=2)) + self.messages = manila_fakes.FakeMessage.create_messages(count=2) self.messages_mock.list.return_value = self.messages - self.values = (oscutils.get_dict_properties( - m._info, COLUMNS) for m in self.messages) + self.values = ( + oscutils.get_dict_properties(m._info, COLUMNS) + for m in self.messages + ) self.cmd = osc_messages.ListMessage(self.app, None) @@ -181,28 +166,31 @@ def test_list_messages(self): 'detail_id': None, 'message_level': None, 'created_since': None, - 'created_before': None - }) + 'created_before': None, + } + ) self.assertEqual(COLUMNS, columns) self.assertEqual(list(self.values), list(data)) def test_list_messages_api_version_exception(self): self.app.client_manager.share.api_version = api_versions.APIVersion( - "2.50") + "2.50" + ) arglist = [ - '--before', '2021-02-06T09:49:58-05:00', - '--since', '2021-02-05T09:49:58-05:00' + '--before', + '2021-02-06T09:49:58-05:00', + '--since', + '2021-02-05T09:49:58-05:00', ] verifylist = [ ('before', '2021-02-06T09:49:58-05:00'), - ('since', '2021-02-05T09:49:58-05:00') + ('since', '2021-02-05T09:49:58-05:00'), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( - exceptions.CommandError, - self.cmd.take_action, - parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) diff --git a/manilaclient/tests/unit/osc/v2/test_quotas.py b/manilaclient/tests/unit/osc/v2/test_quotas.py index c25fd41b..17aa9f97 100644 --- a/manilaclient/tests/unit/osc/v2/test_quotas.py +++ b/manilaclient/tests/unit/osc/v2/test_quotas.py @@ -23,9 +23,8 @@ class TestQuotas(manila_fakes.TestShare): - def setUp(self): - super(TestQuotas, self).setUp() + super().setUp() self.quotas_mock = self.app.client_manager.share.quotas self.quotas_mock.reset_mock() @@ -43,7 +42,7 @@ class TestQuotaSet(TestQuotas): user = identity_fakes.FakeUser.create_one_user() def setUp(self): - super(TestQuotaSet, self).setUp() + super().setUp() self.quotas = manila_fakes.FakeQuotaSet.create_fake_quotas() self.quotas_mock.update = mock.Mock() @@ -55,15 +54,11 @@ def setUp(self): self.cmd = osc_quotas.QuotaSet(self.app, None) def test_quota_set_default_class_shares(self): - arglist = [ - 'default', - '--class', - '--shares', '40' - ] + arglist = ['default', '--class', '--shares', '40'] verifylist = [ ('project', 'default'), ('quota_class', True), - ('shares', 40) + ('shares', 40), ] with mock.patch('osc_lib.utils.find_resource') as mock_find_resource: @@ -78,20 +73,15 @@ def test_quota_set_default_class_shares(self): share_networks=None, shares=40, snapshot_gigabytes=None, - snapshots=None) + snapshots=None, + ) self.assertIsNone(result) mock_find_resource.assert_not_called() self.quotas_mock.assert_not_called() def test_quota_set_shares(self): - arglist = [ - self.project.id, - '--shares', '40' - ] - verifylist = [ - ('project', self.project.id), - ('shares', 40) - ] + arglist = [self.project.id, '--shares', '40'] + verifylist = [('project', self.project.id), ('shares', 40)] with mock.patch('osc_lib.utils.find_resource') as mock_find_resource: mock_find_resource.return_value = self.project @@ -107,18 +97,13 @@ def test_quota_set_shares(self): snapshot_gigabytes=None, snapshots=None, tenant_id=self.project.id, - user_id=None) + user_id=None, + ) self.assertIsNone(result) def test_quota_set_gigabytes(self): - arglist = [ - self.project.id, - '--gigabytes', '1100' - ] - verifylist = [ - ('project', self.project.id), - ('gigabytes', 1100) - ] + arglist = [self.project.id, '--gigabytes', '1100'] + verifylist = [('project', self.project.id), ('gigabytes', 1100)] with mock.patch('osc_lib.utils.find_resource') as mock_find_resource: mock_find_resource.return_value = self.project @@ -134,18 +119,13 @@ def test_quota_set_gigabytes(self): snapshot_gigabytes=None, snapshots=None, tenant_id=self.project.id, - user_id=None) + user_id=None, + ) self.assertIsNone(result) def test_quota_set_share_type(self): - arglist = [ - self.project.id, - '--share-type', 'default' - ] - verifylist = [ - ('project', self.project.id), - ('share_type', 'default') - ] + arglist = [self.project.id, '--share-type', 'default'] + verifylist = [('project', self.project.id), ('share_type', 'default')] with mock.patch('osc_lib.utils.find_resource') as mock_find_resource: mock_find_resource.return_value = self.project @@ -162,19 +142,16 @@ def test_quota_set_share_type(self): snapshot_gigabytes=None, snapshots=None, tenant_id=self.project.id, - user_id=None) + user_id=None, + ) self.assertIsNone(result) def test_quota_set_force(self): - arglist = [ - self.project.id, - '--force', - '--shares', '40' - ] + arglist = [self.project.id, '--force', '--shares', '40'] verifylist = [ ('project', self.project.id), ('force', True), - ('shares', 40) + ('shares', 40), ] with mock.patch('osc_lib.utils.find_resource') as mock_find_resource: @@ -191,7 +168,8 @@ def test_quota_set_force(self): snapshot_gigabytes=None, snapshots=None, tenant_id=self.project.id, - user_id=None) + user_id=None, + ) self.assertIsNone(result) def test_quota_set_api_version_exception(self): @@ -199,63 +177,54 @@ def test_quota_set_api_version_exception(self): '2.39' ) - arglist = [ - self.project.id, - '--share-groups', '40' - ] - verifylist = [ - ('project', self.project.id), - ('share_groups', 40) - ] + arglist = [self.project.id, '--share-groups', '40'] + verifylist = [('project', self.project.id), ('share_groups', 40)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( - exceptions.CommandError, self.cmd.take_action, parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_quota_set_update_project_exception(self): arglist = [ self.project.id, - '--share-groups', '40', - '--share-group-snapshots', '40' + '--share-groups', + '40', + '--share-group-snapshots', + '40', ] verifylist = [ ('project', self.project.id), ('share_groups', 40), - ('share_group_snapshots', 40) + ('share_group_snapshots', 40), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.quotas_mock.update.side_effect = BadRequest() self.assertRaises( - exceptions.CommandError, self.cmd.take_action, parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_quota_set_update_class_exception(self): - arglist = [ - 'default', - '--class', - '--gigabytes', '40' - ] - verifylist = [ - ('project', 'default'), - ('gigabytes', 40) - ] + arglist = ['default', '--class', '--gigabytes', '40'] + verifylist = [('project', 'default'), ('gigabytes', 40)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.quota_classes_mock.update.side_effect = BadRequest() self.assertRaises( - exceptions.CommandError, self.cmd.take_action, parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_quota_set_nothing_to_set_exception(self): arglist = [ self.project.id, ] - verifylist = [ - ('project', self.project.id) - ] + verifylist = [('project', self.project.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( - exceptions.CommandError, self.cmd.take_action, parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_quota_set_share_replicas(self): self.app.client_manager.share.api_version = api_versions.APIVersion( @@ -264,12 +233,10 @@ def test_quota_set_share_replicas(self): arglist = [ self.project.id, - '--share-replicas', '2', - ] - verifylist = [ - ('project', self.project.id), - ('share_replicas', 2) + '--share-replicas', + '2', ] + verifylist = [('project', self.project.id), ('share_replicas', 2)] with mock.patch('osc_lib.utils.find_resource') as mock_find_resource: mock_find_resource.return_value = self.project @@ -286,49 +253,54 @@ def test_quota_set_share_replicas(self): snapshot_gigabytes=None, snapshots=None, tenant_id=self.project.id, - user_id=None) + user_id=None, + ) self.assertIsNone(result) def test_quota_set_replica_gigabytes_exception(self): self.app.client_manager.share.api_version = api_versions.APIVersion( - '2.51') + '2.51' + ) arglist = [ self.project.id, - '--replica-gigabytes', '10', - ] - verifylist = [ - ('project', self.project.id), - ('replica_gigabytes', 10) + '--replica-gigabytes', + '10', ] + verifylist = [('project', self.project.id), ('replica_gigabytes', 10)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( - exceptions.CommandError, self.cmd.take_action, parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_quota_set_per_share_gigabytes_exception(self): self.app.client_manager.share.api_version = api_versions.APIVersion( - '2.61') + '2.61' + ) arglist = [ self.project.id, - '--per-share-gigabytes', '10', + '--per-share-gigabytes', + '10', ] verifylist = [ ('project', self.project.id), - ('per_share_gigabytes', 10) + ('per_share_gigabytes', 10), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( - exceptions.CommandError, self.cmd.take_action, parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_quota_set_per_share_gigabytes(self): arglist = [ self.project.id, - '--per-share-gigabytes', '10', + '--per-share-gigabytes', + '10', ] verifylist = [ ('project', self.project.id), - ('per_share_gigabytes', 10) + ('per_share_gigabytes', 10), ] with mock.patch('osc_lib.utils.find_resource') as mock_find_resource: @@ -346,34 +318,33 @@ def test_quota_set_per_share_gigabytes(self): snapshots=None, per_share_gigabytes=10, tenant_id=self.project.id, - user_id=None) + user_id=None, + ) self.assertIsNone(result) def test_quota_set_encryption_keys_exception(self): self.app.client_manager.share.api_version = api_versions.APIVersion( - '2.89') + '2.89' + ) arglist = [ self.project.id, - '--encryption-keys', '10', - ] - verifylist = [ - ('project', self.project.id), - ('encryption_keys', 10) + '--encryption-keys', + '10', ] + verifylist = [('project', self.project.id), ('encryption_keys', 10)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( - exceptions.CommandError, self.cmd.take_action, parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_quota_set_encryption_keys(self): arglist = [ self.project.id, - '--encryption-keys', '10', - ] - verifylist = [ - ('project', self.project.id), - ('encryption_keys', 10) + '--encryption-keys', + '10', ] + verifylist = [('project', self.project.id), ('encryption_keys', 10)] with mock.patch('osc_lib.utils.find_resource') as mock_find_resource: mock_find_resource.return_value = self.project @@ -390,7 +361,8 @@ def test_quota_set_encryption_keys(self): snapshots=None, encryption_keys=10, tenant_id=self.project.id, - user_id=None) + user_id=None, + ) self.assertIsNone(result) @@ -399,19 +371,15 @@ class TestQuotaShow(TestQuotas): user = identity_fakes.FakeUser.create_one_user() def setUp(self): - super(TestQuotaShow, self).setUp() + super().setUp() self.quotas = manila_fakes.FakeQuotaSet.create_fake_quotas() self.quotas_mock.get.return_value = self.quotas self.cmd = osc_quotas.QuotaShow(self.app, None) def test_quota_show(self): - arglist = [ - self.project.id - ] - verifylist = [ - ('project', self.project.id) - ] + arglist = [self.project.id] + verifylist = [('project', self.project.id)] with mock.patch('osc_lib.utils.find_resource') as mock_find_resource: mock_find_resource.return_value = self.project @@ -420,9 +388,7 @@ def test_quota_show(self): columns, data = self.cmd.take_action(parsed_args) self.quotas_mock.get.assert_called_with( - detail=False, - tenant_id=self.project.id, - user_id=None + detail=False, tenant_id=self.project.id, user_id=None ) self.assertCountEqual(columns, self.quotas.keys()) @@ -433,28 +399,17 @@ def test_quota_show_api_version_exception(self): '2.38' ) - arglist = [ - self.project.id, - '--share-type', 'default' - ] - verifylist = [ - ('project', self.project.id), - ('share_type', 'default') - ] + arglist = [self.project.id, '--share-type', 'default'] + verifylist = [('project', self.project.id), ('share_type', 'default')] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( - exceptions.CommandError, self.cmd.take_action, parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_quota_show_defaults(self): - arglist = [ - self.project.id, - '--defaults' - ] - verifylist = [ - ('project', self.project.id), - ('defaults', True) - ] + arglist = [self.project.id, '--defaults'] + verifylist = [('project', self.project.id), ('defaults', True)] self.quotas_mock.defaults = mock.Mock() self.quotas_mock.defaults.return_value = self.quotas @@ -476,19 +431,15 @@ class TestQuotaDelete(TestQuotas): user = identity_fakes.FakeUser.create_one_user() def setUp(self): - super(TestQuotaDelete, self).setUp() + super().setUp() self.quotas = manila_fakes.FakeQuotaSet.create_fake_quotas() self.quotas_mock.delete.return_value = None self.cmd = osc_quotas.QuotaDelete(self.app, None) def test_quota_delete(self): - arglist = [ - self.project.id - ] - verifylist = [ - ('project', self.project.id) - ] + arglist = [self.project.id] + verifylist = [('project', self.project.id)] with mock.patch('osc_lib.utils.find_resource') as mock_find_resource: mock_find_resource.return_value = self.project @@ -497,19 +448,13 @@ def test_quota_delete(self): result = self.cmd.take_action(parsed_args) self.quotas_mock.delete.assert_called_with( - tenant_id=self.project.id, - user_id=None) + tenant_id=self.project.id, user_id=None + ) self.assertIsNone(result) def test_quota_delete_share_type(self): - arglist = [ - self.project.id, - '--share-type', 'default' - ] - verifylist = [ - ('project', self.project.id), - ('share_type', 'default') - ] + arglist = [self.project.id, '--share-type', 'default'] + verifylist = [('project', self.project.id), ('share_type', 'default')] with mock.patch('osc_lib.utils.find_resource') as mock_find_resource: mock_find_resource.return_value = self.project @@ -518,9 +463,8 @@ def test_quota_delete_share_type(self): result = self.cmd.take_action(parsed_args) self.quotas_mock.delete.assert_called_with( - share_type='default', - tenant_id=self.project.id, - user_id=None) + share_type='default', tenant_id=self.project.id, user_id=None + ) self.assertIsNone(result) def test_quota_delete_api_version_exception(self): @@ -528,15 +472,10 @@ def test_quota_delete_api_version_exception(self): '2.38' ) - arglist = [ - self.project.id, - '--share-type', 'default' - ] - verifylist = [ - ('project', self.project.id), - ('share_type', 'default') - ] + arglist = [self.project.id, '--share-type', 'default'] + verifylist = [('project', self.project.id), ('share_type', 'default')] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( - exceptions.CommandError, self.cmd.take_action, parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) diff --git a/manilaclient/tests/unit/osc/v2/test_resource_locks.py b/manilaclient/tests/unit/osc/v2/test_resource_locks.py index 6c5ca06f..c1a2ee3b 100644 --- a/manilaclient/tests/unit/osc/v2/test_resource_locks.py +++ b/manilaclient/tests/unit/osc/v2/test_resource_locks.py @@ -42,9 +42,8 @@ class TestResourceLock(manila_fakes.TestShare): - def setUp(self): - super(TestResourceLock, self).setUp() + super().setUp() self.shares_mock = self.app.client_manager.share.shares self.shares_mock.reset_mock() @@ -53,13 +52,13 @@ def setUp(self): self.locks_mock.reset_mock() self.app.client_manager.share.api_version = api_versions.APIVersion( - api_versions.MAX_VERSION) + api_versions.MAX_VERSION + ) class TestResourceLockCreate(TestResourceLock): - def setUp(self): - super(TestResourceLockCreate, self).setUp() + super().setUp() self.share = manila_fakes.FakeShare.create_one_share() self.shares_mock.create.return_value = self.share @@ -67,7 +66,8 @@ def setUp(self): self.shares_mock.get.return_value = self.share self.lock = manila_fakes.FakeResourceLock.create_one_lock( - attrs={'resource_id': self.share.id}) + attrs={'resource_id': self.share.id} + ) self.locks_mock.get.return_value = self.lock self.locks_mock.create.return_value = self.lock @@ -80,13 +80,20 @@ def test_share_lock_create_missing_required_args(self): arglist = [] verifylist = [] - self.assertRaises(osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_lock_create(self): arglist = [ - '--resource-action', 'revert_to_snapshot', - '--lock-reason', "you cannot go back in time", + '--resource-action', + 'revert_to_snapshot', + '--lock-reason', + "you cannot go back in time", self.share.id, 'share', ] @@ -94,7 +101,7 @@ def test_share_lock_create(self): ('resource', self.share.id), ('resource_type', 'share'), ('resource_action', 'revert_to_snapshot'), - ('lock_reason', 'you cannot go back in time') + ('lock_reason', 'you cannot go back in time'), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -113,9 +120,8 @@ def test_share_lock_create(self): class TestResourceLockDelete(TestResourceLock): - def setUp(self): - super(TestResourceLockDelete, self).setUp() + super().setUp() self.lock = manila_fakes.FakeResourceLock.create_one_lock() @@ -128,16 +134,17 @@ def test_share_lock_delete_missing_args(self): arglist = [] verifylist = [] - self.assertRaises(osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_lock_delete(self): - arglist = [ - self.lock.id - ] - verifylist = [ - ('lock', [self.lock.id]) - ] + arglist = [self.lock.id] + verifylist = [('lock', [self.lock.id])] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -148,41 +155,30 @@ def test_share_lock_delete(self): def test_share_lock_delete_multiple(self): locks = manila_fakes.FakeResourceLock.create_locks(count=2) - arglist = [ - locks[0].id, - locks[1].id - ] - verifylist = [ - ('lock', [locks[0].id, locks[1].id]) - ] + arglist = [locks[0].id, locks[1].id] + verifylist = [('lock', [locks[0].id, locks[1].id])] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - self.assertEqual(self.lock.delete.call_count, - len(locks)) + self.assertEqual(self.lock.delete.call_count, len(locks)) self.assertIsNone(result) def test_share_lock_delete_exception(self): - arglist = [ - self.lock.id - ] - verifylist = [ - ('lock', [self.lock.id]) - ] + arglist = [self.lock.id] + verifylist = [('lock', [self.lock.id])] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.lock.delete.side_effect = exceptions.CommandError() - self.assertRaises(exceptions.CommandError, - self.cmd.take_action, - parsed_args) + self.assertRaises( + exceptions.CommandError, self.cmd.take_action, parsed_args + ) class TestResourceLockShow(TestResourceLock): - def setUp(self): - super(TestResourceLockShow, self).setUp() + super().setUp() self.lock = manila_fakes.FakeResourceLock.create_one_lock() self.locks_mock.get.return_value = self.lock @@ -196,16 +192,19 @@ def test_share_lock_show_missing_args(self): arglist = [] verifylist = [] - self.assertRaises(osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_lock_show(self): arglist = [ self.lock.id, ] - verifylist = [ - ('lock', self.lock.id) - ] + verifylist = [('lock', self.lock.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) @@ -216,26 +215,23 @@ def test_share_lock_show(self): class TestResourceLockList(TestResourceLock): - def setUp(self): - super(TestResourceLockList, self).setUp() + super().setUp() self.locks = manila_fakes.FakeResourceLock.create_locks(count=2) self.locks_mock.list.return_value = self.locks - self.values = (oscutils.get_dict_properties( - m._info, DETAIL_COLUMNS) for m in self.locks) + self.values = ( + oscutils.get_dict_properties(m._info, DETAIL_COLUMNS) + for m in self.locks + ) self.cmd = osc_resource_locks.ListResourceLock(self.app, None) def test_share_lock_list(self): - arglist = [ - '--detailed' - ] - verifylist = [ - ('detailed', True) - ] + arglist = ['--detailed'] + verifylist = [('detailed', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -257,7 +253,7 @@ def test_share_lock_list(self): 'offset': None, }, sort_key=None, - sort_dir=None + sort_dir=None, ) self.assertEqual(sorted(DETAIL_COLUMNS), sorted(columns)) @@ -267,9 +263,8 @@ def test_share_lock_list(self): class TestResourceLockSet(TestResourceLock): - def setUp(self): - super(TestResourceLockSet, self).setUp() + super().setUp() self.lock = manila_fakes.FakeResourceLock.create_one_lock() self.lock.update = mock.Mock() @@ -282,32 +277,35 @@ def test_share_lock_set_missing_args(self): arglist = [] verifylist = [] - self.assertRaises(osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_lock_set(self): arglist = [ self.lock.id, - '--resource-action', 'unmanage', - ] - verifylist = [ - ('lock', self.lock.id), - ('resource_action', 'unmanage') + '--resource-action', + 'unmanage', ] + verifylist = [('lock', self.lock.id), ('resource_action', 'unmanage')] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.assertIsNone(result) - self.locks_mock.update.assert_called_with(self.lock.id, - resource_action='unmanage') + self.locks_mock.update.assert_called_with( + self.lock.id, resource_action='unmanage' + ) class TestResourceLockUnSet(TestResourceLock): - def setUp(self): - super(TestResourceLockUnSet, self).setUp() + super().setUp() self.lock = manila_fakes.FakeResourceLock.create_one_lock() self.lock.update = mock.Mock() @@ -320,23 +318,23 @@ def test_share_lock_unset_missing_args(self): arglist = [] verifylist = [] - self.assertRaises(osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_lock_unset(self): - arglist = [ - self.lock.id, - '--lock-reason' - ] - verifylist = [ - ('lock', self.lock.id), - ('lock_reason', True) - ] + arglist = [self.lock.id, '--lock-reason'] + verifylist = [('lock', self.lock.id), ('lock_reason', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.assertIsNone(result) - self.locks_mock.update.assert_called_with(self.lock.id, - lock_reason=None) + self.locks_mock.update.assert_called_with( + self.lock.id, lock_reason=None + ) diff --git a/manilaclient/tests/unit/osc/v2/test_security_services.py b/manilaclient/tests/unit/osc/v2/test_security_services.py index 7b6a0e11..b41cb6bd 100644 --- a/manilaclient/tests/unit/osc/v2/test_security_services.py +++ b/manilaclient/tests/unit/osc/v2/test_security_services.py @@ -21,12 +21,12 @@ class TestShareSecurityService(manila_fakes.TestShare): - def setUp(self): - super(TestShareSecurityService, self).setUp() + super().setUp() self.security_services_mock = ( - self.app.client_manager.share.security_services) + self.app.client_manager.share.security_services + ) self.security_services_mock.reset_mock() self.share_networks_mock = self.app.client_manager.share.share_networks @@ -39,15 +39,14 @@ def setUp(self): @ddt.ddt class TestShareSecurityServiceCreate(TestShareSecurityService): - def setUp(self): - super(TestShareSecurityServiceCreate, self).setUp() + super().setUp() - self.security_service = manila_fakes.FakeShareSecurityService \ - .create_fake_security_service() + self.security_service = manila_fakes.FakeShareSecurityService.create_fake_security_service() self.security_services_mock.create.return_value = self.security_service self.cmd = osc_security_services.CreateShareSecurityService( - self.app, None) + self.app, None + ) self.data = self.security_service._info.values() self.columns = self.security_service._info.keys() @@ -56,21 +55,35 @@ def test_share_security_service_create_missing_args(self): arglist = [] verifylist = [] - self.assertRaises(osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_security_service_create(self): arglist = [ self.security_service.type, - '--dns-ip', self.security_service.dns_ip, - '--ou', self.security_service.ou, - '--server', self.security_service.server, - '--domain', self.security_service.domain, - '--user', self.security_service.user, - '--password', self.security_service.password, - '--name', self.security_service.name, - '--description', self.security_service.description, - '--default-ad-site', self.security_service.default_ad_site + '--dns-ip', + self.security_service.dns_ip, + '--ou', + self.security_service.ou, + '--server', + self.security_service.server, + '--domain', + self.security_service.domain, + '--user', + self.security_service.user, + '--password', + self.security_service.password, + '--name', + self.security_service.name, + '--description', + self.security_service.description, + '--default-ad-site', + self.security_service.default_ad_site, ] verifylist = [ ('type', self.security_service.type), @@ -82,7 +95,7 @@ def test_share_security_service_create(self): ('password', self.security_service.password), ('name', self.security_service.name), ('description', self.security_service.description), - ('default_ad_site', self.security_service.default_ad_site) + ('default_ad_site', self.security_service.default_ad_site), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -98,15 +111,16 @@ def test_share_security_service_create(self): name=self.security_service.name, description=self.security_service.description, ou=self.security_service.ou, - default_ad_site=self.security_service.default_ad_site + default_ad_site=self.security_service.default_ad_site, ) self.assertCountEqual(self.columns, columns) self.assertCountEqual(self.data, data) @ddt.data('2.43', '2.75') - def test_share_security_service_create_api_version_exception(self, - version): + def test_share_security_service_create_api_version_exception( + self, version + ): self.app.client_manager.share.api_version = api_versions.APIVersion( version ) @@ -123,37 +137,43 @@ def test_share_security_service_create_api_version_exception(self, verifylist.append(('ou', self.security_service.ou)) if api_versions.APIVersion(version) <= api_versions.APIVersion("2.75"): - arglist.extend(['--default-ad-site', - self.security_service.default_ad_site]) - verifylist.append(('default_ad_site', - self.security_service.default_ad_site)) + arglist.extend( + ['--default-ad-site', self.security_service.default_ad_site] + ) + verifylist.append( + ('default_ad_site', self.security_service.default_ad_site) + ) parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( - exceptions.CommandError, self.cmd.take_action, parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) class TestShareSecurityServiceDelete(TestShareSecurityService): - def setUp(self): - super(TestShareSecurityServiceDelete, self).setUp() + super().setUp() - self.security_service = manila_fakes.FakeShareSecurityService \ - .create_fake_security_service() + self.security_service = manila_fakes.FakeShareSecurityService.create_fake_security_service() self.security_services_mock.get.return_value = self.security_service - self.security_services = manila_fakes.FakeShareSecurityService \ - .create_fake_security_services() + self.security_services = manila_fakes.FakeShareSecurityService.create_fake_security_services() self.cmd = osc_security_services.DeleteShareSecurityService( - self.app, None) + self.app, None + ) def test_share_security_service_delete_missing_args(self): arglist = [] verifylist = [] - self.assertRaises(osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_security_service_delete(self): arglist = [ @@ -161,15 +181,19 @@ def test_share_security_service_delete(self): self.security_services[1].id, ] verifylist = [ - ('security_service', [self.security_services[0].id, - self.security_services[1].id]), + ( + 'security_service', + [self.security_services[0].id, self.security_services[1].id], + ), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - self.assertEqual(self.security_services_mock.delete.call_count, - len(self.security_services)) + self.assertEqual( + self.security_services_mock.delete.call_count, + len(self.security_services), + ) self.assertIsNone(result) def test_share_security_service_delete_exception(self): @@ -182,24 +206,24 @@ def test_share_security_service_delete_exception(self): parsed_args = self.check_parser(self.cmd, arglist, verifylist) - self.security_services_mock.delete.side_effect = \ + self.security_services_mock.delete.side_effect = ( exceptions.CommandError() - self.assertRaises(exceptions.CommandError, - self.cmd.take_action, - parsed_args) + ) + self.assertRaises( + exceptions.CommandError, self.cmd.take_action, parsed_args + ) class TestShareSecurityServiceShow(TestShareSecurityService): - def setUp(self): - super(TestShareSecurityServiceShow, self).setUp() + super().setUp() - self.security_service = manila_fakes.FakeShareSecurityService \ - .create_fake_security_service() + self.security_service = manila_fakes.FakeShareSecurityService.create_fake_security_service() self.security_services_mock.get.return_value = self.security_service self.cmd = osc_security_services.ShowShareSecurityService( - self.app, None) + self.app, None + ) self.data = self.security_service._info.values() self.columns = self.security_service._info.keys() @@ -208,16 +232,17 @@ def test_share_security_service_show_missing_args(self): arglist = [] verifylist = [] - self.assertRaises(osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_security_service_show(self): - arglist = [ - self.security_service.id - ] - verifylist = [ - ('security_service', self.security_service.id) - ] + arglist = [self.security_service.id] + verifylist = [('security_service', self.security_service.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) @@ -232,35 +257,52 @@ def test_share_security_service_show(self): @ddt.ddt class TestShareSecurityServiceSet(TestShareSecurityService): - def setUp(self): - super(TestShareSecurityServiceSet, self).setUp() + super().setUp() - self.security_service = manila_fakes.FakeShareSecurityService \ - .create_fake_security_service(methods={'update': None}) + self.security_service = ( + manila_fakes.FakeShareSecurityService.create_fake_security_service( + methods={'update': None} + ) + ) self.security_services_mock.get.return_value = self.security_service self.cmd = osc_security_services.SetShareSecurityService( - self.app, None) + self.app, None + ) def test_share_security_service_set_missing_args(self): arglist = [] verifylist = [] - self.assertRaises(osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_security_service_set(self): arglist = [ self.security_service.id, - '--dns-ip', self.security_service.dns_ip, - '--ou', self.security_service.ou, - '--server', self.security_service.server, - '--domain', self.security_service.domain, - '--user', self.security_service.user, - '--password', self.security_service.password, - '--name', self.security_service.name, - '--description', self.security_service.description, - '--default-ad-site', self.security_service.default_ad_site + '--dns-ip', + self.security_service.dns_ip, + '--ou', + self.security_service.ou, + '--server', + self.security_service.server, + '--domain', + self.security_service.domain, + '--user', + self.security_service.user, + '--password', + self.security_service.password, + '--name', + self.security_service.name, + '--description', + self.security_service.description, + '--default-ad-site', + self.security_service.default_ad_site, ] verifylist = [ ('security_service', self.security_service.id), @@ -272,7 +314,7 @@ def test_share_security_service_set(self): ('password', self.security_service.password), ('name', self.security_service.name), ('description', self.security_service.description), - ('default_ad_site', self.security_service.default_ad_site) + ('default_ad_site', self.security_service.default_ad_site), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -294,7 +336,8 @@ def test_share_security_service_set(self): def test_share_security_service_set_exception(self): arglist = [ self.security_service.id, - '--name', self.security_service.name, + '--name', + self.security_service.name, ] verifylist = [ ('security_service', self.security_service.id), @@ -303,10 +346,10 @@ def test_share_security_service_set_exception(self): parsed_args = self.check_parser(self.cmd, arglist, verifylist) - self.security_service.update.side_effect = \ - exceptions.CommandError() + self.security_service.update.side_effect = exceptions.CommandError() self.assertRaises( - exceptions.CommandError, self.cmd.take_action, parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) @ddt.data('2.43', '2.75') def test_share_security_service_set_api_version_exception(self, version): @@ -326,34 +369,45 @@ def test_share_security_service_set_api_version_exception(self, version): verifylist.append(('ou', self.security_service.ou)) if api_versions.APIVersion(version) <= api_versions.APIVersion("2.75"): - arglist.extend(['--default-ad-site', - self.security_service.default_ad_site]) - verifylist.append(('default_ad_site', - self.security_service.default_ad_site)) + arglist.extend( + ['--default-ad-site', self.security_service.default_ad_site] + ) + verifylist.append( + ('default_ad_site', self.security_service.default_ad_site) + ) parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( - exceptions.CommandError, self.cmd.take_action, parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) @ddt.ddt class TestShareSecurityServiceUnset(TestShareSecurityService): - def setUp(self): - super(TestShareSecurityServiceUnset, self).setUp() + super().setUp() - self.security_service = manila_fakes.FakeShareSecurityService \ - .create_fake_security_service(methods={'update': None}) + self.security_service = ( + manila_fakes.FakeShareSecurityService.create_fake_security_service( + methods={'update': None} + ) + ) self.security_services_mock.get.return_value = self.security_service self.cmd = osc_security_services.UnsetShareSecurityService( - self.app, None) + self.app, None + ) def test_share_security_service_unset_missing_args(self): arglist = [] verifylist = [] - self.assertRaises(osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_security_service_unset(self): arglist = [ @@ -378,7 +432,7 @@ def test_share_security_service_unset(self): ('password', True), ('name', True), ('description', True), - ('default_ad_site', True) + ('default_ad_site', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -393,7 +447,7 @@ def test_share_security_service_unset(self): name='', description='', ou='', - default_ad_site='' + default_ad_site='', ) self.assertIsNone(result) @@ -409,14 +463,13 @@ def test_share_security_service_unset_exception(self): parsed_args = self.check_parser(self.cmd, arglist, verifylist) - self.security_service.update.side_effect = \ - exceptions.CommandError() + self.security_service.update.side_effect = exceptions.CommandError() self.assertRaises( - exceptions.CommandError, self.cmd.take_action, parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) @ddt.data('2.43', '2.75') - def test_share_security_service_unset_api_version_exception(self, - version): + def test_share_security_service_unset_api_version_exception(self, version): self.app.client_manager.share.api_version = api_versions.APIVersion( version ) @@ -433,16 +486,16 @@ def test_share_security_service_unset_api_version_exception(self, verifylist.append(('ou', True)) if api_versions.APIVersion(version) <= api_versions.APIVersion("2.75"): - arglist.extend(['--default-ad-site']), + (arglist.extend(['--default-ad-site']),) verifylist.append(('default_ad_site', True)) parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( - exceptions.CommandError, self.cmd.take_action, parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) class TestShareSecurityServiceList(TestShareSecurityService): - columns = [ 'ID', 'Name', @@ -451,19 +504,22 @@ class TestShareSecurityServiceList(TestShareSecurityService): ] def setUp(self): - super(TestShareSecurityServiceList, self).setUp() + super().setUp() self.share_network = ( - manila_fakes.FakeShareNetwork.create_one_share_network()) + manila_fakes.FakeShareNetwork.create_one_share_network() + ) self.share_networks_mock.get.return_value = self.share_network - self.services_list = manila_fakes.FakeShareSecurityService \ - .create_fake_security_services() + self.services_list = manila_fakes.FakeShareSecurityService.create_fake_security_services() self.security_services_mock.list.return_value = self.services_list - self.values = (oscutils.get_dict_properties( - i._info, self.columns) for i in self.services_list) + self.values = ( + oscutils.get_dict_properties(i._info, self.columns) + for i in self.services_list + ) self.cmd = osc_security_services.ListShareSecurityService( - self.app, None) + self.app, None + ) def test_share_security_service_list_no_args(self): arglist = [] @@ -485,23 +541,35 @@ def test_share_security_service_list_no_args(self): 'offset': None, 'limit': None, }, - detailed=False) + detailed=False, + ) self.assertEqual(self.columns, columns) self.assertEqual(list(self.values), list(data)) def test_share_security_service_list(self): arglist = [ - '--share-network', self.share_network.id, - '--status', self.services_list[0].status, - '--name', self.services_list[0].name, - '--type', self.services_list[0].type, - '--user', self.services_list[0].user, - '--dns-ip', self.services_list[0].dns_ip, - '--ou', self.services_list[0].ou, - '--server', self.services_list[0].server, - '--domain', self.services_list[0].domain, - '--default-ad-site', self.services_list[0].default_ad_site, - '--limit', '1', + '--share-network', + self.share_network.id, + '--status', + self.services_list[0].status, + '--name', + self.services_list[0].name, + '--type', + self.services_list[0].type, + '--user', + self.services_list[0].user, + '--dns-ip', + self.services_list[0].dns_ip, + '--ou', + self.services_list[0].ou, + '--server', + self.services_list[0].server, + '--domain', + self.services_list[0].domain, + '--default-ad-site', + self.services_list[0].default_ad_site, + '--limit', + '1', ] verifylist = [ ('share_network', self.share_network.id), @@ -536,7 +604,8 @@ def test_share_security_service_list(self): 'ou': self.services_list[0].ou, 'share_network_id': self.share_network.id, }, - detailed=False) + detailed=False, + ) self.assertEqual(self.columns, columns) self.assertEqual(list(self.values), list(data)) @@ -546,7 +615,8 @@ def test_share_security_service_list_ou_api_version_exception(self): '2.43' ) arglist = [ - '--ou', self.services_list[0].ou, + '--ou', + self.services_list[0].ou, ] verifylist = [ ('ou', self.services_list[0].ou), @@ -554,14 +624,16 @@ def test_share_security_service_list_ou_api_version_exception(self): parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( - exceptions.CommandError, self.cmd.take_action, parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_share_security_service_list_ad_site_api_version_exception(self): self.app.client_manager.share.api_version = api_versions.APIVersion( '2.75' ) arglist = [ - '--default-ad-site', self.services_list[0].default_ad_site, + '--default-ad-site', + self.services_list[0].default_ad_site, ] verifylist = [ ('default_ad_site', self.services_list[0].default_ad_site), @@ -569,13 +641,11 @@ def test_share_security_service_list_ad_site_api_version_exception(self): parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( - exceptions.CommandError, self.cmd.take_action, parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_share_security_service_list_detail_all_projects(self): - arglist = [ - '--all-projects', - '--detail' - ] + arglist = ['--all-projects', '--detail'] verifylist = [ ('all_projects', True), ('detail', True), @@ -584,8 +654,10 @@ def test_share_security_service_list_detail_all_projects(self): columns_detail.append('Project ID') columns_detail.append('Share Networks') - values_detail = (oscutils.get_dict_properties( - i._info, columns_detail) for i in self.services_list) + values_detail = ( + oscutils.get_dict_properties(i._info, columns_detail) + for i in self.services_list + ) parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -604,6 +676,7 @@ def test_share_security_service_list_detail_all_projects(self): 'offset': None, 'limit': None, }, - detailed=True) + detailed=True, + ) self.assertEqual(columns_detail, columns) self.assertEqual(list(values_detail), list(data)) diff --git a/manilaclient/tests/unit/osc/v2/test_services.py b/manilaclient/tests/unit/osc/v2/test_services.py index f1525b9b..a7956f82 100644 --- a/manilaclient/tests/unit/osc/v2/test_services.py +++ b/manilaclient/tests/unit/osc/v2/test_services.py @@ -21,18 +21,16 @@ class TestShareService(manila_fakes.TestShare): - def setUp(self): - super(TestShareService, self).setUp() + super().setUp() self.services_mock = self.app.client_manager.share.services self.services_mock.reset_mock() class TestShareServiceSet(TestShareService): - def setUp(self): - super(TestShareServiceSet, self).setUp() + super().setUp() self.share_service = ( manila_fakes.FakeShareService.create_fake_service() @@ -43,68 +41,69 @@ def test_share_service_set_enable(self): arglist = [ self.share_service.host, self.share_service.binary, - '--enable' + '--enable', ] verifylist = [ ('host', self.share_service.host), ('binary', self.share_service.binary), - ('enable', True) + ('enable', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.services_mock.enable.assert_called_with( - self.share_service.host, - self.share_service.binary) + self.share_service.host, self.share_service.binary + ) self.assertIsNone(result) def test_share_service_set_enable_exception(self): arglist = [ self.share_service.host, self.share_service.binary, - '--enable' + '--enable', ] verifylist = [ ('host', self.share_service.host), ('binary', self.share_service.binary), - ('enable', True) + ('enable', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.services_mock.enable.side_effect = Exception() self.assertRaises( - exceptions.CommandError, - self.cmd.take_action, - parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_share_service_set_disable(self): arglist = [ self.share_service.host, self.share_service.binary, - '--disable' + '--disable', ] verifylist = [ ('host', self.share_service.host), ('binary', self.share_service.binary), - ('disable', True) + ('disable', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.services_mock.disable.assert_called_with( - self.share_service.host, - self.share_service.binary) + self.share_service.host, self.share_service.binary + ) self.assertIsNone(result) def test_service_set_disable_with_reason(self): self.app.client_manager.share.api_version = api_versions.APIVersion( - "2.83") + "2.83" + ) reason = 'earthquake' arglist = [ '--disable', - '--disable-reason', reason, + '--disable-reason', + reason, self.share_service.host, self.share_service.binary, ] @@ -121,7 +120,7 @@ def test_service_set_disable_with_reason(self): self.services_mock.disable.assert_called_with( self.share_service.host, self.share_service.binary, - disable_reason=reason + disable_reason=reason, ) self.assertIsNone(result) @@ -129,59 +128,56 @@ def test_share_service_set_disable_exception(self): arglist = [ self.share_service.host, self.share_service.binary, - '--disable' + '--disable', ] verifylist = [ ('host', self.share_service.host), ('binary', self.share_service.binary), - ('disable', True) + ('disable', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.services_mock.disable.side_effect = Exception() self.assertRaises( - exceptions.CommandError, - self.cmd.take_action, - parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) @ddt.ddt class TestShareServiceList(TestShareService): - - columns = [ - 'id', - 'binary', - 'host', - 'zone', - 'status', - 'state', - 'updated_at' - ] + columns = ['id', 'binary', 'host', 'zone', 'status', 'state', 'updated_at'] columns_with_reason = columns + ['disabled_reason'] column_headers = utils.format_column_headers(columns) column_headers_with_reason = utils.format_column_headers( - columns_with_reason) + columns_with_reason + ) def setUp(self): - super(TestShareServiceList, self).setUp() + super().setUp() self.services_list = ( manila_fakes.FakeShareService.create_fake_services( - {'disabled_reason': ''}) + {'disabled_reason': ''} + ) ) self.services_mock.list.return_value = self.services_list - self.values = (oscutils.get_dict_properties( - i._info, self.columns) for i in self.services_list) - self.values_with_reason = (oscutils.get_dict_properties( - i._info, self.columns_with_reason) for i in self.services_list) + self.values = ( + oscutils.get_dict_properties(i._info, self.columns) + for i in self.services_list + ) + self.values_with_reason = ( + oscutils.get_dict_properties(i._info, self.columns_with_reason) + for i in self.services_list + ) self.cmd = osc_services.ListShareService(self.app, None) @ddt.data('2.82', '2.83') def test_share_service_list(self, version): self.app.client_manager.share.api_version = api_versions.APIVersion( - version) + version + ) arglist = [] verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -194,8 +190,9 @@ def test_share_service_list(self, version): 'binary': None, 'status': None, 'state': None, - 'zone': None - }) + 'zone': None, + } + ) if api_versions.APIVersion(version) >= api_versions.APIVersion("2.83"): self.assertEqual(self.column_headers_with_reason, columns) self.assertEqual(list(self.values_with_reason), list(data)) @@ -206,14 +203,17 @@ def test_share_service_list(self, version): @ddt.data('2.82', '2.83') def test_share_service_list_host_status(self, version): self.app.client_manager.share.api_version = api_versions.APIVersion( - version) + version + ) arglist = [ - '--host', self.services_list[0].host, - '--status', self.services_list[1].status + '--host', + self.services_list[0].host, + '--status', + self.services_list[1].status, ] verifylist = [ ('host', self.services_list[0].host), - ('status', self.services_list[1].status) + ('status', self.services_list[1].status), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -225,8 +225,9 @@ def test_share_service_list_host_status(self, version): 'binary': None, 'status': self.services_list[1].status, 'state': None, - 'zone': None - }) + 'zone': None, + } + ) if api_versions.APIVersion(version) >= api_versions.APIVersion("2.83"): self.assertEqual(self.column_headers_with_reason, columns) self.assertEqual(list(self.values_with_reason), list(data)) @@ -237,16 +238,20 @@ def test_share_service_list_host_status(self, version): @ddt.data('2.82', '2.83') def test_share_service_list_binary_state_zone(self, version): self.app.client_manager.share.api_version = api_versions.APIVersion( - version) + version + ) arglist = [ - '--binary', self.services_list[0].binary, - '--state', self.services_list[1].state, - '--zone', self.services_list[1].zone + '--binary', + self.services_list[0].binary, + '--state', + self.services_list[1].state, + '--zone', + self.services_list[1].zone, ] verifylist = [ ('binary', self.services_list[0].binary), ('state', self.services_list[1].state), - ('zone', self.services_list[1].zone) + ('zone', self.services_list[1].zone), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -258,8 +263,9 @@ def test_share_service_list_binary_state_zone(self, version): 'binary': self.services_list[0].binary, 'status': None, 'state': self.services_list[1].state, - 'zone': self.services_list[1].zone - }) + 'zone': self.services_list[1].zone, + } + ) if api_versions.APIVersion(version) >= api_versions.APIVersion("2.83"): self.assertEqual(self.column_headers_with_reason, columns) self.assertEqual(list(self.values_with_reason), list(data)) @@ -270,15 +276,15 @@ def test_share_service_list_binary_state_zone(self, version): @ddt.ddt class TestShareServiceEnsureShares(TestShareService): - def setUp(self): - super(TestShareServiceEnsureShares, self).setUp() + super().setUp() self.cmd = osc_services.EnsureShareService(self.app, None) def test_ensure_shares(self): self.app.client_manager.share.api_version = api_versions.APIVersion( - '2.86') + '2.86' + ) fake_host = 'fake_host@fakebackend' arglist = [ fake_host, @@ -294,7 +300,8 @@ def test_ensure_shares(self): def test_ensure_shares_invalid_version(self): self.app.client_manager.share.api_version = api_versions.APIVersion( - '2.85') + '2.85' + ) fake_host = 'fake_host@fakebackend' arglist = [ fake_host, @@ -304,13 +311,14 @@ def test_ensure_shares_invalid_version(self): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - self.assertRaises(exceptions.CommandError, - self.cmd.take_action, - parsed_args) + self.assertRaises( + exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_ensure_shares_command_error(self): self.app.client_manager.share.api_version = api_versions.APIVersion( - '2.86') + '2.86' + ) self.services_mock.ensure_shares.side_effect = Exception() fake_host = 'fake_host@fakebackend' arglist = [ @@ -321,6 +329,6 @@ def test_ensure_shares_command_error(self): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - self.assertRaises(exceptions.CommandError, - self.cmd.take_action, - parsed_args) + self.assertRaises( + exceptions.CommandError, self.cmd.take_action, parsed_args + ) diff --git a/manilaclient/tests/unit/osc/v2/test_share.py b/manilaclient/tests/unit/osc/v2/test_share.py index ff9cf52c..bd26b48a 100644 --- a/manilaclient/tests/unit/osc/v2/test_share.py +++ b/manilaclient/tests/unit/osc/v2/test_share.py @@ -32,9 +32,8 @@ class TestShare(manila_fakes.TestShare): - def setUp(self): - super(TestShare, self).setUp() + super().setUp() self.shares_mock = self.app.client_manager.share.shares self.shares_mock.reset_mock() @@ -59,14 +58,13 @@ def setUp(self): self.share_networks_mock.reset_mock() self.app.client_manager.share.api_version = api_versions.APIVersion( - MAX_VERSION) + MAX_VERSION + ) def setup_shares_mock(self, count): shares = manila_fakes.FakeShare.create_shares(count=count) - self.shares_mock.get = manila_fakes.FakeShare.get_shares( - shares, - 0) + self.shares_mock.get = manila_fakes.FakeShare.get_shares(shares, 0) return shares def setup_share_groups_mock(self): @@ -80,9 +78,8 @@ def setup_share_groups_mock(self): @ddt.ddt class TestShareCreate(TestShare): - def setUp(self): - super(TestShareCreate, self).setUp() + super().setUp() self.new_share = manila_fakes.FakeShare.create_one_share( attrs={'status': 'available'} @@ -91,7 +88,8 @@ def setUp(self): self.shares_mock.get.return_value = self.new_share self.share_snapshot = ( - manila_fakes.FakeShareSnapshot.create_one_snapshot()) + manila_fakes.FakeShareSnapshot.create_one_snapshot() + ) self.snapshots_mock.get.return_value = self.share_snapshot self.share_type = manila_fakes.FakeShareType.create_one_sharetype() self.share_types_mock.get.return_value = self.share_type @@ -108,12 +106,13 @@ def test_share_create_required_args(self): arglist = [ self.new_share.share_proto, str(self.new_share.size), - '--share-type', self.share_type.id, + '--share-type', + self.share_type.id, ] verifylist = [ ('share_proto', self.new_share.share_proto), ('size', self.new_share.size), - ('share_type', self.share_type.id) + ('share_type', self.share_type.id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -145,19 +144,25 @@ def test_share_create_missing_required_arg(self): arglist = [ self.new_share.share_proto, ] - verifylist = [ - ('share_proto', self.new_share.share_proto) - ] - self.assertRaises(osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + verifylist = [('share_proto', self.new_share.share_proto)] + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_create_metadata(self): arglist = [ self.new_share.share_proto, str(self.new_share.size), - '--share-type', self.share_type.id, - '--property', 'Manila=zorilla', - '--property', 'Zorilla=manila' + '--share-type', + self.share_type.id, + '--property', + 'Manila=zorilla', + '--property', + 'Zorilla=manila', ] verifylist = [ ('share_proto', self.new_share.share_proto), @@ -192,7 +197,8 @@ def test_share_create_metadata(self): def test_share_create_scheduler_hints(self): """Verifies scheduler hints are parsed correctly.""" self.app.client_manager.share.api_version = api_versions.APIVersion( - "2.65") + "2.65" + ) shares = self.setup_shares_mock(count=2) share1_name = shares[0].name @@ -201,16 +207,21 @@ def test_share_create_scheduler_hints(self): arglist = [ self.new_share.share_proto, str(self.new_share.size), - '--share-type', self.share_type.id, - '--scheduler-hint', ('same_host=%s' % share1_name), - '--scheduler-hint', ('different_host=%s' % share2_name), + '--share-type', + self.share_type.id, + '--scheduler-hint', + (f'same_host={share1_name}'), + '--scheduler-hint', + (f'different_host={share2_name}'), ] verifylist = [ ('share_proto', self.new_share.share_proto), ('size', self.new_share.size), ('share_type', self.share_type.id), - ('scheduler_hint', - {'same_host': share1_name, 'different_host': share2_name}), + ( + 'scheduler_hint', + {'same_host': share1_name, 'different_host': share2_name}, + ), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -228,8 +239,10 @@ def test_share_create_scheduler_hints(self): share_type=self.share_type.id, size=self.new_share.size, snapshot_id=None, - scheduler_hints={'same_host': shares[0].id, - 'different_host': shares[1].id}, + scheduler_hints={ + 'same_host': shares[0].id, + 'different_host': shares[1].id, + }, mount_point_name=None, encryption_key_ref=None, ) @@ -240,15 +253,18 @@ def test_share_create_scheduler_hints(self): def test_share_create_mount_point_name(self): """Verifies that the mount point name has been passed correctly.""" self.app.client_manager.share.api_version = api_versions.APIVersion( - "2.84") + "2.84" + ) mount_point_name = "fake_mp" arglist = [ self.new_share.share_proto, str(self.new_share.size), - '--share-type', self.share_type.id, - '--mount-point-name', mount_point_name, + '--share-type', + self.share_type.id, + '--mount-point-name', + mount_point_name, ] verifylist = [ ('share_proto', self.new_share.share_proto), @@ -282,15 +298,18 @@ def test_share_create_mount_point_name(self): def test_share_create_encryption_key_ref(self): self.app.client_manager.share.api_version = api_versions.APIVersion( - "2.90") + "2.90" + ) encryption_key_ref = 'fake_ekr' arglist = [ self.new_share.share_proto, str(self.new_share.size), - '--share-type', self.share_type.id, - '--encryption-key-ref', encryption_key_ref, + '--share-type', + self.share_type.id, + '--encryption-key-ref', + encryption_key_ref, ] verifylist = [ ('share_proto', self.new_share.share_proto), @@ -328,24 +347,26 @@ def test_share_create_with_snapshot(self): arglist = [ self.new_share.share_proto, str(self.new_share.size), - '--snapshot-id', self.share_snapshot.id - + '--snapshot-id', + self.share_snapshot.id, ] verifylist = [ ('share_proto', self.new_share.share_proto), ('size', self.new_share.size), - ('snapshot_id', self.share_snapshot.id) + ('snapshot_id', self.share_snapshot.id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) with mock.patch( - 'manilaclient.common.apiclient.utils.find_resource', - mock.Mock(return_value=self.share_snapshot)): + 'manilaclient.common.apiclient.utils.find_resource', + mock.Mock(return_value=self.share_snapshot), + ): columns, data = self.cmd.take_action(parsed_args) osc_shares.apiutils.find_resource.assert_called_once_with( - mock.ANY, self.share_snapshot.id) + mock.ANY, self.share_snapshot.id + ) self.shares_mock.create.assert_called_with( availability_zone=None, @@ -367,18 +388,18 @@ def test_share_create_with_snapshot(self): self.assertCountEqual(self.datalist, data) def test_share_create_wait(self): - arglist = [ self.new_share.share_proto, str(self.new_share.size), - '--share-type', self.share_type.id, - '--wait' + '--share-type', + self.share_type.id, + '--wait', ] verifylist = [ ('share_proto', self.new_share.share_proto), ('size', self.new_share.size), ('share_type', self.share_type.id), - ('wait', True) + ('wait', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -408,18 +429,18 @@ def test_share_create_wait(self): @mock.patch('manilaclient.osc.v2.share.LOG') def test_share_create_wait_error(self, mock_logger): - arglist = [ self.new_share.share_proto, str(self.new_share.size), - '--share-type', self.share_type.id, - '--wait' + '--share-type', + self.share_type.id, + '--wait', ] verifylist = [ ('share_proto', self.new_share.share_proto), ('size', self.new_share.size), ('share_type', self.share_type.id), - ('wait', True) + ('wait', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -445,7 +466,8 @@ def test_share_create_wait_error(self, mock_logger): ) mock_logger.error.assert_called_with( - "ERROR: Share is in error state.") + "ERROR: Share is in error state." + ) self.shares_mock.get.assert_called_with(self.new_share.id) self.assertCountEqual(self.columns, columns) @@ -465,19 +487,19 @@ def test_create_share_with_no_existing_share_type(self): self.share_types_mock.get.side_effect = osc_exceptions.CommandError() self.assertRaises( - osc_exceptions.CommandError, - self.cmd.take_action, - parsed_args) - self.share_types_mock.get.assert_called_once_with( - share_type='default') + osc_exceptions.CommandError, self.cmd.take_action, parsed_args + ) + self.share_types_mock.get.assert_called_once_with(share_type='default') @ddt.data('None', 'NONE', 'none') def test_create_share_with_the_name_none(self, name): arglist = [ - '--name', name, + '--name', + name, self.new_share.share_proto, str(self.new_share.size), - '--share-type', self.share_type.id, + '--share-type', + self.share_type.id, ] verifylist = [ ('name', name), @@ -489,15 +511,13 @@ def test_create_share_with_the_name_none(self, name): parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( - exceptions.CommandError, - self.cmd.take_action, - parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) class TestShareDelete(TestShare): - def setUp(self): - super(TestShareDelete, self).setUp() + super().setUp() self.shares_mock.delete = mock.Mock() self.shares_mock.delete.return_value = None @@ -508,13 +528,11 @@ def setUp(self): def test_share_delete_one(self): shares = self.setup_shares_mock(count=1) - arglist = [ - shares[0].name - ] + arglist = [shares[0].name] verifylist = [ ("force", False), ("share_group", None), - ('shares', [shares[0].name]) + ('shares', [shares[0].name]), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -546,20 +564,18 @@ def test_share_delete_with_share_group(self): shares = self.setup_shares_mock(count=1) share_group = self.setup_share_groups_mock() - arglist = [ - shares[0].name, - '--share-group', share_group['id'] - ] + arglist = [shares[0].name, '--share-group', share_group['id']] verifylist = [ ("share_group", share_group['id']), - ('shares', [shares[0].name]) + ('shares', [shares[0].name]), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.shares_mock.delete.assert_called_with( - shares[0], share_group['id']) + shares[0], share_group['id'] + ) self.assertIsNone(result) def test_share_delete_with_force(self): @@ -607,13 +623,11 @@ def test_share_delete_with_soft(self): def test_share_delete_wrong_name(self): shares = self.setup_shares_mock(count=1) - arglist = [ - shares[0].name + '-wrong-name' - ] + arglist = [shares[0].name + '-wrong-name'] verifylist = [ ("force", False), ("share_group", None), - ('shares', [shares[0].name + '-wrong-name']) + ('shares', [shares[0].name + '-wrong-name']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -623,33 +637,32 @@ def test_share_delete_wrong_name(self): self.shares_mock.delete.side_effect = exceptions.CommandError() self.assertRaises( - osc_exceptions.CommandError, self.cmd.take_action, parsed_args) + osc_exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_share_delete_no_name(self): # self.setup_shares_mock(count=1) arglist = [] - verifylist = [ - ("force", False), - ("share_group", None), - ('shares', '') - ] + verifylist = [("force", False), ("share_group", None), ('shares', '')] - self.assertRaises(osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_delete_wait(self): shares = self.setup_shares_mock(count=1) - arglist = [ - shares[0].name, - '--wait' - ] + arglist = [shares[0].name, '--wait'] verifylist = [ ("force", False), ("share_group", None), ('shares', [shares[0].name]), - ('wait', True) + ('wait', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -663,29 +676,23 @@ def test_share_delete_wait(self): def test_share_delete_wait_error(self): shares = self.setup_shares_mock(count=1) - arglist = [ - shares[0].name, - '--wait' - ] + arglist = [shares[0].name, '--wait'] verifylist = [ ("force", False), ("share_group", None), ('shares', [shares[0].name]), - ('wait', True) + ('wait', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) with mock.patch('osc_lib.utils.wait_for_delete', return_value=False): self.assertRaises( - osc_exceptions.CommandError, - self.cmd.take_action, - parsed_args + osc_exceptions.CommandError, self.cmd.take_action, parsed_args ) class TestShareList(TestShare): - project = identity_fakes.FakeProject.create_one_project() user = identity_fakes.FakeUser.create_one_user() @@ -698,11 +705,11 @@ class TestShareList(TestShare): 'Is Public', 'Share Type Name', 'Host', - 'Availability Zone' + 'Availability Zone', ] def setUp(self): - super(TestShareList, self).setUp() + super().setUp() self.new_share = manila_fakes.FakeShare.create_one_share() self.shares_mock.list.return_value = [self.new_share] @@ -715,17 +722,19 @@ def setUp(self): self.cmd = osc_shares.ListShare(self.app, None) def _get_data(self): - data = (( - self.new_share.id, - self.new_share.name, - self.new_share.size, - self.new_share.share_proto, - self.new_share.status, - self.new_share.is_public, - self.new_share.share_type_name, - self.new_share.host, - self.new_share.availability_zone, - ),) + data = ( + ( + self.new_share.id, + self.new_share.name, + self.new_share.size, + self.new_share.share_proto, + self.new_share.status, + self.new_share.is_public, + self.new_share.share_type_name, + self.new_share.host, + self.new_share.availability_zone, + ), + ) return data def _get_search_opts(self): @@ -780,7 +789,8 @@ def test_share_list_no_options(self): def test_share_list_project(self): arglist = [ - '--project', self.project.name, + '--project', + self.project.name, ] verifylist = [ ('project', self.project.name), @@ -809,8 +819,10 @@ def test_share_list_project(self): def test_share_list_project_domain(self): arglist = [ - '--project', self.project.name, - '--project-domain', self.project.domain_id, + '--project', + self.project.name, + '--project-domain', + self.project.domain_id, ] verifylist = [ ('project', self.project.name), @@ -840,7 +852,8 @@ def test_share_list_project_domain(self): def test_share_list_user(self): arglist = [ - '--user', self.user.name, + '--user', + self.user.name, ] verifylist = [ ('user', self.user.name), @@ -867,8 +880,10 @@ def test_share_list_user(self): def test_share_list_user_domain(self): arglist = [ - '--user', self.user.name, - '--user-domain', self.user.domain_id, + '--user', + self.user.name, + '--user-domain', + self.user.domain_id, ] verifylist = [ ('user', self.user.name), @@ -897,7 +912,8 @@ def test_share_list_user_domain(self): def test_share_list_name(self): arglist = [ - '--name', self.new_share.name, + '--name', + self.new_share.name, ] verifylist = [ ('long', False), @@ -925,7 +941,8 @@ def test_share_list_name(self): def test_share_list_status(self): arglist = [ - '--status', self.new_share.status, + '--status', + self.new_share.status, ] verifylist = [ ('long', False), @@ -1027,48 +1044,52 @@ def test_share_list_long(self): 'Has Replicas', 'Created At', 'Properties', - 'Encryption Key Ref' + 'Encryption Key Ref', ] self.assertEqual(collist, cmd_columns) - data = (( - self.new_share.id, - self.new_share.name, - self.new_share.size, - self.new_share.share_proto, - self.new_share.status, - self.new_share.is_public, - self.new_share.share_type_name, - self.new_share.availability_zone, - self.new_share.description, - self.new_share.share_network_id, - self.new_share.share_server_id, - self.new_share.share_type, - self.new_share.share_group_id, - self.new_share.host, - self.new_share.user_id, - self.new_share.project_id, - self.new_share.access_rules_status, - self.new_share.snapshot_id, - self.new_share.snapshot_support, - self.new_share.create_share_from_snapshot_support, - self.new_share.mount_snapshot_support, - self.new_share.revert_to_snapshot_support, - self.new_share.task_state, - self.new_share.source_share_group_snapshot_member_id, - self.new_share.replication_type, - self.new_share.has_replicas, - self.new_share.created_at, - self.new_share.metadata, - self.new_share.encryption_key_ref - ),) + data = ( + ( + self.new_share.id, + self.new_share.name, + self.new_share.size, + self.new_share.share_proto, + self.new_share.status, + self.new_share.is_public, + self.new_share.share_type_name, + self.new_share.availability_zone, + self.new_share.description, + self.new_share.share_network_id, + self.new_share.share_server_id, + self.new_share.share_type, + self.new_share.share_group_id, + self.new_share.host, + self.new_share.user_id, + self.new_share.project_id, + self.new_share.access_rules_status, + self.new_share.snapshot_id, + self.new_share.snapshot_support, + self.new_share.create_share_from_snapshot_support, + self.new_share.mount_snapshot_support, + self.new_share.revert_to_snapshot_support, + self.new_share.task_state, + self.new_share.source_share_group_snapshot_member_id, + self.new_share.replication_type, + self.new_share.has_replicas, + self.new_share.created_at, + self.new_share.metadata, + self.new_share.encryption_key_ref, + ), + ) self.assertEqual(data, tuple(cmd_data)) def test_share_list_with_marker_and_limit(self): arglist = [ - "--marker", self.new_share.id, - "--limit", "2", + "--marker", + self.new_share.id, + "--limit", + "2", ] verifylist = [ ('long', False), @@ -1091,25 +1112,31 @@ def test_share_list_with_marker_and_limit(self): data = self._get_data() - self.shares_mock.list.assert_called_once_with( - search_opts=search_opts - ) + self.shares_mock.list.assert_called_once_with(search_opts=search_opts) self.assertEqual(data, tuple(cmd_data)) def test_share_list_negative_limit(self): arglist = [ - "--limit", "-2", + "--limit", + "-2", ] verifylist = [ ("limit", -2), ] - self.assertRaises(osc_utils.ParserException, self.check_parser, - self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_list_name_description_filter(self): arglist = [ - '--name~', self.new_share.name, - '--description~', self.new_share.description, + '--name~', + self.new_share.name, + '--description~', + self.new_share.description, ] verifylist = [ @@ -1137,7 +1164,8 @@ def test_share_list_name_description_filter(self): def test_list_share_soft_deleted_api_version_exception(self): self.app.client_manager.share.api_version = api_versions.APIVersion( - "2.60") + "2.60" + ) arglist = [ '--soft-deleted', ] @@ -1151,15 +1179,16 @@ def test_list_share_soft_deleted_api_version_exception(self): parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( - osc_exceptions.CommandError, - self.cmd.take_action, - parsed_args) + osc_exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_list_share_encryption_key_ref_api_version_exception(self): self.app.client_manager.share.api_version = api_versions.APIVersion( - "2.89") + "2.89" + ) arglist = [ - '--encryption-key-ref', 'fake', + '--encryption-key-ref', + 'fake', ] verifylist = [ ('encryption_key_ref', 'fake'), @@ -1168,17 +1197,19 @@ def test_list_share_encryption_key_ref_api_version_exception(self): parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( - osc_exceptions.CommandError, - self.cmd.take_action, - parsed_args) + osc_exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_list_share_api_version_exception(self): self.app.client_manager.share.api_version = api_versions.APIVersion( - "2.35") + "2.35" + ) arglist = [ - '--name~', 'Name', - '--description~', 'Description', + '--name~', + 'Name', + '--description~', + 'Description', ] verifylist = [ ('name~', 'Name'), @@ -1188,55 +1219,55 @@ def test_list_share_api_version_exception(self): parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( - osc_exceptions.CommandError, - self.cmd.take_action, - parsed_args) + osc_exceptions.CommandError, self.cmd.take_action, parsed_args + ) class TestShareShow(TestShare): - def setUp(self): - super(TestShareShow, self).setUp() + super().setUp() self._share = manila_fakes.FakeShare.create_one_share() self.shares_mock.get.return_value = self._share self._export_location = ( - manila_fakes.FakeShareExportLocation.create_one_export_location()) + manila_fakes.FakeShareExportLocation.create_one_export_location() + ) # Get the command object to test self.cmd = osc_shares.ShowShare(self.app, None) def test_share_show(self): - arglist = [ - self._share.id - ] - verifylist = [ - ("share", self._share.id) - ] + arglist = [self._share.id] + verifylist = [("share", self._share.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) cliutils.convert_dict_list_to_string = mock.Mock() cliutils.convert_dict_list_to_string.return_value = dict( - self._export_location) + self._export_location + ) columns, data = self.cmd.take_action(parsed_args) self.shares_mock.get.assert_called_with(self._share.id) self.assertEqual( sorted(manila_fakes.FakeShare.get_share_columns(self._share)), - sorted(columns)) + sorted(columns), + ) self.assertCountEqual( - manila_fakes.FakeShare.get_share_data(self._share), data) + manila_fakes.FakeShare.get_share_data(self._share), data + ) class TestShareSet(TestShare): - def setUp(self): - super(TestShareSet, self).setUp() + super().setUp() self._share = manila_fakes.FakeShare.create_one_share( - methods={"reset_state": None, "reset_task_state": None, - "set_metadata": None} + methods={ + "reset_state": None, + "reset_task_state": None, + "set_metadata": None, + } ) self.shares_mock.get.return_value = self._share @@ -1245,127 +1276,118 @@ def setUp(self): def test_share_set_property(self): arglist = [ - '--property', 'Zorilla=manila', + '--property', + 'Zorilla=manila', self._share.id, ] verifylist = [ ('property', {'Zorilla': 'manila'}), - ('share', self._share.id) + ('share', self._share.id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) - self._share.set_metadata.assert_called_with( - {'Zorilla': 'manila'}) + self._share.set_metadata.assert_called_with({'Zorilla': 'manila'}) def test_share_set_name(self): new_name = uuid.uuid4().hex arglist = [ - '--name', new_name, + '--name', + new_name, self._share.id, ] - verifylist = [ - ('name', new_name), - ('share', self._share.id) - ] + verifylist = [('name', new_name), ('share', self._share.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) self.shares_mock.update.assert_called_with( - self._share.id, - display_name=parsed_args.name) + self._share.id, display_name=parsed_args.name + ) def test_share_set_description(self): new_description = uuid.uuid4().hex arglist = [ - '--description', new_description, + '--description', + new_description, self._share.id, ] verifylist = [ ('description', new_description), - ('share', self._share.id) + ('share', self._share.id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) self.shares_mock.update.assert_called_with( - self._share.id, - display_description=parsed_args.description) + self._share.id, display_description=parsed_args.description + ) def test_share_set_visibility(self): arglist = [ - '--public', 'true', + '--public', + 'true', self._share.id, ] - verifylist = [ - ('public', 'true'), - ('share', self._share.id) - ] + verifylist = [('public', 'true'), ('share', self._share.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) self.shares_mock.update.assert_called_with( - self._share.id, - is_public='true') + self._share.id, is_public='true' + ) def test_share_set_visibility_exception(self): arglist = [ - '--public', 'not_a_boolean_value', + '--public', + 'not_a_boolean_value', self._share.id, ] verifylist = [ ('public', 'not_a_boolean_value'), - ('share', self._share.id) + ('share', self._share.id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) self.shares_mock.update.assert_called_with( - self._share.id, - is_public='not_a_boolean_value') + self._share.id, is_public='not_a_boolean_value' + ) # '--public' takes only boolean value, would raise a BadRequest self.shares_mock.update.side_effect = exceptions.BadRequest() self.assertRaises( - osc_exceptions.CommandError, self.cmd.take_action, parsed_args) + osc_exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_share_set_property_exception(self): arglist = [ - '--property', 'key=', + '--property', + 'key=', self._share.id, ] - verifylist = [ - ('property', {'key': ''}), - ('share', self._share.id) - ] + verifylist = [('property', {'key': ''}), ('share', self._share.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) - self._share.set_metadata.assert_called_with( - {'key': ''}) + self._share.set_metadata.assert_called_with({'key': ''}) # '--property' takes key=value arguments # missing a value would raise a BadRequest self._share.set_metadata.side_effect = exceptions.BadRequest self.assertRaises( - osc_exceptions.CommandError, self.cmd.take_action, parsed_args) + osc_exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_share_set_status(self): new_status = 'available' - arglist = [ - self._share.id, - '--status', new_status - ] - verifylist = [ - ('share', self._share.id), - ('status', new_status) - ] + arglist = [self._share.id, '--status', new_status] + verifylist = [('share', self._share.id), ('status', new_status)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -1375,30 +1397,22 @@ def test_share_set_status(self): def test_share_set_status_exception(self): new_status = 'available' - arglist = [ - self._share.id, - '--status', new_status - ] - verifylist = [ - ('share', self._share.id), - ('status', new_status) - ] + arglist = [self._share.id, '--status', new_status] + verifylist = [('share', self._share.id), ('status', new_status)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self._share.reset_state.side_effect = Exception() self.assertRaises( - osc_exceptions.CommandError, self.cmd.take_action, parsed_args) + osc_exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_share_set_task_state(self): new_task_state = 'migration_starting' - arglist = [ - self._share.id, - '--task-state', new_task_state - ] + arglist = [self._share.id, '--task-state', new_task_state] verifylist = [ ('share', self._share.id), - ('task_state', new_task_state) + ('task_state', new_task_state), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -1407,28 +1421,16 @@ def test_share_set_task_state(self): self.assertIsNone(result) def test_share_set_task_state_none(self): - arglist = [ - self._share.id, - '--task-state' - ] - verifylist = [ - ('share', self._share.id), - ('task_state', None) - ] + arglist = [self._share.id, '--task-state'] + verifylist = [('share', self._share.id), ('task_state', None)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self._share.reset_task_state.assert_called_with(None) self.assertIsNone(result) def test_share_set_task_state_string_none(self): - arglist = [ - self._share.id, - '--task-state', 'None' - ] - verifylist = [ - ('share', self._share.id), - ('task_state', 'None') - ] + arglist = [self._share.id, '--task-state', 'None'] + verifylist = [('share', self._share.id), ('task_state', 'None')] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self._share.reset_task_state.assert_called_with(None) @@ -1436,9 +1438,8 @@ def test_share_set_task_state_string_none(self): class TestShareUnset(TestShare): - def setUp(self): - super(TestShareUnset, self).setUp() + super().setUp() self._share = manila_fakes.FakeShare.create_one_share( methods={"delete_metadata": None} @@ -1450,248 +1451,181 @@ def setUp(self): def test_share_unset_property(self): arglist = [ - '--property', 'Manila', + '--property', + 'Manila', self._share.id, ] - verifylist = [ - ('property', ['Manila']), - ('share', self._share.id) - ] + verifylist = [('property', ['Manila']), ('share', self._share.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) - self._share.delete_metadata.assert_called_with( - parsed_args.property) + self._share.delete_metadata.assert_called_with(parsed_args.property) def test_share_unset_name(self): arglist = [ '--name', self._share.id, ] - verifylist = [ - ('name', True), - ('share', self._share.id) - ] + verifylist = [('name', True), ('share', self._share.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) self.shares_mock.update.assert_called_with( - self._share.id, - display_name=None) + self._share.id, display_name=None + ) def test_share_unset_description(self): arglist = [ '--description', self._share.id, ] - verifylist = [ - ('description', True), - ('share', self._share.id) - ] + verifylist = [('description', True), ('share', self._share.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) self.shares_mock.update.assert_called_with( - self._share.id, - display_description=None) + self._share.id, display_description=None + ) def test_share_unset_name_exception(self): arglist = [ '--name', self._share.id, ] - verifylist = [ - ('name', True), - ('share', self._share.id) - ] + verifylist = [('name', True), ('share', self._share.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.shares_mock.update.side_effect = exceptions.BadRequest() self.assertRaises( - osc_exceptions.CommandError, self.cmd.take_action, parsed_args) + osc_exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_share_unset_property_exception(self): arglist = [ - '--property', 'Manila', + '--property', + 'Manila', self._share.id, ] - verifylist = [ - ('property', ['Manila']), - ('share', self._share.id) - ] + verifylist = [('property', ['Manila']), ('share', self._share.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) - self._share.delete_metadata.assert_called_with( - parsed_args.property) + self._share.delete_metadata.assert_called_with(parsed_args.property) # 404 Not Found would be raised, if property 'Manila' doesn't exist self._share.delete_metadata.side_effect = exceptions.NotFound self.assertRaises( - osc_exceptions.CommandError, self.cmd.take_action, parsed_args) + osc_exceptions.CommandError, self.cmd.take_action, parsed_args + ) class TestResizeShare(TestShare): - def setUp(self): - super(TestResizeShare, self).setUp() + super().setUp() self._share = manila_fakes.FakeShare.create_one_share( - attrs={'size': 2, - 'status': 'available'}) + attrs={'size': 2, 'status': 'available'} + ) self.shares_mock.get.return_value = self._share # Get the command objects to test self.cmd = osc_shares.ResizeShare(self.app, None) def test_share_shrink(self): - arglist = [ - self._share.id, - '1' - ] - verifylist = [ - ('share', self._share.id), - ('new_size', 1) - ] + arglist = [self._share.id, '1'] + verifylist = [('share', self._share.id), ('new_size', 1)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) - self.shares_mock.shrink.assert_called_with( - self._share, - 1 - ) + self.shares_mock.shrink.assert_called_with(self._share, 1) def test_share_shrink_exception(self): - arglist = [ - self._share.id, - '1' - ] - verifylist = [ - ('share', self._share.id), - ('new_size', 1) - ] + arglist = [self._share.id, '1'] + verifylist = [('share', self._share.id), ('new_size', 1)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.shares_mock.shrink.side_effect = Exception() self.assertRaises( - osc_exceptions.CommandError, - self.cmd.take_action, - parsed_args) + osc_exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_share_extend(self): - arglist = [ - self._share.id, - '3' - ] - verifylist = [ - ('share', self._share.id), - ('new_size', 3) - ] + arglist = [self._share.id, '3'] + verifylist = [('share', self._share.id), ('new_size', 3)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) - self.shares_mock.extend.assert_called_with( - self._share, - 3 - ) + self.shares_mock.extend.assert_called_with(self._share, 3) def test_share_extend_exception(self): - arglist = [ - self._share.id, - '3' - ] - verifylist = [ - ('share', self._share.id), - ('new_size', 3) - ] + arglist = [self._share.id, '3'] + verifylist = [('share', self._share.id), ('new_size', 3)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.shares_mock.extend.side_effect = Exception() self.assertRaises( - osc_exceptions.CommandError, - self.cmd.take_action, - parsed_args) + osc_exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_share_resize_already_required_size(self): - arglist = [ - self._share.id, - '2' - ] - verifylist = [ - ('share', self._share.id), - ('new_size', 2) - ] + arglist = [self._share.id, '2'] + verifylist = [('share', self._share.id), ('new_size', 2)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( - osc_exceptions.CommandError, - self.cmd.take_action, - parsed_args + osc_exceptions.CommandError, self.cmd.take_action, parsed_args ) def test_share_missing_args(self): - arglist = [ - self._share.id - ] - verifylist = [ - ('share', self._share.id) - ] + arglist = [self._share.id] + verifylist = [('share', self._share.id)] - self.assertRaises(osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_resize_wait(self): - arglist = [ - self._share.id, - '3', - '--wait' - ] + arglist = [self._share.id, '3', '--wait'] verifylist = [ ('share', self._share.id), ('new_size', 3), - ('wait', True) + ('wait', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) - self.shares_mock.extend.assert_called_with( - self._share, - 3 - ) + self.shares_mock.extend.assert_called_with(self._share, 3) self.shares_mock.get.assert_called_with(self._share.id) def test_share_resize_wait_error(self): - arglist = [ - self._share.id, - '3', - '--wait' - ] + arglist = [self._share.id, '3', '--wait'] verifylist = [ ('share', self._share.id), ('new_size', 3), - ('wait', True) + ('wait', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) with mock.patch('osc_lib.utils.wait_for_status', return_value=False): self.assertRaises( - osc_exceptions.CommandError, - self.cmd.take_action, - parsed_args + osc_exceptions.CommandError, self.cmd.take_action, parsed_args ) class TestAdoptShare(TestShare): - def setUp(self): - super(TestAdoptShare, self).setUp() + super().setUp() self._share_type = manila_fakes.FakeShareType.create_one_sharetype() self.share_types_mock.get.return_value = self._share_type @@ -1700,7 +1634,9 @@ def setUp(self): attrs={ 'status': 'available', 'share_type': self._share_type.id, - 'share_server_id': 'server-id' + uuid.uuid4().hex}) + 'share_server_id': 'server-id' + uuid.uuid4().hex, + } + ) self.shares_mock.get.return_value = self._share self.shares_mock.manage.return_value = self._share @@ -1715,19 +1651,20 @@ def test_share_adopt_missing_args(self): arglist = [] verifylist = [] - self.assertRaises(osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_adopt_required_args(self): - arglist = [ - 'some.host@driver#pool', - 'NFS', - '10.0.0.1:/example_path' - ] + arglist = ['some.host@driver#pool', 'NFS', '10.0.0.1:/example_path'] verifylist = [ ('service_host', 'some.host@driver#pool'), ('protocol', 'NFS'), - ('export_path', '10.0.0.1:/example_path') + ('export_path', '10.0.0.1:/example_path'), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) @@ -1736,7 +1673,7 @@ def test_share_adopt_required_args(self): export_path='10.0.0.1:/example_path', name=None, protocol='NFS', - service_host='some.host@driver#pool' + service_host='some.host@driver#pool', ) self.assertCountEqual(self.columns, columns) self.assertCountEqual(self.datalist, data) @@ -1746,14 +1683,19 @@ def test_share_adopt(self): 'some.host@driver#pool', 'NFS', '10.0.0.1:/example_path', - '--name', self._share.id, - '--description', self._share.description, - '--share-type', self._share.share_type, - '--driver-options', 'key1=value1', 'key2=value2', + '--name', + self._share.id, + '--description', + self._share.description, + '--share-type', + self._share.share_type, + '--driver-options', + 'key1=value1', + 'key2=value2', '--wait', '--public', - '--share-server-id', self._share.share_server_id - + '--share-server-id', + self._share.share_server_id, ] verifylist = [ ('service_host', 'some.host@driver#pool'), @@ -1765,8 +1707,7 @@ def test_share_adopt(self): ('driver_options', ['key1=value1', 'key2=value2']), ('wait', True), ('public', True), - ('share_server_id', self._share.share_server_id) - + ('share_server_id', self._share.share_server_id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -1780,7 +1721,7 @@ def test_share_adopt(self): service_host='some.host@driver#pool', share_server_id=self._share.share_server_id, share_type=self._share_type.id, - public=True + public=True, ) self.assertCountEqual(self.columns, columns) self.assertCountEqual(self.datalist, data) @@ -1791,13 +1732,13 @@ def test_share_adopt_wait_error(self, mock_logger): 'some.host@driver#pool', 'NFS', '10.0.0.1:/example_path', - '--wait' + '--wait', ] verifylist = [ ('service_host', 'some.host@driver#pool'), ('protocol', 'NFS'), ('export_path', '10.0.0.1:/example_path'), - ('wait', True) + ('wait', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -1809,11 +1750,12 @@ def test_share_adopt_wait_error(self, mock_logger): export_path='10.0.0.1:/example_path', name=None, protocol='NFS', - service_host='some.host@driver#pool' + service_host='some.host@driver#pool', ) mock_logger.error.assert_called_with( - "ERROR: Share is in error state.") + "ERROR: Share is in error state." + ) self.shares_mock.get.assert_called_with(self._share.id) self.assertCountEqual(self.columns, columns) @@ -1821,56 +1763,59 @@ def test_share_adopt_wait_error(self, mock_logger): def test_share_adopt_visibility_api_version_exception(self): self.app.client_manager.share.api_version = api_versions.APIVersion( - "2.7") + "2.7" + ) arglist = [ 'some.host@driver#pool', 'NFS', '10.0.0.1:/example_path', - '--public' - + '--public', ] verifylist = [ ('service_host', 'some.host@driver#pool'), ('protocol', 'NFS'), ('export_path', '10.0.0.1:/example_path'), - ('public', True) + ('public', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( - osc_exceptions.CommandError, self.cmd.take_action, parsed_args) + osc_exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_share_adopt_share_server_api_version_exception(self): self.app.client_manager.share.api_version = api_versions.APIVersion( - "2.48") + "2.48" + ) arglist = [ 'some.host@driver#pool', 'NFS', '10.0.0.1:/example_path', - '--share-server-id', self._share.share_server_id - + '--share-server-id', + self._share.share_server_id, ] verifylist = [ ('service_host', 'some.host@driver#pool'), ('protocol', 'NFS'), ('export_path', '10.0.0.1:/example_path'), - ('share_server_id', self._share.share_server_id) + ('share_server_id', self._share.share_server_id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( - osc_exceptions.CommandError, self.cmd.take_action, parsed_args) + osc_exceptions.CommandError, self.cmd.take_action, parsed_args + ) class TestAbandonShare(TestShare): - def setUp(self): - super(TestAbandonShare, self).setUp() + super().setUp() self._share = manila_fakes.FakeShare.create_one_share( - attrs={'status': 'available'}) + attrs={'status': 'available'} + ) self.shares_mock.get.return_value = self._share # Get the command objects to test @@ -1891,14 +1836,8 @@ def test_share_abandon(self): self.assertIsNone(result) def test_share_abandon_wait(self): - arglist = [ - self._share.id, - '--wait' - ] - verifylist = [ - ('share', [self._share.id]), - ('wait', True) - ] + arglist = [self._share.id, '--wait'] + verifylist = [('share', [self._share.id]), ('wait', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -1908,57 +1847,43 @@ def test_share_abandon_wait(self): self.assertIsNone(result) def test_share_abandon_wait_error(self): - arglist = [ - self._share.id, - '--wait' - ] - verifylist = [ - ('share', [self._share.id]), - ('wait', True) - ] + arglist = [self._share.id, '--wait'] + verifylist = [('share', [self._share.id]), ('wait', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) with mock.patch('osc_lib.utils.wait_for_delete', return_value=False): self.assertRaises( - osc_exceptions.CommandError, - self.cmd.take_action, - parsed_args + osc_exceptions.CommandError, self.cmd.take_action, parsed_args ) class TestShareExportLocationShow(TestShare): - def setUp(self): - super(TestShareExportLocationShow, self).setUp() + super().setUp() self._share = manila_fakes.FakeShare.create_one_share() self.shares_mock.get.return_value = self._share self._export_location = ( - manila_fakes.FakeShareExportLocation.create_one_export_location()) - - self.export_locations_mock.get.return_value = ( - self._export_location + manila_fakes.FakeShareExportLocation.create_one_export_location() ) + self.export_locations_mock.get.return_value = self._export_location + # Get the command object to test self.cmd = osc_shares.ShareExportLocationShow(self.app, None) def test_share_show_export_location(self): - arglist = [ - self._share.id, - self._export_location.fake_uuid - ] + arglist = [self._share.id, self._export_location.fake_uuid] verifylist = [ ('share', self._share.id), - ('export_location', self._export_location.fake_uuid) + ('export_location', self._export_location.fake_uuid), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.export_locations_mock.get.assert_called_with( - share=self._share, - export_location=self._export_location.fake_uuid + share=self._share, export_location=self._export_location.fake_uuid ) self.assertEqual(tuple(self._export_location._info.keys()), columns) @@ -1966,49 +1891,42 @@ def test_share_show_export_location(self): class TestShareExportLocationList(TestShare): - columns = ['ID', 'Path', 'Preferred'] def setUp(self): - super(TestShareExportLocationList, self).setUp() + super().setUp() self._share = manila_fakes.FakeShare.create_one_share() self.shares_mock.get.return_value = self._share self._export_locations = [ - manila_fakes.FakeShareExportLocation.create_one_export_location()] + manila_fakes.FakeShareExportLocation.create_one_export_location() + ] - self.export_locations_mock.list.return_value = ( - self._export_locations - ) + self.export_locations_mock.list.return_value = self._export_locations - self.values = (oscutils.get_dict_properties( - e._info, self.columns) for e in self._export_locations) + self.values = ( + oscutils.get_dict_properties(e._info, self.columns) + for e in self._export_locations + ) # Get the command object to test self.cmd = osc_shares.ShareExportLocationList(self.app, None) def test_share_list_export_location(self): - arglist = [ - self._share.id - ] - verifylist = [ - ('share', self._share.id) - ] + arglist = [self._share.id] + verifylist = [('share', self._share.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) - self.export_locations_mock.list.assert_called_with( - share=self._share - ) + self.export_locations_mock.list.assert_called_with(share=self._share) self.assertEqual(self.columns, columns) self.assertCountEqual(self.values, data) class TestExportLocationSet(TestShare): - def setUp(self): - super(TestExportLocationSet, self).setUp() + super().setUp() self._share = manila_fakes.FakeShare.create_one_share( methods={"set_metadata": None} @@ -2017,12 +1935,12 @@ def setUp(self): self._export_location = ( manila_fakes.FakeShareExportLocation.create_one_export_location( - {'fake_share_instance_id': self._share.id})) - - self.export_locations_mock.get.return_value = ( - self._export_location + {'fake_share_instance_id': self._share.id} + ) ) + self.export_locations_mock.get.return_value = self._export_location + self.cmd = osc_shares.ShareExportLocationSet(self.app, None) def test_share_set_export_location_property(self): @@ -2032,8 +1950,8 @@ def test_share_set_export_location_property(self): arglist = [ self._share.id, self._export_location.id, - '--property', 'Bobcat=manila', - + '--property', + 'Bobcat=manila', ] verifylist = [ ('share', self._share.id), @@ -2044,8 +1962,10 @@ def test_share_set_export_location_property(self): parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) self.export_locations_mock.set_metadata.assert_called_once_with( - self._share.id, {'Bobcat': 'manila'}, - subresource=self._export_location.id) + self._share.id, + {'Bobcat': 'manila'}, + subresource=self._export_location.id, + ) def test_share_set_export_location_property_exception(self): self.app.client_manager.share.api_version = api_versions.APIVersion( @@ -2054,7 +1974,8 @@ def test_share_set_export_location_property_exception(self): arglist = [ self._share.id, self._export_location.id, - '--property', 'key=', + '--property', + 'key=', ] verifylist = [ ('share', self._share.id), @@ -2066,20 +1987,20 @@ def test_share_set_export_location_property_exception(self): self.cmd.take_action(parsed_args) self.export_locations_mock.set_metadata.assert_called_once_with( - self._share.id, {'key': ''}, - subresource=self._export_location.id) + self._share.id, {'key': ''}, subresource=self._export_location.id + ) self.export_locations_mock.set_metadata.side_effect = ( - exceptions.BadRequest) + exceptions.BadRequest + ) self.assertRaises( - osc_exceptions.CommandError, self.cmd.take_action, - parsed_args) + osc_exceptions.CommandError, self.cmd.take_action, parsed_args + ) class TestExportLocationUnset(TestShare): - def setUp(self): - super(TestExportLocationUnset, self).setUp() + super().setUp() self._share = manila_fakes.FakeShare.create_one_share( methods={"set_metadata": None} @@ -2088,12 +2009,12 @@ def setUp(self): self._export_location = ( manila_fakes.FakeShareExportLocation.create_one_export_location( - {'fake_share_instance_id': self._share.id})) - - self.export_locations_mock.get.return_value = ( - self._export_location + {'fake_share_instance_id': self._share.id} + ) ) + self.export_locations_mock.get.return_value = self._export_location + self.cmd = osc_shares.ShareExportLocationUnset(self.app, None) def test_share_unset_export_location_property(self): @@ -2103,8 +2024,8 @@ def test_share_unset_export_location_property(self): arglist = [ self._share.id, self._export_location.id, - '--property', 'Bobcat', - + '--property', + 'Bobcat', ] verifylist = [ ('share', self._share.id), @@ -2115,8 +2036,8 @@ def test_share_unset_export_location_property(self): parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) self.export_locations_mock.delete_metadata.assert_called_once_with( - self._share.id, ['Bobcat'], - subresource=self._export_location.id) + self._share.id, ['Bobcat'], subresource=self._export_location.id + ) def test_share_unset_export_location_property_exception(self): self.app.client_manager.share.api_version = api_versions.APIVersion( @@ -2125,7 +2046,8 @@ def test_share_unset_export_location_property_exception(self): arglist = [ self._share.id, self._export_location.id, - '--property', 'key', + '--property', + 'key', ] verifylist = [ ('share', self._share.id), @@ -2136,33 +2058,33 @@ def test_share_unset_export_location_property_exception(self): parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) - self.export_locations_mock.delete_metadata.assert_has_calls([ - mock.call(self._share.id, ['key'], - subresource=self._export_location.id)]) + self.export_locations_mock.delete_metadata.assert_has_calls( + [ + mock.call( + self._share.id, + ['key'], + subresource=self._export_location.id, + ) + ] + ) self.export_locations_mock.delete_metadata.side_effect = ( - exceptions.NotFound) + exceptions.NotFound + ) self.assertRaises( - osc_exceptions.CommandError, self.cmd.take_action, - parsed_args) + osc_exceptions.CommandError, self.cmd.take_action, parsed_args + ) class TestShowShareProperties(TestShare): - - properties = { - 'key1': 'value1', - 'key2': 'value2' - } + properties = {'key1': 'value1', 'key2': 'value2'} def setUp(self): - super(TestShowShareProperties, self).setUp() + super().setUp() self._share = manila_fakes.FakeShare.create_one_share( - attrs={ - 'metadata': osc_fakes.FakeResource( - info=self.properties) - }, - methods={'get_metadata': None} + attrs={'metadata': osc_fakes.FakeResource(info=self.properties)}, + methods={'get_metadata': None}, ) self.shares_mock.get.return_value = self._share self.shares_mock.get_metadata.return_value = self._share.metadata @@ -2174,12 +2096,8 @@ def setUp(self): self.columns = tuple(self._share.metadata._info.keys()) def test_share_show_properties(self): - arglist = [ - self._share.id - ] - verifylist = [ - ("share", self._share.id) - ] + arglist = [self._share.id] + verifylist = [("share", self._share.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.shares_mock.get.assert_called_with(self._share.id) @@ -2190,29 +2108,26 @@ def test_share_show_properties(self): class TestShareRevert(TestShare): - def setUp(self): - super(TestShareRevert, self).setUp() + super().setUp() self.share = manila_fakes.FakeShare.create_one_share( attrs={'revert_to_snapshot_support': True}, - methods={'revert_to_snapshot': None} + methods={'revert_to_snapshot': None}, ) self.share_snapshot = ( manila_fakes.FakeShareSnapshot.create_one_snapshot( - attrs={'share_id': self.share.id})) + attrs={'share_id': self.share.id} + ) + ) self.shares_mock.get.return_value = self.share self.snapshots_mock.get.return_value = self.share_snapshot self.cmd = osc_shares.RevertShare(self.app, None) def test_share_revert(self): - arglist = [ - self.share_snapshot.id - ] - verifylist = [ - ('snapshot', self.share_snapshot.id) - ] + arglist = [self.share_snapshot.id] + verifylist = [('snapshot', self.share_snapshot.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.shares_mock.get.assert_called_with(self.share_snapshot.share_id) @@ -2220,35 +2135,31 @@ def test_share_revert(self): self.assertIsNone(result) def test_share_revert_exception(self): - arglist = [ - self.share_snapshot.id - ] - verifylist = [ - ('snapshot', self.share_snapshot.id) - ] + arglist = [self.share_snapshot.id] + verifylist = [('snapshot', self.share_snapshot.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.share.revert_to_snapshot.side_effect = Exception() self.assertRaises( - osc_exceptions.CommandError, self.cmd.take_action, parsed_args) + osc_exceptions.CommandError, self.cmd.take_action, parsed_args + ) class TestShareMigrationStart(TestShare): - def setUp(self): - super(TestShareMigrationStart, self).setUp() + super().setUp() self.new_share_type = manila_fakes.FakeShareType.create_one_sharetype() self.share_types_mock.get.return_value = self.new_share_type - self.new_share_network = manila_fakes.FakeShareNetwork \ - .create_one_share_network() + self.new_share_network = ( + manila_fakes.FakeShareNetwork.create_one_share_network() + ) self.share_networks_mock.get.return_value = self.new_share_network self._share = manila_fakes.FakeShare.create_one_share( - attrs={ - 'status': 'available'}, - methods={'migration_start': None}) + attrs={'status': 'available'}, methods={'migration_start': None} + ) self.shares_mock.get.return_value = self._share self.shares_mock.manage.return_value = self._share @@ -2261,13 +2172,18 @@ def test_migration_start_with_new_share_type(self): arglist = [ self._share.id, 'host@driver#pool', - '--preserve-metadata', 'False', - '--preserve-snapshots', 'False', - '--writable', 'False', - '--nondisruptive', 'False', - '--new-share-type', self.new_share_type.id, - '--force-host-assisted-migration', 'False' - + '--preserve-metadata', + 'False', + '--preserve-snapshots', + 'False', + '--writable', + 'False', + '--nondisruptive', + 'False', + '--new-share-type', + self.new_share_type.id, + '--force-host-assisted-migration', + 'False', ] verifylist = [ ('share', self._share.id), @@ -2277,8 +2193,7 @@ def test_migration_start_with_new_share_type(self): ('writable', 'False'), ('nondisruptive', 'False'), ('new_share_type', self.new_share_type.id), - ('force_host_assisted_migration', 'False') - + ('force_host_assisted_migration', 'False'), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) @@ -2290,7 +2205,7 @@ def test_migration_start_with_new_share_type(self): 'False', 'False', None, - self.new_share_type.id + self.new_share_type.id, ) self.assertIsNone(result) @@ -2300,13 +2215,18 @@ def test_migration_start_with_new_share_network(self): arglist = [ self._share.id, 'host@driver#pool', - '--preserve-metadata', 'False', - '--preserve-snapshots', 'False', - '--writable', 'False', - '--nondisruptive', 'False', - '--new-share-network', self.new_share_network.id, - '--force-host-assisted-migration', 'False' - + '--preserve-metadata', + 'False', + '--preserve-snapshots', + 'False', + '--writable', + 'False', + '--nondisruptive', + 'False', + '--new-share-network', + self.new_share_network.id, + '--force-host-assisted-migration', + 'False', ] verifylist = [ ('share', self._share.id), @@ -2316,8 +2236,7 @@ def test_migration_start_with_new_share_network(self): ('writable', 'False'), ('nondisruptive', 'False'), ('new_share_network', self.new_share_network.id), - ('force_host_assisted_migration', 'False') - + ('force_host_assisted_migration', 'False'), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) @@ -2329,20 +2248,18 @@ def test_migration_start_with_new_share_network(self): 'False', 'False', self.new_share_network.id, - None + None, ) self.assertIsNone(result) class TestShareMigrationCancel(TestShare): - def setUp(self): - super(TestShareMigrationCancel, self).setUp() + super().setUp() self._share = manila_fakes.FakeShare.create_one_share( - attrs={ - 'status': 'migrating'}, - methods={'migration_cancel': None}) + attrs={'status': 'migrating'}, methods={'migration_cancel': None} + ) self.shares_mock.get.return_value = self._share self.shares_mock.manage.return_value = self._share @@ -2351,9 +2268,7 @@ def setUp(self): self.cmd = osc_shares.ShareMigrationCancel(self.app, None) def test_migration_cancel(self): - arglist = [ - self._share.id - ] + arglist = [self._share.id] verifylist = [ ('share', self._share.id), ] @@ -2364,14 +2279,12 @@ def test_migration_cancel(self): class TestShareMigrationComplete(TestShare): - def setUp(self): - super(TestShareMigrationComplete, self).setUp() + super().setUp() self._share = manila_fakes.FakeShare.create_one_share( - attrs={ - 'status': 'migrating'}, - methods={'migration_complete': None}) + attrs={'status': 'migrating'}, methods={'migration_complete': None} + ) self.shares_mock.get.return_value = self._share self.shares_mock.manage.return_value = self._share @@ -2380,9 +2293,7 @@ def setUp(self): self.cmd = osc_shares.ShareMigrationComplete(self.app, None) def test_migration_complete(self): - arglist = [ - self._share.id - ] + arglist = [self._share.id] verifylist = [ ('share', self._share.id), ] @@ -2393,19 +2304,25 @@ def test_migration_complete(self): class TestShareMigrationShow(TestShare): - def setUp(self): - super(TestShareMigrationShow, self).setUp() + super().setUp() self._share = manila_fakes.FakeShare.create_one_share( attrs={ 'status': 'available', - 'task_state': 'migration_in_progress'}, - methods={'migration_get_progress': ("", - {'total_progress': 0, 'task_state': - 'migration_in_progress', - 'details': {}}) - }) + 'task_state': 'migration_in_progress', + }, + methods={ + 'migration_get_progress': ( + "", + { + 'total_progress': 0, + 'task_state': 'migration_in_progress', + 'details': {}, + }, + ) + }, + ) self.shares_mock.get.return_value = self._share self.shares_mock.manage.return_value = self._share @@ -2414,9 +2331,7 @@ def setUp(self): self.cmd = osc_shares.ShareMigrationShow(self.app, None) def test_migration_show(self): - arglist = [ - self._share.id - ] + arglist = [self._share.id] verifylist = [ ('share', self._share.id), ] @@ -2426,9 +2341,8 @@ def test_migration_show(self): class TestShareRestore(TestShare): - def setUp(self): - super(TestShareRestore, self).setUp() + super().setUp() self.share = manila_fakes.FakeShare.create_one_share( methods={'restore': None} @@ -2437,12 +2351,8 @@ def setUp(self): self.cmd = osc_shares.RestoreShare(self.app, None) def test_share_restore(self): - arglist = [ - self.share.name - ] - verifylist = [ - ('share', [self.share.name]) - ] + arglist = [self.share.name] + verifylist = [('share', [self.share.name])] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) @@ -2451,13 +2361,10 @@ def test_share_restore(self): self.assertIsNone(result) def test_share_restore_exception(self): - arglist = [ - self.share.name - ] - verifylist = [ - ('share', [self.share.name]) - ] + arglist = [self.share.name] + verifylist = [('share', [self.share.name])] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.share.restore.side_effect = Exception() self.assertRaises( - osc_exceptions.CommandError, self.cmd.take_action, parsed_args) + osc_exceptions.CommandError, self.cmd.take_action, parsed_args + ) diff --git a/manilaclient/tests/unit/osc/v2/test_share_access_rules.py b/manilaclient/tests/unit/osc/v2/test_share_access_rules.py index 3447df19..2fe59883 100644 --- a/manilaclient/tests/unit/osc/v2/test_share_access_rules.py +++ b/manilaclient/tests/unit/osc/v2/test_share_access_rules.py @@ -31,38 +31,40 @@ 'access_key', 'created_at', 'updated_at', - 'properties' + 'properties', ] class TestShareAccess(manila_fakes.TestShare): - def setUp(self): - super(TestShareAccess, self).setUp() + super().setUp() self.shares_mock = self.app.client_manager.share.shares self.app.client_manager.share.api_version = api_versions.APIVersion( - api_versions.MAX_VERSION) + api_versions.MAX_VERSION + ) self.shares_mock.reset_mock() self.access_rules_mock = ( - self.app.client_manager.share.share_access_rules) + self.app.client_manager.share.share_access_rules + ) self.access_rules_mock.reset_mock() @ddt.ddt class TestShareAccessCreate(TestShareAccess): - def setUp(self): - super(TestShareAccessCreate, self).setUp() + super().setUp() self.share = manila_fakes.FakeShare.create_one_share( - attrs={"is_public": False}, - methods={'allow': None}) + attrs={"is_public": False}, methods={'allow': None} + ) self.shares_mock.get.return_value = self.share self.access_rule = ( manila_fakes.FakeShareAccessRule.create_one_access_rule( - attrs={"share_id": self.share.id})) + attrs={"share_id": self.share.id} + ) + ) self.share.allow.return_value = self.access_rule._info self.access_rules_mock.get.return_value = self.access_rule @@ -93,12 +95,7 @@ def test_share_access_create_user(self): self.assertCountEqual(self.access_rule._info.values(), data) def test_share_access_create_properties(self): - arglist = [ - self.share.id, - 'user', - 'demo', - '--properties', 'key=value' - ] + arglist = [self.share.id, 'user', 'demo', '--properties', 'key=value'] verifylist = [ ("share", self.share.id), ("access_type", "user"), @@ -118,20 +115,19 @@ def test_share_access_create_properties(self): self.assertCountEqual(self.access_rule._info.values(), data) @ddt.data( - {'lock_visibility': True, 'lock_deletion': True, - 'lock_reason': 'testing resource locks'}, + { + 'lock_visibility': True, + 'lock_deletion': True, + 'lock_reason': 'testing resource locks', + }, {'lock_visibility': False, 'lock_deletion': True, 'lock_reason': None}, {'lock_visibility': True, 'lock_deletion': False, 'lock_reason': None}, ) @ddt.unpack - def test_share_access_create_restrict(self, lock_visibility, - lock_deletion, lock_reason): - arglist = [ - self.share.id, - 'user', - 'demo', - '--properties', 'key=value' - ] + def test_share_access_create_restrict( + self, lock_visibility, lock_deletion, lock_reason + ): + arglist = [self.share.id, 'user', 'demo', '--properties', 'key=value'] verifylist = [ ("share", self.share.id), ("access_type", "user"), @@ -161,7 +157,7 @@ def test_share_access_create_restrict(self, lock_visibility, access="demo", access_level=None, metadata={'key': 'value'}, - **allow_call_kwargs + **allow_call_kwargs, ) self.assertEqual(ACCESS_RULE_ATTRIBUTES, columns) self.assertCountEqual(self.access_rule._info.values(), data) @@ -172,14 +168,16 @@ def test_share_access_create_restrict(self, lock_visibility, ) @ddt.unpack def test_share_access_create_restrict_not_available( - self, lock_visibility, lock_deletion): + self, lock_visibility, lock_deletion + ): arglist = [ self.share.id, 'user', 'demo', ] self.app.client_manager.share.api_version = api_versions.APIVersion( - "2.79") + "2.79" + ) verifylist = [ ("share", self.share.id), ("access_type", "user"), @@ -194,17 +192,11 @@ def test_share_access_create_restrict_not_available( arglist.append('--lock-deletion') parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( - exceptions.CommandError, - self.cmd.take_action, - parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_access_rule_create_access_level(self): - arglist = [ - self.share.id, - 'user', - 'demo', - '--access-level', 'ro' - ] + arglist = [self.share.id, 'user', 'demo', '--access-level', 'ro'] verifylist = [ ("share", self.share.id), ("access_type", "user"), @@ -224,12 +216,7 @@ def test_access_rule_create_access_level(self): self.assertCountEqual(self.access_rule._info.values(), data) def test_share_access_create_wait(self): - arglist = [ - self.share.id, - 'user', - 'demo', - '--wait' - ] + arglist = [self.share.id, 'user', 'demo', '--wait'] verifylist = [ ("share", self.share.id), ("access_type", "user"), @@ -250,12 +237,7 @@ def test_share_access_create_wait(self): @mock.patch('manilaclient.osc.v2.share_access_rules.LOG') def test_share_access_create_wait_error(self, mock_logger): - arglist = [ - self.share.id, - 'user', - 'demo', - '--wait' - ] + arglist = [self.share.id, 'user', 'demo', '--wait'] verifylist = [ ("share", self.share.id), ("access_type", "user"), @@ -276,7 +258,8 @@ def test_share_access_create_wait_error(self, mock_logger): ) mock_logger.error.assert_called_with( - "ERROR: Share access rule is in error state.") + "ERROR: Share access rule is in error state." + ) self.assertEqual(ACCESS_RULE_ATTRIBUTES, columns) self.assertCountEqual(self.access_rule._info.values(), data) @@ -284,26 +267,25 @@ def test_share_access_create_wait_error(self, mock_logger): @ddt.ddt class TestShareAccessDelete(TestShareAccess): - def setUp(self): - super(TestShareAccessDelete, self).setUp() + super().setUp() self.share = manila_fakes.FakeShare.create_one_share( - methods={'deny': None}) + methods={'deny': None} + ) self.shares_mock.get.return_value = self.share self.access_rule = ( manila_fakes.FakeShareAccessRule.create_one_access_rule( - attrs={"share_id": self.share.id})) + attrs={"share_id": self.share.id} + ) + ) # Get the command object to test self.cmd = osc_share_access_rules.ShareAccessDeny(self.app, None) @ddt.data(True, False) def test_share_access_delete(self, unrestrict): - arglist = [ - self.share.id, - self.access_rule.id - ] + arglist = [self.share.id, self.access_rule.id] verifylist = [ ("share", self.share.id), ("id", self.access_rule.id), @@ -316,35 +298,26 @@ def test_share_access_delete(self, unrestrict): parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.shares_mock.get.assert_called_with(self.share.id) - self.share.deny.assert_called_with( - self.access_rule.id, **deny_kwargs) + self.share.deny.assert_called_with(self.access_rule.id, **deny_kwargs) self.assertIsNone(result) def test_share_access_delete_unrestrict_not_available(self): self.app.client_manager.share.api_version = api_versions.APIVersion( - "2.79") - arglist = [ - self.share.id, - self.access_rule.id, - "--unrestrict" - ] + "2.79" + ) + arglist = [self.share.id, self.access_rule.id, "--unrestrict"] verifylist = [ ("share", self.share.id), ("id", self.access_rule.id), - ("unrestrict", True) + ("unrestrict", True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( - exceptions.CommandError, - self.cmd.take_action, - parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_share_access_delete_wait(self): - arglist = [ - self.share.id, - self.access_rule.id, - '--wait' - ] + arglist = [self.share.id, self.access_rule.id, '--wait'] verifylist = [ ("share", self.share.id), ("id", self.access_rule.id), @@ -357,34 +330,26 @@ def test_share_access_delete_wait(self): result = self.cmd.take_action(parsed_args) self.shares_mock.get.assert_called_with(self.share.id) - self.share.deny.assert_called_with( - self.access_rule.id) + self.share.deny.assert_called_with(self.access_rule.id) self.assertIsNone(result) def test_share_access_delete_wait_error(self): - arglist = [ - self.share.id, - self.access_rule.id, - '--wait' - ] + arglist = [self.share.id, self.access_rule.id, '--wait'] verifylist = [ ("share", self.share.id), ("id", self.access_rule.id), - ('wait', True) + ('wait', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) with mock.patch('osc_lib.utils.wait_for_delete', return_value=False): self.assertRaises( - exceptions.CommandError, - self.cmd.take_action, - parsed_args + exceptions.CommandError, self.cmd.take_action, parsed_args ) @ddt.ddt class TestShareAccessList(TestShareAccess): - access_rules_columns = [ 'ID', 'Access Type', @@ -393,62 +358,56 @@ class TestShareAccessList(TestShareAccess): 'State', 'Access Key', 'Created At', - 'Updated At' + 'Updated At', ] def setUp(self): - super(TestShareAccessList, self).setUp() + super().setUp() self.share = manila_fakes.FakeShare.create_one_share() self.access_rule_1 = ( manila_fakes.FakeShareAccessRule.create_one_access_rule( - attrs={"share_id": self.share.id})) + attrs={"share_id": self.share.id} + ) + ) self.access_rule_2 = ( manila_fakes.FakeShareAccessRule.create_one_access_rule( - attrs={"share_id": self.share.id, "access_to": "admin"})) + attrs={"share_id": self.share.id, "access_to": "admin"} + ) + ) self.access_rules = [self.access_rule_1, self.access_rule_2] self.shares_mock.get.return_value = self.share self.access_rules_mock.access_list.return_value = self.access_rules - self.values_list = (oscutils.get_dict_properties( - a._info, self.access_rules_columns) for a in self.access_rules) + self.values_list = ( + oscutils.get_dict_properties(a._info, self.access_rules_columns) + for a in self.access_rules + ) # Get the command object to test self.cmd = osc_share_access_rules.ListShareAccess(self.app, None) def test_access_rules_list(self): - arglist = [ - self.share.id - ] - verifylist = [ - ("share", self.share.id) - ] + arglist = [self.share.id] + verifylist = [("share", self.share.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.shares_mock.get.assert_called_with(self.share.id) - self.access_rules_mock.access_list.assert_called_with( - self.share, - {}) + self.access_rules_mock.access_list.assert_called_with(self.share, {}) self.assertEqual(self.access_rules_columns, columns) self.assertEqual(tuple(self.values_list), tuple(data)) def test_access_rules_list_filter_properties(self): - arglist = [ - self.share.id, - '--properties', 'key=value' - ] - verifylist = [ - ("share", self.share.id), - ('properties', ['key=value']) - ] + arglist = [self.share.id, '--properties', 'key=value'] + verifylist = [("share", self.share.id), ('properties', ['key=value'])] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.shares_mock.get.assert_called_with(self.share.id) self.access_rules_mock.access_list.assert_called_with( - self.share, - {'metadata': {'key': 'value'}}) + self.share, {'metadata': {'key': 'value'}} + ) self.assertEqual(self.access_rules_columns, columns) self.assertEqual(tuple(self.values_list), tuple(data)) @@ -475,8 +434,8 @@ def test_access_rules_list_access_filters(self, filters): self.shares_mock.get.assert_called_with(self.share.id) self.access_rules_mock.access_list.assert_called_with( - self.share, - filters) + self.share, filters + ) self.assertEqual(self.access_rules_columns, columns) self.assertEqual(tuple(self.values_list), tuple(data)) @@ -486,7 +445,8 @@ def test_access_rules_list_access_filters(self, filters): ) def test_access_rules_list_access_filters_command_error(self, filters): self.app.client_manager.share.api_version = api_versions.APIVersion( - "2.81") + "2.81" + ) arglist = [ self.share.id, ] @@ -500,32 +460,28 @@ def test_access_rules_list_access_filters_command_error(self, filters): verifylist.append((filter_key, filter_value)) parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( - exceptions.CommandError, - self.cmd.take_action, - parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) class TestShareAccessShow(TestShareAccess): - def setUp(self): - super(TestShareAccessShow, self).setUp() + super().setUp() self.share = manila_fakes.FakeShare.create_one_share() self.access_rule = ( manila_fakes.FakeShareAccessRule.create_one_access_rule( - attrs={"share_id": self.share.id})) + attrs={"share_id": self.share.id} + ) + ) self.access_rules_mock.get.return_value = self.access_rule # Get the command object to test self.cmd = osc_share_access_rules.ShowShareAccess(self.app, None) def test_access_rule_show(self): - arglist = [ - self.access_rule.id - ] - verifylist = [ - ("access_id", self.access_rule.id) - ] + arglist = [self.access_rule.id] + verifylist = [("access_id", self.access_rule.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) @@ -535,81 +491,74 @@ def test_access_rule_show(self): class TestShareAccessSet(TestShareAccess): - def setUp(self): - super(TestShareAccessSet, self).setUp() + super().setUp() self.share = manila_fakes.FakeShare.create_one_share() self.access_rule = ( manila_fakes.FakeShareAccessRule.create_one_access_rule( - attrs={"share_id": self.share.id})) + attrs={"share_id": self.share.id} + ) + ) self.access_rules_mock.get.return_value = self.access_rule # Get the command object to test self.cmd = osc_share_access_rules.SetShareAccess(self.app, None) def test_access_rule_set_metadata(self): - arglist = [ - self.access_rule.id, - '--property', 'key1=value1' - ] + arglist = [self.access_rule.id, '--property', 'key1=value1'] verifylist = [ ("access_id", self.access_rule.id), - ('property', {'key1': 'value1'}) + ('property', {'key1': 'value1'}), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.access_rules_mock.set_metadata.assert_called_with( - self.access_rule, - {'key1': 'value1'}) + self.access_rule, {'key1': 'value1'} + ) self.assertIsNone(result) def test_access_rule_set_access_level(self): - arglist = [ - self.access_rule.id, - '--access-level', 'ro' - ] + arglist = [self.access_rule.id, '--access-level', 'ro'] verifylist = [ ("access_id", self.access_rule.id), - ('access_level', 'ro') + ('access_level', 'ro'), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.access_rules_mock.set_access_level.assert_called_with( - self.access_rule, - 'ro') + self.access_rule, 'ro' + ) self.assertIsNone(result) class TestShareAccessUnset(TestShareAccess): - def setUp(self): - super(TestShareAccessUnset, self).setUp() + super().setUp() self.share = manila_fakes.FakeShare.create_one_share() self.access_rule = ( manila_fakes.FakeShareAccessRule.create_one_access_rule( - attrs={"share_id": self.share.id})) + attrs={"share_id": self.share.id} + ) + ) self.access_rules_mock.get.return_value = self.access_rule # Get the command object to test self.cmd = osc_share_access_rules.UnsetShareAccess(self.app, None) def test_access_rule_unset(self): - arglist = [ - self.access_rule.id, - '--property', 'key1' - ] + arglist = [self.access_rule.id, '--property', 'key1'] verifylist = [ ("access_id", self.access_rule.id), - ('property', ['key1']) + ('property', ['key1']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.access_rules_mock.unset_metadata.assert_called_with( - self.access_rule, - ['key1']) + self.access_rule, ['key1'] + ) self.assertIsNone(result) diff --git a/manilaclient/tests/unit/osc/v2/test_share_backups.py b/manilaclient/tests/unit/osc/v2/test_share_backups.py index 4c9b76e3..c9ca24d1 100644 --- a/manilaclient/tests/unit/osc/v2/test_share_backups.py +++ b/manilaclient/tests/unit/osc/v2/test_share_backups.py @@ -21,9 +21,8 @@ class TestShareBackup(manila_fakes.TestShare): - def setUp(self): - super(TestShareBackup, self).setUp() + super().setUp() self.shares_mock = self.app.client_manager.share.shares self.shares_mock.reset_mock() @@ -31,21 +30,20 @@ def setUp(self): self.backups_mock = self.app.client_manager.share.share_backups self.backups_mock.reset_mock() self.app.client_manager.share.api_version = api_versions.APIVersion( - MAX_VERSION) + MAX_VERSION + ) class TestShareBackupCreate(TestShareBackup): - def setUp(self): - super(TestShareBackupCreate, self).setUp() + super().setUp() self.share = manila_fakes.FakeShare.create_one_share() self.shares_mock.get.return_value = self.share - self.share_backup = ( - manila_fakes.FakeShareBackup.create_one_backup( - attrs={'status': 'available'} - )) + self.share_backup = manila_fakes.FakeShareBackup.create_one_backup( + attrs={'status': 'available'} + ) self.backups_mock.create.return_value = self.share_backup self.backups_mock.get.return_value = self.share_backup self.cmd = osc_share_backups.CreateShareBackup(self.app, None) @@ -58,15 +56,15 @@ def test_share_backup_create_missing_args(self): self.assertRaises( osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_backup_create(self): - arglist = [ - self.share.id - ] - verifylist = [ - ('share', self.share.id) - ] + arglist = [self.share.id] + verifylist = [('share', self.share.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) @@ -78,13 +76,10 @@ def test_share_backup_create(self): self.assertCountEqual(self.data, data) def test_share_backup_create_name(self): - arglist = [ - self.share.id, - '--name', "FAKE_SHARE_BACKUP_NAME" - ] + arglist = [self.share.id, '--name', "FAKE_SHARE_BACKUP_NAME"] verifylist = [ ('share', self.share.id), - ('name', "FAKE_SHARE_BACKUP_NAME") + ('name', "FAKE_SHARE_BACKUP_NAME"), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -99,12 +94,10 @@ def test_share_backup_create_name(self): class TestShareBackupDelete(TestShareBackup): - def setUp(self): - super(TestShareBackupDelete, self).setUp() + super().setUp() - self.share_backup = ( - manila_fakes.FakeShareBackup.create_one_backup()) + self.share_backup = manila_fakes.FakeShareBackup.create_one_backup() self.backups_mock.get.return_value = self.share_backup self.cmd = osc_share_backups.DeleteShareBackup(self.app, None) @@ -113,16 +106,17 @@ def test_share_backup_delete_missing_args(self): arglist = [] verifylist = [] - self.assertRaises(osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_backup_delete(self): - arglist = [ - self.share_backup.id - ] - verifylist = [ - ('backup', [self.share_backup.id]) - ] + arglist = [self.share_backup.id] + verifylist = [('backup', [self.share_backup.id])] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) @@ -130,39 +124,30 @@ def test_share_backup_delete(self): self.assertIsNone(result) def test_share_backup_delete_multiple(self): - share_backups = ( - manila_fakes.FakeShareBackup.create_share_backups( - count=2)) - arglist = [ - share_backups[0].id, - share_backups[1].id - ] - verifylist = [ - ('backup', [share_backups[0].id, share_backups[1].id]) - ] + share_backups = manila_fakes.FakeShareBackup.create_share_backups( + count=2 + ) + arglist = [share_backups[0].id, share_backups[1].id] + verifylist = [('backup', [share_backups[0].id, share_backups[1].id])] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - self.assertEqual(self.backups_mock.delete.call_count, - len(share_backups)) + self.assertEqual( + self.backups_mock.delete.call_count, len(share_backups) + ) self.assertIsNone(result) def test_share_backup_delete_exception(self): - arglist = [ - self.share_backup.id - ] - verifylist = [ - ('backup', [self.share_backup.id]) - ] + arglist = [self.share_backup.id] + verifylist = [('backup', [self.share_backup.id])] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.backups_mock.delete.side_effect = exceptions.CommandError() - self.assertRaises(exceptions.CommandError, - self.cmd.take_action, - parsed_args) + self.assertRaises( + exceptions.CommandError, self.cmd.take_action, parsed_args + ) class TestShareBackupList(TestShareBackup): - columns = [ 'ID', 'Name', @@ -186,18 +171,22 @@ class TestShareBackupList(TestShareBackup): ] def setUp(self): - super(TestShareBackupList, self).setUp() + super().setUp() self.share = manila_fakes.FakeShare.create_one_share() self.shares_mock.get.return_value = self.share - self.backups_list = ( - manila_fakes.FakeShareBackup.create_share_backups( - count=2)) + self.backups_list = manila_fakes.FakeShareBackup.create_share_backups( + count=2 + ) self.backups_mock.list.return_value = self.backups_list - self.values = (oscutils.get_dict_properties( - i._info, self.columns) for i in self.backups_list) - self.detailed_values = (oscutils.get_dict_properties( - i._info, self.detailed_columns) for i in self.backups_list) + self.values = ( + oscutils.get_dict_properties(i._info, self.columns) + for i in self.backups_list + ) + self.detailed_values = ( + oscutils.get_dict_properties(i._info, self.detailed_columns) + for i in self.backups_list + ) self.cmd = osc_share_backups.ListShareBackup(self.app, None) @@ -210,67 +199,74 @@ def test_share_backup_list(self): self.backups_mock.list.assert_called_with( detailed=0, search_opts={ - 'offset': None, 'limit': None, 'name': None, - 'description': None, 'name~': None, 'description~': None, - 'status': None, 'share_id': None + 'offset': None, + 'limit': None, + 'name': None, + 'description': None, + 'name~': None, + 'description~': None, + 'status': None, + 'share_id': None, }, - sort_key=None, sort_dir=None + sort_key=None, + sort_dir=None, ) self.assertEqual(self.columns, columns) self.assertEqual(list(self.values), list(data)) def test_share_backup_list_detail(self): - arglist = [ - '--detail' - ] - verifylist = [ - ('detail', True) - ] + arglist = ['--detail'] + verifylist = [('detail', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.backups_mock.list.assert_called_with( detailed=1, search_opts={ - 'offset': None, 'limit': None, 'name': None, - 'description': None, 'name~': None, 'description~': None, - 'status': None, 'share_id': None + 'offset': None, + 'limit': None, + 'name': None, + 'description': None, + 'name~': None, + 'description~': None, + 'status': None, + 'share_id': None, }, - sort_key=None, sort_dir=None + sort_key=None, + sort_dir=None, ) self.assertEqual(self.detailed_columns, columns) self.assertEqual(list(self.detailed_values), list(data)) def test_share_backup_list_for_share(self): - arglist = [ - '--share', self.share.id - ] - verifylist = [ - ('share', self.share.id) - ] + arglist = ['--share', self.share.id] + verifylist = [('share', self.share.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.backups_mock.list.assert_called_with( detailed=0, search_opts={ - 'offset': None, 'limit': None, 'name': None, - 'description': None, 'name~': None, 'description~': None, - 'status': None, 'share_id': self.share.id + 'offset': None, + 'limit': None, + 'name': None, + 'description': None, + 'name~': None, + 'description~': None, + 'status': None, + 'share_id': self.share.id, }, - sort_key=None, sort_dir=None + sort_key=None, + sort_dir=None, ) self.assertEqual(self.columns, columns) self.assertEqual(list(self.values), list(data)) class TestShareBackupShow(TestShareBackup): - def setUp(self): - super(TestShareBackupShow, self).setUp() - self.share_backup = ( - manila_fakes.FakeShareBackup.create_one_backup() - ) + super().setUp() + self.share_backup = manila_fakes.FakeShareBackup.create_one_backup() self.backups_mock.get.return_value = self.share_backup self.cmd = osc_share_backups.ShowShareBackup(self.app, None) self.data = tuple(self.share_backup._info.values()) @@ -282,40 +278,32 @@ def test_share_backup_show_missing_args(self): self.assertRaises( osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_backup_show(self): - arglist = [ - self.share_backup.id - ] - verifylist = [ - ('backup', self.share_backup.id) - ] + arglist = [self.share_backup.id] + verifylist = [('backup', self.share_backup.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) - self.backups_mock.get.assert_called_with( - self.share_backup.id - ) + self.backups_mock.get.assert_called_with(self.share_backup.id) self.assertCountEqual(self.columns, columns) self.assertCountEqual(self.data, data) class TestShareBackupRestore(TestShareBackup): - def setUp(self): - super(TestShareBackupRestore, self).setUp() - self.share_backup = ( - manila_fakes.FakeShareBackup.create_one_backup() - ) - self.target_share = ( - manila_fakes.FakeShare.create_one_share() - ) + super().setUp() + self.share_backup = manila_fakes.FakeShareBackup.create_one_backup() + self.target_share = manila_fakes.FakeShare.create_one_share() self.backups_mock.get.return_value = self.share_backup self.shares_mock.get.return_value = self.target_share - self.cmd = osc_share_backups.RestoreShareBackup( - self.app, None) + self.cmd = osc_share_backups.RestoreShareBackup(self.app, None) def test_share_backup_restore(self): arglist = [ @@ -332,7 +320,8 @@ def test_share_backup_restore(self): def test_share_backup_restore_to_target(self): arglist = [ self.share_backup.id, - '--target-share', self.target_share.id + '--target-share', + self.target_share.id, ] verifylist = [ ('backup', self.share_backup.id), @@ -342,101 +331,77 @@ def test_share_backup_restore_to_target(self): parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.backups_mock.restore.assert_called_with( - self.share_backup.id, - target_share_id=self.target_share.id + self.share_backup.id, target_share_id=self.target_share.id ) self.assertIsNone(result) class TestShareBackupSet(TestShareBackup): - def setUp(self): - super(TestShareBackupSet, self).setUp() - self.share_backup = ( - manila_fakes.FakeShareBackup.create_one_backup() - ) + super().setUp() + self.share_backup = manila_fakes.FakeShareBackup.create_one_backup() self.backups_mock.get.return_value = self.share_backup self.cmd = osc_share_backups.SetShareBackup(self.app, None) def test_set_share_backup_name(self): - arglist = [ - self.share_backup.id, - '--name', "FAKE_SHARE_BACKUP_NAME" - ] + arglist = [self.share_backup.id, '--name', "FAKE_SHARE_BACKUP_NAME"] verifylist = [ ('backup', self.share_backup.id), - ('name', "FAKE_SHARE_BACKUP_NAME") + ('name', "FAKE_SHARE_BACKUP_NAME"), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - self.backups_mock.update.assert_called_with(self.share_backup, - name=parsed_args.name) + self.backups_mock.update.assert_called_with( + self.share_backup, name=parsed_args.name + ) self.assertIsNone(result) def test_set_backup_status(self): - arglist = [ - self.share_backup.id, - '--status', 'available' - ] + arglist = [self.share_backup.id, '--status', 'available'] verifylist = [ ('backup', self.share_backup.id), - ('status', 'available') + ('status', 'available'), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.backups_mock.reset_status.assert_called_with( - self.share_backup, - parsed_args.status) + self.share_backup, parsed_args.status + ) self.assertIsNone(result) class TestShareBackupUnset(TestShareBackup): - def setUp(self): - super(TestShareBackupUnset, self).setUp() + super().setUp() - self.share_backup = ( - manila_fakes.FakeShareBackup.create_one_backup() - ) + self.share_backup = manila_fakes.FakeShareBackup.create_one_backup() self.backups_mock.get.return_value = self.share_backup self.cmd = osc_share_backups.UnsetShareBackup(self.app, None) def test_unset_backup_name(self): - arglist = [ - self.share_backup.id, - '--name' - ] - verifylist = [ - ('backup', self.share_backup.id), - ('name', True) - ] + arglist = [self.share_backup.id, '--name'] + verifylist = [('backup', self.share_backup.id), ('name', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.backups_mock.update.assert_called_with( - self.share_backup, - name=None) + self.share_backup, name=None + ) self.assertIsNone(result) def test_unset_backup_description(self): - arglist = [ - self.share_backup.id, - '--description' - ] - verifylist = [ - ('backup', self.share_backup.id), - ('description', True) - ] + arglist = [self.share_backup.id, '--description'] + verifylist = [('backup', self.share_backup.id), ('description', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.backups_mock.update.assert_called_with( - self.share_backup, - description=None) + self.share_backup, description=None + ) self.assertIsNone(result) diff --git a/manilaclient/tests/unit/osc/v2/test_share_group_snapshots.py b/manilaclient/tests/unit/osc/v2/test_share_group_snapshots.py index ca7c233e..4644f3cc 100644 --- a/manilaclient/tests/unit/osc/v2/test_share_group_snapshots.py +++ b/manilaclient/tests/unit/osc/v2/test_share_group_snapshots.py @@ -21,7 +21,8 @@ from manilaclient import api_versions from manilaclient.osc.v2 import ( - share_group_snapshots as osc_share_group_snapshots) + share_group_snapshots as osc_share_group_snapshots, +) from manilaclient.tests.unit.osc import osc_utils from manilaclient.tests.unit.osc.v2 import fakes as manila_fakes @@ -29,42 +30,38 @@ class TestShareGroupSnapshot(manila_fakes.TestShare): - def setUp(self): - super(TestShareGroupSnapshot, self).setUp() + super().setUp() self.groups_mock = self.app.client_manager.share.share_groups self.groups_mock.reset_mock() self.group_snapshot_mocks = ( - self.app.client_manager.share.share_group_snapshots) + self.app.client_manager.share.share_group_snapshots + ) self.group_snapshot_mocks.reset_mock() self.app.client_manager.share.api_version = api_versions.APIVersion( - api_versions.MAX_VERSION) + api_versions.MAX_VERSION + ) class TestCreateShareGroupSnapshot(TestShareGroupSnapshot): - def setUp(self): - super(TestCreateShareGroupSnapshot, self).setUp() + super().setUp() - self.share_group = ( - manila_fakes.FakeShareGroup.create_one_share_group() - ) + self.share_group = manila_fakes.FakeShareGroup.create_one_share_group() self.groups_mock.get.return_value = self.share_group - self.share_group_snapshot = ( - manila_fakes.FakeShareGroupSnapshot - .create_one_share_group_snapshot() - ) + self.share_group_snapshot = manila_fakes.FakeShareGroupSnapshot.create_one_share_group_snapshot() self.group_snapshot_mocks.create.return_value = ( - self.share_group_snapshot) - self.group_snapshot_mocks.get.return_value = ( - self.share_group_snapshot) + self.share_group_snapshot + ) + self.group_snapshot_mocks.get.return_value = self.share_group_snapshot self.cmd = osc_share_group_snapshots.CreateShareGroupSnapshot( - self.app, None) + self.app, None + ) self.data = tuple(self.share_group_snapshot._info.values()) self.columns = tuple(self.share_group_snapshot._info.keys()) @@ -75,24 +72,22 @@ def test_share_group_snapshot_create_missing_args(self): self.assertRaises( osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_group_snapshot_create(self): - arglist = [ - self.share_group.id - ] - verifylist = [ - ('share_group', self.share_group.id) - ] + arglist = [self.share_group.id] + verifylist = [('share_group', self.share_group.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.group_snapshot_mocks.create.assert_called_with( - self.share_group, - name=None, - description=None + self.share_group, name=None, description=None ) self.assertCountEqual(self.columns, columns) @@ -101,13 +96,15 @@ def test_share_group_snapshot_create(self): def test_share_group_snapshot_create_options(self): arglist = [ self.share_group.id, - '--name', self.share_group_snapshot.name, - '--description', self.share_group_snapshot.description + '--name', + self.share_group_snapshot.name, + '--description', + self.share_group_snapshot.description, ] verifylist = [ ('share_group', self.share_group.id), ('name', self.share_group_snapshot.name), - ('description', self.share_group_snapshot.description) + ('description', self.share_group_snapshot.description), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -124,14 +121,8 @@ def test_share_group_snapshot_create_options(self): self.assertCountEqual(self.data, data) def test_share_group_snapshot_create_wait(self): - arglist = [ - self.share_group.id, - '--wait' - ] - verifylist = [ - ('share_group', self.share_group.id), - ('wait', True) - ] + arglist = [self.share_group.id, '--wait'] + verifylist = [('share_group', self.share_group.id), ('wait', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -144,20 +135,15 @@ def test_share_group_snapshot_create_wait(self): description=None, ) self.group_snapshot_mocks.get.assert_called_with( - self.share_group_snapshot.id) + self.share_group_snapshot.id + ) self.assertCountEqual(self.columns, columns) self.assertCountEqual(self.data, data) @mock.patch('manilaclient.osc.v2.share_group_snapshots.LOG') def test_share_group_snapshot_create_wait_exception(self, mock_logger): - arglist = [ - self.share_group.id, - '--wait' - ] - verifylist = [ - ('share_group', self.share_group.id), - ('wait', True) - ] + arglist = [self.share_group.id, '--wait'] + verifylist = [('share_group', self.share_group.id), ('wait', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -171,60 +157,57 @@ def test_share_group_snapshot_create_wait_exception(self, mock_logger): ) mock_logger.error.assert_called_with( - "ERROR: Share group snapshot is in error state.") + "ERROR: Share group snapshot is in error state." + ) self.group_snapshot_mocks.get.assert_called_with( - self.share_group_snapshot.id) + self.share_group_snapshot.id + ) self.assertCountEqual(self.columns, columns) self.assertCountEqual(self.data, data) class TestDeleteShareGroupSnapshot(TestShareGroupSnapshot): - def setUp(self): - super(TestDeleteShareGroupSnapshot, self).setUp() + super().setUp() - self.share_group_snapshot = ( - manila_fakes.FakeShareGroupSnapshot - .create_one_share_group_snapshot()) - self.group_snapshot_mocks.get.return_value = ( - self.share_group_snapshot) + self.share_group_snapshot = manila_fakes.FakeShareGroupSnapshot.create_one_share_group_snapshot() + self.group_snapshot_mocks.get.return_value = self.share_group_snapshot self.cmd = osc_share_group_snapshots.DeleteShareGroupSnapshot( - self.app, None) + self.app, None + ) def test_share_group_snapshot_delete_missing_args(self): arglist = [] verifylist = [] - self.assertRaises(osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_group_snapshot_delete(self): - arglist = [ - self.share_group_snapshot.id - ] - verifylist = [ - ('share_group_snapshot', [self.share_group_snapshot.id]) - ] + arglist = [self.share_group_snapshot.id] + verifylist = [('share_group_snapshot', [self.share_group_snapshot.id])] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.group_snapshot_mocks.delete.assert_called_with( - self.share_group_snapshot, - force=False) + self.share_group_snapshot, force=False + ) self.assertIsNone(result) def test_share_group_snapshot_delete_force(self): - arglist = [ - self.share_group_snapshot.id, - '--force' - ] + arglist = [self.share_group_snapshot.id, '--force'] verifylist = [ ('share_group_snapshot', [self.share_group_snapshot.id]), - ('force', True) + ('force', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -232,54 +215,51 @@ def test_share_group_snapshot_delete_force(self): result = self.cmd.take_action(parsed_args) self.group_snapshot_mocks.delete.assert_called_with( - self.share_group_snapshot, - force=True) + self.share_group_snapshot, force=True + ) self.assertIsNone(result) def test_share_group_snapshot_delete_multiple(self): share_group_snapshots = ( - manila_fakes.FakeShareGroupSnapshot. - create_share_group_snapshots(count=2)) - arglist = [ - share_group_snapshots[0].id, - share_group_snapshots[1].id - ] + manila_fakes.FakeShareGroupSnapshot.create_share_group_snapshots( + count=2 + ) + ) + arglist = [share_group_snapshots[0].id, share_group_snapshots[1].id] verifylist = [ - ('share_group_snapshot', [share_group_snapshots[0].id, ( - share_group_snapshots[1].id)]) + ( + 'share_group_snapshot', + [share_group_snapshots[0].id, (share_group_snapshots[1].id)], + ) ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - self.assertEqual(self.group_snapshot_mocks.delete.call_count, - len(share_group_snapshots)) + self.assertEqual( + self.group_snapshot_mocks.delete.call_count, + len(share_group_snapshots), + ) self.assertIsNone(result) def test_share_group_snapshot_delete_exception(self): - arglist = [ - self.share_group_snapshot.id - ] - verifylist = [ - ('share_group_snapshot', [self.share_group_snapshot.id]) - ] + arglist = [self.share_group_snapshot.id] + verifylist = [('share_group_snapshot', [self.share_group_snapshot.id])] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.group_snapshot_mocks.delete.side_effect = ( - exceptions.CommandError()) - self.assertRaises(exceptions.CommandError, - self.cmd.take_action, - parsed_args) + exceptions.CommandError() + ) + self.assertRaises( + exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_share_group_snapshot_delete_wait(self): - arglist = [ - self.share_group_snapshot.id, - '--wait' - ] + arglist = [self.share_group_snapshot.id, '--wait'] verifylist = [ ('share_group_snapshot', [self.share_group_snapshot.id]), - ('wait', True) + ('wait', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -288,45 +268,38 @@ def test_share_group_snapshot_delete_wait(self): result = self.cmd.take_action(parsed_args) self.group_snapshot_mocks.delete.assert_called_with( - self.share_group_snapshot, - force=False) + self.share_group_snapshot, force=False + ) self.group_snapshot_mocks.get.assert_called_with( - self.share_group_snapshot.id) + self.share_group_snapshot.id + ) self.assertIsNone(result) def test_share_group_snapshot_delete_wait_exception(self): - arglist = [ - self.share_group_snapshot.id, - '--wait' - ] + arglist = [self.share_group_snapshot.id, '--wait'] verifylist = [ ('share_group_snapshot', [self.share_group_snapshot.id]), - ('wait', True) + ('wait', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) with mock.patch('osc_lib.utils.wait_for_delete', return_value=False): self.assertRaises( - exceptions.CommandError, - self.cmd.take_action, - parsed_args + exceptions.CommandError, self.cmd.take_action, parsed_args ) class TestShowShareGroupSnapshot(TestShareGroupSnapshot): - def setUp(self): - super(TestShowShareGroupSnapshot, self).setUp() + super().setUp() - self.share_group_snapshot = ( - manila_fakes.FakeShareGroupSnapshot - .create_one_share_group_snapshot()) - self.group_snapshot_mocks.get.return_value = ( - self.share_group_snapshot) + self.share_group_snapshot = manila_fakes.FakeShareGroupSnapshot.create_one_share_group_snapshot() + self.group_snapshot_mocks.get.return_value = self.share_group_snapshot self.cmd = osc_share_group_snapshots.ShowShareGroupSnapshot( - self.app, None) + self.app, None + ) self.data = tuple(self.share_group_snapshot._info.values()) self.columns = tuple(self.share_group_snapshot._info.keys()) @@ -337,15 +310,15 @@ def test_share_group_snapshot_show_missing_args(self): self.assertRaises( osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_group_show(self): - arglist = [ - self.share_group_snapshot.id - ] - verifylist = [ - ('share_group_snapshot', self.share_group_snapshot.id) - ] + arglist = [self.share_group_snapshot.id] + verifylist = [('share_group_snapshot', self.share_group_snapshot.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -360,18 +333,15 @@ def test_share_group_show(self): class TestSetShareGroupSnapshot(TestShareGroupSnapshot): - def setUp(self): - super(TestSetShareGroupSnapshot, self).setUp() + super().setUp() - self.share_group_snapshot = ( - manila_fakes.FakeShareGroupSnapshot - .create_one_share_group_snapshot()) - self.group_snapshot_mocks.get.return_value = ( - self.share_group_snapshot) + self.share_group_snapshot = manila_fakes.FakeShareGroupSnapshot.create_one_share_group_snapshot() + self.group_snapshot_mocks.get.return_value = self.share_group_snapshot self.cmd = osc_share_group_snapshots.SetShareGroupSnapshot( - self.app, None) + self.app, None + ) self.data = tuple(self.share_group_snapshot._info.values()) self.columns = tuple(self.share_group_snapshot._info.keys()) @@ -379,16 +349,19 @@ def setUp(self): def test_set_share_group_snapshot_name_description(self): group_snapshot_name = 'group-snapshot-name-' + uuid.uuid4().hex group_snapshot_description = ( - 'group-snapshot-description-' + uuid.uuid4().hex) + 'group-snapshot-description-' + uuid.uuid4().hex + ) arglist = [ self.share_group_snapshot.id, - '--name', group_snapshot_name, - '--description', group_snapshot_description + '--name', + group_snapshot_name, + '--description', + group_snapshot_description, ] verifylist = [ ('share_group_snapshot', self.share_group_snapshot.id), ('name', group_snapshot_name), - ('description', group_snapshot_description) + ('description', group_snapshot_description), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -397,79 +370,65 @@ def test_set_share_group_snapshot_name_description(self): self.group_snapshot_mocks.update.assert_called_with( self.share_group_snapshot, name=parsed_args.name, - description=parsed_args.description) + description=parsed_args.description, + ) self.assertIsNone(result) def test_set_share_group_snapshot_status(self): - arglist = [ - self.share_group_snapshot.id, - '--status', 'available' - ] + arglist = [self.share_group_snapshot.id, '--status', 'available'] verifylist = [ ('share_group_snapshot', self.share_group_snapshot.id), - ('status', 'available') + ('status', 'available'), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.group_snapshot_mocks.reset_state.assert_called_with( - self.share_group_snapshot, - 'available') + self.share_group_snapshot, 'available' + ) self.assertIsNone(result) def test_set_share_group_snapshot_exception(self): - arglist = [ - self.share_group_snapshot.id, - '--status', 'available' - ] + arglist = [self.share_group_snapshot.id, '--status', 'available'] verifylist = [ ('share_group_snapshot', self.share_group_snapshot.id), - ('status', 'available') + ('status', 'available'), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.group_snapshot_mocks.reset_state.side_effect = Exception() self.assertRaises( - exceptions.CommandError, - self.cmd.take_action, - parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) class TestUnsetShareGroupSnapshot(TestShareGroupSnapshot): - def setUp(self): - super(TestUnsetShareGroupSnapshot, self).setUp() + super().setUp() - self.share_group_snapshot = ( - manila_fakes.FakeShareGroupSnapshot - .create_one_share_group_snapshot()) - self.group_snapshot_mocks.get.return_value = ( - self.share_group_snapshot) + self.share_group_snapshot = manila_fakes.FakeShareGroupSnapshot.create_one_share_group_snapshot() + self.group_snapshot_mocks.get.return_value = self.share_group_snapshot self.cmd = osc_share_group_snapshots.UnsetShareGroupSnapshot( - self.app, None) + self.app, None + ) def test_unset_share_group_snapshot_name_description(self): - arglist = [ - self.share_group_snapshot.id, - '--name', - '--description' - ] + arglist = [self.share_group_snapshot.id, '--name', '--description'] verifylist = [ ('share_group_snapshot', self.share_group_snapshot.id), ('name', True), - ('description', True) + ('description', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.group_snapshot_mocks.update.assert_called_with( - self.share_group_snapshot, - name='', - description='') + self.share_group_snapshot, name='', description='' + ) self.assertIsNone(result) def test_unset_share_group_snapshot_name_exception(self): @@ -486,13 +445,11 @@ def test_unset_share_group_snapshot_name_exception(self): self.group_snapshot_mocks.update.side_effect = Exception() self.assertRaises( - exceptions.CommandError, - self.cmd.take_action, - parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) class TestListShareGroupSnapshot(TestShareGroupSnapshot): - columns = [ 'ID', 'Name', @@ -501,22 +458,19 @@ class TestListShareGroupSnapshot(TestShareGroupSnapshot): ] def setUp(self): - super(TestListShareGroupSnapshot, self).setUp() + super().setUp() - self.share_group = ( - manila_fakes.FakeShareGroup.create_one_share_group() - ) + self.share_group = manila_fakes.FakeShareGroup.create_one_share_group() self.groups_mock.get.return_value = self.share_group - self.share_group_snapshot = ( - manila_fakes.FakeShareGroupSnapshot - .create_one_share_group_snapshot({ - 'share_group_id': self.share_group.id - })) + self.share_group_snapshot = manila_fakes.FakeShareGroupSnapshot.create_one_share_group_snapshot( + {'share_group_id': self.share_group.id} + ) self.share_group_snapshots_list = [self.share_group_snapshot] self.group_snapshot_mocks.list.return_value = ( - self.share_group_snapshots_list) + self.share_group_snapshots_list + ) self.values = ( oscutils.get_dict_properties(s._info, self.columns) @@ -524,7 +478,8 @@ def setUp(self): ) self.cmd = osc_share_group_snapshots.ListShareGroupSnapshot( - self.app, None) + self.app, None + ) def test_share_group_snapshot_list_no_options(self): arglist = [] @@ -542,7 +497,8 @@ def test_share_group_snapshot_list_no_options(self): 'share_group_id': None, 'limit': None, 'offset': None, - }) + } + ) self.assertEqual(self.columns, columns) self.assertEqual(list(self.values), list(data)) @@ -555,12 +511,13 @@ def test_share_group_snapshot_list_detail_all_projects(self): 'Description', 'Created At', 'Share Group ID', - 'Project ID' + 'Project ID', ] values = ( oscutils.get_dict_properties(s._info, columns_detail) - for s in self.share_group_snapshots_list) + for s in self.share_group_snapshots_list + ) arglist = [ '--detailed', @@ -584,16 +541,20 @@ def test_share_group_snapshot_list_detail_all_projects(self): 'share_group_id': None, 'limit': None, 'offset': None, - }) + } + ) self.assertEqual(columns_detail, columns) self.assertEqual(list(values), list(data)) def test_share_group_snapshot_list_search_options(self): arglist = [ - '--name', self.share_group_snapshot.name, - '--status', self.share_group_snapshot.status, - '--share-group', self.share_group.id, + '--name', + self.share_group_snapshot.name, + '--status', + self.share_group_snapshot.status, + '--share-group', + self.share_group.id, ] verifylist = [ ('name', self.share_group_snapshot.name), @@ -614,35 +575,29 @@ def test_share_group_snapshot_list_search_options(self): 'share_group_id': self.share_group.id, 'limit': None, 'offset': None, - }) + } + ) self.assertEqual(self.columns, columns) self.assertEqual(list(self.values), list(data)) class TestListShareGroupSnapshotMembers(TestShareGroupSnapshot): - columns = [ 'Share ID', 'Size', ] def setUp(self): - super(TestListShareGroupSnapshotMembers, self).setUp() + super().setUp() self.share = manila_fakes.FakeShare.create_one_share() - self.share_group_snapshot = ( - manila_fakes.FakeShareGroupSnapshot - .create_one_share_group_snapshot({ - 'members': [{ - 'share_id': self.share.id, - 'size': self.share.size - }] - })) + self.share_group_snapshot = manila_fakes.FakeShareGroupSnapshot.create_one_share_group_snapshot( + {'members': [{'share_id': self.share.id, 'size': self.share.size}]} + ) - self.group_snapshot_mocks.get.return_value = ( - self.share_group_snapshot) + self.group_snapshot_mocks.get.return_value = self.share_group_snapshot self.values = ( oscutils.get_dict_properties(s, self.columns) @@ -650,22 +605,20 @@ def setUp(self): ) self.cmd = osc_share_group_snapshots.ListShareGroupSnapshotMembers( - self.app, None) + self.app, None + ) def test_share_group_snapshot_list_members(self): - arglist = [ - self.share_group_snapshot.id - ] - verifylist = [ - ('share_group_snapshot', self.share_group_snapshot.id) - ] + arglist = [self.share_group_snapshot.id] + verifylist = [('share_group_snapshot', self.share_group_snapshot.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.group_snapshot_mocks.get.assert_called_with( - self.share_group_snapshot.id) + self.share_group_snapshot.id + ) self.assertEqual(self.columns, columns) self.assertEqual(list(self.values), list(data)) diff --git a/manilaclient/tests/unit/osc/v2/test_share_group_type.py b/manilaclient/tests/unit/osc/v2/test_share_group_type.py index 2d311da1..4e56ea36 100644 --- a/manilaclient/tests/unit/osc/v2/test_share_group_type.py +++ b/manilaclient/tests/unit/osc/v2/test_share_group_type.py @@ -35,23 +35,23 @@ class TestShareGroupType(manila_fakes.TestShare): - def setUp(self): - super(TestShareGroupType, self).setUp() + super().setUp() self.sgt_mock = self.app.client_manager.share.share_group_types self.sgt_mock.reset_mock() self.app.client_manager.share.api_version = api_versions.APIVersion( - api_versions.MAX_VERSION) + api_versions.MAX_VERSION + ) class TestShareGroupTypeCreate(TestShareGroupType): - def setUp(self): - super(TestShareGroupTypeCreate, self).setUp() + super().setUp() - self.share_types = ( - manila_fakes.FakeShareType.create_share_types(count=2)) + self.share_types = manila_fakes.FakeShareType.create_share_types( + count=2 + ) formatted_share_types = [] @@ -60,22 +60,23 @@ def setUp(self): self.share_group_type = ( manila_fakes.FakeShareGroupType.create_one_share_group_type( - attrs={ - 'share_types': formatted_share_types - } - )) + attrs={'share_types': formatted_share_types} + ) + ) self.share_group_type_formatted = ( manila_fakes.FakeShareGroupType.create_one_share_group_type( attrs={ 'id': self.share_group_type['id'], 'name': self.share_group_type['name'], - 'share_types': formatted_share_types + 'share_types': formatted_share_types, } - )) + ) + ) formatted_sgt = utils.format_share_group_type( - self.share_group_type_formatted) + self.share_group_type_formatted + ) self.sgt_mock.create.return_value = self.share_group_type self.sgt_mock.get.return_value = self.share_group_type @@ -96,13 +97,16 @@ def test_share_group_type_create_required_args(self): ] verifylist = [ ('name', self.share_group_type.name), - ('share_types', [self.share_types[0].name, - self.share_types[1].name]) + ( + 'share_types', + [self.share_types[0].name, self.share_types[1].name], + ), ] with mock.patch( 'manilaclient.common.apiclient.utils.find_resource', - side_effect=[self.share_types[0], self.share_types[1]]): + side_effect=[self.share_types[0], self.share_types[1]], + ): parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) @@ -112,7 +116,9 @@ def test_share_group_type_create_required_args(self): is_public=True, name=self.share_group_type.name, share_types=[ - self.share_types[0].name, self.share_types[1].name] + self.share_types[0].name, + self.share_types[1].name, + ], ) self.assertCountEqual(self.columns, columns) @@ -124,31 +130,37 @@ def test_share_group_type_create_missing_required_arg(self): arglist = [ self.share_group_type.name, ] - verifylist = [ - ('name', self.share_group_type.name) - ] + verifylist = [('name', self.share_group_type.name)] - self.assertRaises(osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_group_type_create_private(self): arglist = [ self.share_group_type.name, self.share_types[0].name, self.share_types[1].name, - '--public', 'False' + '--public', + 'False', ] verifylist = [ ('name', self.share_group_type.name), - ('share_types', [self.share_types[0].name, - self.share_types[1].name]), - ('public', 'False') + ( + 'share_types', + [self.share_types[0].name, self.share_types[1].name], + ), + ('public', 'False'), ] with mock.patch( 'manilaclient.common.apiclient.utils.find_resource', - side_effect=[self.share_types[0], - self.share_types[1]]): + side_effect=[self.share_types[0], self.share_types[1]], + ): parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) @@ -157,32 +169,36 @@ def test_share_group_type_create_private(self): group_specs={}, is_public=False, name=self.share_group_type.name, - share_types=[self.share_types[0].name, - self.share_types[1].name] + share_types=[ + self.share_types[0].name, + self.share_types[1].name, + ], ) self.assertCountEqual(self.columns, columns) self.assertCountEqual(self.data, data) def test_share_group_type_create_group_specs(self): - arglist = [ self.share_group_type.name, self.share_types[0].name, self.share_types[1].name, - '--group-specs', 'consistent_snapshot_support=true' + '--group-specs', + 'consistent_snapshot_support=true', ] verifylist = [ ('name', self.share_group_type.name), - ('share_types', [self.share_types[0].name, - self.share_types[1].name]), - ('group_specs', ['consistent_snapshot_support=true']) + ( + 'share_types', + [self.share_types[0].name, self.share_types[1].name], + ), + ('group_specs', ['consistent_snapshot_support=true']), ] with mock.patch( 'manilaclient.common.apiclient.utils.find_resource', - side_effect=[self.share_types[0], - self.share_types[1]]): + side_effect=[self.share_types[0], self.share_types[1]], + ): parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) @@ -192,7 +208,9 @@ def test_share_group_type_create_group_specs(self): is_public=True, name=self.share_group_type.name, share_types=[ - self.share_types[0].name, self.share_types[1].name] + self.share_types[0].name, + self.share_types[1].name, + ], ) self.assertCountEqual(self.columns, columns) @@ -202,19 +220,24 @@ def test_create_share_group_type(self): arglist = [ self.share_group_type.name, self.share_types[0].name, - self.share_types[1].name + self.share_types[1].name, ] verifylist = [ ('name', self.share_group_type.name), - ('share_types', [self.share_types[0].name, - self.share_types[1].name]) + ( + 'share_types', + [self.share_types[0].name, self.share_types[1].name], + ), ] with mock.patch( 'manilaclient.common.apiclient.utils.find_resource', - side_effect=[self.share_types[0], - self.share_types[1], - self.share_group_type]): + side_effect=[ + self.share_types[0], + self.share_types[1], + self.share_group_type, + ], + ): parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) @@ -222,8 +245,10 @@ def test_create_share_group_type(self): group_specs={}, is_public=True, name=self.share_group_type.name, - share_types=[self.share_types[0].name, - self.share_types[1].name] + share_types=[ + self.share_types[0].name, + self.share_types[1].name, + ], ) self.assertCountEqual(self.columns, columns) @@ -231,34 +256,31 @@ def test_create_share_group_type(self): class TestShareGroupTypeDelete(TestShareGroupType): - def setUp(self): - super(TestShareGroupTypeDelete, self).setUp() + super().setUp() self.share_group_types = ( - manila_fakes.FakeShareGroupType.create_share_group_types(count=2)) + manila_fakes.FakeShareGroupType.create_share_group_types(count=2) + ) self.sgt_mock.delete.return_value = None self.sgt_mock.get = ( manila_fakes.FakeShareGroupType.get_share_group_types( - self.share_group_types)) + self.share_group_types + ) + ) # Get the command object to test self.cmd = osc_share_group_types.DeleteShareGroupType(self.app, None) def test_share_group_type_delete_one(self): - arglist = [ - self.share_group_types[0].name - ] + arglist = [self.share_group_types[0].name] - verifylist = [ - ('share_group_types', [self.share_group_types[0].name]) - ] + verifylist = [('share_group_types', [self.share_group_types[0].name])] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - self.sgt_mock.delete.assert_called_with( - self.share_group_types[0]) + self.sgt_mock.delete.assert_called_with(self.share_group_types[0]) self.assertIsNone(result) def test_share_group_type_delete_multiple(self): @@ -289,16 +311,13 @@ def test_delete_share_group_type_with_exception(self): parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.sgt_mock.delete.side_effect = exceptions.CommandError() self.assertRaises( - exceptions.CommandError, self.cmd.take_action, parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_delete_share_group_type(self): - arglist = [ - self.share_group_types[0].name - ] + arglist = [self.share_group_types[0].name] - verifylist = [ - ('share_group_types', [self.share_group_types[0].name]) - ] + verifylist = [('share_group_types', [self.share_group_types[0].name])] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -309,13 +328,14 @@ def test_delete_share_group_type(self): class TestShareGroupTypeSet(TestShareGroupType): - def setUp(self): - super(TestShareGroupTypeSet, self).setUp() + super().setUp() self.share_group_type = ( manila_fakes.FakeShareGroupType.create_one_share_group_type( - methods={'set_keys': None, 'update': None})) + methods={'set_keys': None, 'update': None} + ) + ) self.sgt_mock.get.return_value = self.share_group_type # Get the command object to test @@ -324,106 +344,106 @@ def setUp(self): def test_share_group_type_set_group_specs(self): arglist = [ self.share_group_type.id, - '--group-specs', 'consistent_snapshot_support=true' + '--group-specs', + 'consistent_snapshot_support=true', ] verifylist = [ ('share_group_type', self.share_group_type.id), - ('group_specs', ['consistent_snapshot_support=true']) + ('group_specs', ['consistent_snapshot_support=true']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.share_group_type.set_keys.assert_called_with( - {'consistent_snapshot_support': 'True'}) + {'consistent_snapshot_support': 'True'} + ) self.assertIsNone(result) def test_share_group_type_set_extra_specs_exception(self): arglist = [ self.share_group_type.id, - '--group-specs', 'snapshot_support=true' + '--group-specs', + 'snapshot_support=true', ] verifylist = [ ('share_group_type', self.share_group_type.id), - ('group_specs', ['snapshot_support=true']) + ('group_specs', ['snapshot_support=true']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.share_group_type.set_keys.side_effect = BadRequest() self.assertRaises( - exceptions.CommandError, self.cmd.take_action, parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) class TestShareGroupTypeUnset(TestShareGroupType): - def setUp(self): - super(TestShareGroupTypeUnset, self).setUp() + super().setUp() self.share_group_type = ( manila_fakes.FakeShareGroupType.create_one_share_group_type( - methods={'unset_keys': None})) + methods={'unset_keys': None} + ) + ) self.sgt_mock.get.return_value = self.share_group_type # Get the command object to test self.cmd = osc_share_group_types.UnsetShareGroupType(self.app, None) def test_share_group_type_unset_extra_specs(self): - arglist = [ - self.share_group_type.id, - 'consistent_snapshot_support' - ] + arglist = [self.share_group_type.id, 'consistent_snapshot_support'] verifylist = [ ('share_group_type', self.share_group_type.id), - ('group_specs', ['consistent_snapshot_support']) + ('group_specs', ['consistent_snapshot_support']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.share_group_type.unset_keys.assert_called_with( - ['consistent_snapshot_support']) + ['consistent_snapshot_support'] + ) self.assertIsNone(result) def test_share_group_type_unset_exception(self): - arglist = [ - self.share_group_type.id, - 'snapshot_support' - ] + arglist = [self.share_group_type.id, 'snapshot_support'] verifylist = [ ('share_group_type', self.share_group_type.id), - ('group_specs', ['snapshot_support']) + ('group_specs', ['snapshot_support']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.share_group_type.unset_keys.side_effect = NotFound() self.assertRaises( - exceptions.CommandError, self.cmd.take_action, parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) class TestShareGroupTypeList(TestShareGroupType): - def setUp(self): - super(TestShareGroupTypeList, self).setUp() + super().setUp() self.share_group_types = ( - manila_fakes.FakeShareGroupType.create_share_group_types()) + manila_fakes.FakeShareGroupType.create_share_group_types() + ) self.sgt_mock.list.return_value = self.share_group_types # Get the command object to test self.cmd = osc_share_group_types.ListShareGroupType(self.app, None) - self.values = (oscutils.get_dict_properties( - s._info, COLUMNS) for s in self.share_group_types) + self.values = ( + oscutils.get_dict_properties(s._info, COLUMNS) + for s in self.share_group_types + ) def test_share_group_type_list_no_options(self): arglist = [] - verifylist = [ - ('all', False) - ] + verifylist = [('all', False)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.sgt_mock.list.assert_called_once_with( - search_opts={}, - show_all=False + search_opts={}, show_all=False ) self.assertEqual(COLUMNS, columns) self.assertEqual(list(self.values), list(data)) @@ -432,45 +452,41 @@ def test_share_group_type_list_all(self): arglist = [ '--all', ] - verifylist = [ - ('all', True) - ] + verifylist = [('all', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.sgt_mock.list.assert_called_once_with( - search_opts={}, - show_all=True) + search_opts={}, show_all=True + ) self.assertEqual(COLUMNS, columns) self.assertEqual(list(self.values), list(data)) def test_share_group_type_list_group_specs(self): - arglist = [ - '--group-specs', 'consistent_snapshot_support=true' - ] - verifylist = [ - ('group_specs', ['consistent_snapshot_support=true']) - ] + arglist = ['--group-specs', 'consistent_snapshot_support=true'] + verifylist = [('group_specs', ['consistent_snapshot_support=true'])] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.sgt_mock.list.assert_called_once_with( - search_opts={'group_specs': { - 'consistent_snapshot_support': 'True'}}, - show_all=False) + search_opts={ + 'group_specs': {'consistent_snapshot_support': 'True'} + }, + show_all=False, + ) self.assertEqual(COLUMNS, columns) self.assertEqual(list(self.values), list(data)) class TestShareGroupTypeShow(TestShareGroupType): - def setUp(self): - super(TestShareGroupTypeShow, self).setUp() + super().setUp() - self.share_types = ( - manila_fakes.FakeShareType.create_share_types(count=2)) + self.share_types = manila_fakes.FakeShareType.create_share_types( + count=2 + ) formatted_share_types = [] @@ -479,22 +495,23 @@ def setUp(self): self.share_group_type = ( manila_fakes.FakeShareGroupType.create_one_share_group_type( - attrs={ - 'share_types': formatted_share_types - } - )) + attrs={'share_types': formatted_share_types} + ) + ) self.share_group_type_formatted = ( manila_fakes.FakeShareGroupType.create_one_share_group_type( attrs={ 'id': self.share_group_type['id'], 'name': self.share_group_type['name'], - 'share_types': formatted_share_types + 'share_types': formatted_share_types, } - )) + ) + ) formatted_sgt = utils.format_share_group_type( - self.share_group_type_formatted) + self.share_group_type_formatted + ) self.sgt_mock.get.return_value = self.share_group_type @@ -505,12 +522,8 @@ def setUp(self): self.columns = tuple(formatted_sgt.keys()) def test_share_group_type_show(self): - arglist = [ - self.share_group_type.name - ] - verifylist = [ - ("share_group_type", self.share_group_type.name) - ] + arglist = [self.share_group_type.name] + verifylist = [("share_group_type", self.share_group_type.name)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) diff --git a/manilaclient/tests/unit/osc/v2/test_share_group_type_access.py b/manilaclient/tests/unit/osc/v2/test_share_group_type_access.py index fd2000de..95d2b691 100644 --- a/manilaclient/tests/unit/osc/v2/test_share_group_type_access.py +++ b/manilaclient/tests/unit/osc/v2/test_share_group_type_access.py @@ -21,16 +21,17 @@ class TestShareGroupTypeAccess(manila_fakes.TestShare): - def setUp(self): - super(TestShareGroupTypeAccess, self).setUp() + super().setUp() self.type_access_mock = ( - self.app.client_manager.share.share_group_type_access) + self.app.client_manager.share.share_group_type_access + ) self.type_access_mock.reset_mock() self.share_group_types_mock = ( - self.app.client_manager.share.share_group_types) + self.app.client_manager.share.share_group_types + ) self.share_group_types_mock.reset_mock() self.projects_mock = self.app.client_manager.identity.projects @@ -38,9 +39,8 @@ def setUp(self): class TestShareGroupTypeAccessAllow(TestShareGroupTypeAccess): - def setUp(self): - super(TestShareGroupTypeAccessAllow, self).setUp() + super().setUp() self.project = identity_fakes.FakeProject.create_one_project() @@ -58,13 +58,10 @@ def setUp(self): self.cmd = osc_sgta.ShareGroupTypeAccessAllow(self.app, None) def test_share_group_type_access_create(self): - arglist = [ - self.share_group_type.id, - self.project.id - ] + arglist = [self.share_group_type.id, self.project.id] verifylist = [ ('share_group_type', self.share_group_type.id), - ('projects', [self.project.id]) + ('projects', [self.project.id]), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -72,36 +69,33 @@ def test_share_group_type_access_create(self): result = self.cmd.take_action(parsed_args) self.type_access_mock.add_project_access.assert_called_with( - self.share_group_type, self.project.id) + self.share_group_type, self.project.id + ) self.assertIsNone(result) def test_share_group_type_access_create_invalid_project_exception(self): - arglist = [ - self.share_group_type.id, - 'invalid_project_format' - ] + arglist = [self.share_group_type.id, 'invalid_project_format'] verifylist = [ ('share_group_type', self.share_group_type.id), - ('projects', ['invalid_project_format']) + ('projects', ['invalid_project_format']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.type_access_mock.add_project_access.side_effect = BadRequest() self.assertRaises( - exceptions.CommandError, self.cmd.take_action, parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) class TestShareGroupTypeAccessList(TestShareGroupTypeAccess): - columns = ['Project ID'] data = (('',), ('',)) def setUp(self): - super(TestShareGroupTypeAccessList, self).setUp() + super().setUp() - self.type_access_mock.list.return_value = ( - self.columns, self.data) + self.type_access_mock.list.return_value = (self.columns, self.data) # Get the command object to test self.cmd = osc_sgta.ListShareGroupTypeAccess(self.app, None) @@ -117,15 +111,12 @@ def test_share_group_type_access_list(self): arglist = [ share_group_type.id, ] - verifylist = [ - ('share_group_type', share_group_type.id) - ] + verifylist = [('share_group_type', share_group_type.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) - self.type_access_mock.list.assert_called_once_with( - share_group_type) + self.type_access_mock.list.assert_called_once_with(share_group_type) self.assertEqual(self.columns, columns) self.assertEqual(self.data, tuple(data)) @@ -142,25 +133,25 @@ def test_share_group_type_access_list_public_type(self): arglist = [ share_group_type.id, ] - verifylist = [ - ('share_group_type', share_group_type.id) - ] + verifylist = [('share_group_type', share_group_type.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( - exceptions.CommandError, self.cmd.take_action, parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) class TestShareGroupTypeAccessDeny(TestShareGroupTypeAccess): - def setUp(self): - super(TestShareGroupTypeAccessDeny, self).setUp() + super().setUp() self.project = identity_fakes.FakeProject.create_one_project() self.share_group_type = ( manila_fakes.FakeShareGroupType.create_one_share_group_type( - attrs={'is_public': False})) + attrs={'is_public': False} + ) + ) self.share_group_types_mock.get.return_value = self.share_group_type self.projects_mock.get.return_value = self.project @@ -170,13 +161,10 @@ def setUp(self): self.cmd = osc_sgta.ShareGroupTypeAccessDeny(self.app, None) def test_share_group_type_access_delete(self): - arglist = [ - self.share_group_type.id, - self.project.id - ] + arglist = [self.share_group_type.id, self.project.id] verifylist = [ ('share_group_type', self.share_group_type.id), - ('projects', [self.project.id]) + ('projects', [self.project.id]), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -184,21 +172,20 @@ def test_share_group_type_access_delete(self): result = self.cmd.take_action(parsed_args) self.type_access_mock.remove_project_access.assert_called_with( - self.share_group_type, self.project.id) + self.share_group_type, self.project.id + ) self.assertIsNone(result) def test_share_group_type_access_delete_exception(self): - arglist = [ - self.share_group_type.id, - 'invalid_project_format' - ] + arglist = [self.share_group_type.id, 'invalid_project_format'] verifylist = [ ('share_group_type', self.share_group_type.id), - ('projects', ['invalid_project_format']) + ('projects', ['invalid_project_format']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.type_access_mock.remove_project_access.side_effect = BadRequest() self.assertRaises( - exceptions.CommandError, self.cmd.take_action, parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) diff --git a/manilaclient/tests/unit/osc/v2/test_share_groups.py b/manilaclient/tests/unit/osc/v2/test_share_groups.py index 1cf721f9..9e244128 100644 --- a/manilaclient/tests/unit/osc/v2/test_share_groups.py +++ b/manilaclient/tests/unit/osc/v2/test_share_groups.py @@ -26,9 +26,8 @@ class TestShareGroup(manila_fakes.TestShare): - def setUp(self): - super(TestShareGroup, self).setUp() + super().setUp() self.groups_mock = self.app.client_manager.share.share_groups self.groups_mock.reset_mock() @@ -37,17 +36,15 @@ def setUp(self): self.share_types_mock.reset_mock() self.app.client_manager.share.api_version = api_versions.APIVersion( - api_versions.MAX_VERSION) + api_versions.MAX_VERSION + ) class TestShareGroupCreate(TestShareGroup): - def setUp(self): - super(TestShareGroupCreate, self).setUp() + super().setUp() - self.share_group = ( - manila_fakes.FakeShareGroup.create_one_share_group() - ) + self.share_group = manila_fakes.FakeShareGroup.create_one_share_group() self.formatted_result = ( manila_fakes.FakeShareGroup.create_one_share_group( attrs={ @@ -55,9 +52,12 @@ def setUp(self): 'created_at': self.share_group.created_at, "project_id": self.share_group.project_id, 'share_group_type_id': ( - self.share_group.share_group_type_id), - 'share_types': '\n'.join(self.share_group.share_types) - })) + self.share_group.share_group_type_id + ), + 'share_types': '\n'.join(self.share_group.share_types), + } + ) + ) self.groups_mock.create.return_value = self.share_group self.groups_mock.get.return_value = self.share_group @@ -82,7 +82,7 @@ def test_share_group_create_no_args(self): share_group_type=None, share_network=None, source_share_group_snapshot=None, - availability_zone=None + availability_zone=None, ) self.assertCountEqual(self.columns, columns) @@ -90,12 +90,14 @@ def test_share_group_create_no_args(self): def test_share_group_create_with_options(self): arglist = [ - '--name', self.share_group.name, - '--description', self.share_group.description + '--name', + self.share_group.name, + '--description', + self.share_group.description, ] verifylist = [ ('name', self.share_group.name), - ('description', self.share_group.description) + ('description', self.share_group.description), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -109,16 +111,14 @@ def test_share_group_create_with_options(self): share_group_type=None, share_network=None, source_share_group_snapshot=None, - availability_zone=None + availability_zone=None, ) self.assertCountEqual(self.columns, columns) self.assertCountEqual(self.data, data) def test_share_group_create_az(self): - arglist = [ - '--availability-zone', self.share_group.availability_zone - ] + arglist = ['--availability-zone', self.share_group.availability_zone] verifylist = [ ('availability_zone', self.share_group.availability_zone) ] @@ -134,23 +134,19 @@ def test_share_group_create_az(self): share_group_type=None, share_network=None, source_share_group_snapshot=None, - availability_zone=self.share_group.availability_zone + availability_zone=self.share_group.availability_zone, ) self.assertCountEqual(self.columns, columns) self.assertCountEqual(self.data, data) def test_share_group_create_share_types(self): - share_types = manila_fakes.FakeShareType.create_share_types(count=2) self.share_types_mock.get = manila_fakes.FakeShareType.get_share_types( - share_types) - arglist = [ - '--share-types', share_types[0].id, share_types[1].id - ] - verifylist = [ - ('share_types', [share_types[0].id, share_types[1].id]) - ] + share_types + ) + arglist = ['--share-types', share_types[0].id, share_types[1].id] + verifylist = [('share_types', [share_types[0].id, share_types[1].id])] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -163,19 +159,15 @@ def test_share_group_create_share_types(self): share_group_type=None, share_network=None, source_share_group_snapshot=None, - availability_zone=None + availability_zone=None, ) self.assertCountEqual(self.columns, columns) self.assertCountEqual(self.data, data) def test_share_group_create_wait(self): - arglist = [ - '--wait' - ] - verifylist = [ - ('wait', True) - ] + arglist = ['--wait'] + verifylist = [('wait', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -188,7 +180,7 @@ def test_share_group_create_wait(self): share_group_type=None, share_network=None, source_share_group_snapshot=None, - availability_zone=None + availability_zone=None, ) self.groups_mock.get.assert_called_with(self.share_group.id) @@ -201,60 +193,43 @@ def test_share_group_create_wait(self): class TestShareGroupDelete(TestShareGroup): - def setUp(self): - super(TestShareGroupDelete, self).setUp() + super().setUp() - self.share_group = ( - manila_fakes.FakeShareGroup.create_one_share_group()) + self.share_group = manila_fakes.FakeShareGroup.create_one_share_group() self.groups_mock.get.return_value = self.share_group self.cmd = osc_share_groups.DeleteShareGroup(self.app, None) def test_share_group_delete(self): - arglist = [ - self.share_group.id - ] - verifylist = [ - ('share_group', [self.share_group.id]) - ] + arglist = [self.share_group.id] + verifylist = [('share_group', [self.share_group.id])] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.groups_mock.delete.assert_called_with( - self.share_group, - force=False) + self.share_group, force=False + ) self.assertIsNone(result) def test_share_group_delete_force(self): - arglist = [ - self.share_group.id, - '--force' - ] - verifylist = [ - ('share_group', [self.share_group.id]), - ('force', True) - ] + arglist = [self.share_group.id, '--force'] + verifylist = [('share_group', [self.share_group.id]), ('force', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.groups_mock.delete.assert_called_with( - self.share_group, - force=True) + self.share_group, force=True + ) self.assertIsNone(result) def test_share_group_delete_multiple(self): - share_groups = ( - manila_fakes.FakeShareGroup.create_share_groups( - count=2)) - arglist = [ - share_groups[0].id, - share_groups[1].id - ] + share_groups = manila_fakes.FakeShareGroup.create_share_groups(count=2) + arglist = [share_groups[0].id, share_groups[1].id] verifylist = [ ('share_group', [share_groups[0].id, share_groups[1].id]) ] @@ -262,34 +237,23 @@ def test_share_group_delete_multiple(self): result = self.cmd.take_action(parsed_args) - self.assertEqual(self.groups_mock.delete.call_count, - len(share_groups)) + self.assertEqual(self.groups_mock.delete.call_count, len(share_groups)) self.assertIsNone(result) def test_share_group_delete_exception(self): - arglist = [ - self.share_group.id - ] - verifylist = [ - ('share_group', [self.share_group.id]) - ] + arglist = [self.share_group.id] + verifylist = [('share_group', [self.share_group.id])] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.groups_mock.delete.side_effect = exceptions.CommandError() - self.assertRaises(exceptions.CommandError, - self.cmd.take_action, - parsed_args) + self.assertRaises( + exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_share_group_delete_wait(self): - arglist = [ - self.share_group.id, - '--wait' - ] - verifylist = [ - ('share_group', [self.share_group.id]), - ('wait', True) - ] + arglist = [self.share_group.id, '--wait'] + verifylist = [('share_group', [self.share_group.id]), ('wait', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -297,39 +261,28 @@ def test_share_group_delete_wait(self): result = self.cmd.take_action(parsed_args) self.groups_mock.delete.assert_called_with( - self.share_group, - force=False) + self.share_group, force=False + ) self.groups_mock.get.assert_called_with(self.share_group.id) self.assertIsNone(result) def test_share_group_delete_wait_exception(self): - arglist = [ - self.share_group.id, - '--wait' - ] - verifylist = [ - ('share_group', [self.share_group.id]), - ('wait', True) - ] + arglist = [self.share_group.id, '--wait'] + verifylist = [('share_group', [self.share_group.id]), ('wait', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) with mock.patch('osc_lib.utils.wait_for_delete', return_value=False): self.assertRaises( - exceptions.CommandError, - self.cmd.take_action, - parsed_args + exceptions.CommandError, self.cmd.take_action, parsed_args ) class TestShareGroupShow(TestShareGroup): - def setUp(self): - super(TestShareGroupShow, self).setUp() + super().setUp() - self.share_group = ( - manila_fakes.FakeShareGroup.create_one_share_group() - ) + self.share_group = manila_fakes.FakeShareGroup.create_one_share_group() self.formatted_result = ( manila_fakes.FakeShareGroup.create_one_share_group( attrs={ @@ -337,9 +290,12 @@ def setUp(self): 'created_at': self.share_group.created_at, "project_id": self.share_group.project_id, 'share_group_type_id': ( - self.share_group.share_group_type_id), - 'share_types': '\n'.join(self.share_group.share_types) - })) + self.share_group.share_group_type_id + ), + 'share_types': '\n'.join(self.share_group.share_types), + } + ) + ) self.groups_mock.get.return_value = self.share_group self.data = tuple(self.formatted_result._info.values()) @@ -348,33 +304,24 @@ def setUp(self): self.cmd = osc_share_groups.ShowShareGroup(self.app, None) def test_share_group_show(self): - arglist = [ - self.share_group.id - ] - verifylist = [ - ('share_group', self.share_group.id) - ] + arglist = [self.share_group.id] + verifylist = [('share_group', self.share_group.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) - self.groups_mock.get.assert_called_with( - self.share_group.id - ) + self.groups_mock.get.assert_called_with(self.share_group.id) self.assertCountEqual(self.columns, columns) self.assertCountEqual(self.data, data) class TestShareGroupSet(TestShareGroup): - def setUp(self): - super(TestShareGroupSet, self).setUp() + super().setUp() - self.share_group = ( - manila_fakes.FakeShareGroup.create_one_share_group() - ) + self.share_group = manila_fakes.FakeShareGroup.create_one_share_group() self.share_group = manila_fakes.FakeShare.create_one_share( methods={"reset_state": None} ) @@ -385,25 +332,23 @@ def setUp(self): def test_set_share_group_name(self): new_name = uuid.uuid4().hex arglist = [ - '--name', new_name, + '--name', + new_name, self.share_group.id, ] - verifylist = [ - ('name', new_name), - ('share_group', self.share_group.id) - - ] + verifylist = [('name', new_name), ('share_group', self.share_group.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) self.groups_mock.update.assert_called_with( - self.share_group.id, - name=parsed_args.name) + self.share_group.id, name=parsed_args.name + ) def test_set_share_group_description(self): new_description = uuid.uuid4().hex arglist = [ - '--description', new_description, + '--description', + new_description, self.share_group.id, ] verifylist = [ @@ -414,18 +359,15 @@ def test_set_share_group_description(self): self.cmd.take_action(parsed_args) self.groups_mock.update.assert_called_with( - self.share_group.id, - description=parsed_args.description) + self.share_group.id, description=parsed_args.description + ) def test_share_group_set_status(self): new_status = 'available' - arglist = [ - self.share_group.id, - '--status', new_status - ] + arglist = [self.share_group.id, '--status', new_status] verifylist = [ ('share_group', self.share_group.id), - ('status', new_status) + ('status', new_status), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -436,68 +378,52 @@ def test_share_group_set_status(self): def test_share_group_set_status_exception(self): new_status = 'available' - arglist = [ - self.share_group.id, - '--status', new_status - ] + arglist = [self.share_group.id, '--status', new_status] verifylist = [ ('share_group', self.share_group.id), - ('status', new_status) + ('status', new_status), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.share_group.reset_state.side_effect = Exception() self.assertRaises( - osc_exceptions.CommandError, self.cmd.take_action, parsed_args) + osc_exceptions.CommandError, self.cmd.take_action, parsed_args + ) class TestShareGroupUnset(TestShareGroup): - def setUp(self): - super(TestShareGroupUnset, self).setUp() + super().setUp() - self.share_group = ( - manila_fakes.FakeShareGroup.create_one_share_group() - ) + self.share_group = manila_fakes.FakeShareGroup.create_one_share_group() self.groups_mock.get.return_value = self.share_group self.cmd = osc_share_groups.UnsetShareGroup(self.app, None) def test_unset_share_group_name(self): - arglist = [ - self.share_group.id, - '--name' - ] - verifylist = [ - ('share_group', self.share_group.id), - ('name', True) - ] + arglist = [self.share_group.id, '--name'] + verifylist = [('share_group', self.share_group.id), ('name', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - self.groups_mock.update.assert_called_with( - self.share_group, - name=None) + self.groups_mock.update.assert_called_with(self.share_group, name=None) self.assertIsNone(result) def test_unset_share_group_description(self): - arglist = [ - self.share_group.id, - '--description' - ] + arglist = [self.share_group.id, '--description'] verifylist = [ ('share_group', self.share_group.id), - ('description', True) + ('description', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.groups_mock.update.assert_called_with( - self.share_group, - description=None) + self.share_group, description=None + ) self.assertIsNone(result) def test_unset_share_group_name_exception(self): @@ -514,41 +440,35 @@ def test_unset_share_group_name_exception(self): self.groups_mock.update.side_effect = Exception() self.assertRaises( - exceptions.CommandError, - self.cmd.take_action, - parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) class TestShareGroupList(TestShareGroup): - - columns = [ - 'id', - 'name', - 'status', - 'description' - ] + columns = ['id', 'name', 'status', 'description'] column_headers = utils.format_column_headers(columns) def setUp(self): - super(TestShareGroupList, self).setUp() + super().setUp() self.new_share_group = ( manila_fakes.FakeShareGroup.create_one_share_group() ) self.groups_mock.list.return_value = [self.new_share_group] - self.share_group = ( - manila_fakes.FakeShareGroup.create_one_share_group()) + self.share_group = manila_fakes.FakeShareGroup.create_one_share_group() self.groups_mock.get.return_value = self.share_group self.share_groups_list = ( - manila_fakes.FakeShareGroup.create_share_groups( - count=2)) + manila_fakes.FakeShareGroup.create_share_groups(count=2) + ) self.groups_mock.list.return_value = self.share_groups_list - self.values = (oscutils.get_dict_properties( - s._info, self.columns) for s in self.share_groups_list) + self.values = ( + oscutils.get_dict_properties(s._info, self.columns) + for s in self.share_groups_list + ) self.cmd = osc_share_groups.ListShareGroup(self.app, None) @@ -560,89 +480,83 @@ def test_share_group_list(self): columns, data = self.cmd.take_action(parsed_args) - self.groups_mock.list.assert_called_with(search_opts={ - 'all_tenants': False, - 'name': None, - 'status': None, - 'share_server_id': None, - 'share_group_type': None, - 'snapshot': None, - 'host': None, - 'share_network': None, - 'project_id': None, - 'limit': None, - 'offset': None, - 'name~': None, - 'description~': None, - 'description': None - }) + self.groups_mock.list.assert_called_with( + search_opts={ + 'all_tenants': False, + 'name': None, + 'status': None, + 'share_server_id': None, + 'share_group_type': None, + 'snapshot': None, + 'host': None, + 'share_network': None, + 'project_id': None, + 'limit': None, + 'offset': None, + 'name~': None, + 'description~': None, + 'description': None, + } + ) self.assertEqual(self.column_headers, columns) self.assertEqual(list(self.values), list(data)) def test_list_share_group_api_version_exception(self): self.app.client_manager.share.api_version = api_versions.APIVersion( - "2.35") + "2.35" + ) - arglist = [ - '--description', 'Description' - ] - verifylist = [ - ('description', 'Description') - ] + arglist = ['--description', 'Description'] + verifylist = [('description', 'Description')] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( - exceptions.CommandError, - self.cmd.take_action, - parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_list_share_groups_all_projects(self): all_tenants_list = self.column_headers.copy() all_tenants_list.append('Project ID') - list_values = (oscutils.get_dict_properties( - s._info, all_tenants_list) for s in self.share_groups_list) + list_values = ( + oscutils.get_dict_properties(s._info, all_tenants_list) + for s in self.share_groups_list + ) - arglist = [ - '--all-projects' - ] + arglist = ['--all-projects'] - verifylist = [ - ('all_projects', True) - ] + verifylist = [('all_projects', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) - self.groups_mock.list.assert_called_with(search_opts={ - 'all_tenants': True, - 'name': None, - 'status': None, - 'share_server_id': None, - 'share_group_type': None, - 'snapshot': None, - 'host': None, - 'share_network': None, - 'project_id': None, - 'limit': None, - 'offset': None, - 'name~': None, - 'description~': None, - 'description': None - }) + self.groups_mock.list.assert_called_with( + search_opts={ + 'all_tenants': True, + 'name': None, + 'status': None, + 'share_server_id': None, + 'share_group_type': None, + 'snapshot': None, + 'host': None, + 'share_network': None, + 'project_id': None, + 'limit': None, + 'offset': None, + 'name~': None, + 'description~': None, + 'description': None, + } + ) self.assertEqual(all_tenants_list, columns) self.assertEqual(list(list_values), list(data)) def test_share_group_list_name(self): - arglist = [ - '--name', self.new_share_group.name - ] - verifylist = [ - ('name', self.new_share_group.name) - ] + arglist = ['--name', self.new_share_group.name] + verifylist = [('name', self.new_share_group.name)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) @@ -661,7 +575,7 @@ def test_share_group_list_name(self): 'offset': None, 'name~': None, 'description~': None, - 'description': None + 'description': None, } search_opts['name'] = self.new_share_group.name @@ -674,12 +588,8 @@ def test_share_group_list_name(self): self.assertEqual(list(self.values), list(data)) def test_share_group_list_description(self): - arglist = [ - '--description', self.new_share_group.description - ] - verifylist = [ - ('description', self.new_share_group.description) - ] + arglist = ['--description', self.new_share_group.description] + verifylist = [('description', self.new_share_group.description)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) @@ -698,7 +608,7 @@ def test_share_group_list_description(self): 'offset': None, 'name~': None, 'description~': None, - 'description': None + 'description': None, } search_opts['description'] = self.new_share_group.description @@ -712,7 +622,8 @@ def test_share_group_list_description(self): def test_share_group_list_status(self): arglist = [ - '--status', self.new_share_group.status, + '--status', + self.new_share_group.status, ] verifylist = [ ('status', self.new_share_group.status), @@ -735,7 +646,7 @@ def test_share_group_list_status(self): 'offset': None, 'name~': None, 'description~': None, - 'description': None + 'description': None, } search_opts['status'] = self.new_share_group.status @@ -749,8 +660,10 @@ def test_share_group_list_status(self): def test_share_group_list_marker_and_limit(self): arglist = [ - "--marker", self.new_share_group.id, - "--limit", "2", + "--marker", + self.new_share_group.id, + "--limit", + "2", ] verifylist = [ ('marker', self.new_share_group.id), @@ -774,7 +687,7 @@ def test_share_group_list_marker_and_limit(self): 'offset': self.new_share_group.id, 'name~': None, 'description~': None, - 'description': None + 'description': None, } self.groups_mock.list.assert_called_once_with( @@ -786,13 +699,19 @@ def test_share_group_list_marker_and_limit(self): def test_share_group_list_negative_limit(self): arglist = [ - "--limit", "-2", + "--limit", + "-2", ] verifylist = [ ("limit", -2), ] - self.assertRaises(osc_utils.ParserException, self.check_parser, - self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) # TODO(archanaserver): Add test cases for share-server-id, # share-group-type, snapshot, share-network and source- diff --git a/manilaclient/tests/unit/osc/v2/test_share_instance_export_locations.py b/manilaclient/tests/unit/osc/v2/test_share_instance_export_locations.py index 7f5b82e3..484a5077 100644 --- a/manilaclient/tests/unit/osc/v2/test_share_instance_export_locations.py +++ b/manilaclient/tests/unit/osc/v2/test_share_instance_export_locations.py @@ -15,18 +15,17 @@ from osc_lib import utils as osc_lib_utils -from manilaclient.osc.v2 \ - import share_instance_export_locations \ - as osc_share_instance_export_locations +from manilaclient.osc.v2 import ( + share_instance_export_locations as osc_share_instance_export_locations, +) from manilaclient.tests.unit.osc import osc_utils from manilaclient.tests.unit.osc.v2 import fakes as manila_fakes class TestShareInstanceExportLocation(manila_fakes.TestShare): - def setUp(self): - super(TestShareInstanceExportLocation, self).setUp() + super().setUp() self.instances_mock = self.app.client_manager.share.share_instances self.instances_mock.reset_mock() @@ -39,7 +38,6 @@ def setUp(self): class TestShareInstanceExportLocationList(TestShareInstanceExportLocation): - column_headers = [ 'ID', 'Path', @@ -48,27 +46,25 @@ class TestShareInstanceExportLocationList(TestShareInstanceExportLocation): ] def setUp(self): - super(TestShareInstanceExportLocationList, self).setUp() + super().setUp() self.instance = ( manila_fakes.FakeShareInstance.create_one_share_instance() ) self.instances_mock.get.return_value = self.instance - self.instance_export_locations = ( - manila_fakes.FakeShareExportLocation. - create_share_export_locations() - ) - self.instance_export_locations_mock.list.return_value = \ + self.instance_export_locations = manila_fakes.FakeShareExportLocation.create_share_export_locations() + self.instance_export_locations_mock.list.return_value = ( self.instance_export_locations + ) - self.data = (osc_lib_utils.get_dict_properties( - i._info, self.column_headers) - for i in self.instance_export_locations) + self.data = ( + osc_lib_utils.get_dict_properties(i._info, self.column_headers) + for i in self.instance_export_locations + ) - self.cmd = ( - osc_share_instance_export_locations. - ShareInstanceListExportLocation(self.app, None) + self.cmd = osc_share_instance_export_locations.ShareInstanceListExportLocation( + self.app, None ) def test_share_instance_export_locations_list_missing_args(self): @@ -77,28 +73,25 @@ def test_share_instance_export_locations_list_missing_args(self): self.assertRaises( osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_instance_export_locations_list(self): - arglist = [ - self.instance.id - ] + arglist = [self.instance.id] - verifylist = [ - ('instance', self.instance.id) - ] + verifylist = [('instance', self.instance.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) - self.instances_mock.get.assert_called_with( - self.instance.id - ) + self.instances_mock.get.assert_called_with(self.instance.id) self.instance_export_locations_mock.list.assert_called_with( - self.instance, - search_opts=None + self.instance, search_opts=None ) self.assertCountEqual(self.column_headers, columns) @@ -106,25 +99,23 @@ def test_share_instance_export_locations_list(self): class TestShareInstanceExportLocationShow(TestShareInstanceExportLocation): - def setUp(self): - super(TestShareInstanceExportLocationShow, self).setUp() + super().setUp() self.share_instance_export_locations = ( - manila_fakes.FakeShareExportLocation. - create_one_export_location() + manila_fakes.FakeShareExportLocation.create_one_export_location() ) - self.instance_export_locations_mock.get.return_value = \ + self.instance_export_locations_mock.get.return_value = ( self.share_instance_export_locations + ) self.instance = ( manila_fakes.FakeShareInstance.create_one_share_instance() ) self.instances_mock.get.return_value = self.instance - self.cmd = ( - osc_share_instance_export_locations. - ShareInstanceShowExportLocation(self.app, None) + self.cmd = osc_share_instance_export_locations.ShareInstanceShowExportLocation( + self.app, None ) self.data = tuple(self.share_instance_export_locations._info.values()) @@ -136,7 +127,11 @@ def test_share_instance_export_locations_show_missing_args(self): self.assertRaises( osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_instance_export_locations_show(self): arglist = [ @@ -146,20 +141,17 @@ def test_share_instance_export_locations_show(self): verifylist = [ ('instance', self.instance.id), - ('export_location', self.share_instance_export_locations.id) + ('export_location', self.share_instance_export_locations.id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) - self.instances_mock.get.assert_called_with( - self.instance.id - ) + self.instances_mock.get.assert_called_with(self.instance.id) self.instance_export_locations_mock.get.assert_called_with( - self.instance.id, - self.share_instance_export_locations.id + self.instance.id, self.share_instance_export_locations.id ) self.assertCountEqual(self.columns, columns) diff --git a/manilaclient/tests/unit/osc/v2/test_share_instances.py b/manilaclient/tests/unit/osc/v2/test_share_instances.py index 62b2baf9..c8fcbc06 100644 --- a/manilaclient/tests/unit/osc/v2/test_share_instances.py +++ b/manilaclient/tests/unit/osc/v2/test_share_instances.py @@ -25,9 +25,8 @@ class TestShareInstance(manila_fakes.TestShare): - def setUp(self): - super(TestShareInstance, self).setUp() + super().setUp() self.shares_mock = self.app.client_manager.share.shares self.shares_mock.reset_mock() @@ -36,11 +35,13 @@ def setUp(self): self.instances_mock.reset_mock() self.share_instance_export_locations_mock = ( - self.app.client_manager.share.share_instance_export_locations) + self.app.client_manager.share.share_instance_export_locations + ) self.share_instance_export_locations_mock.reset_mock() self.app.client_manager.share.api_version = api_versions.APIVersion( - api_versions.MAX_VERSION) + api_versions.MAX_VERSION + ) class TestShareInstanceList(TestShareInstance): @@ -57,10 +58,11 @@ class TestShareInstanceList(TestShareInstance): column_headers = utils.format_column_headers(columns) def setUp(self): - super(TestShareInstanceList, self).setUp() + super().setUp() self.instances_list = ( - manila_fakes.FakeShareInstance.create_share_instances(count=2)) + manila_fakes.FakeShareInstance.create_share_instances(count=2) + ) self.instances_mock.list.return_value = self.instances_list self.share = manila_fakes.FakeShare.create_one_share() @@ -69,8 +71,10 @@ def setUp(self): self.shares_mock.list_instances.return_value = self.instances_list self.shares_mock.list_instances.return_value = self.instances_list - self.instance_values = (oscutils.get_dict_properties( - instance._info, self.columns) for instance in self.instances_list) + self.instance_values = ( + oscutils.get_dict_properties(instance._info, self.columns) + for instance in self.instances_list + ) self.cmd = osc_share_instances.ShareInstanceList(self.app, None) @@ -88,12 +92,8 @@ def test_share_instance_list(self): self.assertEqual(list(self.instance_values), list(data)) def test_share_instance_list_by_share(self): - argslist = [ - '--share', self.share['id'] - ] - verifylist = [ - ('share', self.share.id) - ] + argslist = ['--share', self.share['id']] + verifylist = [('share', self.share.id)] parsed_args = self.check_parser(self.cmd, argslist, verifylist) @@ -106,48 +106,41 @@ def test_share_instance_list_by_share(self): def test_share_instance_list_by_export_location(self): fake_export_location = '10.1.1.0:/fake_share_el' - argslist = [ - '--export-location', fake_export_location - ] - verifylist = [ - ('export_location', fake_export_location) - ] + argslist = ['--export-location', fake_export_location] + verifylist = [('export_location', fake_export_location)] parsed_args = self.check_parser(self.cmd, argslist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.instances_mock.list.assert_called_with( - export_location=fake_export_location) + export_location=fake_export_location + ) self.assertEqual(self.column_headers, columns) self.assertEqual(list(self.instance_values), list(data)) def test_share_instance_list_by_export_location_invalid_version(self): fake_export_location = '10.1.1.0:/fake_share_el' - argslist = [ - '--export-location', fake_export_location - ] - verifylist = [ - ('export_location', fake_export_location) - ] + argslist = ['--export-location', fake_export_location] + verifylist = [('export_location', fake_export_location)] self.app.client_manager.share.api_version = api_versions.APIVersion( - '2.34') + '2.34' + ) parsed_args = self.check_parser(self.cmd, argslist, verifylist) self.assertRaises( - exceptions.CommandError, - self.cmd.take_action, - parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) class TestShareInstanceDelete(TestShareInstance): - def setUp(self): - super(TestShareInstanceDelete, self).setUp() + super().setUp() self.share_instance = ( - manila_fakes.FakeShareInstance.create_one_share_instance()) + manila_fakes.FakeShareInstance.create_one_share_instance() + ) self.instances_mock.get.return_value = self.share_instance self.cmd = osc_share_instances.ShareInstanceDelete(self.app, None) @@ -156,70 +149,64 @@ def test_share_instance_delete_missing_args(self): arglist = [] verifylist = [] - self.assertRaises(osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_instance_delete(self): - arglist = [ - self.share_instance.id - ] - verifylist = [ - ('instance', [self.share_instance.id]) - ] + arglist = [self.share_instance.id] + verifylist = [('instance', [self.share_instance.id])] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.instances_mock.force_delete.assert_called_with( - self.share_instance) + self.share_instance + ) self.assertIsNone(result) def test_share_instance_delete_multiple(self): share_instances = ( - manila_fakes.FakeShareInstance.create_share_instances(count=2)) + manila_fakes.FakeShareInstance.create_share_instances(count=2) + ) instance_ids = [instance.id for instance in share_instances] arglist = instance_ids verifylist = [('instance', instance_ids)] self.instances_mock.get.side_effect = share_instances - delete_calls = [ - mock.call(instance) for instance in share_instances] + delete_calls = [mock.call(instance) for instance in share_instances] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.instances_mock.force_delete.assert_has_calls(delete_calls) - self.assertEqual(self.instances_mock.force_delete.call_count, - len(share_instances)) + self.assertEqual( + self.instances_mock.force_delete.call_count, len(share_instances) + ) self.assertIsNone(result) def test_share_instance_delete_exception(self): - arglist = [ - self.share_instance.id - ] - verifylist = [ - ('instance', [self.share_instance.id]) - ] + arglist = [self.share_instance.id] + verifylist = [('instance', [self.share_instance.id])] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.instances_mock.force_delete.side_effect = ( - exceptions.CommandError()) - self.assertRaises(exceptions.CommandError, - self.cmd.take_action, - parsed_args) + exceptions.CommandError() + ) + self.assertRaises( + exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_share_instance_delete_wait(self): - arglist = [ - self.share_instance.id, - '--wait' - ] - verifylist = [ - ('instance', [self.share_instance.id]), - ('wait', True) - ] + arglist = [self.share_instance.id, '--wait'] + verifylist = [('instance', [self.share_instance.id]), ('wait', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -227,46 +214,40 @@ def test_share_instance_delete_wait(self): result = self.cmd.take_action(parsed_args) self.instances_mock.force_delete.assert_called_with( - self.share_instance) + self.share_instance + ) self.instances_mock.get.assert_called_with(self.share_instance.id) self.assertIsNone(result) def test_share_instance_delete_wait_exception(self): - arglist = [ - self.share_instance.id, - '--wait' - ] - verifylist = [ - ('instance', [self.share_instance.id]), - ('wait', True) - ] + arglist = [self.share_instance.id, '--wait'] + verifylist = [('instance', [self.share_instance.id]), ('wait', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) with mock.patch('osc_lib.utils.wait_for_delete', return_value=False): self.assertRaises( - exceptions.CommandError, - self.cmd.take_action, - parsed_args + exceptions.CommandError, self.cmd.take_action, parsed_args ) class TestShareInstanceShow(TestShareInstance): - def setUp(self): - super(TestShareInstanceShow, self).setUp() + super().setUp() self.share_instance = ( manila_fakes.FakeShareInstance.create_one_share_instance() ) self.instances_mock.get.return_value = self.share_instance - self.export_locations = ( - [manila_fakes.FakeShareExportLocation.create_one_export_location() - for i in range(2)]) + self.export_locations = [ + manila_fakes.FakeShareExportLocation.create_one_export_location() + for i in range(2) + ] self.share_instance_export_locations_mock.list.return_value = ( - self.export_locations) + self.export_locations + ) self.cmd = osc_share_instances.ShareInstanceShow(self.app, None) @@ -279,7 +260,11 @@ def test_share_instance_show_missing_args(self): self.assertRaises( osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_instance_show(self): expected_columns = tuple(self.share_instance._info.keys()) @@ -294,34 +279,29 @@ def test_share_instance_show(self): cliutils.convert_dict_list_to_string = mock.Mock() cliutils.convert_dict_list_to_string.return_value = dict( - self.export_locations[0]) + self.export_locations[0] + ) - arglist = [ - self.share_instance.id - ] - verifylist = [ - ('instance', self.share_instance.id) - ] + arglist = [self.share_instance.id] + verifylist = [('instance', self.share_instance.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) - self.instances_mock.get.assert_called_with( - self.share_instance.id - ) + self.instances_mock.get.assert_called_with(self.share_instance.id) self.assertCountEqual(expected_columns, columns) self.assertCountEqual(expected_data_dic, data) class TestShareInstanceSet(TestShareInstance): - def setUp(self): - super(TestShareInstanceSet, self).setUp() + super().setUp() self.share_instance = ( - manila_fakes.FakeShareInstance.create_one_share_instance()) + manila_fakes.FakeShareInstance.create_one_share_instance() + ) self.instances_mock.get.return_value = self.share_instance @@ -329,41 +309,34 @@ def setUp(self): def test_share_instance_set_status(self): new_status = 'available' - arglist = [ - self.share_instance.id, - '--status', new_status - ] + arglist = [self.share_instance.id, '--status', new_status] verifylist = [ ('instance', self.share_instance.id), - ('status', new_status) + ('status', new_status), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.instances_mock.reset_state.assert_called_with( - self.share_instance, - new_status) + self.share_instance, new_status + ) self.assertIsNone(result) def test_share_instance_set_status_exception(self): new_status = 'available' - arglist = [ - self.share_instance.id, - '--status', new_status - ] + arglist = [self.share_instance.id, '--status', new_status] verifylist = [ ('instance', self.share_instance.id), - ('status', new_status) + ('status', new_status), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.instances_mock.reset_state.side_effect = Exception() self.assertRaises( - exceptions.CommandError, - self.cmd.take_action, - parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_share_instance_set_nothing_defined(self): arglist = [ @@ -375,6 +348,5 @@ def test_share_instance_set_nothing_defined(self): parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( - exceptions.CommandError, - self.cmd.take_action, - parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) diff --git a/manilaclient/tests/unit/osc/v2/test_share_limits.py b/manilaclient/tests/unit/osc/v2/test_share_limits.py index d70cb5f8..4a80aa80 100644 --- a/manilaclient/tests/unit/osc/v2/test_share_limits.py +++ b/manilaclient/tests/unit/osc/v2/test_share_limits.py @@ -22,22 +22,21 @@ class TestShareLimits(manila_fakes.TestShare): - def setUp(self): - super(TestShareLimits, self).setUp() + super().setUp() self.share_limits_mock = self.app.client_manager.share.limits self.share_limits_mock.reset_mock() self.app.client_manager.share.api_version = api_versions.APIVersion( - MAX_VERSION) + MAX_VERSION + ) @ddt.ddt class TestShareLimitsShow(TestShareLimits): - def setUp(self): - super(TestShareLimitsShow, self).setUp() + super().setUp() # Get the command object to test self.cmd = osc_share_limits.ShareLimitsShow(self.app, None) @@ -54,9 +53,7 @@ def setUp(self): @ddt.data('absolute', 'rate') def test_limits(self, limit_type): - share_limits = ( - manila_fakes.FakeShareLimits.create_one_share_limit() - ) + share_limits = manila_fakes.FakeShareLimits.create_one_share_limit() self.share_limits_mock.get.return_value = share_limits expected_data = share_limits._info[f"{limit_type}_limit"] @@ -66,28 +63,23 @@ def test_limits(self, limit_type): if limit_type == 'absolute': arglist.append('--absolute') - verifylist.extend([ - ('absolute', True), - ('rate', False) - ]) + verifylist.extend([('absolute', True), ('rate', False)]) else: arglist.append('--rate') - verifylist.extend([ - ('absolute', False), - ('rate', True) - ]) + verifylist.extend([('absolute', False), ('rate', True)]) parsed_args = self.check_parser(self.cmd, arglist, verifylist) actual_columns, actual_data = self.cmd.take_action(parsed_args) - self.assertEqual(getattr(self, f"{limit_type}_limit_columns"), - actual_columns) + self.assertEqual( + getattr(self, f"{limit_type}_limit_columns"), actual_columns + ) if limit_type == 'rate': expected_data_tuple = tuple(expected_data.values()) - self.assertEqual(sorted(expected_data_tuple), - sorted(next(actual_data))) + self.assertEqual( + sorted(expected_data_tuple), sorted(next(actual_data)) + ) else: expected_data_tuple = tuple(expected_data.items()) - self.assertEqual(sorted(expected_data_tuple), - sorted(actual_data)) + self.assertEqual(sorted(expected_data_tuple), sorted(actual_data)) diff --git a/manilaclient/tests/unit/osc/v2/test_share_network_subnets.py b/manilaclient/tests/unit/osc/v2/test_share_network_subnets.py index bd2b5863..a34757df 100644 --- a/manilaclient/tests/unit/osc/v2/test_share_network_subnets.py +++ b/manilaclient/tests/unit/osc/v2/test_share_network_subnets.py @@ -23,34 +23,34 @@ class TestShareNetworkSubnet(manila_fakes.TestShare): - def setUp(self): - super(TestShareNetworkSubnet, self).setUp() + super().setUp() self.share_networks_mock = self.app.client_manager.share.share_networks self.share_networks_mock.reset_mock() self.share_subnets_mock = ( - self.app.client_manager.share.share_network_subnets) + self.app.client_manager.share.share_network_subnets + ) self.share_subnets_mock.reset_mock() @ddt.ddt class TestShareNetworkSubnetCreate(TestShareNetworkSubnet): - def setUp(self): - super(TestShareNetworkSubnetCreate, self).setUp() + super().setUp() self.share_network = ( - manila_fakes.FakeShareNetwork.create_one_share_network()) + manila_fakes.FakeShareNetwork.create_one_share_network() + ) self.share_networks_mock.get.return_value = self.share_network self.share_network_subnet = ( - manila_fakes.FakeShareNetworkSubnet.create_one_share_subnet()) + manila_fakes.FakeShareNetworkSubnet.create_one_share_subnet() + ) self.share_subnets_mock.create.return_value = self.share_network_subnet - self.cmd = osc_share_subnets.CreateShareNetworkSubnet( - self.app, None) + self.cmd = osc_share_subnets.CreateShareNetworkSubnet(self.app, None) self.data = self.share_network_subnet._info.values() self.columns = self.share_network_subnet._info.keys() @@ -59,8 +59,13 @@ def test_share_network_subnet_create_missing_args(self): arglist = [] verifylist = [] - self.assertRaises(osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_network_subnet_create(self): fake_neutron_net_id = str(uuid.uuid4()) @@ -68,9 +73,12 @@ def test_share_network_subnet_create(self): arglist = [ self.share_network.id, - '--neutron-net-id', fake_neutron_net_id, - '--neutron-subnet-id', fake_neutron_subnet_id, - '--availability-zone', 'nova', + '--neutron-net-id', + fake_neutron_net_id, + '--neutron-subnet-id', + fake_neutron_subnet_id, + '--availability-zone', + 'nova', ] verifylist = [ ('share_network', self.share_network.id), @@ -87,7 +95,7 @@ def test_share_network_subnet_create(self): neutron_subnet_id=fake_neutron_subnet_id, availability_zone='nova', share_network_id=self.share_network.id, - metadata={} + metadata={}, ) self.assertCountEqual(self.columns, columns) @@ -100,14 +108,18 @@ def test_share_network_subnet_create_valid_neutron_info(self): neutron_client = mock.Mock() self.app.client_manager.network = neutron_client neutron_client.find_network.return_value = mock.Mock( - id=fake_neutron_net_id) + id=fake_neutron_net_id + ) neutron_client.find_subnet.return_value = mock.Mock( - id=fake_neutron_subnet_id) + id=fake_neutron_subnet_id + ) arglist = [ self.share_network.id, - '--neutron-net-id', fake_neutron_net_id, - '--neutron-subnet-id', fake_neutron_subnet_id, + '--neutron-net-id', + fake_neutron_net_id, + '--neutron-subnet-id', + fake_neutron_subnet_id, ] verifylist = [ ('share_network', self.share_network.id), @@ -118,12 +130,10 @@ def test_share_network_subnet_create_valid_neutron_info(self): columns, data = self.cmd.take_action(parsed_args) neutron_client.find_network.assert_called_once_with( - fake_neutron_net_id, - ignore_missing=False + fake_neutron_net_id, ignore_missing=False ) neutron_client.find_subnet.assert_called_once_with( - fake_neutron_subnet_id, - ignore_missing=False + fake_neutron_subnet_id, ignore_missing=False ) self.share_subnets_mock.create.assert_called_once_with( share_network_id=self.share_network.id, @@ -142,12 +152,15 @@ def test_share_network_subnet_create_invalid_neutron_network(self): neutron_client = mock.Mock() self.app.client_manager.network = neutron_client neutron_client.find_network.side_effect = Exception( - "Network not found.") + "Network not found." + ) arglist = [ self.share_network.id, - '--neutron-net-id', fake_neutron_net_id, - '--neutron-subnet-id', fake_neutron_net_id, + '--neutron-net-id', + fake_neutron_net_id, + '--neutron-subnet-id', + fake_neutron_net_id, ] verifylist = [ ('share_network', self.share_network.id), @@ -155,12 +168,11 @@ def test_share_network_subnet_create_invalid_neutron_network(self): ('neutron_subnet_id', fake_neutron_net_id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - self.assertRaises(exceptions.CommandError, - self.cmd.take_action, - parsed_args) + self.assertRaises( + exceptions.CommandError, self.cmd.take_action, parsed_args + ) neutron_client.find_network.assert_called_once_with( - fake_neutron_net_id, - ignore_missing=False + fake_neutron_net_id, ignore_missing=False ) neutron_client.find_subnet.assert_not_called() self.share_subnets_mock.create.assert_not_called() @@ -170,12 +182,13 @@ def test_share_network_subnet_create_invalid_neutron_subnet(self): fake_neutron_subnet_id = str(uuid.uuid4()) neutron_client = mock.Mock() self.app.client_manager.network = neutron_client - neutron_client.find_subnet.side_effect = Exception( - "Subnet not found.") + neutron_client.find_subnet.side_effect = Exception("Subnet not found.") arglist = [ self.share_network.id, - '--neutron-net-id', fake_neutron_net_id, - '--neutron-subnet-id', fake_neutron_subnet_id, + '--neutron-net-id', + fake_neutron_net_id, + '--neutron-subnet-id', + fake_neutron_subnet_id, ] verifylist = [ ('share_network', self.share_network.id), @@ -183,16 +196,14 @@ def test_share_network_subnet_create_invalid_neutron_subnet(self): ('neutron_subnet_id', fake_neutron_subnet_id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - self.assertRaises(exceptions.CommandError, - self.cmd.take_action, - parsed_args) + self.assertRaises( + exceptions.CommandError, self.cmd.take_action, parsed_args + ) neutron_client.find_network.assert_called_once_with( - fake_neutron_net_id, - ignore_missing=False + fake_neutron_net_id, ignore_missing=False ) neutron_client.find_subnet.assert_called_once_with( - fake_neutron_subnet_id, - ignore_missing=False + fake_neutron_subnet_id, ignore_missing=False ) self.share_subnets_mock.create.assert_not_called() @@ -201,24 +212,28 @@ def test_share_network_subnet_create_arg_group_exception(self): arglist = [ self.share_network.id, - '--neutron-net-id', fake_neutron_net_id + '--neutron-net-id', + fake_neutron_net_id, ] verifylist = [ ('share_network', self.share_network.id), - ('neutron_net_id', fake_neutron_net_id) + ('neutron_net_id', fake_neutron_net_id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - self.assertRaises(exceptions.CommandError, - self.cmd.take_action, - parsed_args) + self.assertRaises( + exceptions.CommandError, self.cmd.take_action, parsed_args + ) - @ddt.data({'check_only': False, 'restart_check': True}, - {'check_only': True, 'restart_check': True}, - {'check_only': True, 'restart_check': False}) + @ddt.data( + {'check_only': False, 'restart_check': True}, + {'check_only': True, 'restart_check': True}, + {'check_only': True, 'restart_check': False}, + ) @ddt.unpack def test_share_network_subnet_create_check_api_version_exception( - self, check_only, restart_check): + self, check_only, restart_check + ): self.app.client_manager.share.api_version = api_versions.APIVersion( '2.69' ) @@ -237,19 +252,18 @@ def test_share_network_subnet_create_check_api_version_exception( parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( - exceptions.CommandError, self.cmd.take_action, parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) @ddt.data(True, False) def test_share_network_subnet_create_check(self, restart_check): self.app.client_manager.share.api_version = api_versions.APIVersion( '2.70' ) - self.share_networks_mock.share_network_subnet_create_check = ( - mock.Mock(return_value=(200, {'compatible': True}))) - arglist = [ - self.share_network.id, - '--check-only' - ] + self.share_networks_mock.share_network_subnet_create_check = mock.Mock( + return_value=(200, {'compatible': True}) + ) + arglist = [self.share_network.id, '--check-only'] verifylist = [ ('share_network', self.share_network.id), ('check_only', True), @@ -261,11 +275,15 @@ def test_share_network_subnet_create_check(self, restart_check): self.cmd.take_action(parsed_args) - (self.share_networks_mock.share_network_subnet_create_check - .assert_called_once_with( - share_network_id=self.share_network.id, neutron_net_id=None, - neutron_subnet_id=None, availability_zone=None, - reset_operation=restart_check)) + ( + self.share_networks_mock.share_network_subnet_create_check.assert_called_once_with( + share_network_id=self.share_network.id, + neutron_net_id=None, + neutron_subnet_id=None, + availability_zone=None, + reset_operation=restart_check, + ) + ) def test_share_network_subnet_create_metadata(self): self.app.client_manager.share.api_version = api_versions.APIVersion( @@ -273,8 +291,10 @@ def test_share_network_subnet_create_metadata(self): ) arglist = [ self.share_network.id, - '--property', 'Manila=zorilla', - '--property', 'Zorilla=manila' + '--property', + 'Manila=zorilla', + '--property', + 'Zorilla=manila', ] verifylist = [ ('share_network', self.share_network.id), @@ -301,39 +321,46 @@ def test_share_network_subnet_create_metadata_api_version_exception(self): ) arglist = [ self.share_network.id, - '--property', 'Manila=zorilla', + '--property', + 'Manila=zorilla', ] verifylist = [ ('share_network', self.share_network.id), - ('property', {'Manila': 'zorilla'}) + ('property', {'Manila': 'zorilla'}), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( - exceptions.CommandError, self.cmd.take_action, parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) class TestShareNetworkSubnetDelete(TestShareNetworkSubnet): - def setUp(self): - super(TestShareNetworkSubnetDelete, self).setUp() + super().setUp() self.share_network = ( - manila_fakes.FakeShareNetwork.create_one_share_network()) + manila_fakes.FakeShareNetwork.create_one_share_network() + ) self.share_networks_mock.get.return_value = self.share_network self.share_network_subnets = ( - manila_fakes.FakeShareNetworkSubnet.create_share_network_subnets()) + manila_fakes.FakeShareNetworkSubnet.create_share_network_subnets() + ) - self.cmd = osc_share_subnets.DeleteShareNetworkSubnet( - self.app, None) + self.cmd = osc_share_subnets.DeleteShareNetworkSubnet(self.app, None) def test_share_network_subnet_delete_missing_args(self): arglist = [] verifylist = [] - self.assertRaises(osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_network_subnets_delete(self): arglist = [ @@ -343,15 +370,22 @@ def test_share_network_subnets_delete(self): ] verifylist = [ ('share_network', self.share_network.id), - ('share_network_subnet', [self.share_network_subnets[0].id, - self.share_network_subnets[1].id]), + ( + 'share_network_subnet', + [ + self.share_network_subnets[0].id, + self.share_network_subnets[1].id, + ], + ), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - self.assertEqual(self.share_subnets_mock.delete.call_count, - len(self.share_network_subnets)) + self.assertEqual( + self.share_subnets_mock.delete.call_count, + len(self.share_network_subnets), + ) self.assertIsNone(result) def test_share_network_subnet_delete_exception(self): @@ -367,26 +401,26 @@ def test_share_network_subnet_delete_exception(self): parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.share_subnets_mock.delete.side_effect = exceptions.CommandError() - self.assertRaises(exceptions.CommandError, - self.cmd.take_action, - parsed_args) + self.assertRaises( + exceptions.CommandError, self.cmd.take_action, parsed_args + ) class TestShareNetworkSubnetShow(TestShareNetworkSubnet): - def setUp(self): - super(TestShareNetworkSubnetShow, self).setUp() + super().setUp() self.share_network = ( - manila_fakes.FakeShareNetwork.create_one_share_network()) + manila_fakes.FakeShareNetwork.create_one_share_network() + ) self.share_networks_mock.get.return_value = self.share_network self.share_network_subnet = ( - manila_fakes.FakeShareNetworkSubnet.create_one_share_subnet()) + manila_fakes.FakeShareNetworkSubnet.create_one_share_subnet() + ) self.share_subnets_mock.get.return_value = self.share_network_subnet - self.cmd = osc_share_subnets.ShowShareNetworkSubnet( - self.app, None) + self.cmd = osc_share_subnets.ShowShareNetworkSubnet(self.app, None) self.data = self.share_network_subnet._info.values() self.columns = self.share_network_subnet._info.keys() @@ -395,8 +429,13 @@ def test_share_network_subnet_show_missing_args(self): arglist = [] verifylist = [] - self.assertRaises(osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_network_subnet_show(self): arglist = [ @@ -412,8 +451,7 @@ def test_share_network_subnet_show(self): columns, data = self.cmd.take_action(parsed_args) self.share_subnets_mock.get.assert_called_once_with( - self.share_network.id, - self.share_network_subnet.id + self.share_network.id, self.share_network_subnet.id ) self.assertCountEqual(self.columns, columns) @@ -421,19 +459,19 @@ def test_share_network_subnet_show(self): class TestShareNetworkSubnetSet(TestShareNetworkSubnet): - def setUp(self): - super(TestShareNetworkSubnetSet, self).setUp() + super().setUp() self.share_network = ( - manila_fakes.FakeShareNetwork.create_one_share_network()) + manila_fakes.FakeShareNetwork.create_one_share_network() + ) self.share_networks_mock.get.return_value = self.share_network self.share_network_subnet = ( - manila_fakes.FakeShareNetworkSubnet.create_one_share_subnet()) + manila_fakes.FakeShareNetworkSubnet.create_one_share_subnet() + ) - self.cmd = osc_share_subnets.SetShareNetworkSubnet( - self.app, None) + self.cmd = osc_share_subnets.SetShareNetworkSubnet(self.app, None) def test_set_share_network_subnet_property(self): self.app.client_manager.share.api_version = api_versions.APIVersion( @@ -442,8 +480,10 @@ def test_set_share_network_subnet_property(self): arglist = [ self.share_network.id, self.share_network_subnet.id, - '--property', 'Zorilla=manila', - '--property', 'test=my_test', + '--property', + 'Zorilla=manila', + '--property', + 'test=my_test', ] verifylist = [ ('share_network', self.share_network.id), @@ -455,8 +495,10 @@ def test_set_share_network_subnet_property(self): self.cmd.take_action(parsed_args) self.share_subnets_mock.set_metadata.assert_called_once_with( - self.share_network.id, {'Zorilla': 'manila', 'test': 'my_test'}, - subresource=self.share_network_subnet.id) + self.share_network.id, + {'Zorilla': 'manila', 'test': 'my_test'}, + subresource=self.share_network_subnet.id, + ) def test_set_share_network_subnet_property_exception(self): self.app.client_manager.share.api_version = api_versions.APIVersion( @@ -465,7 +507,8 @@ def test_set_share_network_subnet_property_exception(self): arglist = [ self.share_network.id, self.share_network_subnet.id, - '--property', 'key=1', + '--property', + 'key=1', ] verifylist = [ ('share_network', self.share_network.id), @@ -478,30 +521,33 @@ def test_set_share_network_subnet_property_exception(self): self.cmd.take_action(parsed_args) self.share_subnets_mock.set_metadata.assert_called_once_with( - self.share_network.id, {'key': '1'}, - subresource=self.share_network_subnet.id) + self.share_network.id, + {'key': '1'}, + subresource=self.share_network_subnet.id, + ) self.share_subnets_mock.set_metadata.side_effect = ( - exceptions.BadRequest) + exceptions.BadRequest + ) self.assertRaises( - exceptions.CommandError, self.cmd.take_action, - parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) class TestShareNetworkSubnetUnset(TestShareNetworkSubnet): - def setUp(self): - super(TestShareNetworkSubnetUnset, self).setUp() + super().setUp() self.share_network = ( - manila_fakes.FakeShareNetwork.create_one_share_network()) + manila_fakes.FakeShareNetwork.create_one_share_network() + ) self.share_networks_mock.get.return_value = self.share_network self.share_network_subnet = ( - manila_fakes.FakeShareNetworkSubnet.create_one_share_subnet()) + manila_fakes.FakeShareNetworkSubnet.create_one_share_subnet() + ) - self.cmd = osc_share_subnets.UnsetShareNetworkSubnet( - self.app, None) + self.cmd = osc_share_subnets.UnsetShareNetworkSubnet(self.app, None) def test_unset_share_network_subnet_property(self): self.app.client_manager.share.api_version = api_versions.APIVersion( @@ -510,7 +556,8 @@ def test_unset_share_network_subnet_property(self): arglist = [ self.share_network.id, self.share_network_subnet.id, - '--property', 'Manila', + '--property', + 'Manila', ] verifylist = [ ('share_network', self.share_network.id), @@ -523,8 +570,10 @@ def test_unset_share_network_subnet_property(self): self.cmd.take_action(parsed_args) self.share_subnets_mock.delete_metadata.assert_called_once_with( - self.share_network.id, ['Manila'], - subresource=self.share_network_subnet.id) + self.share_network.id, + ['Manila'], + subresource=self.share_network_subnet.id, + ) def test_unset_share_network_subnet_property_exception(self): self.app.client_manager.share.api_version = api_versions.APIVersion( @@ -533,8 +582,10 @@ def test_unset_share_network_subnet_property_exception(self): arglist = [ self.share_network.id, self.share_network_subnet.id, - '--property', 'Manila', - '--property', 'test', + '--property', + 'Manila', + '--property', + 'test', ] verifylist = [ ('share_network', self.share_network.id), @@ -546,14 +597,25 @@ def test_unset_share_network_subnet_property_exception(self): self.cmd.take_action(parsed_args) - self.share_subnets_mock.delete_metadata.assert_has_calls([ - mock.call(self.share_network.id, ['Manila'], - subresource=self.share_network_subnet.id), - mock.call(self.share_network.id, ['test'], - subresource=self.share_network_subnet.id)]) + self.share_subnets_mock.delete_metadata.assert_has_calls( + [ + mock.call( + self.share_network.id, + ['Manila'], + subresource=self.share_network_subnet.id, + ), + mock.call( + self.share_network.id, + ['test'], + subresource=self.share_network_subnet.id, + ), + ] + ) # 404 Not Found would be raised, if property 'Manila' doesn't exist. self.share_subnets_mock.delete_metadata.side_effect = ( - exceptions.NotFound) + exceptions.NotFound + ) self.assertRaises( - exceptions.CommandError, self.cmd.take_action, parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) diff --git a/manilaclient/tests/unit/osc/v2/test_share_networks.py b/manilaclient/tests/unit/osc/v2/test_share_networks.py index 91dcbd04..d7af09ba 100644 --- a/manilaclient/tests/unit/osc/v2/test_share_networks.py +++ b/manilaclient/tests/unit/osc/v2/test_share_networks.py @@ -37,23 +37,23 @@ class TestShareNetwork(manila_fakes.TestShare): - def setUp(self): - super(TestShareNetwork, self).setUp() + super().setUp() self.share_networks_mock = self.app.client_manager.share.share_networks self.share_networks_mock.reset_mock() self.app.client_manager.share.api_version = api_versions.APIVersion( - api_versions.MAX_VERSION) + api_versions.MAX_VERSION + ) @ddt.ddt class TestShareNetworkCreate(TestShareNetwork): - def setUp(self): - super(TestShareNetworkCreate, self).setUp() + super().setUp() self.share_network = ( - manila_fakes.FakeShareNetwork.create_one_share_network()) + manila_fakes.FakeShareNetwork.create_one_share_network() + ) self.share_networks_mock.create.return_value = self.share_network self.cmd = osc_share_networks.CreateShareNetwork(self.app, None) @@ -64,7 +64,8 @@ def setUp(self): @ddt.data('table', 'yaml') def test_share_network_create_formatter(self, formatter): arglist = [ - '-f', formatter, + '-f', + formatter, ] verifylist = [ ('formatter', formatter), @@ -79,7 +80,8 @@ def test_share_network_create_formatter(self, formatter): name=None, description=None, neutron_net_id=None, - neutron_subnet_id=None) + neutron_subnet_id=None, + ) self.assertCountEqual(self.columns, columns) self.assertCountEqual(expected_data.values(), data) @@ -92,11 +94,16 @@ def test_share_network_create_with_args(self): fake_az.id = str(uuid.uuid4()) arglist = [ - '--name', 'zorilla-net', - '--description', 'fastest-backdoor-network-ever', - '--neutron-net-id', fake_neutron_net_id, - '--neutron-subnet-id', fake_neutron_subnet_id, - '--availability-zone', 'nova', + '--name', + 'zorilla-net', + '--description', + 'fastest-backdoor-network-ever', + '--neutron-net-id', + fake_neutron_net_id, + '--neutron-subnet-id', + fake_neutron_subnet_id, + '--availability-zone', + 'nova', ] verifylist = [ ('name', 'zorilla-net'), @@ -107,8 +114,7 @@ def test_share_network_create_with_args(self): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - with mock.patch('osc_lib.utils.find_resource', - return_value=fake_az): + with mock.patch('osc_lib.utils.find_resource', return_value=fake_az): columns, data = self.cmd.take_action(parsed_args) self.share_networks_mock.create.assert_called_once_with( @@ -130,13 +136,17 @@ def test_share_network_create_with_valid_neutron_info(self): self.app.client_manager.network = neutron_client neutron_client.find_network.return_value = mock.Mock( - id=fake_neutron_net_id) + id=fake_neutron_net_id + ) neutron_client.find_subnet.return_value = mock.Mock( - id=fake_neutron_subnet_id) + id=fake_neutron_subnet_id + ) arglist = [ - '--neutron-net-id', fake_neutron_net_id, - '--neutron-subnet-id', fake_neutron_subnet_id, + '--neutron-net-id', + fake_neutron_net_id, + '--neutron-subnet-id', + fake_neutron_subnet_id, ] verifylist = [ ('neutron_net_id', fake_neutron_net_id), @@ -146,14 +156,16 @@ def test_share_network_create_with_valid_neutron_info(self): columns, data = self.cmd.take_action(parsed_args) neutron_client.find_network.assert_called_once_with( - fake_neutron_net_id, ignore_missing=False) + fake_neutron_net_id, ignore_missing=False + ) neutron_client.find_subnet.assert_called_once_with( - fake_neutron_subnet_id, ignore_missing=False) + fake_neutron_subnet_id, ignore_missing=False + ) self.share_networks_mock.create.assert_called_once_with( name=None, description=None, neutron_net_id=fake_neutron_net_id, - neutron_subnet_id=fake_neutron_subnet_id + neutron_subnet_id=fake_neutron_subnet_id, ) self.assertCountEqual(self.columns, columns) self.assertCountEqual(self.data, data) @@ -165,24 +177,20 @@ def test_share_network_create_with_invalid_neutron_network(self): self.app.client_manager.network = neutron_client neutron_client.find_network.side_effect = Exception( - "Network not found") + "Network not found" + ) - arglist = [ - '--neutron-net-id', fake_neutron_net_id - ] - verifylist = [ - ('neutron_net_id', fake_neutron_net_id) - ] + arglist = ['--neutron-net-id', fake_neutron_net_id] + verifylist = [('neutron_net_id', fake_neutron_net_id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( - exceptions.CommandError, - self.cmd.take_action, - parsed_args + exceptions.CommandError, self.cmd.take_action, parsed_args ) neutron_client.find_network.assert_called_once_with( - fake_neutron_net_id, ignore_missing=False) + fake_neutron_net_id, ignore_missing=False + ) self.share_networks_mock.create.assert_not_called() def test_share_network_create_with_invalid_neutron_subnet(self): @@ -191,36 +199,30 @@ def test_share_network_create_with_invalid_neutron_subnet(self): neutron_client = mock.Mock() self.app.client_manager.network = neutron_client - neutron_client.find_subnet.side_effect = Exception( - "Subnet not found") + neutron_client.find_subnet.side_effect = Exception("Subnet not found") - arglist = [ - '--neutron-subnet-id', fake_neutron_subnet_id - ] - verifylist = [ - ('neutron_subnet_id', fake_neutron_subnet_id) - ] + arglist = ['--neutron-subnet-id', fake_neutron_subnet_id] + verifylist = [('neutron_subnet_id', fake_neutron_subnet_id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( - exceptions.CommandError, - self.cmd.take_action, - parsed_args + exceptions.CommandError, self.cmd.take_action, parsed_args ) neutron_client.find_subnet.assert_called_once_with( - fake_neutron_subnet_id, ignore_missing=False) + fake_neutron_subnet_id, ignore_missing=False + ) self.share_networks_mock.create.assert_not_called() @ddt.ddt class TestShareNetworkDelete(TestShareNetwork): - def setUp(self): - super(TestShareNetworkDelete, self).setUp() + super().setUp() self.share_network = ( - manila_fakes.FakeShareNetwork.create_one_share_network()) + manila_fakes.FakeShareNetwork.create_one_share_network() + ) self.share_networks_mock.get.return_value = self.share_network @@ -230,15 +232,20 @@ def test_share_network_delete_missing_args(self): arglist = [] verifylist = [] - self.assertRaises(osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) @ddt.data(True, False) def test_share_network_delete_with_wait(self, wait): oscutils.wait_for_delete = mock.Mock(return_value=True) - share_networks = ( - manila_fakes.FakeShareNetwork.create_share_networks( - count=2)) + share_networks = manila_fakes.FakeShareNetwork.create_share_networks( + count=2 + ) arglist = [ share_networks[0].id, share_networks[1].name, @@ -253,19 +260,27 @@ def test_share_network_delete_with_wait(self, wait): parsed_args = self.check_parser(self.cmd, arglist, verifylist) - with mock.patch('osc_lib.utils.find_resource', - side_effect=share_networks): + with mock.patch( + 'osc_lib.utils.find_resource', side_effect=share_networks + ): result = self.cmd.take_action(parsed_args) - self.assertEqual(self.share_networks_mock.delete.call_count, - len(share_networks)) + self.assertEqual( + self.share_networks_mock.delete.call_count, len(share_networks) + ) if wait: - oscutils.wait_for_delete.assert_has_calls([ - mock.call(manager=self.share_networks_mock, - res_id=share_networks[0].id), - mock.call(manager=self.share_networks_mock, - res_id=share_networks[1].id) - ]) + oscutils.wait_for_delete.assert_has_calls( + [ + mock.call( + manager=self.share_networks_mock, + res_id=share_networks[0].id, + ), + mock.call( + manager=self.share_networks_mock, + res_id=share_networks[1].id, + ), + ] + ) self.assertIsNone(result) def test_share_network_delete_exception(self): @@ -279,9 +294,9 @@ def test_share_network_delete_exception(self): parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.share_networks_mock.delete.side_effect = exceptions.CommandError() - self.assertRaises(exceptions.CommandError, - self.cmd.take_action, - parsed_args) + self.assertRaises( + exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_share_network_delete_wait_fails(self): oscutils.wait_for_delete = mock.Mock(return_value=False) @@ -294,28 +309,31 @@ def test_share_network_delete_wait_fails(self): ('wait', True), ] - with mock.patch('osc_lib.utils.find_resource', - return_value=self.share_network): + with mock.patch( + 'osc_lib.utils.find_resource', return_value=self.share_network + ): parsed_args = self.check_parser(self.cmd, arglist, verifylist) - self.assertRaises(exceptions.CommandError, - self.cmd.take_action, - parsed_args) + self.assertRaises( + exceptions.CommandError, self.cmd.take_action, parsed_args + ) self.share_networks_mock.delete.assert_called_once_with( - self.share_network) + self.share_network + ) @ddt.ddt class TestShareNetworkShow(TestShareNetwork): - def setUp(self): - super(TestShareNetworkShow, self).setUp() + super().setUp() self.share_network = ( - manila_fakes.FakeShareNetwork.create_one_share_network()) + manila_fakes.FakeShareNetwork.create_one_share_network() + ) self.share_networks_mock.get.return_value = self.share_network self.security_services_mock = ( - self.app.client_manager.share.security_services) + self.app.client_manager.share.security_services + ) self.cmd = osc_share_networks.ShowShareNetwork(self.app, None) @@ -326,17 +344,23 @@ def test_share_network_show_missing_args(self): arglist = [] verifylist = [] - self.assertRaises(osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) @ddt.data('name', 'id') def test_share_network_show_by(self, attr): network_to_show = getattr(self.share_network, attr) fake_security_service = mock.Mock() fake_security_service.id = str(uuid.uuid4()) - fake_security_service.name = 'security-service-%s' % uuid.uuid4().hex + fake_security_service.name = f'security-service-{uuid.uuid4().hex}' self.security_services_mock.list = mock.Mock( - return_value=[fake_security_service]) + return_value=[fake_security_service] + ) arglist = [ network_to_show, @@ -347,34 +371,36 @@ def test_share_network_show_by(self, attr): parsed_args = self.check_parser(self.cmd, arglist, verifylist) - with mock.patch('osc_lib.utils.find_resource', - return_value=self.share_network) as find_resource: - + with mock.patch( + 'osc_lib.utils.find_resource', return_value=self.share_network + ) as find_resource: columns, data = self.cmd.take_action(parsed_args) find_resource.assert_called_once_with( - self.share_networks_mock, network_to_show) + self.share_networks_mock, network_to_show + ) self.assertCountEqual(self.columns, columns) self.assertCountEqual(self.data, data) @ddt.ddt class TestShareNetworkList(TestShareNetwork): - def setUp(self): - super(TestShareNetworkList, self).setUp() + super().setUp() self.share_networks = ( - manila_fakes.FakeShareNetwork.create_share_networks( - count=2)) - self.share_networks_list = oscutils.sort_items(self.share_networks, - 'name:asc', - str) + manila_fakes.FakeShareNetwork.create_share_networks(count=2) + ) + self.share_networks_list = oscutils.sort_items( + self.share_networks, 'name:asc', str + ) self.share_networks_mock.list.return_value = self.share_networks_list - self.values = (oscutils.get_dict_properties( - s._info, COLUMNS) for s in self.share_networks_list) + self.values = ( + oscutils.get_dict_properties(s._info, COLUMNS) + for s in self.share_networks_list + ) self.expected_search_opts = { 'all_tenants': False, 'project_id': None, @@ -399,20 +425,25 @@ def setUp(self): def test_list_share_networks_with_search_opts(self, with_search_opts): if with_search_opts: arglist = [ - '--name', 'foo', - '--ip-version', '4', - '--description~', 'foo-share-network', + '--name', + 'foo', + '--ip-version', + '4', + '--description~', + 'foo-share-network', ] verifylist = [ ('name', 'foo'), ('ip_version', '4'), ('description~', 'foo-share-network'), ] - self.expected_search_opts.update({ - 'name': 'foo', - 'ip_version': '4', - 'description~': 'foo-share-network', - }) + self.expected_search_opts.update( + { + 'name': 'foo', + 'ip_version': '4', + 'description~': 'foo-share-network', + } + ) else: arglist = [] verifylist = [] @@ -422,7 +453,8 @@ def test_list_share_networks_with_search_opts(self, with_search_opts): columns, data = self.cmd.take_action(parsed_args) self.share_networks_mock.list.assert_called_once_with( - search_opts=self.expected_search_opts) + search_opts=self.expected_search_opts + ) self.assertEqual(COLUMNS, columns) self.assertEqual(list(self.values), list(data)) @@ -430,8 +462,10 @@ def test_list_share_networks_all_projects(self): all_tenants_list = COLUMNS.copy() all_tenants_list.append('Project ID') self.expected_search_opts.update({'all_tenants': True}) - list_values = (oscutils.get_dict_properties( - s._info, all_tenants_list) for s in self.share_networks_list) + list_values = ( + oscutils.get_dict_properties(s._info, all_tenants_list) + for s in self.share_networks_list + ) arglist = [ '--all-projects', @@ -446,14 +480,17 @@ def test_list_share_networks_all_projects(self): columns, data = self.cmd.take_action(parsed_args) self.share_networks_mock.list.assert_called_once_with( - search_opts=self.expected_search_opts) + search_opts=self.expected_search_opts + ) self.assertEqual(all_tenants_list, columns) self.assertEqual(list(list_values), list(data)) def test_list_share_networks_detail(self): - values = (oscutils.get_dict_properties( - s._info, COLUMNS_DETAIL) for s in self.share_networks_list) + values = ( + oscutils.get_dict_properties(s._info, COLUMNS_DETAIL) + for s in self.share_networks_list + ) arglist = [ '--detail', @@ -468,13 +505,15 @@ def test_list_share_networks_detail(self): columns, data = self.cmd.take_action(parsed_args) self.share_networks_mock.list.assert_called_once_with( - search_opts=self.expected_search_opts) + search_opts=self.expected_search_opts + ) self.assertEqual(COLUMNS_DETAIL, columns) self.assertEqual(list(values), list(data)) def test_list_share_networks_api_version_exception(self): self.app.client_manager.share.api_version = api_versions.APIVersion( - "2.35") + "2.35" + ) arglist = [ '--description', @@ -487,19 +526,18 @@ def test_list_share_networks_api_version_exception(self): parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( - exceptions.CommandError, - self.cmd.take_action, - parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) @ddt.ddt class TestShareNetworkUnset(TestShareNetwork): - def setUp(self): - super(TestShareNetworkUnset, self).setUp() + super().setUp() self.share_network = ( - manila_fakes.FakeShareNetwork.create_one_share_network()) + manila_fakes.FakeShareNetwork.create_one_share_network() + ) self.share_networks_mock.get.return_value = self.share_network self.cmd = osc_share_networks.UnsetShareNetwork(self.app, None) @@ -515,12 +553,14 @@ def test_unset_share_network_name(self): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - with mock.patch('osc_lib.utils.find_resource', - return_value=self.share_network): + with mock.patch( + 'osc_lib.utils.find_resource', return_value=self.share_network + ): result = self.cmd.take_action(parsed_args) self.share_networks_mock.update.assert_called_once_with( - self.share_network, name='') + self.share_network, name='' + ) self.assertIsNone(result) def test_unset_share_network_description(self): @@ -537,7 +577,8 @@ def test_unset_share_network_description(self): result = self.cmd.take_action(parsed_args) self.share_networks_mock.update.assert_called_once_with( - self.share_network, description='') + self.share_network, description='' + ) self.assertIsNone(result) @ddt.data('name', 'security_service') @@ -559,20 +600,23 @@ def test_unset_share_network_exception_while_updating(self, attr): self.share_networks_mock.update.side_effect = Exception() else: self.share_networks_mock.remove_security_service.side_effect = ( - Exception()) - - with mock.patch('osc_lib.utils.find_resource', - side_effect=[self.share_network, - 'fake-security-service']): - self.assertRaises(exceptions.CommandError, - self.cmd.take_action, - parsed_args) + Exception() + ) + + with mock.patch( + 'osc_lib.utils.find_resource', + side_effect=[self.share_network, 'fake-security-service'], + ): + self.assertRaises( + exceptions.CommandError, self.cmd.take_action, parsed_args + ) self.share_networks_mock.update.assert_called_once_with( - self.share_network, name='') + self.share_network, name='' + ) if attr == 'security_service': - self.share_networks_mock.remove_security_service\ - .assert_called_once_with(self.share_network, - 'fake-security-service') + self.share_networks_mock.remove_security_service.assert_called_once_with( + self.share_network, 'fake-security-service' + ) def test_unset_share_network_security_service(self): arglist = [ @@ -586,51 +630,58 @@ def test_unset_share_network_security_service(self): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - with mock.patch('osc_lib.utils.find_resource', - side_effect=[self.share_network, - 'fake-security-service']): + with mock.patch( + 'osc_lib.utils.find_resource', + side_effect=[self.share_network, 'fake-security-service'], + ): result = self.cmd.take_action(parsed_args) self.assertIsNone(result) - self.share_networks_mock.remove_security_service\ - .assert_called_once_with(self.share_network, - 'fake-security-service') + self.share_networks_mock.remove_security_service.assert_called_once_with( + self.share_network, 'fake-security-service' + ) @ddt.ddt class TestShareNetworkSet(TestShareNetwork): - def setUp(self): - super(TestShareNetworkSet, self).setUp() + super().setUp() self.share_network = ( - manila_fakes.FakeShareNetwork.create_one_share_network()) + manila_fakes.FakeShareNetwork.create_one_share_network() + ) self.share_networks_mock.get.return_value = self.share_network self.cmd = osc_share_networks.SetShareNetwork(self.app, None) - @ddt.data({'status': 'error', - 'current_security_service': str(uuid.uuid4()), - 'check_only': True, - 'restart_check': True}, - {'status': None, - 'current_security_service': str(uuid.uuid4()), - 'check_only': True, - 'restart_check': None}, - {'status': None, - 'current_security_service': str(uuid.uuid4()), - 'check_only': True, - 'restart_check': True}, - ) + @ddt.data( + { + 'status': 'error', + 'current_security_service': str(uuid.uuid4()), + 'check_only': True, + 'restart_check': True, + }, + { + 'status': None, + 'current_security_service': str(uuid.uuid4()), + 'check_only': True, + 'restart_check': None, + }, + { + 'status': None, + 'current_security_service': str(uuid.uuid4()), + 'check_only': True, + 'restart_check': True, + }, + ) @ddt.unpack - def test_set_share_network_api_version_exception(self, - status, - current_security_service, - check_only, - restart_check): + def test_set_share_network_api_version_exception( + self, status, current_security_service, check_only, restart_check + ): self.app.client_manager.share.api_version = api_versions.APIVersion( - "2.62") + "2.62" + ) arglist = [self.share_network.id] verifylist = [('share_network', self.share_network.id)] @@ -638,10 +689,12 @@ def test_set_share_network_api_version_exception(self, arglist.extend(['--status', status]) verifylist.append(('status', status)) if current_security_service: - arglist.extend(['--current-security-service', - current_security_service]) - verifylist.append(('current_security_service', - current_security_service)) + arglist.extend( + ['--current-security-service', current_security_service] + ) + verifylist.append( + ('current_security_service', current_security_service) + ) if check_only and restart_check: arglist.extend(['--check-only', '--restart-check']) verifylist.extend([('check_only', True), ('restart_check', True)]) @@ -649,9 +702,8 @@ def test_set_share_network_api_version_exception(self, parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( - exceptions.CommandError, - self.cmd.take_action, - parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_set_network_properties(self): new_name = 'share-network-name-' + uuid.uuid4().hex @@ -660,9 +712,12 @@ def test_set_network_properties(self): arglist = [ self.share_network.id, - '--name', new_name, - '--description', new_description, - '--neutron-subnet-id', new_neutron_subnet_id, + '--name', + new_name, + '--description', + new_description, + '--neutron-subnet-id', + new_neutron_subnet_id, ] verifylist = [ ('share_network', self.share_network.id), @@ -672,8 +727,9 @@ def test_set_network_properties(self): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - with mock.patch('osc_lib.utils.find_resource', - return_value=self.share_network): + with mock.patch( + 'osc_lib.utils.find_resource', return_value=self.share_network + ): result = self.cmd.take_action(parsed_args) self.share_networks_mock.update.assert_called_once_with( @@ -685,79 +741,81 @@ def test_set_network_properties(self): self.assertIsNone(result) def test_set_share_network_status(self): - arglist = [ - self.share_network.id, - '--status', 'error' - ] + arglist = [self.share_network.id, '--status', 'error'] verifylist = [ ('share_network', self.share_network.id), - ('status', 'error') + ('status', 'error'), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - with mock.patch('osc_lib.utils.find_resource', - return_value=self.share_network): + with mock.patch( + 'osc_lib.utils.find_resource', return_value=self.share_network + ): result = self.cmd.take_action(parsed_args) self.share_networks_mock.reset_state.assert_called_once_with( - self.share_network, parsed_args.status) + self.share_network, parsed_args.status + ) self.assertIsNone(result) def test_set_network_update_exception(self): share_network_name = 'share-network-name-' + uuid.uuid4().hex - arglist = [ - self.share_network.id, - '--name', share_network_name - ] + arglist = [self.share_network.id, '--name', share_network_name] verifylist = [ ('share_network', self.share_network.id), - ('name', share_network_name) + ('name', share_network_name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.share_networks_mock.update.side_effect = Exception() - with mock.patch('osc_lib.utils.find_resource', - return_value=self.share_network): - self.assertRaises(exceptions.CommandError, - self.cmd.take_action, - parsed_args) + with mock.patch( + 'osc_lib.utils.find_resource', return_value=self.share_network + ): + self.assertRaises( + exceptions.CommandError, self.cmd.take_action, parsed_args + ) self.share_networks_mock.update.assert_called_once_with( - self.share_network, name=parsed_args.name) + self.share_network, name=parsed_args.name + ) def test_set_share_network_status_exception(self): - arglist = [ - self.share_network.id, - '--status', 'error' - ] + arglist = [self.share_network.id, '--status', 'error'] verifylist = [ ('share_network', self.share_network.id), - ('status', 'error') + ('status', 'error'), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.share_networks_mock.reset_state.side_effect = Exception() - with mock.patch('osc_lib.utils.find_resource', - return_value=self.share_network): - self.assertRaises(exceptions.CommandError, - self.cmd.take_action, - parsed_args) + with mock.patch( + 'osc_lib.utils.find_resource', return_value=self.share_network + ): + self.assertRaises( + exceptions.CommandError, self.cmd.take_action, parsed_args + ) self.share_networks_mock.reset_state.assert_called_once_with( - self.share_network, parsed_args.status) + self.share_network, parsed_args.status + ) - @ddt.data({'check_only': False, 'restart_check': False}, - {'check_only': True, 'restart_check': True}, - {'check_only': True, 'restart_check': False}) + @ddt.data( + {'check_only': False, 'restart_check': False}, + {'check_only': True, 'restart_check': True}, + {'check_only': True, 'restart_check': False}, + ) @ddt.unpack def test_set_share_network_add_new_security_service_check_reset( - self, check_only, restart_check): - self.share_networks_mock .add_security_service_check = mock.Mock( - return_value=(200, {'compatible': True})) + self, check_only, restart_check + ): + self.share_networks_mock.add_security_service_check = mock.Mock( + return_value=(200, {'compatible': True}) + ) arglist = [ self.share_network.id, - '--new-security-service', 'new-security-service-name', + '--new-security-service', + 'new-security-service-name', ] verifylist = [ ('share_network', self.share_network.id), @@ -773,39 +831,45 @@ def test_set_share_network_add_new_security_service_check_reset( parsed_args = self.check_parser(self.cmd, arglist, verifylist) - with mock.patch('osc_lib.utils.find_resource', - side_effect=[self.share_network, - 'new-security-service']): + with mock.patch( + 'osc_lib.utils.find_resource', + side_effect=[self.share_network, 'new-security-service'], + ): result = self.cmd.take_action(parsed_args) if check_only: - self.share_networks_mock.add_security_service_check\ - .assert_called_once_with(self.share_network, - 'new-security-service', - reset_operation=restart_check) + self.share_networks_mock.add_security_service_check.assert_called_once_with( + self.share_network, + 'new-security-service', + reset_operation=restart_check, + ) self.share_networks_mock.add_security_service.assert_not_called() else: - self.share_networks_mock.add_security_service_check\ - .assert_not_called() - self.share_networks_mock.add_security_service\ - .assert_called_once_with(self.share_network, - 'new-security-service') + self.share_networks_mock.add_security_service_check.assert_not_called() + self.share_networks_mock.add_security_service.assert_called_once_with( + self.share_network, 'new-security-service' + ) self.assertIsNone(result) - @ddt.data({'check_only': False, 'restart_check': False}, - {'check_only': True, 'restart_check': True}, - {'check_only': True, 'restart_check': False}) + @ddt.data( + {'check_only': False, 'restart_check': False}, + {'check_only': True, 'restart_check': True}, + {'check_only': True, 'restart_check': False}, + ) @ddt.unpack def test_set_share_network_update_security_service_check_reset( - self, check_only, restart_check): - self.share_networks_mock\ - .update_share_network_security_service_check = mock.Mock( - return_value=(200, {'compatible': True})) + self, check_only, restart_check + ): + self.share_networks_mock.update_share_network_security_service_check = mock.Mock( + return_value=(200, {'compatible': True}) + ) arglist = [ self.share_network.id, - '--new-security-service', 'new-security-service-name', - '--current-security-service', 'current-security-service-name' + '--new-security-service', + 'new-security-service-name', + '--current-security-service', + 'current-security-service-name', ] verifylist = [ ('share_network', self.share_network.id), @@ -820,27 +884,29 @@ def test_set_share_network_update_security_service_check_reset( verifylist.append(('restart_check', True)) parsed_args = self.check_parser(self.cmd, arglist, verifylist) - with mock.patch('osc_lib.utils.find_resource', - side_effect=[self.share_network, - 'new-security-service', - 'current-security-service']): + with mock.patch( + 'osc_lib.utils.find_resource', + side_effect=[ + self.share_network, + 'new-security-service', + 'current-security-service', + ], + ): result = self.cmd.take_action(parsed_args) if check_only: - self.share_networks_mock\ - .update_share_network_security_service_check\ - .assert_called_once_with(self.share_network, - 'current-security-service', - 'new-security-service', - reset_operation=restart_check) - self.share_networks_mock.update_share_network_security_service\ - .assert_not_called() + self.share_networks_mock.update_share_network_security_service_check.assert_called_once_with( + self.share_network, + 'current-security-service', + 'new-security-service', + reset_operation=restart_check, + ) + self.share_networks_mock.update_share_network_security_service.assert_not_called() else: - self.share_networks_mock\ - .update_share_network_security_service_check\ - .assert_not_called() - self.share_networks_mock.update_share_network_security_service\ - .assert_called_once_with(self.share_network, - 'current-security-service', - 'new-security-service') + self.share_networks_mock.update_share_network_security_service_check.assert_not_called() + self.share_networks_mock.update_share_network_security_service.assert_called_once_with( + self.share_network, + 'current-security-service', + 'new-security-service', + ) self.assertIsNone(result) diff --git a/manilaclient/tests/unit/osc/v2/test_share_pools.py b/manilaclient/tests/unit/osc/v2/test_share_pools.py index e59d7921..9f09c1b5 100644 --- a/manilaclient/tests/unit/osc/v2/test_share_pools.py +++ b/manilaclient/tests/unit/osc/v2/test_share_pools.py @@ -19,9 +19,8 @@ class TestPool(manila_fakes.TestShare): - def setUp(self): - super(TestPool, self).setUp() + super().setUp() self.pools_mock = self.app.client_manager.share.pools self.pools_mock.reset_mock() @@ -30,15 +29,15 @@ def setUp(self): self.share_types_mock.reset_mock() self.app.client_manager.share.api_version = api_versions.APIVersion( - api_versions.MAX_VERSION) + api_versions.MAX_VERSION + ) class TestPoolList(TestPool): - columns = ['Name', 'Host', 'Backend', 'Pool'] def setUp(self): - super(TestPoolList, self).setUp() + super().setUp() self.share_type = manila_fakes.FakeShareType.create_one_sharetype() self.share_types_mock.get.return_value = self.share_type @@ -46,8 +45,10 @@ def setUp(self): self.share_pools = manila_fakes.FakeSharePools.create_share_pools() self.pools_mock.list.return_value = self.share_pools - self.values = (oscutils.get_dict_properties( - pool._info, self.columns) for pool in self.share_pools) + self.values = ( + oscutils.get_dict_properties(pool._info, self.columns) + for pool in self.share_pools + ) self.cmd = share_pools.ListSharePools(self.app, None) @@ -65,21 +66,25 @@ def test_list_share_pools(self): 'backend': None, 'pool': None, 'share_type': None, - }) + }, + ) self.assertEqual(self.columns, columns) self.assertEqual(list(self.values), list(data)) def test_list_share_pools_filters(self): arglist = [ - '--host', self.share_pools[0].host, - '--backend', self.share_pools[0].backend, - '--pool', self.share_pools[0].pool + '--host', + self.share_pools[0].host, + '--backend', + self.share_pools[0].backend, + '--pool', + self.share_pools[0].pool, ] verifylist = [ ('host', self.share_pools[0].host), ('backend', self.share_pools[0].backend), - ('pool', self.share_pools[0].pool) + ('pool', self.share_pools[0].pool), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -92,18 +97,15 @@ def test_list_share_pools_filters(self): 'backend': self.share_pools[0].backend, 'pool': self.share_pools[0].pool, 'share_type': None, - }) + }, + ) self.assertEqual(self.columns, columns) self.assertEqual(list(self.values), list(data)) def test_list_share_pools_share_type(self): - arglist = [ - '--share-type', self.share_type.id - ] - verifylist = [ - ('share_type', self.share_type.id) - ] + arglist = ['--share-type', self.share_type.id] + verifylist = [('share_type', self.share_type.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) @@ -114,35 +116,32 @@ def test_list_share_pools_share_type(self): 'backend': None, 'pool': None, 'share_type': self.share_type.id, - }) + }, + ) self.assertEqual(self.columns, columns) self.assertEqual(list(self.values), list(data)) def test_list_share_pools_share_type_api_version_exception(self): self.app.client_manager.share.api_version = api_versions.APIVersion( - "2.22") + "2.22" + ) - arglist = [ - '--share-type', self.share_type.id - ] - verifylist = [ - ('share_type', self.share_type.id) - ] + arglist = ['--share-type', self.share_type.id] + verifylist = [('share_type', self.share_type.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( - exceptions.CommandError, self.cmd.take_action, parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_list_share_pools_detail(self): detail_columns = ['Name', 'Host', 'Backend', 'Pool', 'Capabilities'] - detail_values = (oscutils.get_dict_properties( - pool._info, detail_columns) for pool in self.share_pools) - arglist = [ - '--detail' - ] - verifylist = [ - ('detail', True) - ] + detail_values = ( + oscutils.get_dict_properties(pool._info, detail_columns) + for pool in self.share_pools + ) + arglist = ['--detail'] + verifylist = [('detail', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) @@ -154,7 +153,8 @@ def test_list_share_pools_detail(self): 'backend': None, 'pool': None, 'share_type': None, - }) + }, + ) self.assertEqual(detail_columns, columns) self.assertEqual(list(detail_values), list(data)) diff --git a/manilaclient/tests/unit/osc/v2/test_share_replica_export_locations.py b/manilaclient/tests/unit/osc/v2/test_share_replica_export_locations.py index 956c751e..569286c2 100644 --- a/manilaclient/tests/unit/osc/v2/test_share_replica_export_locations.py +++ b/manilaclient/tests/unit/osc/v2/test_share_replica_export_locations.py @@ -13,100 +13,87 @@ from osc_lib import utils as oscutils from manilaclient.osc.v2 import ( - share_replica_export_locations as osc_replica_el + share_replica_export_locations as osc_replica_el, ) from manilaclient.tests.unit.osc.v2 import fakes as manila_fakes class TestShareReplica(manila_fakes.TestShare): - def setUp(self): - super(TestShareReplica, self).setUp() + super().setUp() self.replicas_mock = self.app.client_manager.share.share_replicas self.replicas_mock.reset_mock() self.export_locations_mock = ( - self.app.client_manager.share.share_replica_export_locations) + self.app.client_manager.share.share_replica_export_locations + ) self.export_locations_mock.reset_mock() class TestShareReplicaExportLocationList(TestShareReplica): - - columns = [ - 'ID', - 'Availability Zone', - 'Replica State', - 'Preferred', - 'Path' - ] + columns = ['ID', 'Availability Zone', 'Replica State', 'Preferred', 'Path'] def setUp(self): - super(TestShareReplicaExportLocationList, self).setUp() + super().setUp() - self.share_replica = ( - manila_fakes.FakeShareReplica.create_one_replica()) + self.share_replica = manila_fakes.FakeShareReplica.create_one_replica() self.replicas_mock.get.return_value = self.share_replica - self.export_locations = ([ + self.export_locations = [ manila_fakes.FakeShareExportLocation.create_one_export_location() - ]) + ] self.export_locations_mock.list.return_value = self.export_locations - self.values = (oscutils.get_dict_properties( - e._info, self.columns) for e in self.export_locations) + self.values = ( + oscutils.get_dict_properties(e._info, self.columns) + for e in self.export_locations + ) self.cmd = osc_replica_el.ShareReplicaListExportLocation( - self.app, None) + self.app, None + ) def test_replica_export_locations_list(self): - arglist = [ - self.share_replica.id - ] - verifylist = [ - ('replica', self.share_replica.id) - ] + arglist = [self.share_replica.id] + verifylist = [('replica', self.share_replica.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.replicas_mock.get.assert_called_with(self.share_replica.id) - self.export_locations_mock.list.assert_called_with( - self.share_replica) + self.export_locations_mock.list.assert_called_with(self.share_replica) self.assertEqual(self.columns, columns) self.assertCountEqual(self.values, data) class TestShareReplicaExportLocationShow(TestShareReplica): - def setUp(self): - super(TestShareReplicaExportLocationShow, self).setUp() + super().setUp() - self.share_replica = ( - manila_fakes.FakeShareReplica.create_one_replica()) + self.share_replica = manila_fakes.FakeShareReplica.create_one_replica() self.replicas_mock.get.return_value = self.share_replica self.export_location = ( - manila_fakes.FakeShareExportLocation.create_one_export_location()) + manila_fakes.FakeShareExportLocation.create_one_export_location() + ) self.export_locations_mock.get.return_value = self.export_location self.cmd = osc_replica_el.ShareReplicaShowExportLocation( - self.app, None) + self.app, None + ) def test_replica_export_locations_show(self): - arglist = [ - self.share_replica.id, - self.export_location.id - ] + arglist = [self.share_replica.id, self.export_location.id] verifylist = [ ('replica', self.share_replica.id), - ('export_location', self.export_location.id) + ('export_location', self.export_location.id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -115,10 +102,10 @@ def test_replica_export_locations_show(self): self.replicas_mock.get.assert_called_with(self.share_replica.id) self.export_locations_mock.get.assert_called_with( - self.share_replica, - self.export_location.id) + self.share_replica, self.export_location.id + ) self.assertCountEqual( - tuple(self.export_location._info.keys()), - columns) + tuple(self.export_location._info.keys()), columns + ) self.assertCountEqual(self.export_location._info.values(), data) diff --git a/manilaclient/tests/unit/osc/v2/test_share_replicas.py b/manilaclient/tests/unit/osc/v2/test_share_replicas.py index 7da4b2c4..d1592abd 100644 --- a/manilaclient/tests/unit/osc/v2/test_share_replicas.py +++ b/manilaclient/tests/unit/osc/v2/test_share_replicas.py @@ -26,9 +26,8 @@ class TestShareReplica(manila_fakes.TestShare): - def setUp(self): - super(TestShareReplica, self).setUp() + super().setUp() self.shares_mock = self.app.client_manager.share.shares self.shares_mock.reset_mock() @@ -36,28 +35,25 @@ def setUp(self): self.replicas_mock = self.app.client_manager.share.share_replicas self.replicas_mock.reset_mock() self.app.client_manager.share.api_version = api_versions.APIVersion( - api_versions.MAX_VERSION) + api_versions.MAX_VERSION + ) self.replica_el_mock = ( - self.app.client_manager - .share.share_replica_export_locations) + self.app.client_manager.share.share_replica_export_locations + ) self.replica_el_mock.reset_mock() class TestShareReplicaCreate(TestShareReplica): - def setUp(self): - super(TestShareReplicaCreate, self).setUp() + super().setUp() self.share = manila_fakes.FakeShare.create_one_share() self.shares_mock.get.return_value = self.share - self.share_replica = ( - manila_fakes.FakeShareReplica.create_one_replica( - attrs={ - 'availability_zone': 'manila-zone-1', - 'status': 'available'} - )) + self.share_replica = manila_fakes.FakeShareReplica.create_one_replica( + attrs={'availability_zone': 'manila-zone-1', 'status': 'available'} + ) self.replicas_mock.create.return_value = self.share_replica self.replicas_mock.get.return_value = self.share_replica @@ -72,23 +68,22 @@ def test_share_replica_create_missing_args(self): self.assertRaises( osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_replica_create(self): - arglist = [ - self.share.id - ] - verifylist = [ - ('share', self.share.id) - ] + arglist = [self.share.id] + verifylist = [('share', self.share.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.replicas_mock.create.assert_called_with( - share=self.share, - availability_zone=None + share=self.share, availability_zone=None ) self.assertCountEqual(self.columns, columns) @@ -97,11 +92,12 @@ def test_share_replica_create(self): def test_share_replica_create_az(self): arglist = [ self.share.id, - '--availability-zone', self.share.availability_zone + '--availability-zone', + self.share.availability_zone, ] verifylist = [ ('share', self.share.id), - ('availability_zone', self.share.availability_zone) + ('availability_zone', self.share.availability_zone), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -109,8 +105,7 @@ def test_share_replica_create_az(self): columns, data = self.cmd.take_action(parsed_args) self.replicas_mock.create.assert_called_with( - share=self.share, - availability_zone=self.share.availability_zone + share=self.share, availability_zone=self.share.availability_zone ) self.assertCountEqual(self.columns, columns) @@ -119,13 +114,15 @@ def test_share_replica_create_az(self): def test_share_replica_create_scheduler_hint_valid(self): arglist = [ self.share.id, - '--availability-zone', self.share.availability_zone, - '--scheduler-hint', ('only_host=host1@backend1#pool1'), + '--availability-zone', + self.share.availability_zone, + '--scheduler-hint', + ('only_host=host1@backend1#pool1'), ] verifylist = [ ('share', self.share.id), ('availability_zone', self.share.availability_zone), - ('scheduler_hint', {'only_host': 'host1@backend1#pool1'}) + ('scheduler_hint', {'only_host': 'host1@backend1#pool1'}), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -135,7 +132,7 @@ def test_share_replica_create_scheduler_hint_valid(self): self.replicas_mock.create.assert_called_with( share=self.share, availability_zone=self.share.availability_zone, - scheduler_hints={'only_host': 'host1@backend1#pool1'} + scheduler_hints={'only_host': 'host1@backend1#pool1'}, ) self.assertCountEqual(self.columns, columns) @@ -144,53 +141,61 @@ def test_share_replica_create_scheduler_hint_valid(self): def test_share_replica_create_scheduler_hint_invalid_hint(self): arglist = [ self.share.id, - '--availability-zone', self.share.availability_zone, - '--scheduler-hint', 'fake_hint=host1@backend1#pool1' + '--availability-zone', + self.share.availability_zone, + '--scheduler-hint', + 'fake_hint=host1@backend1#pool1', ] verifylist = [ ('share', self.share.id), ('availability_zone', self.share.availability_zone), - ('scheduler_hint', {'fake_hint': 'host1@backend1#pool1'}) + ('scheduler_hint', {'fake_hint': 'host1@backend1#pool1'}), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - self.assertRaises(exceptions.CommandError, - self.cmd.take_action, - parsed_args) + self.assertRaises( + exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_share_replica_create_scheduler_hint_invalid_version(self): self.app.client_manager.share.api_version = api_versions.APIVersion( - "2.66") + "2.66" + ) arglist = [ self.share.id, - '--availability-zone', self.share.availability_zone, - '--scheduler-hint', 'only_host=host1@backend1#pool1' + '--availability-zone', + self.share.availability_zone, + '--scheduler-hint', + 'only_host=host1@backend1#pool1', ] verifylist = [ ('share', self.share.id), ('availability_zone', self.share.availability_zone), - ('scheduler_hint', {'only_host': 'host1@backend1#pool1'}) + ('scheduler_hint', {'only_host': 'host1@backend1#pool1'}), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - self.assertRaises(exceptions.CommandError, - self.cmd.take_action, - parsed_args) + self.assertRaises( + exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_share_replica_create_share_network(self): self.app.client_manager.share.api_version = api_versions.APIVersion( - "2.72") + "2.72" + ) arglist = [ self.share.id, - '--availability-zone', self.share.availability_zone, - '--share-network', self.share.share_network_id + '--availability-zone', + self.share.availability_zone, + '--share-network', + self.share.share_network_id, ] verifylist = [ ('share', self.share.id), ('availability_zone', self.share.availability_zone), - ('share_network', self.share.share_network_id) + ('share_network', self.share.share_network_id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -200,7 +205,7 @@ def test_share_replica_create_share_network(self): self.replicas_mock.create.assert_called_with( share=self.share, availability_zone=self.share.availability_zone, - share_network=self.share.share_network_id + share_network=self.share.share_network_id, ) else: self.replicas_mock.create.assert_called_with( @@ -212,22 +217,15 @@ def test_share_replica_create_share_network(self): self.assertCountEqual(self.data, data) def test_share_replica_create_wait(self): - arglist = [ - self.share.id, - '--wait' - ] - verifylist = [ - ('share', self.share.id), - ('wait', True) - ] + arglist = [self.share.id, '--wait'] + verifylist = [('share', self.share.id), ('wait', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.replicas_mock.create.assert_called_with( - share=self.share, - availability_zone=None + share=self.share, availability_zone=None ) self.replicas_mock.get.assert_called_with(self.share_replica.id) @@ -236,14 +234,8 @@ def test_share_replica_create_wait(self): @mock.patch('manilaclient.osc.v2.share_replicas.LOG') def test_share_replica_create_wait_exception(self, mock_logger): - arglist = [ - self.share.id, - '--wait' - ] - verifylist = [ - ('share', self.share.id), - ('wait', True) - ] + arglist = [self.share.id, '--wait'] + verifylist = [('share', self.share.id), ('wait', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -251,12 +243,12 @@ def test_share_replica_create_wait_exception(self, mock_logger): columns, data = self.cmd.take_action(parsed_args) self.replicas_mock.create.assert_called_with( - share=self.share, - availability_zone=None + share=self.share, availability_zone=None ) mock_logger.error.assert_called_with( - "ERROR: Share replica is in error state.") + "ERROR: Share replica is in error state." + ) self.replicas_mock.get.assert_called_with(self.share_replica.id) self.assertCountEqual(self.columns, columns) @@ -264,12 +256,10 @@ def test_share_replica_create_wait_exception(self, mock_logger): class TestShareReplicaDelete(TestShareReplica): - def setUp(self): - super(TestShareReplicaDelete, self).setUp() + super().setUp() - self.share_replica = ( - manila_fakes.FakeShareReplica.create_one_replica()) + self.share_replica = manila_fakes.FakeShareReplica.create_one_replica() self.replicas_mock.get.return_value = self.share_replica self.cmd = osc_share_replicas.DeleteShareReplica(self.app, None) @@ -278,53 +268,45 @@ def test_share_replica_delete_missing_args(self): arglist = [] verifylist = [] - self.assertRaises(osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_replica_delete(self): - arglist = [ - self.share_replica.id - ] - verifylist = [ - ('replica', [self.share_replica.id]) - ] + arglist = [self.share_replica.id] + verifylist = [('replica', [self.share_replica.id])] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.replicas_mock.delete.assert_called_with( - self.share_replica, - force=False) + self.share_replica, force=False + ) self.assertIsNone(result) def test_share_replica_delete_force(self): - arglist = [ - self.share_replica.id, - '--force' - ] - verifylist = [ - ('replica', [self.share_replica.id]), - ('force', True) - ] + arglist = [self.share_replica.id, '--force'] + verifylist = [('replica', [self.share_replica.id]), ('force', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.replicas_mock.delete.assert_called_with( - self.share_replica, - force=True) + self.share_replica, force=True + ) self.assertIsNone(result) def test_share_replica_delete_multiple(self): - share_replicas = ( - manila_fakes.FakeShareReplica.create_share_replicas( - count=2)) - arglist = [ - share_replicas[0].id, - share_replicas[1].id - ] + share_replicas = manila_fakes.FakeShareReplica.create_share_replicas( + count=2 + ) + arglist = [share_replicas[0].id, share_replicas[1].id] verifylist = [ ('replica', [share_replicas[0].id, share_replicas[1].id]) ] @@ -332,34 +314,25 @@ def test_share_replica_delete_multiple(self): result = self.cmd.take_action(parsed_args) - self.assertEqual(self.replicas_mock.delete.call_count, - len(share_replicas)) + self.assertEqual( + self.replicas_mock.delete.call_count, len(share_replicas) + ) self.assertIsNone(result) def test_share_snapshot_delete_exception(self): - arglist = [ - self.share_replica.id - ] - verifylist = [ - ('replica', [self.share_replica.id]) - ] + arglist = [self.share_replica.id] + verifylist = [('replica', [self.share_replica.id])] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.replicas_mock.delete.side_effect = exceptions.CommandError() - self.assertRaises(exceptions.CommandError, - self.cmd.take_action, - parsed_args) + self.assertRaises( + exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_share_replica_delete_wait(self): - arglist = [ - self.share_replica.id, - '--wait' - ] - verifylist = [ - ('replica', [self.share_replica.id]), - ('wait', True) - ] + arglist = [self.share_replica.id, '--wait'] + verifylist = [('replica', [self.share_replica.id]), ('wait', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -367,33 +340,24 @@ def test_share_replica_delete_wait(self): result = self.cmd.take_action(parsed_args) self.replicas_mock.delete.assert_called_with( - self.share_replica, - force=False) + self.share_replica, force=False + ) self.replicas_mock.get.assert_called_with(self.share_replica.id) self.assertIsNone(result) def test_share_replica_delete_wait_exception(self): - arglist = [ - self.share_replica.id, - '--wait' - ] - verifylist = [ - ('replica', [self.share_replica.id]), - ('wait', True) - ] + arglist = [self.share_replica.id, '--wait'] + verifylist = [('replica', [self.share_replica.id]), ('wait', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) with mock.patch('osc_lib.utils.wait_for_delete', return_value=False): self.assertRaises( - exceptions.CommandError, - self.cmd.take_action, - parsed_args + exceptions.CommandError, self.cmd.take_action, parsed_args ) class TestShareReplicaList(TestShareReplica): - columns = [ 'id', 'status', @@ -407,18 +371,20 @@ class TestShareReplicaList(TestShareReplica): column_headers = utils.format_column_headers(columns) def setUp(self): - super(TestShareReplicaList, self).setUp() + super().setUp() self.share = manila_fakes.FakeShare.create_one_share() self.shares_mock.get.return_value = self.share self.replicas_list = ( - manila_fakes.FakeShareReplica.create_share_replicas( - count=2)) + manila_fakes.FakeShareReplica.create_share_replicas(count=2) + ) self.replicas_mock.list.return_value = self.replicas_list - self.values = (oscutils.get_dict_properties( - i._info, self.columns) for i in self.replicas_list) + self.values = ( + oscutils.get_dict_properties(i._info, self.columns) + for i in self.replicas_list + ) self.cmd = osc_share_replicas.ListShareReplica(self.app, None) @@ -436,12 +402,8 @@ def test_share_replica_list(self): self.assertEqual(list(self.values), list(data)) def test_share_replica_list_for_share(self): - arglist = [ - '--share', self.share.id - ] - verifylist = [ - ('share', self.share.id) - ] + arglist = ['--share', self.share.id] + verifylist = [('share', self.share.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -454,28 +416,25 @@ def test_share_replica_list_for_share(self): class TestShareReplicaShow(TestShareReplica): - def setUp(self): - super(TestShareReplicaShow, self).setUp() + super().setUp() - self.share_replica = ( - manila_fakes.FakeShareReplica.create_one_replica() - ) + self.share_replica = manila_fakes.FakeShareReplica.create_one_replica() self.replicas_mock.get.return_value = self.share_replica self.replica_el_list = ( - manila_fakes.FakeShareExportLocation. - create_share_export_locations(count=2) + manila_fakes.FakeShareExportLocation.create_share_export_locations( + count=2 + ) ) - self.replica_el_mock.list.return_value = ( - self.replica_el_list) + self.replica_el_mock.list.return_value = self.replica_el_list self.cmd = osc_share_replicas.ShowShareReplica(self.app, None) self.share_replica._info['export_locations'] = ( - cliutils.convert_dict_list_to_string( - self.replica_el_list)) + cliutils.convert_dict_list_to_string(self.replica_el_list) + ) self.data = tuple(self.share_replica._info.values()) self.columns = tuple(self.share_replica._info.keys()) @@ -486,115 +445,96 @@ def test_share_replica_show_missing_args(self): self.assertRaises( osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_replica_show(self): - arglist = [ - self.share_replica.id - ] - verifylist = [ - ('replica', self.share_replica.id) - ] + arglist = [self.share_replica.id] + verifylist = [('replica', self.share_replica.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) - self.replicas_mock.get.assert_called_with( - self.share_replica.id - ) + self.replicas_mock.get.assert_called_with(self.share_replica.id) self.assertCountEqual(self.columns, columns) self.assertCountEqual(self.data, data) class TestShareReplicaSet(TestShareReplica): - def setUp(self): - super(TestShareReplicaSet, self).setUp() + super().setUp() - self.share_replica = ( - manila_fakes.FakeShareReplica.create_one_replica() - ) + self.share_replica = manila_fakes.FakeShareReplica.create_one_replica() self.replicas_mock.get.return_value = self.share_replica self.cmd = osc_share_replicas.SetShareReplica(self.app, None) def test_share_replica_set_replica_state(self): new_replica_state = 'in_sync' - arglist = [ - self.share_replica.id, - '--replica-state', new_replica_state - ] + arglist = [self.share_replica.id, '--replica-state', new_replica_state] verifylist = [ ('replica', self.share_replica.id), - ('replica_state', new_replica_state) + ('replica_state', new_replica_state), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.replicas_mock.reset_replica_state.assert_called_with( - self.share_replica, - new_replica_state) + self.share_replica, new_replica_state + ) self.assertIsNone(result) def test_share_replica_set_replica_state_exception(self): new_replica_state = 'in_sync' - arglist = [ - self.share_replica.id, - '--replica-state', new_replica_state - ] + arglist = [self.share_replica.id, '--replica-state', new_replica_state] verifylist = [ ('replica', self.share_replica.id), - ('replica_state', new_replica_state) + ('replica_state', new_replica_state), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.replicas_mock.reset_replica_state.side_effect = Exception() self.assertRaises( - exceptions.CommandError, - self.cmd.take_action, - parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_share_replica_set_status(self): new_status = 'available' - arglist = [ - self.share_replica.id, - '--status', new_status - ] + arglist = [self.share_replica.id, '--status', new_status] verifylist = [ ('replica', self.share_replica.id), - ('status', new_status) + ('status', new_status), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.replicas_mock.reset_state.assert_called_with( - self.share_replica, - new_status) + self.share_replica, new_status + ) self.assertIsNone(result) def test_share_replica_set_status_exception(self): new_status = 'available' - arglist = [ - self.share_replica.id, - '--status', new_status - ] + arglist = [self.share_replica.id, '--status', new_status] verifylist = [ ('replica', self.share_replica.id), - ('status', new_status) + ('status', new_status), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.replicas_mock.reset_state.side_effect = Exception() self.assertRaises( - exceptions.CommandError, - self.cmd.take_action, - parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_share_replica_set_nothing_defined(self): arglist = [ @@ -606,83 +546,67 @@ def test_share_replica_set_nothing_defined(self): parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( - exceptions.CommandError, - self.cmd.take_action, - parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) class TestShareReplicaPromote(TestShareReplica): - def setUp(self): - super(TestShareReplicaPromote, self).setUp() + super().setUp() - self.share_replica = ( - manila_fakes.FakeShareReplica.create_one_replica( - attrs={ - 'status': 'available'} - ) + self.share_replica = manila_fakes.FakeShareReplica.create_one_replica( + attrs={'status': 'available'} ) self.replicas_mock.get.return_value = self.share_replica - self.cmd = osc_share_replicas.PromoteShareReplica( - self.app, None) + self.cmd = osc_share_replicas.PromoteShareReplica(self.app, None) def test_share_replica_promote(self): arglist = [ self.share_replica.id, ] - verifylist = [ - ('replica', self.share_replica.id), - ('wait', False) - ] + verifylist = [('replica', self.share_replica.id), ('wait', False)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - self.replicas_mock.promote.assert_called_with( - self.share_replica) + self.replicas_mock.promote.assert_called_with(self.share_replica) self.assertIsNone(result) def test_share_replica_promote_quiesce_wait_time(self): wait_time = '5' - arglist = [ - self.share_replica.id, - '--quiesce-wait-time', wait_time - ] + arglist = [self.share_replica.id, '--quiesce-wait-time', wait_time] verifylist = [ ('replica', self.share_replica.id), - ('quiesce_wait_time', wait_time) + ('quiesce_wait_time', wait_time), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.replicas_mock.promote.assert_called_with( - self.share_replica, - wait_time) + self.share_replica, wait_time + ) self.assertIsNone(result) - @mock.patch.object(osc_share_replicas.osc_utils, 'wait_for_status', - mock.Mock()) + @mock.patch.object( + osc_share_replicas.osc_utils, 'wait_for_status', mock.Mock() + ) def test_share_replica_promote_wait(self): - arglist = [ - self.share_replica.id, - '--wait' - ] - verifylist = [ - ('replica', self.share_replica.id), - ('wait', True) - ] + arglist = [self.share_replica.id, '--wait'] + verifylist = [('replica', self.share_replica.id), ('wait', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - self.replicas_mock.promote.assert_called_with( - self.share_replica) + self.replicas_mock.promote.assert_called_with(self.share_replica) self.assertIsNone(result) osc_share_replicas.osc_utils.wait_for_status.assert_called_once_with( - status_f=self.replicas_mock.get, res_id=self.share_replica.id, - success_status=['active'], status_field='replica_state') + status_f=self.replicas_mock.get, + res_id=self.share_replica.id, + success_status=['active'], + status_field='replica_state', + ) def test_share_replica_promote_exception(self): arglist = [ @@ -696,23 +620,18 @@ def test_share_replica_promote_exception(self): self.replicas_mock.promote.side_effect = Exception() self.assertRaises( - exceptions.CommandError, - self.cmd.take_action, - parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) class TestShareReplicaResync(TestShareReplica): - def setUp(self): - super(TestShareReplicaResync, self).setUp() + super().setUp() - self.share_replica = ( - manila_fakes.FakeShareReplica.create_one_replica() - ) + self.share_replica = manila_fakes.FakeShareReplica.create_one_replica() self.replicas_mock.get.return_value = self.share_replica - self.cmd = osc_share_replicas.ResyncShareReplica( - self.app, None) + self.cmd = osc_share_replicas.ResyncShareReplica(self.app, None) def test_share_replica_resync(self): arglist = [ @@ -725,8 +644,7 @@ def test_share_replica_resync(self): result = self.cmd.take_action(parsed_args) - self.replicas_mock.resync.assert_called_with( - self.share_replica) + self.replicas_mock.resync.assert_called_with(self.share_replica) self.assertIsNone(result) def test_share_replica_resync_exception(self): @@ -741,6 +659,5 @@ def test_share_replica_resync_exception(self): self.replicas_mock.resync.side_effect = Exception() self.assertRaises( - exceptions.CommandError, - self.cmd.take_action, - parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) diff --git a/manilaclient/tests/unit/osc/v2/test_share_servers.py b/manilaclient/tests/unit/osc/v2/test_share_servers.py index f029cce2..77409107 100644 --- a/manilaclient/tests/unit/osc/v2/test_share_servers.py +++ b/manilaclient/tests/unit/osc/v2/test_share_servers.py @@ -26,9 +26,8 @@ class TestShareServer(manila_fakes.TestShare): - def setUp(self): - super(TestShareServer, self).setUp() + super().setUp() self.servers_mock = self.app.client_manager.share.share_servers self.servers_mock.reset_mock() @@ -37,16 +36,15 @@ def setUp(self): self.share_networks_mock.reset_mock() self.app.client_manager.share.api_version = api_versions.APIVersion( - api_versions.MAX_VERSION) + api_versions.MAX_VERSION + ) class TestDeleteShareServer(TestShareServer): - def setUp(self): - super(TestDeleteShareServer, self).setUp() + super().setUp() - self.share_server = ( - manila_fakes.FakeShareServer.create_one_server()) + self.share_server = manila_fakes.FakeShareServer.create_one_server() self.servers_mock.get.return_value = self.share_server self.cmd = osc_share_servers.DeleteShareServer(self.app, None) @@ -55,33 +53,30 @@ def test_share_server_delete_missing_args(self): arglist = [] verifylist = [] - self.assertRaises(osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_server_delete(self): - arglist = [ - self.share_server.id - ] - verifylist = [ - ('share_servers', [self.share_server.id]) - ] + arglist = [self.share_server.id] + verifylist = [('share_servers', [self.share_server.id])] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - self.servers_mock.delete.assert_called_once_with( - self.share_server) + self.servers_mock.delete.assert_called_once_with(self.share_server) self.assertIsNone(result) def test_share_server_delete_wait(self): - arglist = [ - self.share_server.id, - '--wait' - ] + arglist = [self.share_server.id, '--wait'] verifylist = [ ('share_servers', [self.share_server.id]), - ('wait', True) + ('wait', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -89,37 +84,29 @@ def test_share_server_delete_wait(self): with mock.patch('osc_lib.utils.wait_for_delete', return_value=True): result = self.cmd.take_action(parsed_args) - self.servers_mock.delete.assert_called_once_with( - self.share_server) + self.servers_mock.delete.assert_called_once_with(self.share_server) self.assertIsNone(result) def test_share_server_delete_wait_exception(self): - arglist = [ - self.share_server.id, - '--wait' - ] + arglist = [self.share_server.id, '--wait'] verifylist = [ ('share_servers', [self.share_server.id]), - ('wait', True) + ('wait', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) with mock.patch('osc_lib.utils.wait_for_delete', return_value=False): self.assertRaises( - exceptions.CommandError, - self.cmd.take_action, - parsed_args + exceptions.CommandError, self.cmd.take_action, parsed_args ) class TestShowShareServer(TestShareServer): - def setUp(self): - super(TestShowShareServer, self).setUp() + super().setUp() - self.share_server = ( - manila_fakes.FakeShareServer.create_one_server()) + self.share_server = manila_fakes.FakeShareServer.create_one_server() self.servers_mock.get.return_value = self.share_server self.cmd = osc_share_servers.ShowShareServer(self.app, None) @@ -133,30 +120,27 @@ def test_share_server_show_missing_args(self): self.assertRaises( osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_server_show(self): - arglist = [ - self.share_server.id - ] - verifylist = [ - ('share_server', self.share_server.id) - ] + arglist = [self.share_server.id] + verifylist = [('share_server', self.share_server.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) - self.servers_mock.get.assert_called_with( - self.share_server.id - ) + self.servers_mock.get.assert_called_with(self.share_server.id) self.assertCountEqual(self.columns, columns) self.assertCountEqual(self.data, data) class TestListShareServer(TestShareServer): - columns = [ 'ID', 'Host', @@ -166,15 +150,17 @@ class TestListShareServer(TestShareServer): ] def setUp(self): - super(TestListShareServer, self).setUp() + super().setUp() - self.servers_list = ( - manila_fakes.FakeShareServer.create_share_servers( - count=2)) + self.servers_list = manila_fakes.FakeShareServer.create_share_servers( + count=2 + ) self.servers_mock.list.return_value = self.servers_list - self.values = (oscutils.get_dict_properties( - i._info, self.columns) for i in self.servers_list) + self.values = ( + oscutils.get_dict_properties(i._info, self.columns) + for i in self.servers_list + ) self.cmd = osc_share_servers.ListShareServer(self.app, None) @@ -186,18 +172,21 @@ def test_list_share_server(self): columns, data = self.cmd.take_action(parsed_args) - self.servers_mock.list.assert_called_with(search_opts={ - 'status': None, - 'host': None, - 'project_id': None, - }) + self.servers_mock.list.assert_called_with( + search_opts={ + 'status': None, + 'host': None, + 'project_id': None, + } + ) self.assertEqual(self.columns, columns) self.assertEqual(list(self.values), list(data)) def test_share_server_list_by_status(self): arglist = [ - '--status', self.servers_list[0].status, + '--status', + self.servers_list[0].status, ] verifylist = [ ('status', self.servers_list[0].status), @@ -220,11 +209,12 @@ def test_share_server_list_by_status(self): self.assertEqual(list(self.values), list(data)) def test_share_server_list_by_source_share_server(self): - expected_source_share_server_id = ( - self.servers_list[0].source_share_server_id - ) + expected_source_share_server_id = self.servers_list[ + 0 + ].source_share_server_id arglist = [ - '--source-share-server-id', expected_source_share_server_id, + '--source-share-server-id', + expected_source_share_server_id, ] verifylist = [ ('source_share_server_id', expected_source_share_server_id), @@ -249,8 +239,13 @@ def test_share_server_list_by_source_share_server(self): def test_share_server_list_by_identifier(self): expected_identifier = self.servers_list[0].identifier - arglist = ['--identifier', expected_identifier,] - verifylist = [('identifier', expected_identifier),] + arglist = [ + '--identifier', + expected_identifier, + ] + verifylist = [ + ('identifier', expected_identifier), + ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) @@ -271,29 +266,31 @@ def test_share_server_list_by_identifier(self): class TestAdoptShareServer(TestShareServer): - def setUp(self): - super(TestAdoptShareServer, self).setUp() + super().setUp() - self.share_server = ( - manila_fakes.FakeShareServer.create_one_server( - attrs={'status': 'available'} - )) + self.share_server = manila_fakes.FakeShareServer.create_one_server( + attrs={'status': 'available'} + ) self.servers_mock.get.return_value = self.share_server self.servers_mock.manage.return_value = self.share_server self.share_network_subnets_mock = ( - self.app.client_manager.share.share_network_subnets) + self.app.client_manager.share.share_network_subnets + ) self.share_network = ( manila_fakes.FakeShareNetwork.create_one_share_network( attrs={'status': 'available'} - )) + ) + ) self.share_network_subnet = ( - manila_fakes.FakeShareNetworkSubnet.create_one_share_subnet()) + manila_fakes.FakeShareNetworkSubnet.create_one_share_subnet() + ) self.share_networks_mock.get.return_value = self.share_network self.share_network_subnets_mock.get.return_value = ( - self.share_network_subnet) + self.share_network_subnet + ) self.cmd = osc_share_servers.AdoptShareServer(self.app, None) @@ -304,15 +301,21 @@ def test_share_server_adopt_missing_args(self): arglist = [] verifylist = [] - self.assertRaises(osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_server_adopt(self): arglist = [ 'somehost@backend', self.share_network['id'], 'share_server_identifier', - '--share-network-subnet', self.share_network_subnet['id'], + '--share-network-subnet', + self.share_network_subnet['id'], ] verifylist = [ ('host', 'somehost@backend'), @@ -338,15 +341,16 @@ def test_share_server_adopt_wait(self): 'somehost@backend', self.share_network['id'], 'share_server_identifier', - '--share-network-subnet', self.share_network_subnet['id'], - '--wait' + '--share-network-subnet', + self.share_network_subnet['id'], + '--wait', ] verifylist = [ ('host', 'somehost@backend'), ('share_network', self.share_network['id']), ('identifier', 'share_server_identifier'), ('share_network_subnet', self.share_network_subnet['id']), - ('wait', True) + ('wait', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -358,7 +362,7 @@ def test_share_server_adopt_wait(self): share_network_id=self.share_network['id'], identifier='share_server_identifier', driver_options={}, - share_network_subnet_id=self.share_network_subnet['id'] + share_network_subnet_id=self.share_network_subnet['id'], ) def test_share_server_adopt_subnet_not_supported(self): @@ -366,33 +370,33 @@ def test_share_server_adopt_subnet_not_supported(self): 'somehost@backend', self.share_network['id'], 'share_server_identifier', - '--share-network-subnet', self.share_network_subnet['id'], - '--wait' + '--share-network-subnet', + self.share_network_subnet['id'], + '--wait', ] verifylist = [ ('host', 'somehost@backend'), ('share_network', self.share_network['id']), ('identifier', 'share_server_identifier'), ('share_network_subnet', self.share_network_subnet['id']), - ('wait', True) + ('wait', True), ] self.app.client_manager.share.api_version = api_versions.APIVersion( - "2.50") + "2.50" + ) parsed_args = self.check_parser(self.cmd, arglist, verifylist) - self.assertRaises(exceptions.CommandError, - self.cmd.take_action, - parsed_args) + self.assertRaises( + exceptions.CommandError, self.cmd.take_action, parsed_args + ) class TestAbandonShareServer(TestShareServer): - def setUp(self): - super(TestAbandonShareServer, self).setUp() + super().setUp() - self.share_server = ( - manila_fakes.FakeShareServer.create_one_server()) + self.share_server = manila_fakes.FakeShareServer.create_one_server() self.servers_mock.get.return_value = self.share_server self.cmd = osc_share_servers.AbandonShareServer(self.app, None) @@ -404,33 +408,30 @@ def test_share_server_abandon_missing_args(self): arglist = [] verifylist = [] - self.assertRaises(osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_server_abandon(self): - arglist = [ - self.share_server.id - ] - verifylist = [ - ('share_server', [self.share_server.id]) - ] + arglist = [self.share_server.id] + verifylist = [('share_server', [self.share_server.id])] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - self.servers_mock.unmanage.assert_called_with( - self.share_server) + self.servers_mock.unmanage.assert_called_with(self.share_server) self.assertIsNone(result) def test_share_server_abandon_multiple(self): - share_servers = ( - manila_fakes.FakeShareServer.create_share_servers( - count=2)) - arglist = [ - share_servers[0].id, - share_servers[1].id - ] + share_servers = manila_fakes.FakeShareServer.create_share_servers( + count=2 + ) + arglist = [share_servers[0].id, share_servers[1].id] verifylist = [ ('share_server', [share_servers[0].id, share_servers[1].id]) ] @@ -438,18 +439,16 @@ def test_share_server_abandon_multiple(self): result = self.cmd.take_action(parsed_args) - self.assertEqual(self.servers_mock.unmanage.call_count, - len(share_servers)) + self.assertEqual( + self.servers_mock.unmanage.call_count, len(share_servers) + ) self.assertIsNone(result) def test_share_server_abandon_force(self): - arglist = [ - self.share_server.id, - '--force' - ] + arglist = [self.share_server.id, '--force'] verifylist = [ ('share_server', [self.share_server.id]), - ('force', True) + ('force', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -457,8 +456,8 @@ def test_share_server_abandon_force(self): result = self.cmd.take_action(parsed_args) self.servers_mock.unmanage.assert_called_with( - self.share_server, - force=True) + self.share_server, force=True + ) self.assertIsNone(result) def test_share_server_abandon_force_exception(self): @@ -472,87 +471,68 @@ def test_share_server_abandon_force_exception(self): parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.servers_mock.unmanage.side_effect = exceptions.CommandError() - self.assertRaises(exceptions.CommandError, - self.cmd.take_action, - parsed_args) + self.assertRaises( + exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_share_server_abandon_wait(self): - arglist = [ - self.share_server.id, - '--wait' - ] - verifylist = [ - ('share_server', [self.share_server.id]), - ('wait', True) - ] + arglist = [self.share_server.id, '--wait'] + verifylist = [('share_server', [self.share_server.id]), ('wait', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) with mock.patch('osc_lib.utils.wait_for_delete', return_value=True): result = self.cmd.take_action(parsed_args) - self.servers_mock.unmanage.assert_called_with( - self.share_server) + self.servers_mock.unmanage.assert_called_with(self.share_server) self.assertIsNone(result) def test_share_server_abandon_wait_error(self): - arglist = [ - self.share_server.id, - '--wait' - ] - verifylist = [ - ('share_server', [self.share_server.id]), - ('wait', True) - ] + arglist = [self.share_server.id, '--wait'] + verifylist = [('share_server', [self.share_server.id]), ('wait', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) with mock.patch('osc_lib.utils.wait_for_delete', return_value=False): self.assertRaises( - exceptions.CommandError, - self.cmd.take_action, - parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) class TestSetShareServer(TestShareServer): - def setUp(self): - super(TestSetShareServer, self).setUp() + super().setUp() - self.share_server = ( - manila_fakes.FakeShareServer.create_one_server( - methods={'reset_task_state': None} - ) + self.share_server = manila_fakes.FakeShareServer.create_one_server( + methods={'reset_task_state': None} ) self.servers_mock.get.return_value = self.share_server self.cmd = osc_share_servers.SetShareServer(self.app, None) def test_share_server_set_status(self): - arglist = [ - self.share_server.id, - '--status', 'active' - ] + arglist = [self.share_server.id, '--status', 'active'] verifylist = [ ('share_server', self.share_server.id), - ('status', 'active') + ('status', 'active'), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.servers_mock.reset_state.assert_called_with( - self.share_server, - parsed_args.status) + self.share_server, parsed_args.status + ) self.assertIsNone(result) def test_share_server_set_task_state(self): arglist = [ self.share_server.id, - '--task-state', 'migration_in_progress' + '--task-state', + 'migration_in_progress', ] verifylist = [ ('share_server', self.share_server.id), - ('task_state', 'migration_in_progress') + ('task_state', 'migration_in_progress'), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -560,8 +540,8 @@ def test_share_server_set_task_state(self): result = self.cmd.take_action(parsed_args) self.servers_mock.reset_task_state.assert_called_with( - self.share_server, - parsed_args.task_state) + self.share_server, parsed_args.task_state + ) self.assertIsNone(result) def test_share_server_set_task_state_none(self): @@ -571,7 +551,7 @@ def test_share_server_set_task_state_none(self): ] verifylist = [ ('share_server', self.share_server.id), - ('task_state', None) + ('task_state', None), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -579,18 +559,15 @@ def test_share_server_set_task_state_none(self): result = self.cmd.take_action(parsed_args) self.servers_mock.reset_task_state.assert_called_with( - self.share_server, - None) + self.share_server, None + ) self.assertIsNone(result) def test_share_server_set_task_state_string_none(self): - arglist = [ - self.share_server.id, - '--task-state', 'None' - ] + arglist = [self.share_server.id, '--task-state', 'None'] verifylist = [ ('share_server', self.share_server.id), - ('task_state', 'None') + ('task_state', 'None'), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -598,41 +575,34 @@ def test_share_server_set_task_state_string_none(self): result = self.cmd.take_action(parsed_args) self.servers_mock.reset_task_state.assert_called_with( - self.share_server, - None) + self.share_server, None + ) self.assertIsNone(result) def test_share_server_set_status_exception(self): - arglist = [ - self.share_server.id, - '--status', 'active' - ] + arglist = [self.share_server.id, '--status', 'active'] verifylist = [ ('share_server', self.share_server.id), - ('status', 'active') + ('status', 'active'), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.servers_mock.reset_state.side_effect = Exception() self.assertRaises( - exceptions.CommandError, - self.cmd.take_action, - parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) class TestShareServerMigrationCancel(TestShareServer): - def setUp(self): - super(TestShareServerMigrationCancel, self).setUp() - - self.share_server = ( - manila_fakes.FakeShareServer.create_one_server( - attrs={ - 'status': 'migrating', - }, - methods={'migration_cancel': None} - ) + super().setUp() + + self.share_server = manila_fakes.FakeShareServer.create_one_server( + attrs={ + 'status': 'migrating', + }, + methods={'migration_cancel': None}, ) self.servers_mock.get.return_value = self.share_server @@ -640,65 +610,53 @@ def setUp(self): self.cmd = osc_share_servers.ShareServerMigrationCancel(self.app, None) def test_share_server_migration_cancel(self): - arglist = [ - self.share_server.id - ] - verifylist = [ - ('share_server', self.share_server.id) - ] + arglist = [self.share_server.id] + verifylist = [('share_server', self.share_server.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) self.share_server.migration_cancel.assert_called class TestShareServerMigrationComplete(TestShareServer): - def setUp(self): - super(TestShareServerMigrationComplete, self).setUp() - - self.share_server = ( - manila_fakes.FakeShareServer.create_one_server( - attrs={ - 'status': 'migrating', - }, - methods={'migration_complete': None} - ) + super().setUp() + + self.share_server = manila_fakes.FakeShareServer.create_one_server( + attrs={ + 'status': 'migrating', + }, + methods={'migration_complete': None}, ) self.servers_mock.get.return_value = self.share_server # Get the command objects to test self.cmd = osc_share_servers.ShareServerMigrationComplete( - self.app, None) + self.app, None + ) def test_share_server_migration_complete(self): - arglist = [ - self.share_server.id - ] - verifylist = [ - ('share_server', self.share_server.id) - ] + arglist = [self.share_server.id] + verifylist = [('share_server', self.share_server.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) self.share_server.migration_complete.assert_called class TestShareServerMigrationShow(TestShareServer): - def setUp(self): - super(TestShareServerMigrationShow, self).setUp() + super().setUp() - self.new_share_network = manila_fakes.FakeShareNetwork \ - .create_one_share_network() + self.new_share_network = ( + manila_fakes.FakeShareNetwork.create_one_share_network() + ) self.share_networks_mock.get.return_value = self.new_share_network - self.share_server = ( - manila_fakes.FakeShareServer.create_one_server( - attrs={ - 'status': 'migrating', - 'task_state': 'migration_in_progress' - }, - methods={'migration_get_progress': None} - ) + self.share_server = manila_fakes.FakeShareServer.create_one_server( + attrs={ + 'status': 'migrating', + 'task_state': 'migration_in_progress', + }, + methods={'migration_get_progress': None}, ) self.servers_mock.get.return_value = self.share_server @@ -706,12 +664,8 @@ def setUp(self): self.cmd = osc_share_servers.ShareServerMigrationShow(self.app, None) def test_share_server_migration_show(self): - arglist = [ - self.share_server.id - ] - verifylist = [ - ('share_server', self.share_server.id) - ] + arglist = [self.share_server.id] + verifylist = [('share_server', self.share_server.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) self.share_server.migration_get_progress.assert_called @@ -719,19 +673,19 @@ def test_share_server_migration_show(self): class TestShareServerMigrationStart(TestShareServer): def setUp(self): - super(TestShareServerMigrationStart, self).setUp() + super().setUp() - self.new_share_network = manila_fakes.FakeShareNetwork \ - .create_one_share_network() + self.new_share_network = ( + manila_fakes.FakeShareNetwork.create_one_share_network() + ) self.share_networks_mock.get.return_value = self.new_share_network - self.share_server = ( - manila_fakes.FakeShareServer.create_one_server( - attrs={ - 'check_only': 'False', - }, - methods={'migration_start': None, 'migration_check': None} - )) + self.share_server = manila_fakes.FakeShareServer.create_one_server( + attrs={ + 'check_only': 'False', + }, + methods={'migration_start': None, 'migration_check': None}, + ) self.servers_mock.get.return_value = self.share_server # Get the command objects to test @@ -743,10 +697,14 @@ def test_share_server_migration_start_with_new_share_network(self): arglist = [ '1234', 'host@backend', - '--preserve-snapshots', 'False', - '--writable', 'False', - '--nondisruptive', 'False', - '--new-share-network', self.new_share_network.id + '--preserve-snapshots', + 'False', + '--writable', + 'False', + '--nondisruptive', + 'False', + '--new-share-network', + self.new_share_network.id, ] verifylist = [ @@ -755,11 +713,12 @@ def test_share_server_migration_start_with_new_share_network(self): ('preserve_snapshots', 'False'), ('writable', 'False'), ('nondisruptive', 'False'), - ('new_share_network', self.new_share_network.id) + ('new_share_network', self.new_share_network.id), ] self.app.client_manager.share.api_version = api_versions.APIVersion( - "2.57") + "2.57" + ) parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) @@ -768,7 +727,7 @@ def test_share_server_migration_start_with_new_share_network(self): 'False', 'False', 'False', - self.new_share_network.id + self.new_share_network.id, ) self.assertEqual(result, ({}, {})) @@ -778,10 +737,14 @@ def test_share_server_migration_start_with_check_only(self): arglist = [ '1234', 'host@backend', - '--preserve-snapshots', 'True', - '--writable', 'True', - '--nondisruptive', 'False', - '--new-share-network', self.new_share_network.id, + '--preserve-snapshots', + 'True', + '--writable', + 'True', + '--nondisruptive', + 'False', + '--new-share-network', + self.new_share_network.id, '--check-only', ] @@ -792,7 +755,7 @@ def test_share_server_migration_start_with_check_only(self): ('writable', 'True'), ('nondisruptive', 'False'), ('new_share_network', self.new_share_network.id), - ('check_only', True) + ('check_only', True), ] expected_result = { @@ -802,7 +765,7 @@ def test_share_server_migration_start_with_check_only(self): 'nondisruptive': 'False', 'preserve_snapshots': 'True', 'share_network_id': None, - 'host': 'host@backend' + 'host': 'host@backend', }, 'supported_capabilities': { 'writable': True, @@ -810,14 +773,15 @@ def test_share_server_migration_start_with_check_only(self): 'preserve_snapshots': True, 'share_network_id': self.new_share_network.id, 'migration_cancel': True, - 'migration_get_progress': True - } + 'migration_get_progress': True, + }, } self.share_server.migration_check.return_value = expected_result self.app.client_manager.share.api_version = api_versions.APIVersion( - "2.57") + "2.57" + ) parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) @@ -827,7 +791,6 @@ def test_share_server_migration_start_with_check_only(self): 'False', 'True', self.new_share_network.id, - ) result_dict = {} for count, column in enumerate(columns): @@ -838,14 +801,19 @@ def test_share_server_migration_start_with_api_version_exception(self): """Test share server migration start with API microversion exception""" self.app.client_manager.share.api_version = api_versions.APIVersion( - "2.50") + "2.50" + ) arglist = [ '1234', 'host@backend', - '--preserve-snapshots', 'False', - '--writable', 'False', - '--nondisruptive', 'False', - '--new-share-network', self.new_share_network.id + '--preserve-snapshots', + 'False', + '--writable', + 'False', + '--nondisruptive', + 'False', + '--new-share-network', + self.new_share_network.id, ] verifylist = [ @@ -854,12 +822,11 @@ def test_share_server_migration_start_with_api_version_exception(self): ('preserve_snapshots', 'False'), ('writable', 'False'), ('nondisruptive', 'False'), - ('new_share_network', self.new_share_network.id) + ('new_share_network', self.new_share_network.id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( - exceptions.CommandError, - self.cmd.take_action, - parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) diff --git a/manilaclient/tests/unit/osc/v2/test_share_snapshot_instance_export_locations.py b/manilaclient/tests/unit/osc/v2/test_share_snapshot_instance_export_locations.py index a368ad19..af93f970 100644 --- a/manilaclient/tests/unit/osc/v2/test_share_snapshot_instance_export_locations.py +++ b/manilaclient/tests/unit/osc/v2/test_share_snapshot_instance_export_locations.py @@ -15,8 +15,9 @@ from osc_lib import utils as osc_lib_utils -from manilaclient.osc.v2 import (share_snapshot_instance_export_locations as - osc_snapshot_instance_locations) +from manilaclient.osc.v2 import ( + share_snapshot_instance_export_locations as osc_snapshot_instance_locations, +) from manilaclient.tests.unit.osc import osc_utils from manilaclient.tests.unit.osc.v2 import fakes as manila_fakes @@ -24,62 +25,61 @@ class TestShareSnapshotInstanceExportLocation(manila_fakes.TestShare): - def setUp(self): - super(TestShareSnapshotInstanceExportLocation, self).setUp() + super().setUp() self.share_snapshot_instances_mock = ( - self.app.client_manager.share.share_snapshot_instances) + self.app.client_manager.share.share_snapshot_instances + ) self.share_snapshot_instances_mock.reset_mock() - self.share_snapshot_instances_el_mock = ( - self.app.client_manager - .share.share_snapshot_instance_export_locations) + self.share_snapshot_instances_el_mock = self.app.client_manager.share.share_snapshot_instance_export_locations self.share_snapshot_instances_el_mock.reset_mock() class TestShareSnapshotInstanceExportLocationList( - TestShareSnapshotInstanceExportLocation): - + TestShareSnapshotInstanceExportLocation +): def setUp(self): - super(TestShareSnapshotInstanceExportLocationList, self).setUp() + super().setUp() - self.share_snapshot_instance = ( - manila_fakes.FakeShareSnapshotIntances - .create_one_snapshot_instance()) + self.share_snapshot_instance = manila_fakes.FakeShareSnapshotIntances.create_one_snapshot_instance() - self.share_snapshot_instances_export_locations = ( - manila_fakes.FakeShareSnapshotInstancesExportLocations - .create_share_snapshot_instances(count=2) + self.share_snapshot_instances_export_locations = manila_fakes.FakeShareSnapshotInstancesExportLocations.create_share_snapshot_instances( + count=2 ) self.share_snapshot_instances_mock.get.return_value = ( - self.share_snapshot_instance) + self.share_snapshot_instance + ) self.share_snapshot_instances_el_mock.list.return_value = ( - self.share_snapshot_instances_export_locations) + self.share_snapshot_instances_export_locations + ) - self.cmd = (osc_snapshot_instance_locations - .ShareSnapshotInstanceExportLocationList(self.app, - None)) + self.cmd = osc_snapshot_instance_locations.ShareSnapshotInstanceExportLocationList( + self.app, None + ) def test_share_snapshot_instance_export_location_list_missing_args(self): arglist = [] verifylist = [] - self.assertRaises(osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_snapshot_instance_export_location_list(self): - values = (osc_lib_utils.get_dict_properties( - s._info, COLUMNS) for s in - self.share_snapshot_instances_export_locations) - arglist = [ - self.share_snapshot_instance.id - ] - verifylist = [ - ('instance', self.share_snapshot_instance.id) - ] + values = ( + osc_lib_utils.get_dict_properties(s._info, COLUMNS) + for s in self.share_snapshot_instances_export_locations + ) + arglist = [self.share_snapshot_instance.id] + verifylist = [('instance', self.share_snapshot_instance.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) @@ -89,51 +89,57 @@ def test_share_snapshot_instance_export_location_list(self): class TestShareSnapshotInstanceExportLocationShow( - TestShareSnapshotInstanceExportLocation): - + TestShareSnapshotInstanceExportLocation +): def setUp(self): - super(TestShareSnapshotInstanceExportLocationShow, self).setUp() + super().setUp() - self.share_snapshot_instance = ( - manila_fakes.FakeShareSnapshotIntances - .create_one_snapshot_instance()) + self.share_snapshot_instance = manila_fakes.FakeShareSnapshotIntances.create_one_snapshot_instance() - self.share_snapshot_instances_export_location = ( - manila_fakes.FakeShareSnapshotInstancesExportLocations - .create_one_snapshot_instance() - ) + self.share_snapshot_instances_export_location = manila_fakes.FakeShareSnapshotInstancesExportLocations.create_one_snapshot_instance() self.share_snapshot_instances_mock.get.return_value = ( - self.share_snapshot_instance) + self.share_snapshot_instance + ) self.share_snapshot_instances_el_mock.get.return_value = ( - self.share_snapshot_instances_export_location) + self.share_snapshot_instances_export_location + ) - self.cmd = (osc_snapshot_instance_locations - .ShareSnapshotInstanceExportLocationShow(self.app, - None)) + self.cmd = osc_snapshot_instance_locations.ShareSnapshotInstanceExportLocationShow( + self.app, None + ) - self.data = (self.share_snapshot_instances_export_location. - _info.values()) - self.columns = (self.share_snapshot_instances_export_location. - _info.keys()) + self.data = ( + self.share_snapshot_instances_export_location._info.values() + ) + self.columns = ( + self.share_snapshot_instances_export_location._info.keys() + ) def test_share_snapshot_instance_export_location_show_missing_args(self): arglist = [] verifylist = [] - self.assertRaises(osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_snapshot_instance_export_location_show(self): arglist = [ self.share_snapshot_instance.id, - self.share_snapshot_instances_export_location.id + self.share_snapshot_instances_export_location.id, ] verifylist = [ ('snapshot_instance', self.share_snapshot_instance.id), - ('export_location', - self.share_snapshot_instances_export_location.id) + ( + 'export_location', + self.share_snapshot_instances_export_location.id, + ), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -141,9 +147,11 @@ def test_share_snapshot_instance_export_location_show(self): columns, data = self.cmd.take_action(parsed_args) self.share_snapshot_instances_mock.get.assert_called_with( - self.share_snapshot_instance.id) + self.share_snapshot_instance.id + ) self.share_snapshot_instances_el_mock.get.assert_called_with( self.share_snapshot_instances_export_location.id, - snapshot_instance=self.share_snapshot_instance) + snapshot_instance=self.share_snapshot_instance, + ) self.assertCountEqual(self.columns, columns) self.assertCountEqual(self.data, data) diff --git a/manilaclient/tests/unit/osc/v2/test_share_snapshot_instances.py b/manilaclient/tests/unit/osc/v2/test_share_snapshot_instances.py index b846548b..789e2daa 100644 --- a/manilaclient/tests/unit/osc/v2/test_share_snapshot_instances.py +++ b/manilaclient/tests/unit/osc/v2/test_share_snapshot_instances.py @@ -19,7 +19,8 @@ from manilaclient.common.apiclient import exceptions as api_exceptions from manilaclient.common import cliutils from manilaclient.osc.v2 import ( - share_snapshot_instances as osc_share_snapshot_instances) + share_snapshot_instances as osc_share_snapshot_instances, +) from manilaclient.tests.unit.osc import osc_utils from manilaclient.tests.unit.osc.v2 import fakes as manila_fakes @@ -34,48 +35,49 @@ 'Share ID', 'Share Instance ID', 'Progress', - 'Provider Location' + 'Provider Location', ] class TestShareSnapshotInstance(manila_fakes.TestShare): - def setUp(self): - super(TestShareSnapshotInstance, self).setUp() + super().setUp() self.share_snapshots_mock = ( - self.app.client_manager.share.share_snapshots) + self.app.client_manager.share.share_snapshots + ) self.share_snapshots_mock.reset_mock() self.share_snapshot_instances_mock = ( - self.app.client_manager.share.share_snapshot_instances) + self.app.client_manager.share.share_snapshot_instances + ) self.share_snapshot_instances_mock.reset_mock() - self.share_snapshot_instances_el_mock = ( - self.app.client_manager - .share.share_snapshot_instance_export_locations) + self.share_snapshot_instances_el_mock = self.app.client_manager.share.share_snapshot_instance_export_locations self.share_snapshot_instances_el_mock.reset_mock() class TestShareSnapshotInstanceList(TestShareSnapshotInstance): - def setUp(self): - super(TestShareSnapshotInstanceList, self).setUp() + super().setUp() - self.share_snapshot_instances = ( - manila_fakes.FakeShareSnapshotIntances - .create_share_snapshot_instances(count=2)) + self.share_snapshot_instances = manila_fakes.FakeShareSnapshotIntances.create_share_snapshot_instances( + count=2 + ) self.share_snapshot_instances_mock.list.return_value = ( - self.share_snapshot_instances) + self.share_snapshot_instances + ) - self.cmd = ( - osc_share_snapshot_instances.ListShareSnapshotInstance(self.app, - None)) + self.cmd = osc_share_snapshot_instances.ListShareSnapshotInstance( + self.app, None + ) def test_share_snapshot_instance_list(self): - values = (osc_lib_utils.get_dict_properties( - s._info, COLUMNS) for s in self.share_snapshot_instances) + values = ( + osc_lib_utils.get_dict_properties(s._info, COLUMNS) + for s in self.share_snapshot_instances + ) arglist = [] verifylist = [] @@ -88,16 +90,14 @@ def test_share_snapshot_instance_list(self): self.assertEqual(list(values), list(data)) def test_share_snapshot_instance_list_detail(self): - values = (osc_lib_utils.get_dict_properties( - s._info, COLUMNS_DETAIL) for s in self.share_snapshot_instances) + values = ( + osc_lib_utils.get_dict_properties(s._info, COLUMNS_DETAIL) + for s in self.share_snapshot_instances + ) - arglist = [ - '--detailed' - ] + arglist = ['--detailed'] - verifylist = [ - ('detailed', True) - ] + verifylist = [('detailed', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -108,21 +108,21 @@ def test_share_snapshot_instance_list_detail(self): def test_share_snapshot_instance_list_snapshot_id(self): self.share_snapshot = ( - manila_fakes.FakeShareSnapshot.create_one_snapshot()) + manila_fakes.FakeShareSnapshot.create_one_snapshot() + ) self.share_snapshots_mock.get.return_value = self.share_snapshot - self.share_snapshot_instances_mock.list.return_value = ( - [self.share_snapshot_instances[0]]) + self.share_snapshot_instances_mock.list.return_value = [ + self.share_snapshot_instances[0] + ] - values = (osc_lib_utils.get_dict_properties( - s._info, COLUMNS) for s in [self.share_snapshot_instances[0]]) + values = ( + osc_lib_utils.get_dict_properties(s._info, COLUMNS) + for s in [self.share_snapshot_instances[0]] + ) - arglist = [ - '--snapshot', self.share_snapshot.id - ] - verifylist = [ - ('snapshot', self.share_snapshot.id) - ] + arglist = ['--snapshot', self.share_snapshot.id] + verifylist = [('snapshot', self.share_snapshot.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -133,31 +133,32 @@ def test_share_snapshot_instance_list_snapshot_id(self): class TestShareSnapshotInstanceShow(TestShareSnapshotInstance): - def setUp(self): - super(TestShareSnapshotInstanceShow, self).setUp() + super().setUp() - self.share_snapshot_instance = ( - manila_fakes.FakeShareSnapshotIntances - .create_one_snapshot_instance()) + self.share_snapshot_instance = manila_fakes.FakeShareSnapshotIntances.create_one_snapshot_instance() self.share_snapshot_instances_mock.get.return_value = ( - self.share_snapshot_instance) + self.share_snapshot_instance + ) - self.share_snapshot_instances_el_list = ( - manila_fakes.FakeShareSnapshotInstancesExportLocations - .create_share_snapshot_instances(count=2) + self.share_snapshot_instances_el_list = manila_fakes.FakeShareSnapshotInstancesExportLocations.create_share_snapshot_instances( + count=2 ) self.share_snapshot_instances_el_mock.list.return_value = ( - self.share_snapshot_instances_el_list) + self.share_snapshot_instances_el_list + ) - self.cmd = (osc_share_snapshot_instances - .ShowShareSnapshotInstance(self.app, None)) + self.cmd = osc_share_snapshot_instances.ShowShareSnapshotInstance( + self.app, None + ) self.share_snapshot_instance._info['export_locations'] = ( cliutils.convert_dict_list_to_string( - self.share_snapshot_instances_el_list)) + self.share_snapshot_instances_el_list + ) + ) self.data = self.share_snapshot_instance._info.values() self.columns = self.share_snapshot_instance._info.keys() @@ -166,75 +167,85 @@ def test_share_snapshot_instance_show_missing_args(self): arglist = [] verifylist = [] - self.assertRaises(osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_snapshot_instance_show(self): - arglist = [ - self.share_snapshot_instance.id - ] - verifylist = [ - ('snapshot_instance', self.share_snapshot_instance.id) - ] + arglist = [self.share_snapshot_instance.id] + verifylist = [('snapshot_instance', self.share_snapshot_instance.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.share_snapshot_instances_mock.get.assert_called_with( - self.share_snapshot_instance.id) + self.share_snapshot_instance.id + ) self.assertCountEqual(self.columns, columns) self.assertCountEqual(self.data, data) class TestShareSnapshotInstanceSet(TestShareSnapshotInstance): - def setUp(self): - super(TestShareSnapshotInstanceSet, self).setUp() + super().setUp() - self.share_snapshot_instance = ( - manila_fakes.FakeShareSnapshotIntances - .create_one_snapshot_instance()) + self.share_snapshot_instance = manila_fakes.FakeShareSnapshotIntances.create_one_snapshot_instance() self.snapshot_instance_status = 'available' - self.cmd = (osc_share_snapshot_instances - .SetShareSnapshotInstance(self.app, None)) + self.cmd = osc_share_snapshot_instances.SetShareSnapshotInstance( + self.app, None + ) def test_share_snapshot_instance_set_missing_args(self): arglist = [] verifylist = [] - self.assertRaises(osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_snapshot_instance_set_instance_not_found(self): arglist = [ self.share_snapshot_instance.id, - '--status', self.snapshot_instance_status + '--status', + self.snapshot_instance_status, ] verifylist = [ ('snapshot_instance', self.share_snapshot_instance.id), - ('status', self.snapshot_instance_status) + ('status', self.snapshot_instance_status), ] self.share_snapshot_instances_mock.reset_state.side_effect = ( - api_exceptions.NotFound()) + api_exceptions.NotFound() + ) parsed_args = self.check_parser(self.cmd, arglist, verifylist) - self.assertRaises(osc_exceptions.CommandError, - self.cmd.take_action, parsed_args) + self.assertRaises( + osc_exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_share_snapshot_instance_set(self): arglist = [ self.share_snapshot_instance.id, - '--status', self.snapshot_instance_status + '--status', + self.snapshot_instance_status, ] verifylist = [ ('snapshot_instance', self.share_snapshot_instance.id), - ('status', self.snapshot_instance_status) + ('status', self.snapshot_instance_status), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) self.share_snapshot_instances_mock.reset_state.assert_called_with( - self.share_snapshot_instance.id, self.snapshot_instance_status) + self.share_snapshot_instance.id, self.snapshot_instance_status + ) diff --git a/manilaclient/tests/unit/osc/v2/test_share_snapshots.py b/manilaclient/tests/unit/osc/v2/test_share_snapshots.py index 2ffe50a1..59e6e9b1 100644 --- a/manilaclient/tests/unit/osc/v2/test_share_snapshots.py +++ b/manilaclient/tests/unit/osc/v2/test_share_snapshots.py @@ -39,14 +39,13 @@ 'Share ID', 'Share Proto', 'Share Size', - 'User ID' + 'User ID', ] class TestShareSnapshot(manila_fakes.TestShare): - def setUp(self): - super(TestShareSnapshot, self).setUp() + super().setUp() self.shares_mock = self.app.client_manager.share.shares self.shares_mock.reset_mock() @@ -54,20 +53,22 @@ def setUp(self): self.snapshots_mock = self.app.client_manager.share.share_snapshots self.snapshots_mock.reset_mock() self.app.client_manager.share.api_version = api_versions.APIVersion( - api_versions.MAX_VERSION) + api_versions.MAX_VERSION + ) self.export_locations_mock = ( - self.app.client_manager.share.share_snapshot_export_locations) + self.app.client_manager.share.share_snapshot_export_locations + ) self.export_locations_mock.reset_mock() self.app.client_manager.share.api_version = api_versions.APIVersion( - api_versions.MAX_VERSION) + api_versions.MAX_VERSION + ) class TestShareSnapshotCreate(TestShareSnapshot): - def setUp(self): - super(TestShareSnapshotCreate, self).setUp() + super().setUp() self.share = manila_fakes.FakeShare.create_one_share() self.shares_mock.create.return_value = self.share @@ -77,7 +78,8 @@ def setUp(self): self.share_snapshot = ( manila_fakes.FakeShareSnapshot.create_one_snapshot( attrs={'status': 'available'} - )) + ) + ) self.snapshots_mock.get.return_value = self.share_snapshot self.snapshots_mock.create.return_value = self.share_snapshot @@ -90,16 +92,17 @@ def test_share_snapshot_create_missing_args(self): arglist = [] verifylist = [] - self.assertRaises(osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_snapshot_create_required_args(self): - arglist = [ - self.share.id - ] - verifylist = [ - ('share', self.share.id) - ] + arglist = [self.share.id] + verifylist = [('share', self.share.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -110,21 +113,15 @@ def test_share_snapshot_create_required_args(self): force=False, name=None, description=None, - metadata={} + metadata={}, ) self.assertCountEqual(self.columns, columns) self.assertCountEqual(self.data, data) def test_share_snapshot_create_force(self): - arglist = [ - self.share.id, - '--force' - ] - verifylist = [ - ('share', self.share.id), - ('force', True) - ] + arglist = [self.share.id, '--force'] + verifylist = [('share', self.share.id), ('force', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -135,7 +132,7 @@ def test_share_snapshot_create_force(self): force=True, name=None, description=None, - metadata={} + metadata={}, ) self.assertCountEqual(columns, columns) @@ -144,13 +141,15 @@ def test_share_snapshot_create_force(self): def test_share_snapshot_create(self): arglist = [ self.share.id, - '--name', self.share_snapshot.name, - '--description', self.share_snapshot.description + '--name', + self.share_snapshot.name, + '--description', + self.share_snapshot.description, ] verifylist = [ ('share', self.share.id), ('name', self.share_snapshot.name), - ('description', self.share_snapshot.description) + ('description', self.share_snapshot.description), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -162,7 +161,7 @@ def test_share_snapshot_create(self): force=False, name=self.share_snapshot.name, description=self.share_snapshot.description, - metadata={} + metadata={}, ) self.assertCountEqual(self.columns, columns) @@ -171,10 +170,14 @@ def test_share_snapshot_create(self): def test_share_snapshot_create_metadata(self): arglist = [ self.share.id, - '--name', self.share_snapshot.name, - '--description', self.share_snapshot.description, - '--property', 'Manila=zorilla', - '--property', 'Zorilla=manila' + '--name', + self.share_snapshot.name, + '--description', + self.share_snapshot.description, + '--property', + 'Manila=zorilla', + '--property', + 'Zorilla=manila', ] verifylist = [ ('share', self.share.id), @@ -199,14 +202,8 @@ def test_share_snapshot_create_metadata(self): self.assertCountEqual(self.data, data) def test_share_snapshot_create_wait(self): - arglist = [ - self.share.id, - '--wait' - ] - verifylist = [ - ('share', self.share.id), - ('wait', True) - ] + arglist = [self.share.id, '--wait'] + verifylist = [('share', self.share.id), ('wait', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -217,24 +214,17 @@ def test_share_snapshot_create_wait(self): force=False, name=None, description=None, - metadata={} + metadata={}, ) - self.snapshots_mock.get.assert_called_with( - self.share_snapshot.id) + self.snapshots_mock.get.assert_called_with(self.share_snapshot.id) self.assertCountEqual(self.columns, columns) self.assertCountEqual(self.data, data) @mock.patch('manilaclient.osc.v2.share_snapshots.LOG') def test_share_snapshot_create_wait_error(self, mock_logger): - arglist = [ - self.share.id, - '--wait' - ] - verifylist = [ - ('share', self.share.id), - ('wait', True) - ] + arglist = [self.share.id, '--wait'] + verifylist = [('share', self.share.id), ('wait', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -246,25 +236,25 @@ def test_share_snapshot_create_wait_error(self, mock_logger): force=False, name=None, description=None, - metadata={} + metadata={}, ) mock_logger.error.assert_called_with( - "ERROR: Share snapshot is in error state.") + "ERROR: Share snapshot is in error state." + ) - self.snapshots_mock.get.assert_called_with( - self.share_snapshot.id) + self.snapshots_mock.get.assert_called_with(self.share_snapshot.id) self.assertCountEqual(self.columns, columns) self.assertCountEqual(self.data, data) class TestShareSnapshotDelete(TestShareSnapshot): - def setUp(self): - super(TestShareSnapshotDelete, self).setUp() + super().setUp() self.share_snapshot = ( - manila_fakes.FakeShareSnapshot.create_one_snapshot()) + manila_fakes.FakeShareSnapshot.create_one_snapshot() + ) self.snapshots_mock.get.return_value = self.share_snapshot @@ -274,16 +264,17 @@ def test_share_snapshot_delete_missing_args(self): arglist = [] verifylist = [] - self.assertRaises(osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_snapshot_delete(self): - arglist = [ - self.share_snapshot.id - ] - verifylist = [ - ('snapshot', [self.share_snapshot.id]) - ] + arglist = [self.share_snapshot.id] + verifylist = [('snapshot', [self.share_snapshot.id])] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -293,31 +284,23 @@ def test_share_snapshot_delete(self): self.assertIsNone(result) def test_share_snapshot_delete_force(self): - arglist = [ - self.share_snapshot.id, - '--force' - ] - verifylist = [ - ('snapshot', [self.share_snapshot.id]), - ('force', True) - ] + arglist = [self.share_snapshot.id, '--force'] + verifylist = [('snapshot', [self.share_snapshot.id]), ('force', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.snapshots_mock.force_delete.assert_called_with( - self.share_snapshot) + self.share_snapshot + ) self.assertIsNone(result) def test_share_snapshot_delete_multiple(self): share_snapshots = ( - manila_fakes.FakeShareSnapshot.create_share_snapshots( - count=2)) - arglist = [ - share_snapshots[0].id, - share_snapshots[1].id - ] + manila_fakes.FakeShareSnapshot.create_share_snapshots(count=2) + ) + arglist = [share_snapshots[0].id, share_snapshots[1].id] verifylist = [ ('snapshot', [share_snapshots[0].id, share_snapshots[1].id]) ] @@ -325,34 +308,25 @@ def test_share_snapshot_delete_multiple(self): result = self.cmd.take_action(parsed_args) - self.assertEqual(self.snapshots_mock.delete.call_count, - len(share_snapshots)) + self.assertEqual( + self.snapshots_mock.delete.call_count, len(share_snapshots) + ) self.assertIsNone(result) def test_share_snapshot_delete_exception(self): - arglist = [ - self.share_snapshot.id - ] - verifylist = [ - ('snapshot', [self.share_snapshot.id]) - ] + arglist = [self.share_snapshot.id] + verifylist = [('snapshot', [self.share_snapshot.id])] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.snapshots_mock.delete.side_effect = exceptions.CommandError() - self.assertRaises(exceptions.CommandError, - self.cmd.take_action, - parsed_args) + self.assertRaises( + exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_share_snapshot_delete_wait(self): - arglist = [ - self.share_snapshot.id, - '--wait' - ] - verifylist = [ - ('snapshot', [self.share_snapshot.id]), - ('wait', True) - ] + arglist = [self.share_snapshot.id, '--wait'] + verifylist = [('snapshot', [self.share_snapshot.id]), ('wait', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -363,38 +337,29 @@ def test_share_snapshot_delete_wait(self): self.assertIsNone(result) def test_share_snapshot_delete_wait_error(self): - arglist = [ - self.share_snapshot.id, - '--wait' - ] - verifylist = [ - ('snapshot', [self.share_snapshot.id]), - ('wait', True) - ] + arglist = [self.share_snapshot.id, '--wait'] + verifylist = [('snapshot', [self.share_snapshot.id]), ('wait', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) with mock.patch('osc_lib.utils.wait_for_delete', return_value=False): self.assertRaises( - exceptions.CommandError, - self.cmd.take_action, - parsed_args + exceptions.CommandError, self.cmd.take_action, parsed_args ) class TestShareSnapshotShow(TestShareSnapshot): - def setUp(self): - super(TestShareSnapshotShow, self).setUp() + super().setUp() self.export_location = ( - manila_fakes.FakeShareExportLocation.create_one_export_location()) + manila_fakes.FakeShareExportLocation.create_one_export_location() + ) self.share_snapshot = ( manila_fakes.FakeShareSnapshot.create_one_snapshot( - attrs={ - 'export_locations': self.export_location - } - )) + attrs={'export_locations': self.export_location} + ) + ) self.snapshots_mock.get.return_value = self.share_snapshot self.cmd = osc_share_snapshots.ShowShareSnapshot(self.app, None) @@ -407,21 +372,23 @@ def test_share_snapshot_show_missing_args(self): arglist = [] verifylist = [] - self.assertRaises(osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_snapshot_show(self): - arglist = [ - self.share_snapshot.id - ] - verifylist = [ - ('snapshot', self.share_snapshot.id) - ] + arglist = [self.share_snapshot.id] + verifylist = [('snapshot', self.share_snapshot.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) cliutils.convert_dict_list_to_string = mock.Mock() cliutils.convert_dict_list_to_string.return_value = ( - self.export_location) + self.export_location + ) columns, data = self.cmd.take_action(parsed_args) self.snapshots_mock.get.assert_called_with(self.share_snapshot.id) @@ -430,14 +397,14 @@ def test_share_snapshot_show(self): class TestShareSnapshotSet(TestShareSnapshot): - def setUp(self): - super(TestShareSnapshotSet, self).setUp() + super().setUp() self.share_snapshot = ( manila_fakes.FakeShareSnapshot.create_one_snapshot( methods={"set_metadata": None} - )) + ) + ) self.snapshots_mock.get.return_value = self.share_snapshot @@ -445,64 +412,56 @@ def setUp(self): def test_set_snapshot_name(self): snapshot_name = 'snapshot-name-' + uuid.uuid4().hex - arglist = [ - self.share_snapshot.id, - '--name', snapshot_name - ] + arglist = [self.share_snapshot.id, '--name', snapshot_name] verifylist = [ ('snapshot', self.share_snapshot.id), - ('name', snapshot_name) + ('name', snapshot_name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.snapshots_mock.update.assert_called_with( - self.share_snapshot, - display_name=parsed_args.name) + self.share_snapshot, display_name=parsed_args.name + ) self.assertIsNone(result) def test_set_snapshot_description(self): description = 'snapshot-description-' + uuid.uuid4().hex - arglist = [ - self.share_snapshot.id, - '--description', description - ] + arglist = [self.share_snapshot.id, '--description', description] verifylist = [ ('snapshot', self.share_snapshot.id), - ('description', description) + ('description', description), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.snapshots_mock.update.assert_called_with( - self.share_snapshot, - display_description=parsed_args.description) + self.share_snapshot, display_description=parsed_args.description + ) self.assertIsNone(result) def test_set_snapshot_status(self): - arglist = [ - self.share_snapshot.id, - '--status', 'available' - ] + arglist = [self.share_snapshot.id, '--status', 'available'] verifylist = [ ('snapshot', self.share_snapshot.id), - ('status', 'available') + ('status', 'available'), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.snapshots_mock.reset_state.assert_called_with( - self.share_snapshot, - parsed_args.status) + self.share_snapshot, parsed_args.status + ) self.assertIsNone(result) def test_set_snapshot_property(self): arglist = [ self.share_snapshot.id, - '--property', 'Zorilla=manila', + '--property', + 'Zorilla=manila', ] verifylist = [ ('snapshot', self.share_snapshot.id), @@ -513,193 +472,175 @@ def test_set_snapshot_property(self): self.cmd.take_action(parsed_args) self.share_snapshot.set_metadata.assert_called_with( - {'Zorilla': 'manila'}) + {'Zorilla': 'manila'} + ) def test_set_snapshot_update_exception(self): snapshot_name = 'snapshot-name-' + uuid.uuid4().hex - arglist = [ - self.share_snapshot.id, - '--name', snapshot_name - ] + arglist = [self.share_snapshot.id, '--name', snapshot_name] verifylist = [ ('snapshot', self.share_snapshot.id), - ('name', snapshot_name) + ('name', snapshot_name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.snapshots_mock.update.side_effect = Exception() self.assertRaises( - exceptions.CommandError, - self.cmd.take_action, - parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_set_snapshot_status_exception(self): - arglist = [ - self.share_snapshot.id, - '--status', 'available' - ] + arglist = [self.share_snapshot.id, '--status', 'available'] verifylist = [ ('snapshot', self.share_snapshot.id), - ('status', 'available') + ('status', 'available'), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.snapshots_mock.reset_state.side_effect = Exception() self.assertRaises( - exceptions.CommandError, - self.cmd.take_action, - parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_set_snapshot_property_exception(self): arglist = [ - '--property', 'key=', + '--property', + 'key=', self.share_snapshot.id, ] verifylist = [ ('property', {'key': ''}), - ('snapshot', self.share_snapshot.id) + ('snapshot', self.share_snapshot.id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) - self.share_snapshot.set_metadata.assert_called_with( - {'key': ''}) + self.share_snapshot.set_metadata.assert_called_with({'key': ''}) # '--property' takes key=value arguments # missing a value would raise a BadRequest self.share_snapshot.set_metadata.side_effect = exceptions.BadRequest self.assertRaises( - exceptions.CommandError, self.cmd.take_action, - parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) class TestShareSnapshotUnset(TestShareSnapshot): - def setUp(self): - super(TestShareSnapshotUnset, self).setUp() + super().setUp() self.share_snapshot = ( manila_fakes.FakeShareSnapshot.create_one_snapshot( methods={"delete_metadata": None} - )) + ) + ) self.snapshots_mock.get.return_value = self.share_snapshot self.cmd = osc_share_snapshots.UnsetShareSnapshot(self.app, None) def test_unset_snapshot_name(self): - arglist = [ - self.share_snapshot.id, - '--name' - ] - verifylist = [ - ('snapshot', self.share_snapshot.id), - ('name', True) - ] + arglist = [self.share_snapshot.id, '--name'] + verifylist = [('snapshot', self.share_snapshot.id), ('name', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.snapshots_mock.update.assert_called_with( - self.share_snapshot, - display_name=None) + self.share_snapshot, display_name=None + ) self.assertIsNone(result) def test_unset_snapshot_description(self): - arglist = [ - self.share_snapshot.id, - '--description' - ] + arglist = [self.share_snapshot.id, '--description'] verifylist = [ ('snapshot', self.share_snapshot.id), - ('description', True) + ('description', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.snapshots_mock.update.assert_called_with( - self.share_snapshot, - display_description=None) + self.share_snapshot, display_description=None + ) self.assertIsNone(result) def test_unset_snapshot_property(self): arglist = [ - '--property', 'Manila', + '--property', + 'Manila', self.share_snapshot.id, ] verifylist = [ ('property', ['Manila']), - ('snapshot', self.share_snapshot.id) + ('snapshot', self.share_snapshot.id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) self.share_snapshot.delete_metadata.assert_called_with( - parsed_args.property) + parsed_args.property + ) def test_unset_snapshot_name_exception(self): - arglist = [ - self.share_snapshot.id, - '--name' - ] - verifylist = [ - ('snapshot', self.share_snapshot.id), - ('name', True) - ] + arglist = [self.share_snapshot.id, '--name'] + verifylist = [('snapshot', self.share_snapshot.id), ('name', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.snapshots_mock.update.side_effect = Exception() self.assertRaises( - exceptions.CommandError, - self.cmd.take_action, - parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_unset_snapshot_property_exception(self): arglist = [ - '--property', 'Manila', + '--property', + 'Manila', self.share_snapshot.id, ] verifylist = [ ('property', ['Manila']), - ('snapshot', self.share_snapshot.id) + ('snapshot', self.share_snapshot.id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) self.share_snapshot.delete_metadata.assert_called_with( - parsed_args.property) + parsed_args.property + ) # 404 Not Found would be raised, if property 'Manila' doesn't exist self.share_snapshot.delete_metadata.side_effect = exceptions.NotFound self.assertRaises( - exceptions.CommandError, self.cmd.take_action, parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) @ddt.ddt class TestShareSnapshotList(TestShareSnapshot): - def setUp(self): - super(TestShareSnapshotList, self).setUp() + super().setUp() self.share_snapshots = ( - manila_fakes.FakeShareSnapshot.create_share_snapshots( - count=2)) + manila_fakes.FakeShareSnapshot.create_share_snapshots(count=2) + ) self.snapshots_list = oscutils.sort_items( - self.share_snapshots, - 'name:asc', - str) + self.share_snapshots, 'name:asc', str + ) self.snapshots_mock.list.return_value = self.snapshots_list - self.values = (oscutils.get_dict_properties( - s._info, COLUMNS) for s in self.snapshots_list) + self.values = ( + oscutils.get_dict_properties(s._info, COLUMNS) + for s in self.snapshots_list + ) self.cmd = osc_share_snapshots.ListShareSnapshot(self.app, None) @@ -724,7 +665,8 @@ def test_list_snapshots(self): 'name~': None, 'description~': None, 'description': None, - }) + } + ) self.assertEqual(COLUMNS, columns) self.assertEqual(list(self.values), list(data)) @@ -732,16 +674,14 @@ def test_list_snapshots(self): def test_list_snapshots_all_projects(self): all_tenants_list = COLUMNS.copy() all_tenants_list.append('Project ID') - list_values = (oscutils.get_dict_properties( - s._info, all_tenants_list) for s in self.snapshots_list) + list_values = ( + oscutils.get_dict_properties(s._info, all_tenants_list) + for s in self.snapshots_list + ) - arglist = [ - '--all-projects' - ] + arglist = ['--all-projects'] - verifylist = [ - ('all_projects', True) - ] + verifylist = [('all_projects', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -760,22 +700,21 @@ def test_list_snapshots_all_projects(self): 'name~': None, 'description~': None, 'description': None, - }) + } + ) self.assertEqual(all_tenants_list, columns) self.assertEqual(list(list_values), list(data)) def test_list_snapshots_detail(self): - values = (oscutils.get_dict_properties( - s._info, COLUMNS_DETAIL) for s in self.snapshots_list) + values = ( + oscutils.get_dict_properties(s._info, COLUMNS_DETAIL) + for s in self.snapshots_list + ) - arglist = [ - '--detail' - ] + arglist = ['--detail'] - verifylist = [ - ('detail', True) - ] + verifylist = [('detail', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -793,8 +732,9 @@ def test_list_snapshots_detail(self): 'metadata': {}, 'name~': None, 'description~': None, - 'description': None - }) + 'description': None, + } + ) self.assertEqual(COLUMNS_DETAIL, columns) self.assertEqual(list(values), list(data)) @@ -804,43 +744,35 @@ def test_list_snapshots_api_version_exception(self, v): self.app.client_manager.share.api_version = api_versions.APIVersion(v) if v == "2.35": - arglist = [ - '--description', 'Description' - ] - verifylist = [ - ('description', 'Description') - ] + arglist = ['--description', 'Description'] + verifylist = [('description', 'Description')] elif v == "2.78": arglist = [ '--count', ] - verifylist = [ - ('count', True) - ] + verifylist = [('count', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( - exceptions.CommandError, - self.cmd.take_action, - parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_list_snapshots_share_id(self): self.share = manila_fakes.FakeShare.create_one_share( - attrs={'id': self.snapshots_list[0].id}) + attrs={'id': self.snapshots_list[0].id} + ) self.shares_mock.get.return_value = self.share self.snapshots_mock.list.return_value = [self.snapshots_list[0]] - values = (oscutils.get_dict_properties( - s._info, COLUMNS) for s in [self.snapshots_list[0]]) + values = ( + oscutils.get_dict_properties(s._info, COLUMNS) + for s in [self.snapshots_list[0]] + ) - arglist = [ - '--share', self.share.id - ] - verifylist = [ - ('share', self.share.id) - ] + arglist = ['--share', self.share.id] + verifylist = [('share', self.share.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -858,24 +790,24 @@ def test_list_snapshots_share_id(self): 'metadata': {}, 'name~': None, 'description~': None, - 'description': None - }) + 'description': None, + } + ) self.assertEqual(COLUMNS, columns) self.assertEqual(list(values), list(data)) def test_list_snapshots_with_count(self): self.app.client_manager.share.api_version = api_versions.APIVersion( - '2.79') + '2.79' + ) self.snapshots_mock.list.return_value = self.snapshots_list, 2 arglist = [ '--count', ] - verifylist = [ - ('count', True) - ] + verifylist = [('count', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -895,27 +827,27 @@ def test_list_snapshots_with_count(self): 'description~': None, 'description': None, 'with_count': True, - }) + } + ) class TestShareSnapshotAdopt(TestShareSnapshot): - def setUp(self): - super(TestShareSnapshotAdopt, self).setUp() + super().setUp() self.share = manila_fakes.FakeShare.create_one_share() self.shares_mock.get.return_value = self.share self.share_snapshot = ( manila_fakes.FakeShareSnapshot.create_one_snapshot( - attrs={ - 'status': 'available' - } - )) + attrs={'status': 'available'} + ) + ) self.snapshots_mock.get.return_value = self.share_snapshot self.export_location = ( - manila_fakes.FakeShareExportLocation.create_one_export_location()) + manila_fakes.FakeShareExportLocation.create_one_export_location() + ) self.snapshots_mock.manage.return_value = self.share_snapshot @@ -928,17 +860,19 @@ def test_share_snapshot_adopt_missing_args(self): arglist = [] verifylist = [] - self.assertRaises(osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_snapshot_adopt(self): - arglist = [ - self.share.id, - self.export_location.fake_path - ] + arglist = [self.share.id, self.export_location.fake_path] verifylist = [ ('share', self.share.id), - ('provider_location', self.export_location.fake_path) + ('provider_location', self.export_location.fake_path), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -950,7 +884,7 @@ def test_snapshot_adopt(self): provider_location=self.export_location.fake_path, driver_options={}, name=None, - description=None + description=None, ) self.assertCountEqual(self.columns, columns) @@ -961,12 +895,13 @@ def test_snapshot_adopt_name(self): arglist = [ self.share.id, self.export_location.fake_path, - '--name', name, + '--name', + name, ] verifylist = [ ('share', self.share.id), ('provider_location', self.export_location.fake_path), - ('name', name) + ('name', name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -978,7 +913,7 @@ def test_snapshot_adopt_name(self): provider_location=self.export_location.fake_path, driver_options={}, name=name, - description=None + description=None, ) self.assertCountEqual(self.columns, columns) @@ -988,13 +923,15 @@ def test_snapshot_adopt_driver_option(self): arglist = [ self.share.id, self.export_location.fake_path, - '--driver-option', 'key1=value1', - '--driver-option', 'key2=value2' + '--driver-option', + 'key1=value1', + '--driver-option', + 'key2=value2', ] verifylist = [ ('share', self.share.id), ('provider_location', self.export_location.fake_path), - ('driver_option', {'key1': 'value1', 'key2': 'value2'}) + ('driver_option', {'key1': 'value1', 'key2': 'value2'}), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -1004,27 +941,20 @@ def test_snapshot_adopt_driver_option(self): self.snapshots_mock.manage.assert_called_with( share=self.share, provider_location=self.export_location.fake_path, - driver_options={ - 'key1': 'value1', - 'key2': 'value2' - }, + driver_options={'key1': 'value1', 'key2': 'value2'}, name=None, - description=None + description=None, ) self.assertCountEqual(self.columns, columns) self.assertCountEqual(self.data, data) def test_snapshot_adopt_wait(self): - arglist = [ - self.share.id, - self.export_location.fake_path, - '--wait' - ] + arglist = [self.share.id, self.export_location.fake_path, '--wait'] verifylist = [ ('share', self.share.id), ('provider_location', self.export_location.fake_path), - ('wait', True) + ('wait', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -1036,22 +966,18 @@ def test_snapshot_adopt_wait(self): provider_location=self.export_location.fake_path, driver_options={}, name=None, - description=None + description=None, ) self.assertCountEqual(self.columns, columns) self.assertCountEqual(self.data, data) def test_snapshot_adopt_wait_error(self): - arglist = [ - self.share.id, - self.export_location.fake_path, - '--wait' - ] + arglist = [self.share.id, self.export_location.fake_path, '--wait'] verifylist = [ ('share', self.share.id), ('provider_location', self.export_location.fake_path), - ('wait', True) + ('wait', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -1064,21 +990,21 @@ def test_snapshot_adopt_wait_error(self): provider_location=self.export_location.fake_path, driver_options={}, name=None, - description=None + description=None, ) self.assertCountEqual(self.columns, columns) self.assertCountEqual(self.data, data) class TestShareSnapshotAbandon(TestShareSnapshot): - def setUp(self): - super(TestShareSnapshotAbandon, self).setUp() + super().setUp() self.share_snapshot = ( manila_fakes.FakeShareSnapshot.create_one_snapshot( attrs={'status': 'available'} - )) + ) + ) self.snapshots_mock.get.return_value = self.share_snapshot @@ -1088,16 +1014,17 @@ def test_share_snapshot_abandon_missing_args(self): arglist = [] verifylist = [] - self.assertRaises(osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_snapshot_abandon(self): - arglist = [ - self.share_snapshot.id - ] - verifylist = [ - ('snapshot', [self.share_snapshot.id]) - ] + arglist = [self.share_snapshot.id] + verifylist = [('snapshot', [self.share_snapshot.id])] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -1108,12 +1035,9 @@ def test_share_snapshot_abandon(self): def test_share_snapshot_abandon_multiple(self): share_snapshots = ( - manila_fakes.FakeShareSnapshot.create_share_snapshots( - count=2)) - arglist = [ - share_snapshots[0].id, - share_snapshots[1].id - ] + manila_fakes.FakeShareSnapshot.create_share_snapshots(count=2) + ) + arglist = [share_snapshots[0].id, share_snapshots[1].id] verifylist = [ ('snapshot', [share_snapshots[0].id, share_snapshots[1].id]) ] @@ -1121,74 +1045,59 @@ def test_share_snapshot_abandon_multiple(self): result = self.cmd.take_action(parsed_args) - self.assertEqual(self.snapshots_mock.unmanage.call_count, - len(share_snapshots)) + self.assertEqual( + self.snapshots_mock.unmanage.call_count, len(share_snapshots) + ) self.assertIsNone(result) def test_share_snapshot_abandon_wait(self): - arglist = [ - self.share_snapshot.id, - '--wait' - ] - verifylist = [ - ('snapshot', [self.share_snapshot.id]), - ('wait', True) - ] + arglist = [self.share_snapshot.id, '--wait'] + verifylist = [('snapshot', [self.share_snapshot.id]), ('wait', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) with mock.patch('osc_lib.utils.wait_for_delete', return_value=True): result = self.cmd.take_action(parsed_args) self.snapshots_mock.unmanage.assert_called_with( - self.share_snapshot) + self.share_snapshot + ) self.assertIsNone(result) def test_share_snapshot_abandon_wait_error(self): - arglist = [ - self.share_snapshot.id, - '--wait' - ] - verifylist = [ - ('snapshot', [self.share_snapshot.id]), - ('wait', True) - ] + arglist = [self.share_snapshot.id, '--wait'] + verifylist = [('snapshot', [self.share_snapshot.id]), ('wait', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) with mock.patch('osc_lib.utils.wait_for_delete', return_value=False): self.assertRaises( - exceptions.CommandError, - self.cmd.take_action, - parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) class TestShareSnapshotAccessAllow(TestShareSnapshot): - def setUp(self): - super(TestShareSnapshotAccessAllow, self).setUp() + super().setUp() self.share_snapshot = ( - manila_fakes.FakeShareSnapshot.create_one_snapshot()) + manila_fakes.FakeShareSnapshot.create_one_snapshot() + ) self.snapshots_mock.get.return_value = self.share_snapshot self.access_rule = ( - manila_fakes.FakeSnapshotAccessRule.create_one_access_rule()) + manila_fakes.FakeSnapshotAccessRule.create_one_access_rule() + ) self.snapshots_mock.allow.return_value = self.access_rule._info - self.cmd = osc_share_snapshots.ShareSnapshotAccessAllow( - self.app, None) + self.cmd = osc_share_snapshots.ShareSnapshotAccessAllow(self.app, None) def test_share_snapshot_access_allow(self): - arglist = [ - self.share_snapshot.id, - 'user', - 'demo' - ] + arglist = [self.share_snapshot.id, 'user', 'demo'] verifylist = [ ('snapshot', self.share_snapshot.id), ('access_type', 'user'), - ('access_to', 'demo') + ('access_to', 'demo'), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -1196,48 +1105,42 @@ def test_share_snapshot_access_allow(self): columns, data = self.cmd.take_action(parsed_args) self.snapshots_mock.allow.assert_called_with( - snapshot=self.share_snapshot, - access_type='user', - access_to='demo' + snapshot=self.share_snapshot, access_type='user', access_to='demo' ) self.assertEqual(tuple(self.access_rule._info.keys()), columns) self.assertCountEqual(self.access_rule._info.values(), data) def test_share_snapshot_access_allow_exception(self): - arglist = [ - self.share_snapshot.id, - 'user', - 'demo' - ] + arglist = [self.share_snapshot.id, 'user', 'demo'] verifylist = [ ('snapshot', self.share_snapshot.id), ('access_type', 'user'), - ('access_to', 'demo') + ('access_to', 'demo'), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.snapshots_mock.allow.side_effect = exceptions.CommandError() - self.assertRaises(exceptions.CommandError, - self.cmd.take_action, - parsed_args) + self.assertRaises( + exceptions.CommandError, self.cmd.take_action, parsed_args + ) class TestShareSnapshotAccessDeny(TestShareSnapshot): - def setUp(self): - super(TestShareSnapshotAccessDeny, self).setUp() + super().setUp() self.share_snapshot = ( - manila_fakes.FakeShareSnapshot.create_one_snapshot()) + manila_fakes.FakeShareSnapshot.create_one_snapshot() + ) self.snapshots_mock.get.return_value = self.share_snapshot self.access_rule = ( - manila_fakes.FakeSnapshotAccessRule.create_one_access_rule()) + manila_fakes.FakeSnapshotAccessRule.create_one_access_rule() + ) - self.cmd = osc_share_snapshots.ShareSnapshotAccessDeny( - self.app, None) + self.cmd = osc_share_snapshots.ShareSnapshotAccessDeny(self.app, None) def test_share_snapshot_access_deny(self): arglist = [ @@ -1254,15 +1157,14 @@ def test_share_snapshot_access_deny(self): result = self.cmd.take_action(parsed_args) self.snapshots_mock.deny.assert_called_with( - snapshot=self.share_snapshot, - id=self.access_rule.id + snapshot=self.share_snapshot, id=self.access_rule.id ) self.assertIsNone(result) def test_share_snapshot_access_deny_multiple(self): - access_rules = ( - manila_fakes.FakeSnapshotAccessRule.create_access_rules( - count=2)) + access_rules = manila_fakes.FakeSnapshotAccessRule.create_access_rules( + count=2 + ) arglist = [ self.share_snapshot.id, @@ -1278,8 +1180,9 @@ def test_share_snapshot_access_deny_multiple(self): result = self.cmd.take_action(parsed_args) - self.assertEqual(self.snapshots_mock.deny.call_count, - len(access_rules)) + self.assertEqual( + self.snapshots_mock.deny.call_count, len(access_rules) + ) self.assertIsNone(result) def test_share_snapshot_access_deny_exception(self): @@ -1295,13 +1198,12 @@ def test_share_snapshot_access_deny_exception(self): parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.snapshots_mock.deny.side_effect = exceptions.CommandError() - self.assertRaises(exceptions.CommandError, - self.cmd.take_action, - parsed_args) + self.assertRaises( + exceptions.CommandError, self.cmd.take_action, parsed_args + ) class TestShareSnapshotAccessList(TestShareSnapshot): - access_rules_columns = [ 'ID', 'Access Type', @@ -1310,52 +1212,49 @@ class TestShareSnapshotAccessList(TestShareSnapshot): ] def setUp(self): - super(TestShareSnapshotAccessList, self).setUp() + super().setUp() self.share_snapshot = ( - manila_fakes.FakeShareSnapshot.create_one_snapshot()) + manila_fakes.FakeShareSnapshot.create_one_snapshot() + ) self.snapshots_mock.get.return_value = self.share_snapshot self.access_rules = ( - manila_fakes.FakeSnapshotAccessRule.create_access_rules( - count=2)) + manila_fakes.FakeSnapshotAccessRule.create_access_rules(count=2) + ) self.snapshots_mock.access_list.return_value = self.access_rules - self.cmd = osc_share_snapshots.ShareSnapshotAccessList( - self.app, None) + self.cmd = osc_share_snapshots.ShareSnapshotAccessList(self.app, None) - self.values = (oscutils.get_dict_properties( - a._info, self.access_rules_columns) for a in self.access_rules) + self.values = ( + oscutils.get_dict_properties(a._info, self.access_rules_columns) + for a in self.access_rules + ) def test_share_snapshot_access_list(self): - arglist = [ - self.share_snapshot.id - ] - verifylist = [ - ('snapshot', self.share_snapshot.id) - ] + arglist = [self.share_snapshot.id] + verifylist = [('snapshot', self.share_snapshot.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) - self.snapshots_mock.access_list.assert_called_with( - self.share_snapshot) + self.snapshots_mock.access_list.assert_called_with(self.share_snapshot) self.assertEqual(self.access_rules_columns, columns) self.assertCountEqual(self.values, data) class TestShareSnapshotExportLocationList(TestShareSnapshot): - columns = ["ID", "Path"] def setUp(self): - super(TestShareSnapshotExportLocationList, self).setUp() + super().setUp() self.share_snapshot = ( - manila_fakes.FakeShareSnapshot.create_one_snapshot()) + manila_fakes.FakeShareSnapshot.create_one_snapshot() + ) self.snapshots_mock.get.return_value = self.share_snapshot @@ -1364,38 +1263,38 @@ def setUp(self): ) self.export_locations_mock.list.return_value = self.export_locations - self.values = (oscutils.get_dict_properties( - e._info, self.columns) for e in self.export_locations) + self.values = ( + oscutils.get_dict_properties(e._info, self.columns) + for e in self.export_locations + ) self.cmd = osc_share_snapshots.ShareSnapshotListExportLocation( - self.app, None) + self.app, None + ) def test_snapshot_export_locations_list(self): - arglist = [ - self.share_snapshot.id - ] - verifylist = [ - ('snapshot', self.share_snapshot.id) - ] + arglist = [self.share_snapshot.id] + verifylist = [('snapshot', self.share_snapshot.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.export_locations_mock.list.assert_called_with( - snapshot=self.share_snapshot) + snapshot=self.share_snapshot + ) self.assertEqual(self.columns, columns) self.assertCountEqual(self.values, data) class TestShareSnapshotExportLocationShow(TestShareSnapshot): - def setUp(self): - super(TestShareSnapshotExportLocationShow, self).setUp() + super().setUp() self.share_snapshot = ( - manila_fakes.FakeShareSnapshot.create_one_snapshot()) + manila_fakes.FakeShareSnapshot.create_one_snapshot() + ) self.snapshots_mock.get.return_value = self.share_snapshot @@ -1406,16 +1305,14 @@ def setUp(self): self.export_locations_mock.get.return_value = self.export_location self.cmd = osc_share_snapshots.ShareSnapshotShowExportLocation( - self.app, None) + self.app, None + ) def test_snapshot_export_locations_list(self): - arglist = [ - self.share_snapshot.id, - self.export_location.id - ] + arglist = [self.share_snapshot.id, self.export_location.id] verifylist = [ ('snapshot', self.share_snapshot.id), - ('export_location', self.export_location.id) + ('export_location', self.export_location.id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -1424,7 +1321,8 @@ def test_snapshot_export_locations_list(self): self.export_locations_mock.get.assert_called_with( export_location=self.export_location.id, - snapshot=self.share_snapshot) + snapshot=self.share_snapshot, + ) self.assertEqual(tuple(self.export_location._info.keys()), columns) self.assertCountEqual(self.export_location._info.values(), data) diff --git a/manilaclient/tests/unit/osc/v2/test_share_transfers.py b/manilaclient/tests/unit/osc/v2/test_share_transfers.py index 5a74dc98..b08a8c68 100644 --- a/manilaclient/tests/unit/osc/v2/test_share_transfers.py +++ b/manilaclient/tests/unit/osc/v2/test_share_transfers.py @@ -30,14 +30,13 @@ 'Source Project Id', 'Destination Project Id', 'Accepted', - 'Expires At' + 'Expires At', ] class TestShareTransfer(manila_fakes.TestShare): - def setUp(self): - super(TestShareTransfer, self).setUp() + super().setUp() self.shares_mock = self.app.client_manager.share.shares self.shares_mock.reset_mock() @@ -46,13 +45,13 @@ def setUp(self): self.transfers_mock.reset_mock() self.app.client_manager.share.api_version = api_versions.APIVersion( - api_versions.MAX_VERSION) + api_versions.MAX_VERSION + ) class TestShareTransferCreate(TestShareTransfer): - def setUp(self): - super(TestShareTransferCreate, self).setUp() + super().setUp() self.share = manila_fakes.FakeShare.create_one_share() self.shares_mock.create.return_value = self.share @@ -60,7 +59,8 @@ def setUp(self): self.shares_mock.get.return_value = self.share self.share_transfer = ( - manila_fakes.FakeShareTransfer.create_one_transfer()) + manila_fakes.FakeShareTransfer.create_one_transfer() + ) self.transfers_mock.get.return_value = self.share_transfer self.transfers_mock.create.return_value = self.share_transfer @@ -73,37 +73,33 @@ def test_share_transfer_create_missing_args(self): arglist = [] verifylist = [] - self.assertRaises(osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_transfer_create_required_args(self): - arglist = [ - self.share.id - ] - verifylist = [ - ('share', self.share.id) - ] + arglist = [self.share.id] + verifylist = [('share', self.share.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) - self.transfers_mock.create.assert_called_with( - self.share.id, - name=None - ) + self.transfers_mock.create.assert_called_with(self.share.id, name=None) self.assertCountEqual(self.columns, columns) self.assertCountEqual(self.data, data) class TestShareTransferDelete(TestShareTransfer): - def setUp(self): - super(TestShareTransferDelete, self).setUp() + super().setUp() - self.transfer = ( - manila_fakes.FakeShareTransfer.create_one_transfer()) + self.transfer = manila_fakes.FakeShareTransfer.create_one_transfer() self.transfers_mock.get.return_value = self.transfer @@ -113,16 +109,17 @@ def test_share_transfer_delete_missing_args(self): arglist = [] verifylist = [] - self.assertRaises(osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_transfer_delete(self): - arglist = [ - self.transfer.id - ] - verifylist = [ - ('transfer', [self.transfer.id]) - ] + arglist = [self.transfer.id] + verifylist = [('transfer', [self.transfer.id])] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -132,47 +129,35 @@ def test_share_transfer_delete(self): self.assertIsNone(result) def test_share_transfer_delete_multiple(self): - transfers = ( - manila_fakes.FakeShareTransfer.create_share_transfers( - count=2)) - arglist = [ - transfers[0].id, - transfers[1].id - ] - verifylist = [ - ('transfer', [transfers[0].id, transfers[1].id]) - ] + transfers = manila_fakes.FakeShareTransfer.create_share_transfers( + count=2 + ) + arglist = [transfers[0].id, transfers[1].id] + verifylist = [('transfer', [transfers[0].id, transfers[1].id])] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - self.assertEqual(self.transfers_mock.delete.call_count, - len(transfers)) + self.assertEqual(self.transfers_mock.delete.call_count, len(transfers)) self.assertIsNone(result) def test_share_transfer_delete_exception(self): - arglist = [ - self.transfer.id - ] - verifylist = [ - ('transfer', [self.transfer.id]) - ] + arglist = [self.transfer.id] + verifylist = [('transfer', [self.transfer.id])] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.transfers_mock.delete.side_effect = exceptions.CommandError() - self.assertRaises(exceptions.CommandError, - self.cmd.take_action, - parsed_args) + self.assertRaises( + exceptions.CommandError, self.cmd.take_action, parsed_args + ) class TestShareTransferShow(TestShareTransfer): - def setUp(self): - super(TestShareTransferShow, self).setUp() + super().setUp() - self.transfer = ( - manila_fakes.FakeShareTransfer.create_one_transfer()) + self.transfer = manila_fakes.FakeShareTransfer.create_one_transfer() self.transfers_mock.get.return_value = self.transfer self.cmd = osc_share_transfers.ShowShareTransfer(self.app, None) @@ -185,16 +170,17 @@ def test_share_transfer_show_missing_args(self): arglist = [] verifylist = [] - self.assertRaises(osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_transfer_show(self): - arglist = [ - self.transfer.id - ] - verifylist = [ - ('transfer', self.transfer.id) - ] + arglist = [self.transfer.id] + verifylist = [('transfer', self.transfer.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) @@ -204,28 +190,25 @@ def test_share_transfer_show(self): class TestShareTransferList(TestShareTransfer): - def setUp(self): - super(TestShareTransferList, self).setUp() + super().setUp() - self.transfers = ( - manila_fakes.FakeShareTransfer.create_share_transfers( - count=2)) + self.transfers = manila_fakes.FakeShareTransfer.create_share_transfers( + count=2 + ) self.transfers_mock.list.return_value = self.transfers - self.values = (oscutils.get_dict_properties( - m._info, COLUMNS) for m in self.transfers) + self.values = ( + oscutils.get_dict_properties(m._info, COLUMNS) + for m in self.transfers + ) self.cmd = osc_share_transfers.ListShareTransfer(self.app, None) def test_list_transfers(self): - arglist = [ - '--detailed' - ] - verifylist = [ - ('detailed', True) - ] + arglist = ['--detailed'] + verifylist = [('detailed', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -241,9 +224,10 @@ def test_list_transfers(self): 'offset': None, 'resource_type': None, 'resource_id': None, - 'source_project_id': None}, + 'source_project_id': None, + }, sort_key=None, - sort_dir=None + sort_dir=None, ) self.assertEqual(COLUMNS, columns) @@ -251,12 +235,10 @@ def test_list_transfers(self): class TestShareTransferAccept(TestShareTransfer): - def setUp(self): - super(TestShareTransferAccept, self).setUp() + super().setUp() - self.transfer = ( - manila_fakes.FakeShareTransfer.create_one_transfer()) + self.transfer = manila_fakes.FakeShareTransfer.create_one_transfer() self.transfers_mock.get.return_value = self.transfer @@ -266,24 +248,26 @@ def test_share_transfer_accept_missing_args(self): arglist = [] verifylist = [] - self.assertRaises(osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_transfer_accept(self): - arglist = [ - self.transfer.id, - self.transfer.auth_key - ] + arglist = [self.transfer.id, self.transfer.auth_key] verifylist = [ ('transfer', self.transfer.id), - ('auth_key', self.transfer.auth_key) + ('auth_key', self.transfer.auth_key), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - self.transfers_mock.accept.assert_called_with(self.transfer.id, - self.transfer.auth_key, - clear_access_rules=False) + self.transfers_mock.accept.assert_called_with( + self.transfer.id, self.transfer.auth_key, clear_access_rules=False + ) self.assertIsNone(result) diff --git a/manilaclient/tests/unit/osc/v2/test_share_type.py b/manilaclient/tests/unit/osc/v2/test_share_type.py index 487eea05..be55ec0d 100644 --- a/manilaclient/tests/unit/osc/v2/test_share_type.py +++ b/manilaclient/tests/unit/osc/v2/test_share_type.py @@ -31,25 +31,24 @@ 'is_default', 'required_extra_specs', 'optional_extra_specs', - 'description' + 'description', ] class TestShareType(manila_fakes.TestShare): - def setUp(self): - super(TestShareType, self).setUp() + super().setUp() self.shares_mock = self.app.client_manager.share.share_types self.shares_mock.reset_mock() self.app.client_manager.share.api_version = api_versions.APIVersion( - api_versions.MAX_VERSION) + api_versions.MAX_VERSION + ) class TestShareTypeCreate(TestShareType): - def setUp(self): - super(TestShareTypeCreate, self).setUp() + super().setUp() self.new_share_type = manila_fakes.FakeShareType.create_one_sharetype() self.shares_mock.create.return_value = self.new_share_type @@ -63,11 +62,13 @@ def setUp(self): 'public', self.new_share_type.is_default, 'driver_handles_share_servers : True', - ('replication_type : readable\n' - 'mount_snapshot_support : False\n' - 'revert_to_snapshot_support : False\n' - 'create_share_from_snapshot_support : True\n' - 'snapshot_support : True'), + ( + 'replication_type : readable\n' + 'mount_snapshot_support : False\n' + 'revert_to_snapshot_support : False\n' + 'create_share_from_snapshot_support : True\n' + 'snapshot_support : True' + ), self.new_share_type.description, ] @@ -77,24 +78,23 @@ def setUp(self): 'public', self.new_share_type.is_default, {'driver_handles_share_servers': True}, - {'replication_type': 'readable', - 'mount_snapshot_support': False, - 'revert_to_snapshot_support': False, - 'create_share_from_snapshot_support': True, - 'snapshot_support': True}, + { + 'replication_type': 'readable', + 'mount_snapshot_support': False, + 'revert_to_snapshot_support': False, + 'create_share_from_snapshot_support': True, + 'snapshot_support': True, + }, self.new_share_type.description, ] def test_share_type_create_required_args(self): """Verifies required arguments.""" - arglist = [ - self.new_share_type.name, - 'True' - ] + arglist = [self.new_share_type.name, 'True'] verifylist = [ ('name', self.new_share_type.name), - ('spec_driver_handles_share_servers', 'True') + ('spec_driver_handles_share_servers', 'True'), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -105,7 +105,7 @@ def test_share_type_create_required_args(self): extra_specs={}, is_public=True, name=self.new_share_type.name, - spec_driver_handles_share_servers=True + spec_driver_handles_share_servers=True, ) self.assertCountEqual(COLUMNS, columns) @@ -114,14 +114,10 @@ def test_share_type_create_required_args(self): def test_share_type_create_json_fomrat(self): """Verifies --format json.""" - arglist = [ - self.new_share_type.name, - 'True', - '-f', 'json' - ] + arglist = [self.new_share_type.name, 'True', '-f', 'json'] verifylist = [ ('name', self.new_share_type.name), - ('spec_driver_handles_share_servers', 'True') + ('spec_driver_handles_share_servers', 'True'), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -132,7 +128,7 @@ def test_share_type_create_json_fomrat(self): extra_specs={}, is_public=True, name=self.new_share_type.name, - spec_driver_handles_share_servers=True + spec_driver_handles_share_servers=True, ) self.assertCountEqual(COLUMNS, columns) @@ -141,26 +137,23 @@ def test_share_type_create_json_fomrat(self): def test_share_type_create_missing_required_arg(self): """Verifies missing required arguments.""" - arglist = [ - self.new_share_type.name - ] - verifylist = [ - ('name', self.new_share_type.name) - ] + arglist = [self.new_share_type.name] + verifylist = [('name', self.new_share_type.name)] - self.assertRaises(osc_utils.ParserException, - self.check_parser, self.cmd, arglist, verifylist) + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) def test_share_type_create_private(self): - arglist = [ - self.new_share_type.name, - 'True', - '--public', 'False' - ] + arglist = [self.new_share_type.name, 'True', '--public', 'False'] verifylist = [ ('name', self.new_share_type.name), ('spec_driver_handles_share_servers', 'True'), - ('public', 'False') + ('public', 'False'), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -171,7 +164,7 @@ def test_share_type_create_private(self): extra_specs={}, is_public=False, name=self.new_share_type.name, - spec_driver_handles_share_servers=True + spec_driver_handles_share_servers=True, ) self.assertCountEqual(COLUMNS, columns) @@ -181,12 +174,13 @@ def test_share_type_create_extra_specs(self): arglist = [ self.new_share_type.name, 'True', - '--extra-specs', 'snapshot_support=true' + '--extra-specs', + 'snapshot_support=true', ] verifylist = [ ('name', self.new_share_type.name), ('spec_driver_handles_share_servers', 'True'), - ('extra_specs', ['snapshot_support=true']) + ('extra_specs', ['snapshot_support=true']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -197,71 +191,75 @@ def test_share_type_create_extra_specs(self): extra_specs={'snapshot_support': 'True'}, is_public=True, name=self.new_share_type.name, - spec_driver_handles_share_servers=True + spec_driver_handles_share_servers=True, ) self.assertCountEqual(COLUMNS, columns) self.assertCountEqual(self.data, data) def test_share_type_create_dhss_invalid_value(self): - arglist = [ - self.new_share_type.name, - 'non_bool_value' - ] + arglist = [self.new_share_type.name, 'non_bool_value'] verifylist = [ ('name', self.new_share_type.name), - ('spec_driver_handles_share_servers', 'non_bool_value') + ('spec_driver_handles_share_servers', 'non_bool_value'), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( - exceptions.CommandError, self.cmd.take_action, parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_share_type_create_api_version_exception(self): self.app.client_manager.share.api_version = api_versions.APIVersion( - "2.40") + "2.40" + ) arglist = [ self.new_share_type.name, 'True', - '--description', 'Description' + '--description', + 'Description', ] verifylist = [ ('name', self.new_share_type.name), ('spec_driver_handles_share_servers', 'True'), - ('description', 'Description') + ('description', 'Description'), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( - exceptions.CommandError, self.cmd.take_action, parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_share_type_create_dhss_defined_twice(self): arglist = [ self.new_share_type.name, 'True', - '--extra-specs', 'driver_handles_share_servers=true' + '--extra-specs', + 'driver_handles_share_servers=true', ] verifylist = [ ('name', self.new_share_type.name), ('spec_driver_handles_share_servers', 'True'), - ('extra_specs', ['driver_handles_share_servers=true']) + ('extra_specs', ['driver_handles_share_servers=true']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( - exceptions.CommandError, self.cmd.take_action, parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_share_type_create_bool_args(self): arglist = [ self.new_share_type.name, 'True', - '--snapshot-support', 'true' + '--snapshot-support', + 'true', ] verifylist = [ ('name', self.new_share_type.name), ('spec_driver_handles_share_servers', 'True'), - ('snapshot_support', 'true') + ('snapshot_support', 'true'), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -271,7 +269,7 @@ def test_share_type_create_bool_args(self): extra_specs={'snapshot_support': 'True'}, is_public=True, name=self.new_share_type.name, - spec_driver_handles_share_servers=True + spec_driver_handles_share_servers=True, ) self.assertCountEqual(COLUMNS, columns) @@ -279,27 +277,23 @@ def test_share_type_create_bool_args(self): class TestShareTypeDelete(TestShareType): - share_types = manila_fakes.FakeShareType.create_share_types(count=2) def setUp(self): - super(TestShareTypeDelete, self).setUp() + super().setUp() self.shares_mock.get = manila_fakes.FakeShareType.get_share_types( - self.share_types) + self.share_types + ) self.shares_mock.delete.return_value = None # Get the command object to test self.cmd = osc_share_types.DeleteShareType(self.app, None) def test_share_type_delete_one(self): - arglist = [ - self.share_types[0].id - ] + arglist = [self.share_types[0].id] - verifylist = [ - ('share_types', [self.share_types[0].id]) - ] + verifylist = [('share_types', [self.share_types[0].id])] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -335,16 +329,17 @@ def test_delete_share_type_with_exception(self): parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.shares_mock.delete.side_effect = exceptions.CommandError() self.assertRaises( - exceptions.CommandError, self.cmd.take_action, parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) class TestShareTypeSet(TestShareType): - def setUp(self): - super(TestShareTypeSet, self).setUp() + super().setUp() self.share_type = manila_fakes.FakeShareType.create_one_sharetype( - methods={'set_keys': None, 'update': None}) + methods={'set_keys': None, 'update': None} + ) self.shares_mock.get.return_value = self.share_type # Get the command object to test @@ -353,88 +348,78 @@ def setUp(self): def test_share_type_set_extra_specs(self): arglist = [ self.share_type.id, - '--extra-specs', 'snapshot_support=true' + '--extra-specs', + 'snapshot_support=true', ] verifylist = [ ('share_type', self.share_type.id), - ('extra_specs', ['snapshot_support=true']) + ('extra_specs', ['snapshot_support=true']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.share_type.set_keys.assert_called_with( - {'snapshot_support': 'True'}) + {'snapshot_support': 'True'} + ) self.assertIsNone(result) def test_share_type_set_name(self): - arglist = [ - self.share_type.id, - '--name', 'new name' - ] - verifylist = [ - ('share_type', self.share_type.id), - ('name', 'new name') - ] + arglist = [self.share_type.id, '--name', 'new name'] + verifylist = [('share_type', self.share_type.id), ('name', 'new name')] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - self.share_type.update.assert_called_with( - name='new name') + self.share_type.update.assert_called_with(name='new name') self.assertIsNone(result) def test_share_type_set_description(self): - arglist = [ - self.share_type.id, - '--description', 'new description' - ] + arglist = [self.share_type.id, '--description', 'new description'] verifylist = [ ('share_type', self.share_type.id), - ('description', 'new description') + ('description', 'new description'), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.share_type.update.assert_called_with( - description='new description') + description='new description' + ) self.assertIsNone(result) def test_share_type_set_visibility(self): - arglist = [ - self.share_type.id, - '--public', 'false' - ] - verifylist = [ - ('share_type', self.share_type.id), - ('public', 'false') - ] + arglist = [self.share_type.id, '--public', 'false'] + verifylist = [('share_type', self.share_type.id), ('public', 'false')] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - self.share_type.update.assert_called_with( - is_public=False) + self.share_type.update.assert_called_with(is_public=False) self.assertIsNone(result) def test_share_type_set_extra_specs_exception(self): arglist = [ self.share_type.id, - '--extra-specs', 'snapshot_support=true' + '--extra-specs', + 'snapshot_support=true', ] verifylist = [ ('share_type', self.share_type.id), - ('extra_specs', ['snapshot_support=true']) + ('extra_specs', ['snapshot_support=true']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.share_type.set_keys.side_effect = BadRequest() self.assertRaises( - exceptions.CommandError, self.cmd.take_action, parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) def test_share_type_set_api_version_exception(self): self.app.client_manager.share.api_version = api_versions.APIVersion( - "2.49") + "2.49" + ) arglist = [ self.share_type.id, - '--name', 'new name', + '--name', + 'new name', ] verifylist = [ ('share_type', self.share_type.id), @@ -442,29 +427,27 @@ def test_share_type_set_api_version_exception(self): ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( - exceptions.CommandError, self.cmd.take_action, parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) class TestShareTypeUnset(TestShareType): - def setUp(self): - super(TestShareTypeUnset, self).setUp() + super().setUp() self.share_type = manila_fakes.FakeShareType.create_one_sharetype( - methods={'unset_keys': None}) + methods={'unset_keys': None} + ) self.shares_mock.get.return_value = self.share_type # Get the command object to test self.cmd = osc_share_types.UnsetShareType(self.app, None) def test_share_type_unset_extra_specs(self): - arglist = [ - self.share_type.id, - 'snapshot_support' - ] + arglist = [self.share_type.id, 'snapshot_support'] verifylist = [ ('share_type', self.share_type.id), - ('extra_specs', ['snapshot_support']) + ('extra_specs', ['snapshot_support']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -473,48 +456,44 @@ def test_share_type_unset_extra_specs(self): self.assertIsNone(result) def test_share_type_unset_exception(self): - arglist = [ - self.share_type.id, - 'snapshot_support' - ] + arglist = [self.share_type.id, 'snapshot_support'] verifylist = [ ('share_type', self.share_type.id), - ('extra_specs', ['snapshot_support']) + ('extra_specs', ['snapshot_support']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.share_type.unset_keys.side_effect = NotFound() self.assertRaises( - exceptions.CommandError, self.cmd.take_action, parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) class TestShareTypeList(TestShareType): - share_types = manila_fakes.FakeShareType.create_share_types() columns = utils.format_column_headers(COLUMNS) def setUp(self): - super(TestShareTypeList, self).setUp() + super().setUp() self.shares_mock.list.return_value = self.share_types # Get the command object to test self.cmd = osc_share_types.ListShareType(self.app, None) - self.values = (oscutils.get_dict_properties( - s._info, COLUMNS) for s in self.share_types) + self.values = ( + oscutils.get_dict_properties(s._info, COLUMNS) + for s in self.share_types + ) def test_share_type_list_no_options(self): arglist = [] - verifylist = [ - ('all', False) - ] + verifylist = [('all', False)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.shares_mock.list.assert_called_once_with( - search_opts={}, - show_all=False + search_opts={}, show_all=False ) self.assertEqual(self.columns, columns) self.assertEqual(list(self.values), list(data)) @@ -523,56 +502,48 @@ def test_share_type_list_all(self): arglist = [ '--all', ] - verifylist = [ - ('all', True) - ] + verifylist = [('all', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.shares_mock.list.assert_called_once_with( - search_opts={}, - show_all=True) + search_opts={}, show_all=True + ) self.assertEqual(self.columns, columns) self.assertEqual(list(self.values), list(data)) def test_share_type_list_extra_specs(self): - arglist = [ - '--extra-specs', 'snapshot_support=true' - ] - verifylist = [ - ('extra_specs', ['snapshot_support=true']) - ] + arglist = ['--extra-specs', 'snapshot_support=true'] + verifylist = [('extra_specs', ['snapshot_support=true'])] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.shares_mock.list.assert_called_once_with( search_opts={'extra_specs': {'snapshot_support': 'True'}}, - show_all=False) + show_all=False, + ) self.assertEqual(self.columns, columns) self.assertEqual(list(self.values), list(data)) def test_share_type_list_api_versions_exception(self): self.app.client_manager.share.api_version = api_versions.APIVersion( - "2.42") + "2.42" + ) - arglist = [ - '--extra-specs', 'snapshot_support=true' - ] - verifylist = [ - ('extra_specs', ['snapshot_support=true']) - ] + arglist = ['--extra-specs', 'snapshot_support=true'] + verifylist = [('extra_specs', ['snapshot_support=true'])] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( - exceptions.CommandError, self.cmd.take_action, parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) class TestShareTypeShow(TestShareType): - def setUp(self): - super(TestShareTypeShow, self).setUp() + super().setUp() self.share_type = manila_fakes.FakeShareType.create_one_sharetype() @@ -587,11 +558,13 @@ def setUp(self): 'public', self.share_type.is_default, 'driver_handles_share_servers : True', - ('replication_type : readable\n' - 'mount_snapshot_support : False\n' - 'revert_to_snapshot_support : False\n' - 'create_share_from_snapshot_support : True\n' - 'snapshot_support : True'), + ( + 'replication_type : readable\n' + 'mount_snapshot_support : False\n' + 'revert_to_snapshot_support : False\n' + 'create_share_from_snapshot_support : True\n' + 'snapshot_support : True' + ), self.share_type.description, ] @@ -601,21 +574,19 @@ def setUp(self): 'public', self.share_type.is_default, {'driver_handles_share_servers': True}, - {'replication_type': 'readable', - 'mount_snapshot_support': False, - 'revert_to_snapshot_support': False, - 'create_share_from_snapshot_support': True, - 'snapshot_support': True}, + { + 'replication_type': 'readable', + 'mount_snapshot_support': False, + 'revert_to_snapshot_support': False, + 'create_share_from_snapshot_support': True, + 'snapshot_support': True, + }, self.share_type.description, ] def test_share_type_show(self): - arglist = [ - self.share_type.id - ] - verifylist = [ - ("share_type", self.share_type.id) - ] + arglist = [self.share_type.id] + verifylist = [("share_type", self.share_type.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) @@ -627,11 +598,10 @@ def test_share_type_show(self): def test_share_type_show_json_format(self): arglist = [ self.share_type.id, - '-f', 'json', - ] - verifylist = [ - ("share_type", self.share_type.id) + '-f', + 'json', ] + verifylist = [("share_type", self.share_type.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) diff --git a/manilaclient/tests/unit/osc/v2/test_share_type_access.py b/manilaclient/tests/unit/osc/v2/test_share_type_access.py index 00a7a2ba..506965e4 100644 --- a/manilaclient/tests/unit/osc/v2/test_share_type_access.py +++ b/manilaclient/tests/unit/osc/v2/test_share_type_access.py @@ -21,12 +21,10 @@ class TestShareTypeAccess(manila_fakes.TestShare): - def setUp(self): - super(TestShareTypeAccess, self).setUp() + super().setUp() - self.type_access_mock = ( - self.app.client_manager.share.share_type_access) + self.type_access_mock = self.app.client_manager.share.share_type_access self.type_access_mock.reset_mock() @@ -38,14 +36,14 @@ def setUp(self): class TestShareTypeAccessAllow(TestShareTypeAccess): - def setUp(self): - super(TestShareTypeAccessAllow, self).setUp() + super().setUp() self.project = identity_fakes.FakeProject.create_one_project() self.share_type = manila_fakes.FakeShareType.create_one_sharetype( - attrs={'share_type_access:is_public': False}) + attrs={'share_type_access:is_public': False} + ) self.share_types_mock.get.return_value = self.share_type self.type_access_mock.add_project_access.return_value = None @@ -54,13 +52,10 @@ def setUp(self): self.cmd = osc_share_type_access.ShareTypeAccessAllow(self.app, None) def test_share_type_access_create(self): - arglist = [ - self.share_type.id, - self.project.id - ] + arglist = [self.share_type.id, self.project.id] verifylist = [ ('share_type', self.share_type.id), - ('project_id', self.project.id) + ('project_id', self.project.id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -68,89 +63,83 @@ def test_share_type_access_create(self): result = self.cmd.take_action(parsed_args) self.type_access_mock.add_project_access.assert_called_with( - self.share_type, - self.project.id) + self.share_type, self.project.id + ) self.assertIsNone(result) def test_share_type_access_create_throws_exception(self): - arglist = [ - self.share_type.id, - 'invalid_project_format' - ] + arglist = [self.share_type.id, 'invalid_project_format'] verifylist = [ ('share_type', self.share_type.id), - ('project_id', 'invalid_project_format') + ('project_id', 'invalid_project_format'), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.type_access_mock.add_project_access.side_effect = BadRequest() self.assertRaises( - exceptions.CommandError, self.cmd.take_action, parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) class TestShareTypeAccessList(TestShareTypeAccess): - columns = ['Project ID'] data = (('',), ('',)) def setUp(self): - super(TestShareTypeAccessList, self).setUp() + super().setUp() - self.type_access_mock.list.return_value = ( - self.columns, self.data) + self.type_access_mock.list.return_value = (self.columns, self.data) # Get the command object to test self.cmd = osc_share_type_access.ListShareTypeAccess(self.app, None) def test_share_type_access_list(self): share_type = manila_fakes.FakeShareType.create_one_sharetype( - attrs={'share_type_access:is_public': False}) + attrs={'share_type_access:is_public': False} + ) self.share_types_mock.get.return_value = share_type arglist = [ share_type.id, ] - verifylist = [ - ('share_type', share_type.id) - ] + verifylist = [('share_type', share_type.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) - self.type_access_mock.list.assert_called_once_with( - share_type) + self.type_access_mock.list.assert_called_once_with(share_type) self.assertEqual(self.columns, columns) self.assertEqual(self.data, tuple(data)) def test_share_type_access_list_public_type(self): share_type = manila_fakes.FakeShareType.create_one_sharetype( - attrs={'share_type_access:is_public': True}) + attrs={'share_type_access:is_public': True} + ) self.share_types_mock.get.return_value = share_type arglist = [ share_type.id, ] - verifylist = [ - ('share_type', share_type.id) - ] + verifylist = [('share_type', share_type.id)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises( - exceptions.CommandError, self.cmd.take_action, parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) class TestShareTypeAccessDeny(TestShareTypeAccess): - def setUp(self): - super(TestShareTypeAccessDeny, self).setUp() + super().setUp() self.project = identity_fakes.FakeProject.create_one_project() self.share_type = manila_fakes.FakeShareType.create_one_sharetype( - attrs={'share_type_access:is_public': False}) + attrs={'share_type_access:is_public': False} + ) self.share_types_mock.get.return_value = self.share_type self.type_access_mock.remove_project_access.return_value = None @@ -159,13 +148,10 @@ def setUp(self): self.cmd = osc_share_type_access.ShareTypeAccessDeny(self.app, None) def test_share_type_access_delete(self): - arglist = [ - self.share_type.id, - self.project.id - ] + arglist = [self.share_type.id, self.project.id] verifylist = [ ('share_type', self.share_type.id), - ('project_id', self.project.id) + ('project_id', self.project.id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -173,22 +159,20 @@ def test_share_type_access_delete(self): result = self.cmd.take_action(parsed_args) self.type_access_mock.remove_project_access.assert_called_with( - self.share_type, - self.project.id) + self.share_type, self.project.id + ) self.assertIsNone(result) def test_share_type_access_delete_exception(self): - arglist = [ - self.share_type.id, - 'invalid_project_format' - ] + arglist = [self.share_type.id, 'invalid_project_format'] verifylist = [ ('share_type', self.share_type.id), - ('project_id', 'invalid_project_format') + ('project_id', 'invalid_project_format'), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.type_access_mock.remove_project_access.side_effect = BadRequest() self.assertRaises( - exceptions.CommandError, self.cmd.take_action, parsed_args) + exceptions.CommandError, self.cmd.take_action, parsed_args + ) diff --git a/manilaclient/tests/unit/test_api_versions.py b/manilaclient/tests/unit/test_api_versions.py index c853171c..f71cfaa2 100644 --- a/manilaclient/tests/unit/test_api_versions.py +++ b/manilaclient/tests/unit/test_api_versions.py @@ -59,8 +59,9 @@ def test_null_version(self): "2.", ) def test_invalid_version_strings(self, version): - self.assertRaises(exceptions.UnsupportedVersion, - api_versions.APIVersion, version) + self.assertRaises( + exceptions.UnsupportedVersion, api_versions.APIVersion, version + ) def test_version_comparisons(self): v1 = api_versions.APIVersion("2.0") @@ -116,24 +117,17 @@ def test_get_string(self): v1 = api_versions.APIVersion(v1_string) self.assertEqual(v1_string, v1.get_string()) - self.assertRaises(ValueError, - api_versions.APIVersion().get_string) - - @ddt.data("2.0", - "2.5", - "2.45", - "3.3", - "3.23", - "2.0", - "3.3", - "4.0") + self.assertRaises(ValueError, api_versions.APIVersion().get_string) + + @ddt.data("2.0", "2.5", "2.45", "3.3", "3.23", "2.0", "3.3", "4.0") def test_representation(self, version): version_major, version_minor = version.split('.') api_version = api_versions.APIVersion(version) - self.assertEqual(str(api_version), - ("API Version Major: %s, Minor: %s" % - (version_major, version_minor))) - self.assertEqual(repr(api_version), "" % version) + self.assertEqual( + str(api_version), + (f"API Version Major: {version_major}, Minor: {version_minor}"), + ) + self.assertEqual(repr(api_version), f"") def test_is_latest(self): v1 = api_versions.APIVersion("1.0") @@ -143,25 +137,28 @@ def test_is_latest(self): class GetAPIVersionTestCase(utils.TestCase): - def test_wrong_format(self): - self.assertRaises(exceptions.UnsupportedVersion, - api_versions.get_api_version, "something_wrong") + self.assertRaises( + exceptions.UnsupportedVersion, + api_versions.get_api_version, + "something_wrong", + ) def test_wrong_major_version(self): - self.assertRaises(exceptions.UnsupportedVersion, - api_versions.get_api_version, "1") + self.assertRaises( + exceptions.UnsupportedVersion, api_versions.get_api_version, "1" + ) @mock.patch("manilaclient.api_versions.APIVersion") def test_major_and_minor_parts_is_presented(self, mock_apiversion): version = "2.7" - self.assertEqual(mock_apiversion.return_value, - api_versions.get_api_version(version)) + self.assertEqual( + mock_apiversion.return_value, api_versions.get_api_version(version) + ) mock_apiversion.assert_called_once_with(version) class WrapsTestCase(utils.TestCase): - def _get_obj_with_vers(self, vers): return mock.MagicMock(api_version=api_versions.APIVersion(vers)) @@ -184,13 +181,17 @@ def foo(*args, **kwargs): foo(self._get_obj_with_vers('2.4')) mock_versioned_method.assert_called_once_with( - func_name, api_versions.APIVersion('2.2'), - api_versions.APIVersion(api_versions.MAX_VERSION), mock.ANY) + func_name, + api_versions.APIVersion('2.2'), + api_versions.APIVersion(api_versions.MAX_VERSION), + mock.ANY, + ) @mock.patch("manilaclient.utils.get_function_name") @mock.patch("manilaclient.api_versions.VersionedMethod") - def test_start_and_end_version_are_presented(self, mock_versioned_method, - mock_name): + def test_start_and_end_version_are_presented( + self, mock_versioned_method, mock_name + ): func_name = "foo" mock_name.return_value = func_name mock_versioned_method.side_effect = self._side_effect_of_vers_method @@ -202,8 +203,11 @@ def foo(*args, **kwargs): foo(self._get_obj_with_vers("2.4")) mock_versioned_method.assert_called_once_with( - func_name, api_versions.APIVersion("2.2"), - api_versions.APIVersion("2.6"), mock.ANY) + func_name, + api_versions.APIVersion("2.2"), + api_versions.APIVersion("2.6"), + mock.ANY, + ) @mock.patch("manilaclient.utils.get_function_name") @mock.patch("manilaclient.api_versions.VersionedMethod") @@ -216,12 +220,16 @@ def test_api_version_doesnt_match(self, mock_versioned_method, mock_name): def foo(*args, **kwargs): pass - self.assertRaises(exceptions.UnsupportedVersion, - foo, self._get_obj_with_vers("2.1")) + self.assertRaises( + exceptions.UnsupportedVersion, foo, self._get_obj_with_vers("2.1") + ) mock_versioned_method.assert_called_once_with( - func_name, api_versions.APIVersion("2.2"), - api_versions.APIVersion("2.6"), mock.ANY) + func_name, + api_versions.APIVersion("2.2"), + api_versions.APIVersion("2.6"), + mock.ANY, + ) def test_define_method_is_actually_called(self): checker = mock.MagicMock() @@ -239,7 +247,6 @@ def some_func(*args, **kwargs): checker.assert_called_once_with(*((obj,) + some_args), **some_kwargs) def test_cli_args_are_copied(self): - @api_versions.wraps("2.2", "2.6") @cliutils.arg("name_1", help="Name of the something") @cliutils.arg("action_1", help="Some action") @@ -252,18 +259,22 @@ def some_func_1(cs, args): def some_func_2(cs, args): pass - args_1 = [(('name_1',), {'help': 'Name of the something'}), - (('action_1',), {'help': 'Some action'})] + args_1 = [ + (('name_1',), {'help': 'Name of the something'}), + (('action_1',), {'help': 'Some action'}), + ] self.assertEqual(args_1, some_func_1.arguments) - args_2 = [(('name_2',), {'help': 'Name of the something'}), - (('action_2',), {'help': 'Some action'})] + args_2 = [ + (('name_2',), {'help': 'Name of the something'}), + (('action_2',), {'help': 'Some action'}), + ] self.assertEqual(args_2, some_func_2.arguments) class DiscoverVersionTestCase(utils.TestCase): def setUp(self): - super(DiscoverVersionTestCase, self).setUp() + super().setUp() self.orig_max = manilaclient.API_MAX_VERSION self.orig_min = manilaclient.API_MIN_VERSION self.addCleanup(self._clear_fake_version) @@ -273,11 +284,14 @@ def _clear_fake_version(self): manilaclient.API_MAX_VERSION = self.orig_max manilaclient.API_MIN_VERSION = self.orig_min - def _mock_returned_server_version(self, server_version, - server_min_version): - version_mock = mock.MagicMock(version=server_version, - min_version=server_min_version, - status='CURRENT') + def _mock_returned_server_version( + self, server_version, server_min_version + ): + version_mock = mock.MagicMock( + version=server_version, + min_version=server_min_version, + status='CURRENT', + ) val = [version_mock] self.fake_client.services.server_api_version.return_value = val @@ -286,11 +300,13 @@ def test_server_is_too_new(self): manilaclient.API_MAX_VERSION = api_versions.APIVersion("2.3") manilaclient.API_MIN_VERSION = api_versions.APIVersion("2.1") - self.assertRaisesRegex(exceptions.UnsupportedVersion, - ".*range is '2.4' to '2.7'.*", - api_versions.discover_version, - self.fake_client, - api_versions.APIVersion("2.3")) + self.assertRaisesRegex( + exceptions.UnsupportedVersion, + ".*range is '2.4' to '2.7'.*", + api_versions.discover_version, + self.fake_client, + api_versions.APIVersion("2.3"), + ) self.assertTrue(self.fake_client.services.server_api_version.called) def test_server_is_too_old(self): @@ -298,10 +314,12 @@ def test_server_is_too_old(self): manilaclient.API_MAX_VERSION = api_versions.APIVersion("2.10") manilaclient.API_MIN_VERSION = api_versions.APIVersion("2.9") - self.assertRaises(exceptions.UnsupportedVersion, - api_versions.discover_version, - self.fake_client, - api_versions.APIVersion("2.10")) + self.assertRaises( + exceptions.UnsupportedVersion, + api_versions.discover_version, + self.fake_client, + api_versions.APIVersion("2.10"), + ) self.assertTrue(self.fake_client.services.server_api_version.called) def test_requested_version_is_less_than_server_max(self): @@ -329,8 +347,8 @@ def test_server_and_client_max_are_same(self): manilaclient.API_MIN_VERSION = api_versions.APIVersion("2.5") discovered_version = api_versions.discover_version( - self.fake_client, - manilaclient.API_MAX_VERSION) + self.fake_client, manilaclient.API_MAX_VERSION + ) self.assertEqual("2.5", discovered_version.get_string()) self.assertTrue(self.fake_client.services.server_api_version.called) @@ -339,8 +357,8 @@ def test_pre_microversion_server(self): manilaclient.API_MAX_VERSION = api_versions.APIVersion("2.5") manilaclient.API_MIN_VERSION = api_versions.APIVersion("2.5") discovered_version = api_versions.discover_version( - self.fake_client, - manilaclient.API_MAX_VERSION) + self.fake_client, manilaclient.API_MAX_VERSION + ) self.assertEqual("1.0", discovered_version.get_string()) self.assertTrue(self.fake_client.services.server_api_version.called) @@ -350,8 +368,8 @@ def test_requested_version_in_range(self): manilaclient.API_MIN_VERSION = api_versions.APIVersion("2.1") discovered_version = api_versions.discover_version( - self.fake_client, - api_versions.APIVersion('2.7')) + self.fake_client, api_versions.APIVersion('2.7') + ) self.assertEqual('2.7', discovered_version.get_string()) self.assertTrue(self.fake_client.services.server_api_version.called) @@ -361,10 +379,11 @@ def test_server_without_microversion(self): manilaclient.API_MIN_VERSION = api_versions.APIVersion("2.1") discovered_version = api_versions.discover_version( - self.fake_client, - api_versions.APIVersion('2.7')) - self.assertEqual(api_versions.DEPRECATED_VERSION, - discovered_version.get_string()) + self.fake_client, api_versions.APIVersion('2.7') + ) + self.assertEqual( + api_versions.DEPRECATED_VERSION, discovered_version.get_string() + ) self.assertTrue(self.fake_client.services.server_api_version.called) @@ -373,8 +392,10 @@ def test_requested_version_is_too_old(self): manilaclient.API_MAX_VERSION = api_versions.APIVersion("2.5") manilaclient.API_MIN_VERSION = api_versions.APIVersion("2.5") - self.assertRaisesRegex(exceptions.UnsupportedVersion, - ".*range is '2.0' to '2.5'.*", - api_versions.discover_version, - self.fake_client, - api_versions.APIVersion("1.0")) + self.assertRaisesRegex( + exceptions.UnsupportedVersion, + ".*range is '2.0' to '2.5'.*", + api_versions.discover_version, + self.fake_client, + api_versions.APIVersion("1.0"), + ) diff --git a/manilaclient/tests/unit/test_base.py b/manilaclient/tests/unit/test_base.py index bbb2ad9f..3158a7b7 100644 --- a/manilaclient/tests/unit/test_base.py +++ b/manilaclient/tests/unit/test_base.py @@ -23,7 +23,6 @@ class BaseTest(utils.TestCase): - def test_resource_repr(self): r = base.Resource(None, dict(foo="bar", baz="spam")) self.assertEqual(repr(r), "") @@ -59,12 +58,13 @@ def test_findall_invalid_attribute(self): cs.shares.findall(vegetable='carrot') # However, find() should raise an error - self.assertRaises(exceptions.NotFound, - cs.shares.find, - vegetable='carrot') + self.assertRaises( + exceptions.NotFound, cs.shares.find, vegetable='carrot' + ) def test_findall_with_all_tenants(self): cs.shares.list = mock.Mock(return_value=[]) cs.shares.findall() cs.shares.list.assert_called_with( - search_opts={'all_tenants': 1, 'is_soft_deleted': True}) + search_opts={'all_tenants': 1, 'is_soft_deleted': True} + ) diff --git a/manilaclient/tests/unit/test_client.py b/manilaclient/tests/unit/test_client.py index 9f5fbdac..9200c9db 100644 --- a/manilaclient/tests/unit/test_client.py +++ b/manilaclient/tests/unit/test_client.py @@ -24,14 +24,16 @@ @ddt.ddt class ClientTest(utils.TestCase): - def test_get_client_class_v2(self): output = manilaclient.client.get_client_class('2') self.assertEqual(output, manilaclient.v2.client.Client) def test_get_client_class_unknown(self): - self.assertRaises(manilaclient.exceptions.UnsupportedVersion, - manilaclient.client.get_client_class, '0') + self.assertRaises( + manilaclient.exceptions.UnsupportedVersion, + manilaclient.client.get_client_class, + '0', + ) @ddt.data('1', '1.0') def test_init_client_with_string_v1_version(self, version): @@ -43,7 +45,8 @@ def test_init_client_with_string_v1_version(self, version): manilaclient.client.Client(version, 'foo', bar='quuz') manilaclient.v1.client.Client.assert_called_once_with( - 'foo', api_version=api_instance, bar='quuz') + 'foo', api_version=api_instance, bar='quuz' + ) api_versions.APIVersion.assert_called_once_with('1.0') @ddt.data( @@ -61,17 +64,18 @@ def test_init_client_with_string_v2_version(self, provided, expected): manilaclient.client.Client(provided, 'foo', bar='quuz') manilaclient.v2.client.Client.assert_called_once_with( - 'foo', api_version=api_instance, bar='quuz') + 'foo', api_version=api_instance, bar='quuz' + ) api_versions.APIVersion.assert_called_once_with(expected) def test_init_client_with_api_version_instance(self): version = manilaclient.API_MAX_VERSION with mock.patch.object(manilaclient.v2.client, 'Client'): - manilaclient.client.Client(version, 'foo', bar='quuz') manilaclient.v2.client.Client.assert_called_once_with( - 'foo', api_version=version, bar='quuz') + 'foo', api_version=version, bar='quuz' + ) @ddt.data(None, '', '3', 'v1', 'v2', 'v1.0', 'v2.0') def test_init_client_with_unsupported_version(self, v): @@ -93,7 +97,6 @@ def test_init_client_with_unsupported_version(self, v): ) @ddt.unpack def test_init_client_with_version_parms(self, pos, kw): - major = int(float(pos)) pos_av = mock.Mock() kw_av = mock.Mock() @@ -114,21 +117,24 @@ def test_init_client_with_version_parms(self, pos, kw): if int(float(pos)) == 1: expected_client_ver = api_versions.DEPRECATED_VERSION self.assertFalse(manilaclient.v2.client.Client.called) - manilaclient.v1.client.Client.assert_has_calls([ - mock.call('foo', api_version=expected_av) - ]) + manilaclient.v1.client.Client.assert_has_calls( + [mock.call('foo', api_version=expected_av)] + ) else: expected_client_ver = api_versions.MIN_VERSION self.assertFalse(manilaclient.v1.client.Client.called) - manilaclient.v2.client.Client.assert_has_calls([ - mock.call('foo', api_version=expected_av) - ]) + manilaclient.v2.client.Client.assert_has_calls( + [mock.call('foo', api_version=expected_av)] + ) if kw is None: api_versions.APIVersion.assert_called_once_with( - expected_client_ver) + expected_client_ver + ) else: - api_versions.APIVersion.assert_has_calls([ - mock.call(expected_client_ver), - mock.call(kw), - ]) + api_versions.APIVersion.assert_has_calls( + [ + mock.call(expected_client_ver), + mock.call(kw), + ] + ) diff --git a/manilaclient/tests/unit/test_functional_utils.py b/manilaclient/tests/unit/test_functional_utils.py index c8d79432..3ba09b12 100644 --- a/manilaclient/tests/unit/test_functional_utils.py +++ b/manilaclient/tests/unit/test_functional_utils.py @@ -21,7 +21,6 @@ @ddt.ddt class ShellTest(utils.TestCase): - OUTPUT_LINES_SIMPLE = """ +----+------+---------+ | ID | Name | Status | @@ -113,28 +112,32 @@ class ShellTest(utils.TestCase): +----------+--------+ """ - @ddt.data({'input': OUTPUT_LINES_SIMPLE, - 'valid_values': [ - ['11', 'foo', 'BUILD'], - ['21', 'bar', 'ERROR'] - ]}, - {'input': OUTPUT_LINES_ONE_MULTI_ROW, - 'valid_values': [ - ['11', 'foo', 'BUILD'], - ['21', 'bar', ['ERROR', 'ERROR2']], - ['31', 'bee', 'None'], - ]}, - {'input': OUTPUT_LINES_COMPLICATED_MULTI_ROW, - 'valid_values': [ - ['11', 'foo', 'BUILD'], - ['21', 'bar', ['ERROR', 'ERROR2', 'ERROR3']], - ['31', ['bee', 'bee2', 'bee3'], 'None'], - ['41', ['rand', 'rend'], ['None', 'None2']], - ['', '', ''] - ]}) + @ddt.data( + { + 'input': OUTPUT_LINES_SIMPLE, + 'valid_values': [['11', 'foo', 'BUILD'], ['21', 'bar', 'ERROR']], + }, + { + 'input': OUTPUT_LINES_ONE_MULTI_ROW, + 'valid_values': [ + ['11', 'foo', 'BUILD'], + ['21', 'bar', ['ERROR', 'ERROR2']], + ['31', 'bee', 'None'], + ], + }, + { + 'input': OUTPUT_LINES_COMPLICATED_MULTI_ROW, + 'valid_values': [ + ['11', 'foo', 'BUILD'], + ['21', 'bar', ['ERROR', 'ERROR2', 'ERROR3']], + ['31', ['bee', 'bee2', 'bee3'], 'None'], + ['41', ['rand', 'rend'], ['None', 'None2']], + ['', '', ''], + ], + }, + ) @ddt.unpack def test_multi_line_row_table(self, input, valid_values): - actual_result = func_utils.multi_line_row_table(input) self.assertEqual(['ID', 'Name', 'Status'], actual_result['headers']) @@ -147,44 +150,54 @@ def test_multi_line_row_table_shifted_id_column(self): ['', '21', 'bar', ['ERROR', 'ERROR2', 'ERROR3']], ['', '', '', ''], ['**', '31', ['bee', 'bee2'], 'None'], - ['', '', '', ''] + ['', '', '', ''], ] actual_result = func_utils.multi_line_row_table( - input, group_by_column_index=1) + input, group_by_column_index=1 + ) - self.assertEqual(['**', 'ID', 'Name', 'Status'], - actual_result['headers']) + self.assertEqual( + ['**', 'ID', 'Name', 'Status'], actual_result['headers'] + ) self.assertEqual(valid_values, actual_result['values']) - @ddt.data({'input': OUTPUT_LINES_NESTED_TABLE, - 'valid_nested': { - 'headers': ['aa', 'bb'], - 'values': [] - }}, - {'input': OUTPUT_LINES_NESTED_TABLE_MULTI_LINE, - 'valid_nested': { - 'headers': ['id', 'bb'], - 'values': [['01', ['a1', 'a2']]] - }},) + @ddt.data( + { + 'input': OUTPUT_LINES_NESTED_TABLE, + 'valid_nested': {'headers': ['aa', 'bb'], 'values': []}, + }, + { + 'input': OUTPUT_LINES_NESTED_TABLE_MULTI_LINE, + 'valid_nested': { + 'headers': ['id', 'bb'], + 'values': [['01', ['a1', 'a2']]], + }, + }, + ) @ddt.unpack def test_nested_tables(self, input, valid_nested): - actual_result = func_utils.multi_line_row_table( - input, group_by_column_index=1) + input, group_by_column_index=1 + ) - self.assertEqual(['**', 'ID', 'Name', 'Status'], - actual_result['headers']) + self.assertEqual( + ['**', 'ID', 'Name', 'Status'], actual_result['headers'] + ) self.assertEqual(2, len(actual_result['values'])) self.assertEqual(valid_nested, actual_result['values'][0][3]) - @ddt.data({'input': OUTPUT_LINES_DETAILS, - 'valid_values': [ - ['foo', 'BUILD'], - ['bar', ['ERROR', 'ERROR2', 'ERROR3']], - ['bee', 'None'], - ]}) + @ddt.data( + { + 'input': OUTPUT_LINES_DETAILS, + 'valid_values': [ + ['foo', 'BUILD'], + ['bar', ['ERROR', 'ERROR2', 'ERROR3']], + ['bee', 'None'], + ], + } + ) @ddt.unpack def test_details(self, input, valid_values): actual_result = func_utils.multi_line_row_table(input) @@ -192,33 +205,53 @@ def test_details(self, input, valid_values): self.assertEqual(['Property', 'Value'], actual_result['headers']) self.assertEqual(valid_values, actual_result['values']) - @ddt.data({'input_data': OUTPUT_LINES_DETAILS, - 'output_data': [ - {'Property': 'foo', 'Value': 'BUILD'}, - {'Property': 'bar', 'Value': ['ERROR', 'ERROR2', 'ERROR3']}, - {'Property': 'bee', 'Value': 'None'}]}, - {'input_data': OUTPUT_LINES_SIMPLE, - 'output_data': [ - {'ID': '11', 'Name': 'foo', 'Status': 'BUILD'}, - {'ID': '21', 'Name': 'bar', 'Status': 'ERROR'}, - ]}, - {'input_data': OUTPUT_LINES_ONE_MULTI_ROW, - 'output_data': [ - {'ID': '11', 'Name': 'foo', 'Status': 'BUILD'}, - {'ID': '21', 'Name': 'bar', 'Status': ['ERROR', 'ERROR2']}, - {'ID': '31', 'Name': 'bee', 'Status': 'None'}, - ]}, - {'input_data': OUTPUT_LINES_COMPLICATED_MULTI_ROW, - 'output_data': [ - {'ID': '11', 'Name': 'foo', 'Status': 'BUILD'}, - {'ID': '21', 'Name': 'bar', - 'Status': ['ERROR', 'ERROR2', 'ERROR3']}, - {'ID': '31', 'Name': ['bee', 'bee2', 'bee3'], - 'Status': 'None'}, - {'ID': '41', 'Name': ['rand', 'rend'], - 'Status': ['None', 'None2']}, - {'ID': '', 'Name': '', 'Status': ''}, - ]}) + @ddt.data( + { + 'input_data': OUTPUT_LINES_DETAILS, + 'output_data': [ + {'Property': 'foo', 'Value': 'BUILD'}, + {'Property': 'bar', 'Value': ['ERROR', 'ERROR2', 'ERROR3']}, + {'Property': 'bee', 'Value': 'None'}, + ], + }, + { + 'input_data': OUTPUT_LINES_SIMPLE, + 'output_data': [ + {'ID': '11', 'Name': 'foo', 'Status': 'BUILD'}, + {'ID': '21', 'Name': 'bar', 'Status': 'ERROR'}, + ], + }, + { + 'input_data': OUTPUT_LINES_ONE_MULTI_ROW, + 'output_data': [ + {'ID': '11', 'Name': 'foo', 'Status': 'BUILD'}, + {'ID': '21', 'Name': 'bar', 'Status': ['ERROR', 'ERROR2']}, + {'ID': '31', 'Name': 'bee', 'Status': 'None'}, + ], + }, + { + 'input_data': OUTPUT_LINES_COMPLICATED_MULTI_ROW, + 'output_data': [ + {'ID': '11', 'Name': 'foo', 'Status': 'BUILD'}, + { + 'ID': '21', + 'Name': 'bar', + 'Status': ['ERROR', 'ERROR2', 'ERROR3'], + }, + { + 'ID': '31', + 'Name': ['bee', 'bee2', 'bee3'], + 'Status': 'None', + }, + { + 'ID': '41', + 'Name': ['rand', 'rend'], + 'Status': ['None', 'None2'], + }, + {'ID': '', 'Name': '', 'Status': ''}, + ], + }, + ) @ddt.unpack def test_listing(self, input_data, output_data): actual_result = func_utils.listing(input_data) diff --git a/manilaclient/tests/unit/test_shell.py b/manilaclient/tests/unit/test_shell.py index 9ac524c0..478ffd85 100644 --- a/manilaclient/tests/unit/test_shell.py +++ b/manilaclient/tests/unit/test_shell.py @@ -31,7 +31,6 @@ @ddt.ddt class OpenstackManilaShellTest(utils.TestCase): - FAKE_ENV = { 'OS_USERNAME': 'username', 'OS_PASSWORD': 'password', @@ -44,12 +43,14 @@ def set_env_vars(self, env_vars): for k, v in env_vars.items(): self.useFixture(fixtures.EnvironmentVariable(k, v)) - def shell_discover_client(self, - current_client, - os_api_version, - os_endpoint_type, - os_service_type, - client_args): + def shell_discover_client( + self, + current_client, + os_api_version, + os_endpoint_type, + os_service_type, + client_args, + ): return current_client, manilaclient.API_MAX_VERSION def shell(self, argstr): @@ -73,10 +74,16 @@ def shell(self, argstr): {}, {'OS_AUTH_URL': 'http://foo.bar'}, {'OS_AUTH_URL': 'http://foo.bar', 'OS_USERNAME': 'foo'}, - {'OS_AUTH_URL': 'http://foo.bar', 'OS_USERNAME': 'foo_user', - 'OS_PASSWORD': 'foo_password'}, - {'OS_TENANT_NAME': 'foo_tenant', 'OS_USERNAME': 'foo_user', - 'OS_PASSWORD': 'foo_password'}, + { + 'OS_AUTH_URL': 'http://foo.bar', + 'OS_USERNAME': 'foo_user', + 'OS_PASSWORD': 'foo_password', + }, + { + 'OS_TENANT_NAME': 'foo_tenant', + 'OS_USERNAME': 'foo_user', + 'OS_PASSWORD': 'foo_password', + }, {'OS_TOKEN': 'foo_token'}, {'OS_MANILA_BYPASS_URL': 'http://foo.foo'}, ) @@ -99,7 +106,6 @@ def test_main_success(self, os_key): 'OS_PROJECT_ID': 'foo_project_id', 'OS_PROJECT_DOMAIN_ID': 'foo_project_domain_id', 'OS_PROJECT_DOMAIN_NAME': 'foo_project_domain_name', - 'OS_PROJECT_DOMAIN_ID': 'foo_project_domain_id', 'OS_USER_DOMAIN_NAME': 'foo_user_domain_name', 'OS_USER_DOMAIN_ID': 'foo_user_domain_id', 'OS_CERT': 'foo_cert', @@ -111,7 +117,6 @@ def test_main_success(self, os_key): cert = (cert, env_vars['OS_KEY']) with mock.patch.object(shell, 'client') as mock_client: - self.shell('list') mock_client.Client.assert_called_with( @@ -143,37 +148,73 @@ def test_main_success(self, os_key): ) @ddt.data( - {"env_vars": {"OS_MANILA_BYPASS_URL": "http://foo.url", - "OS_TOKEN": "foo_token"}, - "kwargs": {"--os-token": "bar_token", - "--bypass-url": "http://bar.url"}, - "expected": {"input_auth_token": "bar_token", - "service_catalog_url": "http://bar.url"}}, - {"env_vars": {"OS_MANILA_BYPASS_URL": "http://foo.url", - "OS_TOKEN": "foo_token"}, - "kwargs": {}, - "expected": {"input_auth_token": "foo_token", - "service_catalog_url": "http://foo.url"}}, - {"env_vars": {}, - "kwargs": {"--os-token": "bar_token", - "--bypass-url": "http://bar.url"}, - "expected": {"input_auth_token": "bar_token", - "service_catalog_url": "http://bar.url"}}, - {"env_vars": {"MANILACLIENT_BYPASS_URL": "http://foo.url", - "OS_TOKEN": "foo_token"}, - "kwargs": {}, - "expected": {"input_auth_token": "foo_token", - "service_catalog_url": "http://foo.url"}}, - {"env_vars": {"OS_TOKEN": "foo_token"}, - "kwargs": {"--bypass-url": "http://bar.url"}, - "expected": {"input_auth_token": "foo_token", - "service_catalog_url": "http://bar.url"}}, - {"env_vars": {"MANILACLIENT_BYPASS_URL": "http://foo.url", - "OS_MANILA_BYPASS_URL": "http://bar.url", - "OS_TOKEN": "foo_token"}, - "kwargs": {"--os-token": "bar_token"}, - "expected": {"input_auth_token": "bar_token", - "service_catalog_url": "http://bar.url"}}, + { + "env_vars": { + "OS_MANILA_BYPASS_URL": "http://foo.url", + "OS_TOKEN": "foo_token", + }, + "kwargs": { + "--os-token": "bar_token", + "--bypass-url": "http://bar.url", + }, + "expected": { + "input_auth_token": "bar_token", + "service_catalog_url": "http://bar.url", + }, + }, + { + "env_vars": { + "OS_MANILA_BYPASS_URL": "http://foo.url", + "OS_TOKEN": "foo_token", + }, + "kwargs": {}, + "expected": { + "input_auth_token": "foo_token", + "service_catalog_url": "http://foo.url", + }, + }, + { + "env_vars": {}, + "kwargs": { + "--os-token": "bar_token", + "--bypass-url": "http://bar.url", + }, + "expected": { + "input_auth_token": "bar_token", + "service_catalog_url": "http://bar.url", + }, + }, + { + "env_vars": { + "MANILACLIENT_BYPASS_URL": "http://foo.url", + "OS_TOKEN": "foo_token", + }, + "kwargs": {}, + "expected": { + "input_auth_token": "foo_token", + "service_catalog_url": "http://foo.url", + }, + }, + { + "env_vars": {"OS_TOKEN": "foo_token"}, + "kwargs": {"--bypass-url": "http://bar.url"}, + "expected": { + "input_auth_token": "foo_token", + "service_catalog_url": "http://bar.url", + }, + }, + { + "env_vars": { + "MANILACLIENT_BYPASS_URL": "http://foo.url", + "OS_MANILA_BYPASS_URL": "http://bar.url", + "OS_TOKEN": "foo_token", + }, + "kwargs": {"--os-token": "bar_token"}, + "expected": { + "input_auth_token": "bar_token", + "service_catalog_url": "http://bar.url", + }, + }, ) @ddt.unpack def test_main_success_with_token(self, env_vars, kwargs, expected): @@ -181,7 +222,7 @@ def test_main_success_with_token(self, env_vars, kwargs, expected): with mock.patch.object(shell, "client") as mock_client: cmd = "" for k, v in kwargs.items(): - cmd += "%s=%s " % (k, v) + cmd += f"{k}={v} " cmd += "list" self.shell(cmd) @@ -217,42 +258,58 @@ def test_main_success_with_token(self, env_vars, kwargs, expected): @ddt.data( # default without any env var or kwargs { - "env_vars": {"OS_TOKEN": "foo_token", - "OS_MANILA_BYPASS_URL": "http://bar.url"}, + "env_vars": { + "OS_TOKEN": "foo_token", + "OS_MANILA_BYPASS_URL": "http://bar.url", + }, "kwargs": {}, - "expected": {"input_auth_token": "foo_token", - "service_catalog_url": "http://bar.url", - "os_endpoint_type": "publicURL"} + "expected": { + "input_auth_token": "foo_token", + "service_catalog_url": "http://bar.url", + "os_endpoint_type": "publicURL", + }, }, # only env var { - "env_vars": {"OS_TOKEN": "foo_token", - "OS_MANILA_BYPASS_URL": "http://bar.url", - "OS_MANILA_ENDPOINT_TYPE": "custom-endpoint-type"}, + "env_vars": { + "OS_TOKEN": "foo_token", + "OS_MANILA_BYPASS_URL": "http://bar.url", + "OS_MANILA_ENDPOINT_TYPE": "custom-endpoint-type", + }, "kwargs": {}, - "expected": {"input_auth_token": "foo_token", - "service_catalog_url": "http://bar.url", - "os_endpoint_type": "custom-endpoint-type"}, + "expected": { + "input_auth_token": "foo_token", + "service_catalog_url": "http://bar.url", + "os_endpoint_type": "custom-endpoint-type", + }, }, # only kwargs { - "env_vars": {"OS_TOKEN": "foo_token", - "OS_MANILA_BYPASS_URL": "http://bar.url"}, + "env_vars": { + "OS_TOKEN": "foo_token", + "OS_MANILA_BYPASS_URL": "http://bar.url", + }, "kwargs": {"--endpoint-type": "custom-kwargs-endpoint-type"}, - "expected": {"input_auth_token": "foo_token", - "service_catalog_url": "http://bar.url", - "os_endpoint_type": "custom-kwargs-endpoint-type"}, + "expected": { + "input_auth_token": "foo_token", + "service_catalog_url": "http://bar.url", + "os_endpoint_type": "custom-kwargs-endpoint-type", + }, }, # env var *and* kwargs (kwargs should win) { - "env_vars": {"OS_TOKEN": "foo_token", - "OS_MANILA_BYPASS_URL": "http://bar.url", - "os_endpoint_type": "custom-env-endpoint-type"}, + "env_vars": { + "OS_TOKEN": "foo_token", + "OS_MANILA_BYPASS_URL": "http://bar.url", + "os_endpoint_type": "custom-env-endpoint-type", + }, "kwargs": {"--endpoint-type": "custom-kwargs-endpoint-type"}, - "expected": {"input_auth_token": "foo_token", - "service_catalog_url": "http://bar.url", - "os_endpoint_type": "custom-kwargs-endpoint-type"}, - } + "expected": { + "input_auth_token": "foo_token", + "service_catalog_url": "http://bar.url", + "os_endpoint_type": "custom-kwargs-endpoint-type", + }, + }, ) @ddt.unpack def test_main_success_with_os_endpoint(self, env_vars, kwargs, expected): @@ -260,7 +317,7 @@ def test_main_success_with_os_endpoint(self, env_vars, kwargs, expected): with mock.patch.object(shell, "client") as mock_client: cmd = "" for k, v in kwargs.items(): - cmd += "%s=%s " % (k, v) + cmd += f"{k}={v} " cmd += "list" self.shell(cmd) @@ -304,19 +361,38 @@ def test_help_on_subcommand(self, cmd): ] help_text = self.shell(cmd) for r in required: - self.assertThat(help_text, - matchers.MatchesRegex(r, re.DOTALL | re.MULTILINE)) + self.assertThat( + help_text, matchers.MatchesRegex(r, re.DOTALL | re.MULTILINE) + ) def test_common_args_in_help_message(self): expected_args = ( - '--version', '', '--debug', '--os-cache', '--os-reset-cache', - '--os-user-id', '--os-username', '--os-password', - '--os-tenant-name', '--os-project-name', '--os-tenant-id', - '--os-project-id', '--os-user-domain-id', '--os-user-domain-name', - '--os-project-domain-id', '--os-project-domain-name', - '--os-auth-url', '--os-region-name', '--service-type', - '--service-name', '--share-service-name', '--endpoint-type', - '--os-share-api-version', '--os-cacert', '--retries', '--os-cert', + '--version', + '', + '--debug', + '--os-cache', + '--os-reset-cache', + '--os-user-id', + '--os-username', + '--os-password', + '--os-tenant-name', + '--os-project-name', + '--os-tenant-id', + '--os-project-id', + '--os-user-domain-id', + '--os-user-domain-name', + '--os-project-domain-id', + '--os-project-domain-name', + '--os-auth-url', + '--os-region-name', + '--service-type', + '--service-name', + '--share-service-name', + '--endpoint-type', + '--os-share-api-version', + '--os-cacert', + '--retries', + '--os-cert', '--os-key', ) @@ -327,7 +403,6 @@ def test_common_args_in_help_message(self): class CustomOpenStackManilaShell(shell.OpenStackManilaShell): - @staticmethod @cliutils.arg( '--default-is-none', @@ -336,7 +411,8 @@ class CustomOpenStackManilaShell(shell.OpenStackManilaShell): metavar='', action='single_alias', help='Default value is None and metavar set.', - default=None) + default=None, + ) def do_foo(cs, args): cliutils.print_dict({'key': args.default_is_none}) @@ -347,7 +423,8 @@ def do_foo(cs, args): type=str, action='single_alias', help='Default value is not None and metavar not set.', - default='bar') + default='bar', + ) def do_bar(cs, args): cliutils.print_dict({'key': args.default_is_not_none}) @@ -358,7 +435,8 @@ def do_bar(cs, args): nargs='*', action='single_alias', help='Default value is None, metavar not set and result is list.', - default=None) + default=None, + ) def do_quuz(cs, args): cliutils.print_dict({'key': args.list_like}) @@ -377,15 +455,19 @@ def setUp(self): for k, v in self.FAKE_ENV.items(): self.useFixture(fixtures.EnvironmentVariable(k, v)) self.mock_object( - shell.client, 'get_client_class', - mock.Mock(return_value=fakes.FakeClient)) - - def shell_discover_client(self, - current_client, - os_api_version, - os_endpoint_type, - os_service_type, - client_args): + shell.client, + 'get_client_class', + mock.Mock(return_value=fakes.FakeClient), + ) + + def shell_discover_client( + self, + current_client, + os_api_version, + os_endpoint_type, + os_service_type, + client_args, + ): return current_client, manilaclient.API_MAX_VERSION def shell(self, argstr): @@ -413,7 +495,7 @@ def shell(self, argstr): ) @ddt.unpack def test_foo_success(self, options_str, expected_result): - output = self.shell('foo %s' % options_str) + output = self.shell(f'foo {options_str}') parsed_output = output_parser.details(output) self.assertEqual({'key': expected_result}, parsed_output) @@ -424,7 +506,8 @@ def test_foo_success(self, options_str, expected_result): ) def test_foo_error(self, options_str): self.assertRaises( - matchers.MismatchError, self.shell, 'foo %s' % options_str) + matchers.MismatchError, self.shell, f'foo {options_str}' + ) @ddt.data( ('--default-is-not-none bar', 'bar'), @@ -435,7 +518,7 @@ def test_foo_error(self, options_str): ) @ddt.unpack def test_bar_success(self, options_str, expected_result): - output = self.shell('bar %s' % options_str) + output = self.shell(f'bar {options_str}') parsed_output = output_parser.details(output) self.assertEqual({'key': expected_result}, parsed_output) @@ -446,18 +529,21 @@ def test_bar_success(self, options_str, expected_result): ) def test_bar_error(self, options_str): self.assertRaises( - matchers.MismatchError, self.shell, 'bar %s' % options_str) + matchers.MismatchError, self.shell, f'bar {options_str}' + ) @ddt.data( ('--list-like q=w', "['q=w']"), ('--list-like q=w --list_like q=w', "['q=w']"), - ('--list-like q=w e=r t=y --list_like e=r t=y q=w', - "['e=r', 'q=w', 't=y']"), + ( + '--list-like q=w e=r t=y --list_like e=r t=y q=w', + "['e=r', 'q=w', 't=y']", + ), ('--list_like q=w e=r t=y', "['e=r', 'q=w', 't=y']"), ) @ddt.unpack def test_quuz_success(self, options_str, expected_result): - output = self.shell('quuz %s' % options_str) + output = self.shell(f'quuz {options_str}') parsed_output = output_parser.details(output) self.assertEqual({'key': expected_result}, parsed_output) @@ -466,4 +552,5 @@ def test_quuz_success(self, options_str, expected_result): ) def test_quuz_error(self, options_str): self.assertRaises( - matchers.MismatchError, self.shell, 'quuz %s' % options_str) + matchers.MismatchError, self.shell, f'quuz {options_str}' + ) diff --git a/manilaclient/tests/unit/utils.py b/manilaclient/tests/unit/utils.py index 0b642d43..f2f582bb 100644 --- a/manilaclient/tests/unit/utils.py +++ b/manilaclient/tests/unit/utils.py @@ -24,13 +24,17 @@ class TestCase(testtools.TestCase): } def setUp(self): - super(TestCase, self).setUp() - if (os.environ.get('OS_STDOUT_CAPTURE') == 'True' or - os.environ.get('OS_STDOUT_CAPTURE') == '1'): + super().setUp() + if ( + os.environ.get('OS_STDOUT_CAPTURE') == 'True' + or os.environ.get('OS_STDOUT_CAPTURE') == '1' + ): stdout = self.useFixture(fixtures.StringStream('stdout')).stream self.useFixture(fixtures.MonkeyPatch('sys.stdout', stdout)) - if (os.environ.get('OS_STDERR_CAPTURE') == 'True' or - os.environ.get('OS_STDERR_CAPTURE') == '1'): + if ( + os.environ.get('OS_STDERR_CAPTURE') == 'True' + or os.environ.get('OS_STDERR_CAPTURE') == '1' + ): stderr = self.useFixture(fixtures.StringStream('stderr')).stream self.useFixture(fixtures.MonkeyPatch('sys.stderr', stderr)) @@ -50,7 +54,8 @@ def mock_object(self, obj, attr_name, new_attr=None, **kwargs): def mock_completion(self): patcher = mock.patch( - 'manilaclient.base.Manager.write_to_completion_cache') + 'manilaclient.base.Manager.write_to_completion_cache' + ) patcher.start() self.addCleanup(patcher.stop) @@ -68,12 +73,13 @@ class TestResponse(requests.Response): def __init__(self, data): self._text = None - super(TestResponse, self) + super() if isinstance(data, dict): self.status_code = data.get('status_code', None) self.headers = data.get('headers', {}) self.headers['x-openstack-request-id'] = data.get( - 'x-openstack-request-id', 'fake-request-id') + 'x-openstack-request-id', 'fake-request-id' + ) # Fake the text attribute to streamline Response creation self._text = data.get('text', None) else: diff --git a/manilaclient/tests/unit/v1/test_limits.py b/manilaclient/tests/unit/v1/test_limits.py index 1ef77059..8140d11c 100644 --- a/manilaclient/tests/unit/v1/test_limits.py +++ b/manilaclient/tests/unit/v1/test_limits.py @@ -17,14 +17,15 @@ class LimitsV1Test(utils.TestCase): - def test_import_v1_limits_module(self): try: from manilaclient.v1 import limits except Exception as e: - msg = ("module 'manilaclient.v1.limits' cannot be imported " - "with error: %s") % str(e) + msg = ( + "module 'manilaclient.v1.limits' cannot be imported " + f"with error: {str(e)}" + ) assert False, msg for cls in ('Limits', 'RateLimit', 'AbsoluteLimit', 'LimitsManager'): - msg = "Module 'limits' has no '%s' attr." % cls + msg = f"Module 'limits' has no '{cls}' attr." self.assertTrue(hasattr(limits, cls), msg) diff --git a/manilaclient/tests/unit/v1/test_quota_classes.py b/manilaclient/tests/unit/v1/test_quota_classes.py index 498ddfb5..637675b4 100644 --- a/manilaclient/tests/unit/v1/test_quota_classes.py +++ b/manilaclient/tests/unit/v1/test_quota_classes.py @@ -17,14 +17,15 @@ class QuotaClassesV1Test(utils.TestCase): - def test_import_v1_quota_classes_module(self): try: from manilaclient.v1 import quota_classes except Exception as e: - msg = ("module 'manilaclient.v1.quota_classes' cannot be imported " - "with error: %s") % str(e) + msg = ( + "module 'manilaclient.v1.quota_classes' cannot be imported " + f"with error: {str(e)}" + ) assert False, msg for cls in ('QuotaClassSet', 'QuotaClassSetManager'): - msg = "Module 'quota_classes' has no '%s' attr." % cls + msg = f"Module 'quota_classes' has no '{cls}' attr." self.assertTrue(hasattr(quota_classes, cls), msg) diff --git a/manilaclient/tests/unit/v1/test_quotas.py b/manilaclient/tests/unit/v1/test_quotas.py index cb2058ce..1c2a299c 100644 --- a/manilaclient/tests/unit/v1/test_quotas.py +++ b/manilaclient/tests/unit/v1/test_quotas.py @@ -17,14 +17,15 @@ class QuotasV1Test(utils.TestCase): - def test_import_v1_quotas_module(self): try: from manilaclient.v1 import quotas except Exception as e: - msg = ("module 'manilaclient.v1.quotas' cannot be imported " - "with error: %s") % str(e) + msg = ( + "module 'manilaclient.v1.quotas' cannot be imported " + f"with error: {str(e)}" + ) assert False, msg for cls in ('QuotaSet', 'QuotaSetManager'): - msg = "Module 'quotas' has no '%s' attr." % cls + msg = f"Module 'quotas' has no '{cls}' attr." self.assertTrue(hasattr(quotas, cls), msg) diff --git a/manilaclient/tests/unit/v1/test_scheduler_stats.py b/manilaclient/tests/unit/v1/test_scheduler_stats.py index 777f1e59..8c863e1a 100644 --- a/manilaclient/tests/unit/v1/test_scheduler_stats.py +++ b/manilaclient/tests/unit/v1/test_scheduler_stats.py @@ -17,14 +17,15 @@ class SchedulerStatsV1Test(utils.TestCase): - def test_import_v1_scheduler_stats_module(self): try: from manilaclient.v1 import scheduler_stats except Exception as e: - msg = ("module 'manilaclient.v1.scheduler_stats' cannot be " - "imported with error: %s") % str(e) + msg = ( + "module 'manilaclient.v1.scheduler_stats' cannot be " + f"imported with error: {str(e)}" + ) assert False, msg for cls in ('Pool', 'PoolManager'): - msg = "Module 'scheduler_stats' has no '%s' attr." % cls + msg = f"Module 'scheduler_stats' has no '{cls}' attr." self.assertTrue(hasattr(scheduler_stats, cls), msg) diff --git a/manilaclient/tests/unit/v1/test_security_services.py b/manilaclient/tests/unit/v1/test_security_services.py index 49d9013d..a90862a6 100644 --- a/manilaclient/tests/unit/v1/test_security_services.py +++ b/manilaclient/tests/unit/v1/test_security_services.py @@ -17,14 +17,15 @@ class SecurityServicesV1Test(utils.TestCase): - def test_import_v1_security_services_module(self): try: from manilaclient.v1 import security_services except Exception as e: - msg = ("module 'manilaclient.v1.security_services' cannot be " - "imported with error: %s") % str(e) + msg = ( + "module 'manilaclient.v1.security_services' cannot be " + f"imported with error: {str(e)}" + ) assert False, msg for cls in ('SecurityService', 'SecurityServiceManager'): - msg = "Module 'security_services' has no '%s' attr." % cls + msg = f"Module 'security_services' has no '{cls}' attr." self.assertTrue(hasattr(security_services, cls), msg) diff --git a/manilaclient/tests/unit/v1/test_services.py b/manilaclient/tests/unit/v1/test_services.py index 81edd710..66910644 100644 --- a/manilaclient/tests/unit/v1/test_services.py +++ b/manilaclient/tests/unit/v1/test_services.py @@ -17,14 +17,15 @@ class ServicesV1Test(utils.TestCase): - def test_import_v1_services_module(self): try: from manilaclient.v1 import services except Exception as e: - msg = ("module 'manilaclient.v1.services' cannot be imported " - "with error: %s") % str(e) + msg = ( + "module 'manilaclient.v1.services' cannot be imported " + f"with error: {str(e)}" + ) assert False, msg for cls in ('Service', 'ServiceManager'): - msg = "Module 'services' has no '%s' attr." % cls + msg = f"Module 'services' has no '{cls}' attr." self.assertTrue(hasattr(services, cls), msg) diff --git a/manilaclient/tests/unit/v1/test_share_networks.py b/manilaclient/tests/unit/v1/test_share_networks.py index 7191e51b..5aef7d34 100644 --- a/manilaclient/tests/unit/v1/test_share_networks.py +++ b/manilaclient/tests/unit/v1/test_share_networks.py @@ -17,14 +17,15 @@ class ShareNetworksV1Test(utils.TestCase): - def test_import_v1_share_networks_module(self): try: from manilaclient.v1 import share_networks except Exception as e: - msg = ("module 'manilaclient.v1.share_networks' cannot be " - "imported with error: %s") % str(e) + msg = ( + "module 'manilaclient.v1.share_networks' cannot be " + f"imported with error: {str(e)}" + ) assert False, msg for cls in ('ShareNetwork', 'ShareNetworkManager'): - msg = "Module 'share_networks' has no '%s' attr." % cls + msg = f"Module 'share_networks' has no '{cls}' attr." self.assertTrue(hasattr(share_networks, cls), msg) diff --git a/manilaclient/tests/unit/v1/test_share_servers.py b/manilaclient/tests/unit/v1/test_share_servers.py index 0416032b..42e8c25f 100644 --- a/manilaclient/tests/unit/v1/test_share_servers.py +++ b/manilaclient/tests/unit/v1/test_share_servers.py @@ -17,14 +17,15 @@ class ShareServersV1Test(utils.TestCase): - def test_import_v1_share_servers_module(self): try: from manilaclient.v1 import share_servers except Exception as e: - msg = ("module 'manilaclient.v1.share_servers' cannot be imported " - "with error: %s") % str(e) + msg = ( + "module 'manilaclient.v1.share_servers' cannot be imported " + f"with error: {str(e)}" + ) assert False, msg for cls in ('ShareServer', 'ShareServerManager'): - msg = "Module 'share_servers' has no '%s' attr." % cls + msg = f"Module 'share_servers' has no '{cls}' attr." self.assertTrue(hasattr(share_servers, cls), msg) diff --git a/manilaclient/tests/unit/v1/test_share_snapshots.py b/manilaclient/tests/unit/v1/test_share_snapshots.py index 6205a6f3..2cfb5a3a 100644 --- a/manilaclient/tests/unit/v1/test_share_snapshots.py +++ b/manilaclient/tests/unit/v1/test_share_snapshots.py @@ -17,14 +17,15 @@ class ShareSnapshotsV1Test(utils.TestCase): - def test_import_v1_share_snapshots_module(self): try: from manilaclient.v1 import share_snapshots except Exception as e: - msg = ("module 'manilaclient.v1.share_snapshots' cannot be " - "imported with error: %s") % str(e) + msg = ( + "module 'manilaclient.v1.share_snapshots' cannot be " + f"imported with error: {str(e)}" + ) assert False, msg for cls in ('ShareSnapshot', 'ShareSnapshotManager'): - msg = "Module 'share_snapshots' has no '%s' attr." % cls + msg = f"Module 'share_snapshots' has no '{cls}' attr." self.assertTrue(hasattr(share_snapshots, cls), msg) diff --git a/manilaclient/tests/unit/v1/test_share_type_access.py b/manilaclient/tests/unit/v1/test_share_type_access.py index 839ec002..f2f8d504 100644 --- a/manilaclient/tests/unit/v1/test_share_type_access.py +++ b/manilaclient/tests/unit/v1/test_share_type_access.py @@ -17,14 +17,15 @@ class ShareTypeAccessV1Test(utils.TestCase): - def test_import_v1_share_type_access_module(self): try: from manilaclient.v1 import share_type_access except Exception as e: - msg = ("module 'manilaclient.v1.share_type_access' cannot be " - "imported with error: %s") % str(e) + msg = ( + "module 'manilaclient.v1.share_type_access' cannot be " + f"imported with error: {str(e)}" + ) assert False, msg for cls in ('ShareTypeAccess', 'ShareTypeAccessManager'): - msg = "Module 'share_type_access' has no '%s' attr." % cls + msg = f"Module 'share_type_access' has no '{cls}' attr." self.assertTrue(hasattr(share_type_access, cls), msg) diff --git a/manilaclient/tests/unit/v1/test_share_types.py b/manilaclient/tests/unit/v1/test_share_types.py index b55e530d..ac38ab83 100644 --- a/manilaclient/tests/unit/v1/test_share_types.py +++ b/manilaclient/tests/unit/v1/test_share_types.py @@ -17,14 +17,15 @@ class ShareTypesV1Test(utils.TestCase): - def test_import_v1_share_types_module(self): try: from manilaclient.v1 import share_types except Exception as e: - msg = ("module 'manilaclient.v1.share_types' cannot be imported " - "with error: %s") % str(e) + msg = ( + "module 'manilaclient.v1.share_types' cannot be imported " + f"with error: {str(e)}" + ) assert False, msg for cls in ('ShareType', 'ShareTypeManager'): - msg = "Module 'share_types' has no '%s' attr." % cls + msg = f"Module 'share_types' has no '{cls}' attr." self.assertTrue(hasattr(share_types, cls), msg) diff --git a/manilaclient/tests/unit/v1/test_shares.py b/manilaclient/tests/unit/v1/test_shares.py index 0e2a3c13..376462ae 100644 --- a/manilaclient/tests/unit/v1/test_shares.py +++ b/manilaclient/tests/unit/v1/test_shares.py @@ -17,14 +17,15 @@ class SharesV1Test(utils.TestCase): - def test_import_v1_shares_module(self): try: from manilaclient.v1 import shares except Exception as e: - msg = ("module 'manilaclient.v1.shares' cannot be imported " - "with error: %s") % str(e) + msg = ( + "module 'manilaclient.v1.shares' cannot be imported " + f"with error: {str(e)}" + ) assert False, msg for cls in ('Share', 'ShareManager'): - msg = "Module 'shares' has no '%s' attr." % cls + msg = f"Module 'shares' has no '{cls}' attr." self.assertTrue(hasattr(shares, cls), msg) diff --git a/manilaclient/tests/unit/v2/fake_clients.py b/manilaclient/tests/unit/v2/fake_clients.py index d6f7141e..0e48a6e4 100644 --- a/manilaclient/tests/unit/v2/fake_clients.py +++ b/manilaclient/tests/unit/v2/fake_clients.py @@ -22,18 +22,21 @@ class FakeClient(fakes.FakeClient, client.Client): - def __init__(self, *args, **kwargs): api_version = kwargs.get('version') or api_versions.MAX_VERSION - client.Client.__init__(self, 'username', 'password', - 'project_id', 'auth_url', - extensions=kwargs.get('extensions'), - version=api_version) + client.Client.__init__( + self, + 'username', + 'password', + 'project_id', + 'auth_url', + extensions=kwargs.get('extensions'), + version=api_version, + ) self.client = FakeHTTPClient(**kwargs) class FakeHTTPClient(httpclient.HTTPClient): - def __init__(self, **kwargs): api_version = kwargs.get('version') or api_versions.MAX_VERSION self.username = 'username' @@ -67,21 +70,24 @@ def _cs_request_with_retries(self, url, method, **kwargs): munged_url = munged_url.strip('/').replace('/', '_').replace('.', '_') munged_url = munged_url.replace('-', '_') - callback = "%s_%s" % (method.lower(), munged_url) + callback = f"{method.lower()}_{munged_url}" if not hasattr(self, callback): - raise AssertionError('Called unknown API method: %s %s, ' - 'expected fakes method name: %s' % - (method, url, callback)) + raise AssertionError( + f'Called unknown API method: {method} {url}, ' + f'expected fakes method name: {callback}' + ) # Note the call self.callstack.append((method, url, kwargs.get('body', None))) status, headers, body = getattr(self, callback)(**kwargs) - r = utils.TestResponse({ - "status_code": status, - "text": body, - "headers": headers, - }) + r = utils.TestResponse( + { + "status_code": status, + "text": body, + "headers": headers, + } + ) return r, body # @@ -122,8 +128,7 @@ def get_os_quota_sets_test_defaults(self): def put_os_quota_sets_test(self, body, **kw): assert list(body) == ['quota_set'] - fakes.assert_has_keys(body['quota_set'], - required=['tenant_id']) + fakes.assert_has_keys(body['quota_set'], required=['tenant_id']) quota_set = { 'quota_set': { 'tenant_id': 'test', @@ -161,8 +166,7 @@ def get_os_quota_class_sets_test(self, **kw): def put_os_quota_class_sets_test(self, body, **kw): assert list(body) == ['quota_class_set'] - fakes.assert_has_keys(body['quota_class_set'], - required=['class_name']) + fakes.assert_has_keys(body['quota_class_set'], required=['class_name']) quota_class_set = { 'quota_class_set': { 'class_name': 'test', @@ -194,18 +198,22 @@ def get_extensions(self, **kw): "description": "Fake extension number 1", "links": [], "name": "Fake1", - "namespace": ("http://docs.openstack.org/" - "/ext/fake1/api/v1.1"), - "updated": "2011-06-09T00:00:00+00:00" + "namespace": ("http://docs.openstack.org//ext/fake1/api/v1.1"), + "updated": "2011-06-09T00:00:00+00:00", }, { "alias": "FAKE-2", "description": "Fake extension number 2", "links": [], "name": "Fake2", - "namespace": ("http://docs.openstack.org/" - "/ext/fake1/api/v1.1"), - "updated": "2011-06-09T00:00:00+00:00" + "namespace": ("http://docs.openstack.org//ext/fake1/api/v1.1"), + "updated": "2011-06-09T00:00:00+00:00", }, ] - return (200, {}, {"extensions": exts, }) + return ( + 200, + {}, + { + "extensions": exts, + }, + ) diff --git a/manilaclient/tests/unit/v2/fakes.py b/manilaclient/tests/unit/v2/fakes.py index cf845291..8c715979 100644 --- a/manilaclient/tests/unit/v2/fakes.py +++ b/manilaclient/tests/unit/v2/fakes.py @@ -20,7 +20,6 @@ class FakeClient(fakes.FakeClient): - def __init__(self, *args, **kwargs): client.Client.__init__( self, @@ -32,7 +31,9 @@ def __init__(self, *args, **kwargs): input_auth_token='token', extensions=kwargs.get('extensions'), service_catalog_url='http://localhost:8786', - api_version=kwargs.get("api_version", manilaclient.API_MAX_VERSION) + api_version=kwargs.get( + "api_version", manilaclient.API_MAX_VERSION + ), ) self.client = FakeHTTPClient(**kwargs) @@ -70,7 +71,6 @@ def get_fake_snapshot_export_location(): class FakeHTTPClient(fakes.FakeHTTPClient): - def get_(self, **kw): body = { "versions": [ @@ -86,11 +86,12 @@ def get_(self, **kw): { "href": "http://localhost:8786/v2/", "rel": "self", - } + }, ], "min_version": "2.0", "version": self.default_headers[ - "X-Openstack-Manila-Api-Version"], + "X-Openstack-Manila-Api-Version" + ], "id": "v2.0", } ] @@ -100,14 +101,18 @@ def get_(self, **kw): def get_availability_zones(self): availability_zones = { "availability_zones": [ - {"id": "368c5780-ad72-4bcf-a8b6-19e45f4fafoo", - "name": "foo", - "created_at": "2016-07-08T14:13:12.000000", - "updated_at": "2016-07-08T15:14:13.000000"}, - {"id": "368c5780-ad72-4bcf-a8b6-19e45f4fabar", - "name": "bar", - "created_at": "2016-07-08T14:13:12.000000", - "updated_at": "2016-07-08T15:14:13.000000"}, + { + "id": "368c5780-ad72-4bcf-a8b6-19e45f4fafoo", + "name": "foo", + "created_at": "2016-07-08T14:13:12.000000", + "updated_at": "2016-07-08T15:14:13.000000", + }, + { + "id": "368c5780-ad72-4bcf-a8b6-19e45f4fabar", + "name": "bar", + "created_at": "2016-07-08T14:13:12.000000", + "updated_at": "2016-07-08T15:14:13.000000", + }, ] } return (200, {}, availability_zones) @@ -115,20 +120,24 @@ def get_availability_zones(self): def get_os_services(self, **kw): services = { "services": [ - {"status": "enabled", - "binary": "manila-scheduler", - "zone": "foozone", - "state": "up", - "updated_at": "2015-10-09T13:54:09.000000", - "host": "lucky-star", - "id": 1}, - {"status": "enabled", - "binary": "manila-share", - "zone": "foozone", - "state": "up", - "updated_at": "2015-10-09T13:54:05.000000", - "host": "lucky-star", - "id": 2}, + { + "status": "enabled", + "binary": "manila-scheduler", + "zone": "foozone", + "state": "up", + "updated_at": "2015-10-09T13:54:09.000000", + "host": "lucky-star", + "id": 1, + }, + { + "status": "enabled", + "binary": "manila-share", + "zone": "foozone", + "state": "up", + "updated_at": "2015-10-09T13:54:05.000000", + "host": "lucky-star", + "id": 2, + }, ] } return (200, {}, services) @@ -136,14 +145,20 @@ def get_os_services(self, **kw): get_services = get_os_services def put_os_services_enable(self, **kw): - return (200, {}, {'host': 'foo', 'binary': 'manila-share', - 'disabled': False}) + return ( + 200, + {}, + {'host': 'foo', 'binary': 'manila-share', 'disabled': False}, + ) put_services_enable = put_os_services_enable def put_os_services_disable(self, **kw): - return (200, {}, {'host': 'foo', 'binary': 'manila-share', - 'disabled': True}) + return ( + 200, + {}, + {'host': 'foo', 'binary': 'manila-share', 'disabled': True}, + ) put_services_disable = put_os_services_disable @@ -162,7 +177,7 @@ def get_v2(self, **kw): { "href": "http://localhost:8786/v2/", "rel": "self", - } + }, ], "min_version": "2.0", "version": "2.5", @@ -214,8 +229,12 @@ def get_shares(self, **kw): 'id': share_id, 'name': 'sharename', 'links': [ - {"href": endpoint + "/fake_project/shares/" + share_id, - "rel": "self"}, + { + "href": endpoint + + "/fake_project/shares/" + + share_id, + "rel": "self", + }, ], }, ] @@ -240,10 +259,14 @@ def get_shares_detail(self, **kw): 'export_location': 'fake_export_location', 'snapshot_id': 'fake_snapshot_id', 'links': [ - {"href": endpoint + "/fake_project/shares/" - + share_id1234, "rel": "self"}, + { + "href": endpoint + + "/fake_project/shares/" + + share_id1234, + "rel": "self", + }, ], - 'metadata': {} + 'metadata': {}, }, { 'id': share_id1111, @@ -254,10 +277,14 @@ def get_shares_detail(self, **kw): 'export_location': 'fake_export_location', 'snapshot_id': 'fake_snapshot_id', 'links': [ - {"href": endpoint + "/fake_project/shares/" - + share_id1111, "rel": "self"}, + { + "href": endpoint + + "/fake_project/shares/" + + share_id1111, + "rel": "self", + }, ], - 'metadata': {} + 'metadata': {}, }, { 'id': share_id2222, @@ -268,10 +295,14 @@ def get_shares_detail(self, **kw): 'export_location': 'fake_export_location', 'snapshot_id': 'fake_snapshot_id', 'links': [ - {"href": endpoint + "/fake_project/shares/" - + share_id2222, "rel": "self"}, + { + "href": endpoint + + "/fake_project/shares/" + + share_id2222, + "rel": "self", + }, ], - 'metadata': {'key1': 'value1'} + 'metadata': {'key1': 'value1'}, }, { 'id': share_id3333, @@ -282,10 +313,14 @@ def get_shares_detail(self, **kw): 'export_location': 'fake_export_location', 'snapshot_id': 'fake_snapshot_id', 'links': [ - {"href": endpoint + "/fake_project/shares/" - + share_id3333, "rel": "self"}, + { + "href": endpoint + + "/fake_project/shares/" + + share_id3333, + "rel": "self", + }, ], - 'metadata': {'key1': 'value1', 'key2': 'value2'} + 'metadata': {'key1': 'value1', 'key2': 'value2'}, }, ], } @@ -296,8 +331,13 @@ def get_shares_detail(self, **kw): return (200, {}, shares) def get_snapshots_1234(self, **kw): - snapshot = {'snapshot': {'id': 1234, 'name': 'sharename', - 'status': 'available'}} + snapshot = { + 'snapshot': { + 'id': 1234, + 'name': 'sharename', + 'status': 'available', + } + } return (200, {}, snapshot) def get_share_servers(self, **kw): @@ -324,10 +364,11 @@ def post_snapshots_1234_action(self, body, **kw): action = list(body)[0] if action in ('reset_status', 'os-reset_status'): assert 'status' in body.get( - 'reset_status', body.get('os-reset_status')) + 'reset_status', body.get('os-reset_status') + ) elif action in ('force_delete', 'os-force_delete'): assert body[action] is None - elif action in ('unmanage', ): + elif action in ('unmanage',): assert body[action] is None elif action in 'allow_access': assert 'access_type' in body['allow_access'] @@ -336,7 +377,7 @@ def post_snapshots_1234_action(self, body, **kw): elif action in 'deny_access': assert 'access_id' in body['deny_access'] else: - raise AssertionError("Unexpected action: %s" % action) + raise AssertionError(f"Unexpected action: {action}") return (resp, {}, _body) post_snapshots_5678_action = post_snapshots_1234_action @@ -345,20 +386,18 @@ def post_snapshots_manage(self, body, **kw): _body = {'snapshot': {'id': 'fake'}} resp = 202 - if not ('share_id' in body['snapshot'] - and 'provider_location' in body['snapshot'] - and 'driver_options' in body['snapshot']): + if not ( + 'share_id' in body['snapshot'] + and 'provider_location' in body['snapshot'] + and 'driver_options' in body['snapshot'] + ): resp = 422 result = (resp, {}, _body) return result def _share_instances(self): - instances = { - 'share_instances': [ - fake_share_instance - ] - } + instances = {'share_instances': [fake_share_instance]} return (200, {}, instances) def put_quota_sets_1234(self, *args, **kwargs): @@ -381,21 +420,15 @@ def get_quota_sets_1234_detail(self, *args, **kwargs): quota_set = { 'quota_set': { 'id': '1234', - 'shares': {'in_use': 0, - 'limit': 50, - 'reserved': 0}, - 'gigabytes': {'in_use': 0, - 'limit': 10000, - 'reserved': 0}, - 'snapshots': {'in_use': 0, - 'limit': 50, - 'reserved': 0}, - 'snapshot_gigabytes': {'in_use': 0, - 'limit': 1000, - 'reserved': 0}, - 'share_networks': {'in_use': 0, - 'limit': 10, - 'reserved': 0}, + 'shares': {'in_use': 0, 'limit': 50, 'reserved': 0}, + 'gigabytes': {'in_use': 0, 'limit': 10000, 'reserved': 0}, + 'snapshots': {'in_use': 0, 'limit': 50, 'reserved': 0}, + 'snapshot_gigabytes': { + 'in_use': 0, + 'limit': 1000, + 'reserved': 0, + }, + 'share_networks': {'in_use': 0, 'limit': 10, 'reserved': 0}, } } return (200, {}, quota_set) @@ -412,14 +445,16 @@ def get_share_instances_1234_export_locations(self, **kw): return (200, {}, export_locations) get_shares_1234_export_locations = ( - get_share_instances_1234_export_locations) + get_share_instances_1234_export_locations + ) def get_share_instances_1234_export_locations_fake_el_uuid(self, **kw): export_location = {'export_location': get_fake_export_location()} return (200, {}, export_location) get_shares_1234_export_locations_fake_el_uuid = ( - get_share_instances_1234_export_locations_fake_el_uuid) + get_share_instances_1234_export_locations_fake_el_uuid + ) def get_shares_fake_instances(self, **kw): return self._share_instances() @@ -437,11 +472,12 @@ def post_share_instances_1234_action(self, body, **kw): action = list(body)[0] if action in ('reset_status', 'os-reset_status'): assert 'status' in body.get( - 'reset_status', body.get('os-reset_status')) + 'reset_status', body.get('os-reset_status') + ) elif action == 'os-force_delete': assert body[action] is None else: - raise AssertionError("Unexpected share action: %s" % action) + raise AssertionError(f"Unexpected share action: {action}") return (resp, {}, _body) def get_snapshots(self, **kw): @@ -457,17 +493,21 @@ def get_snapshots(self, **kw): return (200, {}, snapshots) def get_snapshots_detail(self, **kw): - snapshots = {'snapshots': [{ - 'id': 1234, - 'created_at': '2012-08-27T00:00:00.000000', - 'share_size': 1, - 'share_id': 4321, - 'status': 'available', - 'name': 'sharename', - 'display_description': 'description', - 'share_proto': 'type', - 'export_location': 'location', - }]} + snapshots = { + 'snapshots': [ + { + 'id': 1234, + 'created_at': '2012-08-27T00:00:00.000000', + 'share_size': 1, + 'share_id': 4321, + 'status': 'available', + 'name': 'sharename', + 'display_description': 'description', + 'share_proto': 'type', + 'export_location': 'location', + } + ] + } if kw.get('with_count'): snapshots.update({'count': 2}) @@ -477,11 +517,13 @@ def post_os_share_manage(self, body, **kw): _body = {'share': {'id': 'fake'}} resp = 202 - if not ('service_host' in body['share'] - and 'share_type' in body['share'] - and 'export_path' in body['share'] - and 'protocol' in body['share'] - and 'driver_options' in body['share']): + if not ( + 'service_host' in body['share'] + and 'share_type' in body['share'] + and 'export_path' in body['share'] + and 'protocol' in body['share'] + and 'driver_options' in body['share'] + ): resp = 422 result = (resp, {}, _body) @@ -493,9 +535,11 @@ def post_share_servers_manage(self, body, **kw): _body = {'share_server': {'id': 'fake'}} resp = 202 - if not ('host' in body['share_server'] - and 'share_network' in body['share_server'] - and 'identifier' in body['share_server']): + if not ( + 'host' in body['share_server'] + and 'share_network' in body['share_server'] + and 'identifier' in body['share_server'] + ): resp = 422 result = (resp, {}, _body) @@ -506,28 +550,32 @@ def post_share_servers_1234_action(self, body, **kw): assert len(list(body)) == 1 action = list(body)[0] - if action in ('reset_status', ): + if action in ('reset_status',): assert 'status' in body.get( - 'reset_status', body.get('os-reset_status')) + 'reset_status', body.get('os-reset_status') + ) _body = { 'reset_status': {'status': body['reset_status']['status']} } - elif action in ('unmanage', ): + elif action in ('unmanage',): assert 'force' in body[action] elif action in ( - 'migration_cancel', 'migration_complete', - 'migration_get_progress'): + 'migration_cancel', + 'migration_complete', + 'migration_get_progress', + ): assert body[action] is None if 'migration_get_progress' == action: - _body = {'total_progress': 50, - 'task_state': 'fake_task_state', - 'destination_share_server_id': 'fake_dest_id'} + _body = { + 'total_progress': 50, + 'task_state': 'fake_task_state', + 'destination_share_server_id': 'fake_dest_id', + } return 200, {}, _body elif 'migration_complete' == action: _body = {'destination_share_server_id': 'fake_dest_id'} return 200, {}, _body - elif action in ( - 'migration_start', 'migration_check'): + elif action in ('migration_start', 'migration_check'): assert 'host' in body[action] if 'migration-check': _body = { @@ -560,7 +608,7 @@ def post_shares_1234_action(self, body, **kw): if action in ('os-allow_access', 'allow_access'): expected = ['access_to', 'access_type'] actual = sorted(list(body[action])) - err_msg = "expected '%s', actual is '%s'" % (expected, actual) + err_msg = f"expected '{expected}', actual is '{actual}'" assert expected == actual, err_msg _body = {'access': {}} elif action in ('os-deny_access', 'deny_access'): @@ -569,34 +617,39 @@ def post_shares_1234_action(self, body, **kw): assert body[action] is None elif action in ('os-reset_status', 'reset_status'): assert 'status' in body.get( - 'reset_status', body.get('os-reset_status')) + 'reset_status', body.get('os-reset_status') + ) elif action in ('os-force_delete', 'force_delete'): assert body[action] is None elif action in ('os-extend', 'os-shrink', 'extend', 'shrink'): assert body[action] is not None assert body[action]['new_size'] is not None - elif action in ('unmanage', ): + elif action in ('unmanage',): assert body[action] is None - elif action in ('revert', ): + elif action in ('revert',): assert body[action] is not None assert body[action]['snapshot_id'] is not None elif action in ( - 'migration_cancel', 'migration_complete', - 'migration_get_progress'): + 'migration_cancel', + 'migration_complete', + 'migration_get_progress', + ): assert body[action] is None if 'migration_get_progress' == action: _body = {'total_progress': 50} return 200, {}, _body elif action in ( - 'os-migrate_share', 'migrate_share', - 'migration_start'): + 'os-migrate_share', + 'migrate_share', + 'migration_start', + ): assert 'host' in body[action] elif action == 'reset_task_state': assert 'task_state' in body[action] elif action in ('soft_delete', 'restore'): assert body[action] is None else: - raise AssertionError("Unexpected share action: %s" % action) + raise AssertionError(f"Unexpected share action: {action}") return (resp, {}, _body) def post_shares_1111_action(self, body, **kw): @@ -607,34 +660,38 @@ def post_shares_1111_action(self, body, **kw): if action in ('allow_access', 'os-allow_access'): expected = ['access_level', 'access_to', 'access_type'] actual = sorted(list(body[action])) - err_msg = "expected '%s', actual is '%s'" % (expected, actual) + err_msg = f"expected '{expected}', actual is '{actual}'" assert expected == actual, err_msg _body = {'access': {}} elif action in ('access_list', 'os-access_list'): assert body[action] is None _body = { - 'access_list': [{ - 'access_level': 'rw', - 'state': 'active', - 'id': '1122', - 'access_type': 'ip', - 'access_to': '10.0.0.7' - }] + 'access_list': [ + { + 'access_level': 'rw', + 'state': 'active', + 'id': '1122', + 'access_type': 'ip', + 'access_to': '10.0.0.7', + } + ] } else: - raise AssertionError("Unexpected share action: %s" % action) + raise AssertionError(f"Unexpected share action: {action}") return (resp, {}, _body) def get_share_access_rules(self, **kw): access = { - 'access_list': [{ - 'access_level': 'rw', - 'state': 'active', - 'id': '1122', - 'access_type': 'ip', - 'access_to': '10.0.0.7', - 'metadata': {'key1': 'v1'} - }] + 'access_list': [ + { + 'access_level': 'rw', + 'state': 'active', + 'id': '1122', + 'access_type': 'ip', + 'access_to': '10.0.0.7', + 'metadata': {'key1': 'v1'}, + } + ] } return (200, {}, access) @@ -646,7 +703,7 @@ def get_share_access_rules_9999(self, **kw): 'id': '9999', 'access_type': 'ip', 'access_to': '10.0.0.7', - 'metadata': {'key1': 'v1'} + 'metadata': {'key1': 'v1'}, } } return (200, {}, access) @@ -832,7 +889,7 @@ def get_scheduler_stats_pools(self, **kw): 'host': 'host1', 'backend': 'backend1', 'pool': 'pool2', - } + }, ] } return (200, {}, pools) @@ -853,7 +910,7 @@ def get_scheduler_stats_pools_detail(self, **kw): 'backend': 'backend1', 'pool': 'pool2', 'capabilities': {'qos': False}, - } + }, ] } return (200, {}, pools) @@ -1008,7 +1065,7 @@ def post_share_replicas_1234_action(self, body, **kw): assert body[action] is None else: if action not in ('promote'): - raise AssertionError("Unexpected share action: %s" % action) + raise AssertionError(f"Unexpected share action: {action}") return (resp, {}, _body) # @@ -1036,27 +1093,40 @@ def get_types_default(self, **kw): return self.get_types_1(**kw) def get_types_1234(self, **kw): - return (200, {}, { - 'share_type': {'id': 1234, - 'name': 'test-type-1234', - 'share_type_access:is_public': True, - 'description': "test share type desc", - 'extra_specs': {'test': 'test'}, - 'required_extra_specs': {'test': 'test'}}}) + return ( + 200, + {}, + { + 'share_type': { + 'id': 1234, + 'name': 'test-type-1234', + 'share_type_access:is_public': True, + 'description': "test share type desc", + 'extra_specs': {'test': 'test'}, + 'required_extra_specs': {'test': 'test'}, + } + }, + ) def get_types(self, **kw): req_version = self.default_headers['X-Openstack-Manila-Api-Version'] if not isinstance(req_version, api_versions.APIVersion): req_version = api_versions.APIVersion(req_version) response_body = { - 'share_types': [{'id': 1, - 'name': 'test-type-1', - 'extra_specs': {'test1': 'test1'}, - 'required_extra_specs': {'test': 'test'}}, - {'id': 2, - 'name': 'test-type-2', - 'extra_specs': {'test1': 'test1'}, - 'required_extra_specs': {'test': 'test'}}] + 'share_types': [ + { + 'id': 1, + 'name': 'test-type-1', + 'extra_specs': {'test1': 'test1'}, + 'required_extra_specs': {'test': 'test'}, + }, + { + 'id': 2, + 'name': 'test-type-2', + 'extra_specs': {'test1': 'test1'}, + 'required_extra_specs': {'test': 'test'}, + }, + ] } if req_version >= api_versions.APIVersion('2.46'): @@ -1066,55 +1136,82 @@ def get_types(self, **kw): return 200, {}, response_body def get_types_1(self, **kw): - return (200, {}, {'share_type': { - 'id': 1, - 'name': 'test-type-1', - 'extra_specs': {'test': 'test'}, - 'required_extra_specs': {'test': 'test'}}}) + return ( + 200, + {}, + { + 'share_type': { + 'id': 1, + 'name': 'test-type-1', + 'extra_specs': {'test': 'test'}, + 'required_extra_specs': {'test': 'test'}, + } + }, + ) def get_types_2(self, **kw): - return (200, {}, {'share_type': { - 'id': 2, - 'name': 'test-type-2', - 'extra_specs': {'test': 'test'}, - 'required_extra_specs': {'test': 'test'}}}) + return ( + 200, + {}, + { + 'share_type': { + 'id': 2, + 'name': 'test-type-2', + 'extra_specs': {'test': 'test'}, + 'required_extra_specs': {'test': 'test'}, + } + }, + ) def get_types_3(self, **kw): - return (200, {}, { - 'share_type': { - 'id': 3, - 'name': 'test-type-3', - 'extra_specs': {}, - 'os-share-type-access:is_public': False - } - }) + return ( + 200, + {}, + { + 'share_type': { + 'id': 3, + 'name': 'test-type-3', + 'extra_specs': {}, + 'os-share-type-access:is_public': False, + } + }, + ) def get_types_4(self, **kw): - return (200, {}, { - 'share_type': { - 'id': 4, - 'name': 'test-type-3', - 'extra_specs': {}, - 'os-share-type-access:is_public': True - } - }) + return ( + 200, + {}, + { + 'share_type': { + 'id': 4, + 'name': 'test-type-3', + 'extra_specs': {}, + 'os-share-type-access:is_public': True, + } + }, + ) def post_types(self, body, **kw): share_type = body['share_type'] required_extra_specs = { - "driver_handles_share_servers": share_type[ - 'extra_specs']['driver_handles_share_servers'], + "driver_handles_share_servers": share_type['extra_specs'][ + 'driver_handles_share_servers' + ], } - return (202, {}, { - 'share_type': { - 'id': 3, - 'name': 'test-type-3', - 'is_default': False, - 'description': 'test description', - 'extra_specs': share_type['extra_specs'], - 'required_extra_specs': required_extra_specs, - } - }) + return ( + 202, + {}, + { + 'share_type': { + 'id': 3, + 'name': 'test-type-3', + 'is_default': False, + 'description': 'test description', + 'extra_specs': share_type['extra_specs'], + 'required_extra_specs': required_extra_specs, + } + }, + ) def post_types_3_action(self, body, **kw): _body = None @@ -1126,7 +1223,7 @@ def post_types_3_action(self, body, **kw): elif action == 'removeProjectAccess': assert 'project' in body['removeProjectAccess'] else: - raise AssertionError('Unexpected action: %s' % action) + raise AssertionError(f'Unexpected action: {action}') return (resp, {}, _body) def post_types_1_extra_specs(self, body, **kw): @@ -1140,10 +1237,18 @@ def delete_types_1(self, **kw): return (202, {}, None) def get_types_3_os_share_type_access(self, **kw): - return (200, {}, {'share_type_access': [ - {'share_type_id': '11111111-1111-1111-1111-111111111111', - 'project_id': '00000000-0000-0000-0000-000000000000'} - ]}) + return ( + 200, + {}, + { + 'share_type_access': [ + { + 'share_type_id': '11111111-1111-1111-1111-111111111111', + 'project_id': '00000000-0000-0000-0000-000000000000', + } + ] + }, + ) get_types_3_share_type_access = get_types_3_os_share_type_access @@ -1184,31 +1289,52 @@ def get_snapshot_instances_1234(self, **kw): return (200, {}, instances) def get_snapshot_instances_1234_export_locations_fake_el_id(self, **kw): - return (200, {}, {'share_snapshot_export_location': { - 'id': 'fake_id', 'path': '/fake_path'}}) + return ( + 200, + {}, + { + 'share_snapshot_export_location': { + 'id': 'fake_id', + 'path': '/fake_path', + } + }, + ) def get_snapshots_1234_export_locations_fake_el_id(self, **kw): - return (200, {}, {'share_snapshot_export_location': { - 'id': 'fake_id', 'path': '/fake_path'}}) + return ( + 200, + {}, + { + 'share_snapshot_export_location': { + 'id': 'fake_id', + 'path': '/fake_path', + } + }, + ) - def get_snapshot_instances_1234_export_locations( - self, **kw): - snapshot_export_location = {'share_snapshot_export_locations': - [get_fake_export_location()]} + def get_snapshot_instances_1234_export_locations(self, **kw): + snapshot_export_location = { + 'share_snapshot_export_locations': [get_fake_export_location()] + } return (200, {}, snapshot_export_location) def get_snapshots_1234_export_locations(self): - snapshot_export_location = {'share_snapshot_export_locations': - [get_fake_export_location()]} + snapshot_export_location = { + 'share_snapshot_export_locations': [get_fake_export_location()] + } return (200, {}, snapshot_export_location) def get_snapshots_1234_access_list(self, **kw): - access_list = {'snapshot_access_list': [{ - 'state': 'active', - 'id': '1234', - 'access_type': 'ip', - 'access_to': '6.6.6.6' - }]} + access_list = { + 'snapshot_access_list': [ + { + 'state': 'active', + 'id': '1234', + 'access_type': 'ip', + 'access_to': '6.6.6.6', + } + ] + } return (200, {}, access_list) def delete_snapshots_1234_metadata_test_key(self, **kw): @@ -1237,7 +1363,7 @@ def post_snapshot_instances_1234_action(self, body, **kw): if action == 'reset_status': assert 'status' in body.get(action) else: - raise AssertionError("Unexpected share action: %s" % action) + raise AssertionError(f"Unexpected share action: {action}") return (resp, {}, _body) def get_share_group_types_default(self, **kw): @@ -1257,7 +1383,8 @@ def get_share_group_types(self, **kw): 'type2', ], 'is_public': True, - }, { + }, + { 'id': 2, 'name': 'test-type-2', 'group_specs': { @@ -1332,7 +1459,7 @@ def post_share_group_types_1234_action(self, body, **kw): elif action == 'removeProjectAccess': assert 'project' in body['removeProjectAccess'] else: - raise AssertionError('Unexpected action: %s' % action) + raise AssertionError(f'Unexpected action: {action}') return 202, {}, None def post_share_group_types_1_specs(self, body, **kw): @@ -1347,10 +1474,12 @@ def delete_share_group_types_1234(self, **kw): def get_share_group_types_1234_access(self, **kw): sg_type_access = { - 'share_group_type_access': [{ - 'group_type_id': '11111111-1111-1111-1111-111111111111', - 'project_id': '00000000-0000-0000-0000-000000000000', - }], + 'share_group_type_access': [ + { + 'group_type_id': '11111111-1111-1111-1111-111111111111', + 'project_id': '00000000-0000-0000-0000-000000000000', + } + ], } return 200, {}, sg_type_access @@ -1424,8 +1553,7 @@ def fake_update(url, body, response_key): return {'url': url, 'body': body, 'resp_key': response_key} -class FakeQuotaSet(object): - +class FakeQuotaSet: def __init__(self, dictionary): self.dictionary = dictionary @@ -1433,29 +1561,29 @@ def to_dict(self): return self.dictionary -class ShareNetwork(object): +class ShareNetwork: id = 'fake share network id' name = 'fake share network name' -class ShareType(object): +class ShareType: id = 'fake share type id' name = 'fake share type name' -class ShareGroupType(object): +class ShareGroupType: id = 'fake group type id' name = 'fake group type name' share_types = [ShareType().id] is_public = False -class ShareGroupTypeAccess(object): +class ShareGroupTypeAccess: id = 'fake group type access id' name = 'fake group type access name' -class ShareGroup(object): +class ShareGroup: id = 'fake group id' share_types = [ShareType().id] group_type_id = ShareGroupType().id @@ -1465,15 +1593,15 @@ class ShareGroup(object): availability_zone = 'fake az' -class ShareGroupSnapshot(object): +class ShareGroupSnapshot: id = 'fake group snapshot id' - share_group_id = ShareGroup().id, + share_group_id = (ShareGroup().id,) share_network_id = ShareNetwork().id name = 'fake name' description = 'fake description' -class Message(object): +class Message: id = 'fake message id' action_id = '001' detail_id = '002' diff --git a/manilaclient/tests/unit/v2/test_availability_zones.py b/manilaclient/tests/unit/v2/test_availability_zones.py index d82ea461..4fe16b47 100644 --- a/manilaclient/tests/unit/v2/test_availability_zones.py +++ b/manilaclient/tests/unit/v2/test_availability_zones.py @@ -24,16 +24,17 @@ @ddt.ddt class AvailabilityZoneTest(utils.TestCase): - def _get_manager(self, microversion): version = api_versions.APIVersion(microversion) mock_microversion = mock.Mock(api_version=version) return availability_zones.AvailabilityZoneManager( - api=mock_microversion) + api=mock_microversion + ) def _get_resource_path(self, microversion): - if (api_versions.APIVersion(microversion) > - api_versions.APIVersion("2.6")): + if api_versions.APIVersion(microversion) > api_versions.APIVersion( + "2.6" + ): return availability_zones.RESOURCE_PATH return availability_zones.RESOURCE_PATH_LEGACY @@ -46,7 +47,8 @@ def test_list(self, microversion): result = manager.list() manager._list.assert_called_once_with( - resource_path, availability_zones.RESOURCE_NAME) + resource_path, availability_zones.RESOURCE_NAME + ) self.assertEqual(manager._list.return_value, result) def test_representation(self): diff --git a/manilaclient/tests/unit/v2/test_client.py b/manilaclient/tests/unit/v2/test_client.py index 79c12e7c..409dc82e 100644 --- a/manilaclient/tests/unit/v2/test_client.py +++ b/manilaclient/tests/unit/v2/test_client.py @@ -37,26 +37,35 @@ def test_adapter_properties(self): base_url = uuidutils.generate_uuid(dashed=False) s = client.session.Session() - c = client.Client(session=s, - api_version=manilaclient.API_MAX_VERSION, - service_catalog_url=base_url, retries=retries, - input_auth_token='token') + c = client.Client( + session=s, + api_version=manilaclient.API_MAX_VERSION, + service_catalog_url=base_url, + retries=retries, + input_auth_token='token', + ) self.assertEqual(base_url, c.client.endpoint_url) self.assertEqual(retries, c.client.retries) def test_auth_via_token_invalid(self): - self.assertRaises(exceptions.ClientException, client.Client, - api_version=manilaclient.API_MAX_VERSION, - input_auth_token="token") + self.assertRaises( + exceptions.ClientException, + client.Client, + api_version=manilaclient.API_MAX_VERSION, + input_auth_token="token", + ) def test_auth_via_token_and_session(self): s = client.session.Session() base_url = uuidutils.generate_uuid(dashed=False) - c = client.Client(input_auth_token='token', - service_catalog_url=base_url, session=s, - api_version=manilaclient.API_MAX_VERSION) + c = client.Client( + input_auth_token='token', + service_catalog_url=base_url, + session=s, + api_version=manilaclient.API_MAX_VERSION, + ) self.assertIsNotNone(c.client) self.assertIsNone(c.keystone_client) @@ -64,9 +73,11 @@ def test_auth_via_token_and_session(self): def test_auth_via_token(self): base_url = uuidutils.generate_uuid(dashed=False) - c = client.Client(input_auth_token='token', - service_catalog_url=base_url, - api_version=manilaclient.API_MAX_VERSION) + c = client.Client( + input_auth_token='token', + service_catalog_url=base_url, + api_version=manilaclient.API_MAX_VERSION, + ) self.assertIsNotNone(c.client) self.assertIsNone(c.keystone_client) @@ -77,9 +88,11 @@ def test_valid_region_name_v1(self): kc = client.Client._get_keystone_client.return_value kc.service_catalog = mock.Mock() kc.service_catalog.get_endpoints = mock.Mock(return_value=self.catalog) - c = client.Client(api_version=manilaclient.API_DEPRECATED_VERSION, - service_type="share", - region_name='TestRegion') + c = client.Client( + api_version=manilaclient.API_DEPRECATED_VERSION, + service_type="share", + region_name='TestRegion', + ) self.assertTrue(client.Client._get_keystone_client.called) kc.service_catalog.get_endpoints.assert_called_with('share') client.httpclient.HTTPClient.assert_called_with( @@ -92,7 +105,8 @@ def test_valid_region_name_v1(self): timeout=None, retries=None, http_log_debug=False, - api_version=manilaclient.API_DEPRECATED_VERSION) + api_version=manilaclient.API_DEPRECATED_VERSION, + ) self.assertIsNotNone(c.client) @mock.patch.object(client.Client, '_get_keystone_client', mock.Mock()) @@ -100,9 +114,12 @@ def test_nonexistent_region_name(self): kc = client.Client._get_keystone_client.return_value kc.service_catalog = mock.Mock() kc.service_catalog.get_endpoints = mock.Mock(return_value=self.catalog) - self.assertRaises(RuntimeError, client.Client, - api_version=manilaclient.API_MAX_VERSION, - region_name='FakeRegion') + self.assertRaises( + RuntimeError, + client.Client, + api_version=manilaclient.API_MAX_VERSION, + region_name='FakeRegion', + ) self.assertTrue(client.Client._get_keystone_client.called) kc.service_catalog.get_endpoints.assert_called_with('sharev2') @@ -119,9 +136,11 @@ def test_regions_with_same_name(self): kc = client.Client._get_keystone_client.return_value kc.service_catalog = mock.Mock() kc.service_catalog.get_endpoints = mock.Mock(return_value=catalog) - c = client.Client(api_version=manilaclient.API_MIN_VERSION, - service_type='sharev2', - region_name='SecondRegion') + c = client.Client( + api_version=manilaclient.API_MIN_VERSION, + service_type='sharev2', + region_name='SecondRegion', + ) self.assertTrue(client.Client._get_keystone_client.called) kc.service_catalog.get_endpoints.assert_called_with('sharev2') client.httpclient.HTTPClient.assert_called_with( @@ -134,7 +153,8 @@ def test_regions_with_same_name(self): timeout=None, retries=None, http_log_debug=False, - api_version=manilaclient.API_MIN_VERSION) + api_version=manilaclient.API_MIN_VERSION, + ) self.assertIsNotNone(c.client) def test_client_respects_region_name(self): @@ -179,12 +199,17 @@ def _get_client_args(self, **kwargs): return client_args @ddt.data( - {'auth_url': 'http://identity.example.com', - 'password': 'password_backward_compat', - 'endpoint_type': 'publicURL', - 'project_id': 'foo_tenant_project_id'}, - {'password': 'renamed_api_key', 'endpoint_type': 'public', - 'tenant_id': 'foo_tenant_project_id'}, + { + 'auth_url': 'http://identity.example.com', + 'password': 'password_backward_compat', + 'endpoint_type': 'publicURL', + 'project_id': 'foo_tenant_project_id', + }, + { + 'password': 'renamed_api_key', + 'endpoint_type': 'public', + 'tenant_id': 'foo_tenant_project_id', + }, ) def test_client_init_no_session_no_auth_token(self, kwargs): def fake_url_for(version): @@ -202,53 +227,90 @@ def fake_url_for(version): self.auth_url = client_args['auth_url'] catalog = { 'share': [ - {'region': 'SecondRegion', 'region_id': 'SecondRegion', - 'url': 'http://4.4.4.4', 'interface': 'public', - }, + { + 'region': 'SecondRegion', + 'region_id': 'SecondRegion', + 'url': 'http://4.4.4.4', + 'interface': 'public', + }, ], 'sharev2': [ - {'region': 'FirstRegion', 'interface': 'public', - 'region_id': 'SecondRegion', 'url': 'http://1.1.1.1'}, - {'region': 'secondregion', 'interface': 'public', - 'region_id': 'SecondRegion', 'url': 'http://2.2.2.2'}, - {'region': 'SecondRegion', 'interface': 'internal', - 'region_id': 'SecondRegion', 'url': 'http://3.3.3.1'}, - {'region': 'SecondRegion', 'interface': 'public', - 'region_id': 'SecondRegion', 'url': 'http://3.3.3.3'}, - {'region': 'SecondRegion', 'interface': 'admin', - 'region_id': 'SecondRegion', 'url': 'http://3.3.3.2'}, + { + 'region': 'FirstRegion', + 'interface': 'public', + 'region_id': 'SecondRegion', + 'url': 'http://1.1.1.1', + }, + { + 'region': 'secondregion', + 'interface': 'public', + 'region_id': 'SecondRegion', + 'url': 'http://2.2.2.2', + }, + { + 'region': 'SecondRegion', + 'interface': 'internal', + 'region_id': 'SecondRegion', + 'url': 'http://3.3.3.1', + }, + { + 'region': 'SecondRegion', + 'interface': 'public', + 'region_id': 'SecondRegion', + 'url': 'http://3.3.3.3', + }, + { + 'region': 'SecondRegion', + 'interface': 'admin', + 'region_id': 'SecondRegion', + 'url': 'http://3.3.3.2', + }, ], } client.session.discover.Discover.return_value.url_for.side_effect = ( - fake_url_for) + fake_url_for + ) client.ks_client.Client.return_value.auth_token.return_value = ( - 'fake_token') + 'fake_token' + ) mocked_ks_client = client.ks_client.Client.return_value mocked_ks_client.service_catalog.get_endpoints.return_value = catalog client.Client(**client_args) client.httpclient.HTTPClient.assert_called_with( - 'http://3.3.3.3', mock.ANY, 'python-manilaclient', insecure=False, - cacert=None, cert=client_args['cert'], timeout=None, retries=None, - http_log_debug=False, api_version=manilaclient.API_MIN_VERSION) + 'http://3.3.3.3', + mock.ANY, + 'python-manilaclient', + insecure=False, + cacert=None, + cert=client_args['cert'], + timeout=None, + retries=None, + http_log_debug=False, + api_version=manilaclient.API_MIN_VERSION, + ) client.ks_client.Client.assert_called_with( - session=mock.ANY, version=(3, 0), auth_url='url_v3.0', + session=mock.ANY, + version=(3, 0), + auth_url='url_v3.0', username=client_args['username'], password=client_args.get('password'), user_id=client_args['user_id'], user_domain_name=client_args['user_domain_name'], user_domain_id=client_args['user_domain_id'], - project_id=client_args.get('tenant_id', - client_args.get('project_id')), + project_id=client_args.get( + 'tenant_id', client_args.get('project_id') + ), project_name=client_args['project_name'], project_domain_name=client_args['project_domain_name'], project_domain_id=client_args['project_domain_id'], region_name=client_args['region_name'], ) mocked_ks_client.service_catalog.get_endpoints.assert_called_with( - client_args['service_type']) + client_args['service_type'] + ) mocked_ks_client.authenticate.assert_called_with() @mock.patch.object(client.ks_client, 'Client', mock.Mock()) @@ -259,13 +321,15 @@ def test_client_init_no_session_no_auth_token_endpoint_not_found(self): client_args = self._get_client_args( auth_urli='fake_url', password='foo_password', - tenant_id='foo_tenant_id') + tenant_id='foo_tenant_id', + ) discover = client.session.discover.Discover discover.return_value.url_for.return_value = None mocked_ks_client = client.ks_client.Client.return_value self.assertRaises( - exceptions.CommandError, client.Client, **client_args) + exceptions.CommandError, client.Client, **client_args + ) self.assertTrue(client.session.Session.called) self.assertTrue(client.session.discover.Discover.called) diff --git a/manilaclient/tests/unit/v2/test_limits.py b/manilaclient/tests/unit/v2/test_limits.py index 6e38aa40..17836b94 100644 --- a/manilaclient/tests/unit/v2/test_limits.py +++ b/manilaclient/tests/unit/v2/test_limits.py @@ -21,59 +21,72 @@ from manilaclient.v2 import limits -def _get_default_RateLimit(verb="verb1", uri="uri1", regex="regex1", - value="value1", - remain="remain1", unit="unit1", - next_available="next1"): - return limits.RateLimit(verb, uri, regex, value, remain, unit, - next_available) +def _get_default_RateLimit( + verb="verb1", + uri="uri1", + regex="regex1", + value="value1", + remain="remain1", + unit="unit1", + next_available="next1", +): + return limits.RateLimit( + verb, uri, regex, value, remain, unit, next_available + ) class TestLimits(utils.TestCase): - def test_repr(self): li = limits.Limits(None, {"foo": "bar"}) self.assertEqual("", repr(li)) def test_absolute(self): - li = limits.Limits(None, - {"absolute": {"name1": "value1", - "name2": "value2"}}) + li = limits.Limits( + None, {"absolute": {"name1": "value1", "name2": "value2"}} + ) l1 = limits.AbsoluteLimit("name1", "value1") l2 = limits.AbsoluteLimit("name2", "value2") for item in li.absolute: self.assertIn(item, [l1, l2]) def test_rate(self): - limit_param = { - "rate": [{ - "uri": "uri1", - "regex": "regex1", - "limit": [{ - "verb": "verb1", - "value": "value1", - "remaining": "remain1", - "unit": "unit1", - "next-available": "next1" - }] - }, { - "uri": "uri2", - "regex": "regex2", - "limit": [{ - "verb": "verb2", - "value": "value2", - "remaining": "remain2", - "unit": "unit2", - "next-available": "next2" - }] - }] + "rate": [ + { + "uri": "uri1", + "regex": "regex1", + "limit": [ + { + "verb": "verb1", + "value": "value1", + "remaining": "remain1", + "unit": "unit1", + "next-available": "next1", + } + ], + }, + { + "uri": "uri2", + "regex": "regex2", + "limit": [ + { + "verb": "verb2", + "value": "value2", + "remaining": "remain2", + "unit": "unit2", + "next-available": "next2", + } + ], + }, + ] } li = limits.Limits(None, limit_param) - l1 = limits.RateLimit("verb1", "uri1", "regex1", "value1", "remain1", - "unit1", "next1") - l2 = limits.RateLimit("verb2", "uri2", "regex2", "value2", "remain2", - "unit2", "next2") + l1 = limits.RateLimit( + "verb1", "uri1", "regex1", "value1", "remain1", "unit1", "next1" + ) + l2 = limits.RateLimit( + "verb2", "uri2", "regex2", "value2", "remain2", "unit2", "next2" + ) for item in li.rate: self.assertIn(item, [l1, l2]) @@ -151,8 +164,19 @@ def test_get(self): api = mock.Mock() api.client.get.return_value = ( None, - {"limits": {"absolute": {"name1": "value1", }}, - "no-limits": {"absolute": {"name2": "value2", }}}) + { + "limits": { + "absolute": { + "name1": "value1", + } + }, + "no-limits": { + "absolute": { + "name2": "value2", + } + }, + }, + ) l1 = limits.AbsoluteLimit("name1", "value1") limitsManager = limits.LimitsManager(api) diff --git a/manilaclient/tests/unit/v2/test_messages.py b/manilaclient/tests/unit/v2/test_messages.py index 77a3a24a..f4a3cb95 100644 --- a/manilaclient/tests/unit/v2/test_messages.py +++ b/manilaclient/tests/unit/v2/test_messages.py @@ -23,12 +23,10 @@ class MessageTest(utils.TestCase): - def setUp(self): - super(MessageTest, self).setUp() + super().setUp() self.manager = messages.MessageManager(fake.FakeClient()) - self.message = messages.Message( - self.manager, {'id': 'fake_id'}) + self.message = messages.Message(self.manager, {'id': 'fake_id'}) self.fake_kwargs = {'key': 'value'} def test_repr(self): @@ -46,69 +44,86 @@ def test_delete(self): @ddt.ddt class MessageManagerTest(utils.TestCase): - def setUp(self): - super(MessageManagerTest, self).setUp() + super().setUp() self.manager = messages.MessageManager(fake.FakeClient()) def test_get(self): fake_message = fake.Message() mock_get = self.mock_object( - self.manager, '_get', mock.Mock(return_value=fake_message)) + self.manager, '_get', mock.Mock(return_value=fake_message) + ) result = self.manager.get(fake.Message.id) self.assertIs(fake_message, result) mock_get.assert_called_once_with( - messages.RESOURCE_PATH % fake.Message.id, - messages.RESOURCE_NAME) + messages.RESOURCE_PATH % fake.Message.id, messages.RESOURCE_NAME + ) def test_list(self): fake_message = fake.Message() mock_list = self.mock_object( - self.manager, '_list', mock.Mock(return_value=[fake_message])) + self.manager, '_list', mock.Mock(return_value=[fake_message]) + ) result = self.manager.list() self.assertEqual([fake_message], result) mock_list.assert_called_once_with( - messages.RESOURCES_PATH, - messages.RESOURCES_NAME) + messages.RESOURCES_PATH, messages.RESOURCES_NAME + ) @ddt.data( - ({'action_id': 1, 'resource_type': 'share'}, - '?action_id=1&resource_type=share'), + ( + {'action_id': 1, 'resource_type': 'share'}, + '?action_id=1&resource_type=share', + ), ({'action_id': 1}, '?action_id=1'), ) @ddt.unpack def test_list_with_filters(self, filters, filters_path): fake_message = fake.Message() mock_list = self.mock_object( - self.manager, '_list', mock.Mock(return_value=[fake_message])) + self.manager, '_list', mock.Mock(return_value=[fake_message]) + ) result = self.manager.list(search_opts=filters) self.assertEqual([fake_message], result) - expected_path = (messages.RESOURCES_PATH + filters_path) + expected_path = messages.RESOURCES_PATH + filters_path mock_list.assert_called_once_with( - expected_path, messages.RESOURCES_NAME) + expected_path, messages.RESOURCES_NAME + ) - @ddt.data('id', 'project_id', 'request_id', 'resource_type', 'action_id', - 'detail_id', 'resource_id', 'message_level', 'expires_at', - 'request_id', 'created_at') + @ddt.data( + 'id', + 'project_id', + 'request_id', + 'resource_type', + 'action_id', + 'detail_id', + 'resource_id', + 'message_level', + 'expires_at', + 'request_id', + 'created_at', + ) def test_list_with_sorting(self, key): fake_message = fake.Message() mock_list = self.mock_object( - self.manager, '_list', mock.Mock(return_value=[fake_message])) + self.manager, '_list', mock.Mock(return_value=[fake_message]) + ) result = self.manager.list(sort_dir='asc', sort_key=key) self.assertEqual([fake_message], result) expected_path = ( - messages.RESOURCES_PATH + '?sort_dir=asc&sort_key=' + - key) + messages.RESOURCES_PATH + '?sort_dir=asc&sort_key=' + key + ) mock_list.assert_called_once_with( - expected_path, messages.RESOURCES_NAME) + expected_path, messages.RESOURCES_NAME + ) @ddt.data( ('name', 'invalid'), @@ -117,8 +132,8 @@ def test_list_with_sorting(self, key): @ddt.unpack def test_list_with_invalid_sorting(self, sort_key, sort_dir): self.assertRaises( - ValueError, - self.manager.list, sort_dir=sort_dir, sort_key=sort_key) + ValueError, self.manager.list, sort_dir=sort_dir, sort_key=sort_key + ) def test_delete(self): mock_delete = self.mock_object(self.manager, '_delete') @@ -127,5 +142,6 @@ def test_delete(self): self.manager.delete(fake.Message()) mock_delete.assert_called_once_with( - messages.RESOURCE_PATH % fake.Message.id) + messages.RESOURCE_PATH % fake.Message.id + ) self.assertFalse(mock_post.called) diff --git a/manilaclient/tests/unit/v2/test_quota_classes.py b/manilaclient/tests/unit/v2/test_quota_classes.py index 6fdff517..282c9c22 100644 --- a/manilaclient/tests/unit/v2/test_quota_classes.py +++ b/manilaclient/tests/unit/v2/test_quota_classes.py @@ -24,15 +24,15 @@ @ddt.ddt class QuotaClassSetsTest(utils.TestCase): - def _get_manager(self, microversion): version = api_versions.APIVersion(microversion) mock_microversion = mock.Mock(api_version=version) return quota_classes.QuotaClassSetManager(api=mock_microversion) def _get_resource_path(self, microversion): - if (api_versions.APIVersion(microversion) > - api_versions.APIVersion("2.6")): + if api_versions.APIVersion(microversion) > api_versions.APIVersion( + "2.6" + ): return quota_classes.RESOURCE_PATH return quota_classes.RESOURCE_PATH_LEGACY @@ -41,20 +41,22 @@ def test_class_quotas_get(self, microversion): class_name = 'test' manager = self._get_manager(microversion) resource_path = self._get_resource_path(microversion) - expected_url = "%s/test" % resource_path - with mock.patch.object(manager, '_get', - mock.Mock(return_value='fake_get')): + expected_url = f"{resource_path}/test" + with mock.patch.object( + manager, '_get', mock.Mock(return_value='fake_get') + ): manager.get(class_name) manager._get.assert_called_once_with( - expected_url, "quota_class_set") + expected_url, "quota_class_set" + ) @ddt.data("2.6", "2.7") def test_update_quota(self, microversion): class_name = 'test' manager = self._get_manager(microversion) resource_path = self._get_resource_path(microversion) - expected_url = "%s/test" % resource_path + expected_url = f"{resource_path}/test" expected_body = { 'quota_class_set': { 'class_name': class_name, @@ -65,11 +67,18 @@ def test_update_quota(self, microversion): 'share_networks': 5, }, } - with mock.patch.object(manager, '_update', - mock.Mock(return_value='fake_update')): + with mock.patch.object( + manager, '_update', mock.Mock(return_value='fake_update') + ): manager.update( - class_name, shares=1, snapshots=2, gigabytes=3, - snapshot_gigabytes=4, share_networks=5) + class_name, + shares=1, + snapshots=2, + gigabytes=3, + snapshot_gigabytes=4, + share_networks=5, + ) manager._update.assert_called_once_with( - expected_url, expected_body) + expected_url, expected_body + ) diff --git a/manilaclient/tests/unit/v2/test_quotas.py b/manilaclient/tests/unit/v2/test_quotas.py index 754362df..365b4970 100644 --- a/manilaclient/tests/unit/v2/test_quotas.py +++ b/manilaclient/tests/unit/v2/test_quotas.py @@ -26,15 +26,15 @@ @ddt.ddt class QuotaSetsTest(utils.TestCase): - def _get_manager(self, microversion): version = api_versions.APIVersion(microversion) mock_microversion = mock.Mock(api_version=version) return quotas.QuotaSetManager(api=mock_microversion) def _get_resource_path(self, microversion): - if (api_versions.APIVersion(microversion) > - api_versions.APIVersion("2.6")): + if api_versions.APIVersion(microversion) > api_versions.APIVersion( + "2.6" + ): return quotas.RESOURCE_PATH return quotas.RESOURCE_PATH_LEGACY @@ -45,13 +45,13 @@ def test_tenant_quotas_get(self, microversion): resource_path = self._get_resource_path(microversion) version = api_versions.APIVersion(microversion) if version >= api_versions.APIVersion('2.25'): - expected_url = "%s/test/detail" % resource_path + expected_url = f"{resource_path}/test/detail" else: - expected_url = ("%s/test" - % resource_path) + expected_url = f"{resource_path}/test" - with mock.patch.object(manager, '_get', - mock.Mock(return_value='fake_get')): + with mock.patch.object( + manager, '_get', mock.Mock(return_value='fake_get') + ): manager.get(tenant_id, detail=True) manager._get.assert_called_once_with(expected_url, "quota_set") @@ -64,14 +64,13 @@ def test_user_quotas_get(self, microversion): resource_path = self._get_resource_path(microversion) version = api_versions.APIVersion(microversion) if version >= api_versions.APIVersion('2.25'): - expected_url = ("%s/test/detail?user_id=fake_user" - % resource_path) + expected_url = f"{resource_path}/test/detail?user_id=fake_user" else: - expected_url = ("%s/test?user_id=fake_user" - % resource_path) + expected_url = f"{resource_path}/test?user_id=fake_user" - with mock.patch.object(manager, '_get', - mock.Mock(return_value='fake_get')): + with mock.patch.object( + manager, '_get', mock.Mock(return_value='fake_get') + ): manager.get(tenant_id, user_id=user_id, detail=True) manager._get.assert_called_once_with(expected_url, "quota_set") @@ -81,11 +80,13 @@ def test_share_type_quotas_get(self): share_type = 'fake_share_type' manager = self._get_manager('2.39') resource_path = self._get_resource_path('2.39') - expected_url = ("%s/%s/detail?share_type=%s" - % (resource_path, tenant_id, share_type)) + expected_url = ( + f"{resource_path}/{tenant_id}/detail?share_type={share_type}" + ) - with mock.patch.object(manager, '_get', - mock.Mock(return_value='fake_get')): + with mock.patch.object( + manager, '_get', mock.Mock(return_value='fake_get') + ): manager.get(tenant_id, share_type=share_type, detail=True) manager._get.assert_called_once_with(expected_url, "quota_set") @@ -95,27 +96,32 @@ def test_tenant_quotas_defaults(self, microversion): tenant_id = 'test' manager = self._get_manager(microversion) resource_path = self._get_resource_path(microversion) - expected_url = "%s/test/defaults" % resource_path - with mock.patch.object(manager, '_get', - mock.Mock(return_value='fake_get')): + expected_url = f"{resource_path}/test/defaults" + with mock.patch.object( + manager, '_get', mock.Mock(return_value='fake_get') + ): manager.defaults(tenant_id) manager._get.assert_called_once_with(expected_url, "quota_set") @ddt.data( - ("2.6", {}), ("2.6", {"force": True}), - ("2.7", {}), ("2.7", {"force": True}), - ("2.38", {}), ("2.38", {"force": True}), - ("2.39", {}), ("2.39", {"force": True}), - ("2.53", {}), ("2.53", {"force": True, "share_replicas": 8, - "replica_gigabytes": 9}), + ("2.6", {}), + ("2.6", {"force": True}), + ("2.7", {}), + ("2.7", {"force": True}), + ("2.38", {}), + ("2.38", {"force": True}), + ("2.39", {}), + ("2.39", {"force": True}), + ("2.53", {}), + ("2.53", {"force": True, "share_replicas": 8, "replica_gigabytes": 9}), ) @ddt.unpack def test_update_quota(self, microversion, extra_data): tenant_id = 'test' manager = self._get_manager(microversion) resource_path = self._get_resource_path(microversion) - expected_url = "%s/test" % resource_path + expected_url = f"{resource_path}/test" expected_body = { 'quota_set': { 'tenant_id': tenant_id, @@ -127,23 +133,32 @@ def test_update_quota(self, microversion, extra_data): }, } expected_body['quota_set'].update(extra_data) - with mock.patch.object(manager, '_update', - mock.Mock(return_value='fake_update')): + with mock.patch.object( + manager, '_update', mock.Mock(return_value='fake_update') + ): manager.update( - tenant_id, shares=1, snapshots=2, gigabytes=3, - snapshot_gigabytes=4, share_networks=5, **extra_data) + tenant_id, + shares=1, + snapshots=2, + gigabytes=3, + snapshot_gigabytes=4, + share_networks=5, + **extra_data, + ) manager._update.assert_called_once_with( - expected_url, expected_body, "quota_set") + expected_url, expected_body, "quota_set" + ) - @ddt.data("2.6", "2.7", "2.38", "2.39", "2.40", - REPLICA_QUOTAS_MICROVERSION) + @ddt.data( + "2.6", "2.7", "2.38", "2.39", "2.40", REPLICA_QUOTAS_MICROVERSION + ) def test_update_user_quota(self, microversion): tenant_id = 'test' user_id = 'fake_user' manager = self._get_manager(microversion) resource_path = self._get_resource_path(microversion) - expected_url = "%s/test?user_id=fake_user" % resource_path + expected_url = f"{resource_path}/test?user_id=fake_user" expected_body = { 'quota_set': { 'tenant_id': tenant_id, @@ -159,38 +174,47 @@ def test_update_user_quota(self, microversion): 'snapshots': expected_body['quota_set']['snapshots'], 'gigabytes': expected_body['quota_set']['gigabytes'], 'snapshot_gigabytes': expected_body['quota_set'][ - 'snapshot_gigabytes'], + 'snapshot_gigabytes' + ], 'share_networks': expected_body['quota_set']['share_networks'], 'user_id': user_id, } - if (api_versions.APIVersion(microversion) >= - api_versions.APIVersion('2.40')): + if api_versions.APIVersion(microversion) >= api_versions.APIVersion( + '2.40' + ): expected_body['quota_set']['share_groups'] = 6 expected_body['quota_set']['share_group_snapshots'] = 7 - kwargs['share_groups'] = expected_body['quota_set'][ - 'share_groups'] + kwargs['share_groups'] = expected_body['quota_set']['share_groups'] kwargs['share_group_snapshots'] = expected_body['quota_set'][ - 'share_group_snapshots'] - if (api_versions.APIVersion(microversion) >= - api_versions.APIVersion(REPLICA_QUOTAS_MICROVERSION)): + 'share_group_snapshots' + ] + if api_versions.APIVersion(microversion) >= api_versions.APIVersion( + REPLICA_QUOTAS_MICROVERSION + ): expected_body['quota_set']['share_replicas'] = 8 expected_body['quota_set']['replica_gigabytes'] = 9 kwargs['share_replicas'] = expected_body['quota_set'][ - 'share_replicas'] + 'share_replicas' + ] kwargs['replica_gigabytes'] = expected_body['quota_set'][ - 'replica_gigabytes'] - if (api_versions.APIVersion(microversion) >= - api_versions.APIVersion('2.62')): + 'replica_gigabytes' + ] + if api_versions.APIVersion(microversion) >= api_versions.APIVersion( + '2.62' + ): expected_body['quota_set']['per_share_gigabytes'] = 10 kwargs['per_share_gigabytes'] = expected_body['quota_set'][ - 'per_share_gigabytes'] + 'per_share_gigabytes' + ] - with mock.patch.object(manager, '_update', - mock.Mock(return_value='fake_update')): + with mock.patch.object( + manager, '_update', mock.Mock(return_value='fake_update') + ): manager.update(tenant_id, **kwargs) manager._update.assert_called_once_with( - expected_url, expected_body, "quota_set") + expected_url, expected_body, "quota_set" + ) @ddt.data('2.39', REPLICA_QUOTAS_MICROVERSION) def test_update_share_type_quota(self, microversion): @@ -198,8 +222,7 @@ def test_update_share_type_quota(self, microversion): share_type = 'fake_share_type' manager = self._get_manager(microversion) resource_path = self._get_resource_path(microversion) - expected_url = "%s/%s?share_type=%s" % ( - resource_path, tenant_id, share_type) + expected_url = f"{resource_path}/{tenant_id}?share_type={share_type}" expected_body = { 'quota_set': { 'tenant_id': tenant_id, @@ -217,24 +240,34 @@ def test_update_share_type_quota(self, microversion): if microversion >= '2.62': expected_body['quota_set']['per_share_gigabytes'] = 10 kwargs = {'per_share_gigabytes': 10} - with mock.patch.object(manager, '_update', - mock.Mock(return_value='fake_update')): + with mock.patch.object( + manager, '_update', mock.Mock(return_value='fake_update') + ): manager.update( - tenant_id, shares=1, snapshots=2, gigabytes=3, - snapshot_gigabytes=4, share_type=share_type, **kwargs) + tenant_id, + shares=1, + snapshots=2, + gigabytes=3, + snapshot_gigabytes=4, + share_type=share_type, + **kwargs, + ) manager._update.assert_called_once_with( - expected_url, expected_body, "quota_set") + expected_url, expected_body, "quota_set" + ) def test_update_share_type_quotas_for_share_networks(self): manager = self._get_manager("2.39") - with mock.patch.object(manager, '_update', - mock.Mock(return_value='fake_delete')): + with mock.patch.object( + manager, '_update', mock.Mock(return_value='fake_delete') + ): self.assertRaises( ValueError, manager.update, - 'fake_tenant_id', share_type='fake_share_type', + 'fake_tenant_id', + share_type='fake_share_type', share_networks=13, ) @@ -245,9 +278,10 @@ def test_quotas_delete(self, microversion): tenant_id = 'test' manager = self._get_manager(microversion) resource_path = self._get_resource_path(microversion) - expected_url = "%s/test" % resource_path - with mock.patch.object(manager, '_delete', - mock.Mock(return_value='fake_delete')): + expected_url = f"{resource_path}/test" + with mock.patch.object( + manager, '_delete', mock.Mock(return_value='fake_delete') + ): manager.delete(tenant_id) manager._delete.assert_called_once_with(expected_url) @@ -258,9 +292,10 @@ def test_user_quotas_delete(self, microversion): user_id = 'fake_user' manager = self._get_manager(microversion) resource_path = self._get_resource_path(microversion) - expected_url = "%s/test?user_id=fake_user" % resource_path - with mock.patch.object(manager, '_delete', - mock.Mock(return_value='fake_delete')): + expected_url = f"{resource_path}/test?user_id=fake_user" + with mock.patch.object( + manager, '_delete', mock.Mock(return_value='fake_delete') + ): manager.delete(tenant_id, user_id=user_id) manager._delete.assert_called_once_with(expected_url) @@ -270,9 +305,10 @@ def test_share_type_quotas_delete(self): share_type = 'fake_st' manager = self._get_manager("2.39") resource_path = self._get_resource_path("2.39") - expected_url = "%s/test?share_type=fake_st" % resource_path - with mock.patch.object(manager, '_delete', - mock.Mock(return_value='fake_delete')): + expected_url = f"{resource_path}/test?share_type=fake_st" + with mock.patch.object( + manager, '_delete', mock.Mock(return_value='fake_delete') + ): manager.delete(tenant_id, share_type=share_type) manager._delete.assert_called_once_with(expected_url) @@ -281,12 +317,14 @@ def test_share_type_quotas_delete(self): def test_share_type_quotas_using_old_microversion(self, operation): manager = self._get_manager("2.38") - with mock.patch.object(manager, '_%s' % operation, - mock.Mock(return_value='fake_delete')): + with mock.patch.object( + manager, f'_{operation}', mock.Mock(return_value='fake_delete') + ): self.assertRaises( TypeError, getattr(manager, operation), - 'fake_tenant_id', share_type='fake_share_type', + 'fake_tenant_id', + share_type='fake_share_type', ) - getattr(manager, '_%s' % operation).assert_not_called() + getattr(manager, f'_{operation}').assert_not_called() diff --git a/manilaclient/tests/unit/v2/test_scheduler_stats.py b/manilaclient/tests/unit/v2/test_scheduler_stats.py index 59c528a1..afd6a30b 100644 --- a/manilaclient/tests/unit/v2/test_scheduler_stats.py +++ b/manilaclient/tests/unit/v2/test_scheduler_stats.py @@ -20,9 +20,8 @@ class PoolTest(utils.TestCase): - def setUp(self): - super(PoolTest, self).setUp() + super().setUp() self.name = 'fake_host@fake_backend#fake_pool' info = { @@ -34,48 +33,50 @@ def setUp(self): self.resource_class = scheduler_stats.Pool(manager=self, info=info) def test_get_repr_of_share_server(self): - self.assertEqual('' % self.name, repr(self.resource_class)) + self.assertEqual(f'', repr(self.resource_class)) class PoolManagerTest(utils.TestCase): - def setUp(self): - super(PoolManagerTest, self).setUp() + super().setUp() self.manager = scheduler_stats.PoolManager(fakes.FakeClient()) @mock.patch.object(scheduler_stats.PoolManager, '_list', mock.Mock()) def test_list(self): self.manager.list(detailed=False) self.manager._list.assert_called_once_with( - scheduler_stats.RESOURCES_PATH, - scheduler_stats.RESOURCES_NAME) + scheduler_stats.RESOURCES_PATH, scheduler_stats.RESOURCES_NAME + ) @mock.patch.object(scheduler_stats.PoolManager, '_list', mock.Mock()) def test_list_detail(self): self.manager.list() self.manager._list.assert_called_once_with( scheduler_stats.RESOURCES_PATH + '/detail', - scheduler_stats.RESOURCES_NAME) + scheduler_stats.RESOURCES_NAME, + ) @mock.patch.object(scheduler_stats.PoolManager, '_list', mock.Mock()) def test_list_with_one_search_opt(self): host = 'fake_host' - query_string = "?host=%s" % host + query_string = f"?host={host}" self.manager.list(detailed=False, search_opts={'host': host}) self.manager._list.assert_called_once_with( scheduler_stats.RESOURCES_PATH + query_string, - scheduler_stats.RESOURCES_NAME) + scheduler_stats.RESOURCES_NAME, + ) @mock.patch.object(scheduler_stats.PoolManager, '_list', mock.Mock()) def test_list_detail_with_two_search_opts(self): host = 'fake_host' backend = 'fake_backend' - query_string = "?backend=%s&host=%s" % (backend, host) + query_string = f"?backend={backend}&host={host}" self.manager.list(search_opts={'host': host, 'backend': backend}) self.manager._list.assert_called_once_with( scheduler_stats.RESOURCES_PATH + '/detail' + query_string, - scheduler_stats.RESOURCES_NAME) + scheduler_stats.RESOURCES_NAME, + ) diff --git a/manilaclient/tests/unit/v2/test_security_services.py b/manilaclient/tests/unit/v2/test_security_services.py index c780df42..c56ebb73 100644 --- a/manilaclient/tests/unit/v2/test_security_services.py +++ b/manilaclient/tests/unit/v2/test_security_services.py @@ -25,14 +25,14 @@ @ddt.ddt class SecurityServiceTest(utils.TestCase): - - class _FakeSecurityService(object): + class _FakeSecurityService: id = 'fake_security_service_id' def setUp(self): - super(SecurityServiceTest, self).setUp() + super().setUp() self.manager = security_services.SecurityServiceManager( - fakes.FakeClient()) + fakes.FakeClient() + ) def test_create_all_fields(self): values = { @@ -51,14 +51,18 @@ def test_create_all_fields(self): result = self.manager.create(**values) self.assertEqual(result['url'], security_services.RESOURCES_PATH) - self.assertEqual(result['resp_key'], - security_services.RESOURCE_NAME) + self.assertEqual( + result['resp_key'], security_services.RESOURCE_NAME + ) self.assertIn(security_services.RESOURCE_NAME, result['body']) - self.assertEqual(result['body'][security_services.RESOURCE_NAME], - values) + self.assertEqual( + result['body'][security_services.RESOURCE_NAME], values + ) - @ddt.data({'server': 'fake.ad.server'}, - {'default_ad_site': 'fake.ad.default_ad_site'}) + @ddt.data( + {'server': 'fake.ad.server'}, + {'default_ad_site': 'fake.ad.default_ad_site'}, + ) def test_create_all_fields_active_directory(self, option): values = { 'type': 'active_directory', @@ -76,11 +80,13 @@ def test_create_all_fields_active_directory(self, option): result = self.manager.create(**values) self.assertEqual(result['url'], security_services.RESOURCES_PATH) - self.assertEqual(result['resp_key'], - security_services.RESOURCE_NAME) + self.assertEqual( + result['resp_key'], security_services.RESOURCE_NAME + ) self.assertIn(security_services.RESOURCE_NAME, result['body']) - self.assertEqual(result['body'][security_services.RESOURCE_NAME], - values) + self.assertEqual( + result['body'][security_services.RESOURCE_NAME], values + ) def test_create_some_fields(self): values = { @@ -95,25 +101,29 @@ def test_create_some_fields(self): result = self.manager.create(**values) self.assertEqual(result['url'], security_services.RESOURCES_PATH) - self.assertEqual(result['resp_key'], - security_services.RESOURCE_NAME) + self.assertEqual( + result['resp_key'], security_services.RESOURCE_NAME + ) self.assertIn(security_services.RESOURCE_NAME, result['body']) - self.assertEqual(result['body'][security_services.RESOURCE_NAME], - values) + self.assertEqual( + result['body'][security_services.RESOURCE_NAME], values + ) def test_delete(self): security_service = 'fake service' with mock.patch.object(self.manager, '_delete', mock.Mock()): self.manager.delete(security_service) self.manager._delete.assert_called_once_with( - security_services.RESOURCE_PATH % security_service) + security_services.RESOURCE_PATH % security_service + ) def test_delete_by_object(self): security_service = self._FakeSecurityService() with mock.patch.object(self.manager, '_delete', mock.Mock()): self.manager.delete(security_service) self.manager._delete.assert_called_once_with( - security_services.RESOURCE_PATH % security_service.id) + security_services.RESOURCE_PATH % security_service.id + ) def test_get(self): security_service = 'fake service' @@ -121,7 +131,8 @@ def test_get(self): self.manager.get(security_service) self.manager._get.assert_called_once_with( security_services.RESOURCE_PATH % security_service, - security_services.RESOURCE_NAME) + security_services.RESOURCE_NAME, + ) def test_get_by_object(self): security_service = self._FakeSecurityService() @@ -129,41 +140,50 @@ def test_get_by_object(self): self.manager.get(security_service) self.manager._get.assert_called_once_with( security_services.RESOURCE_PATH % security_service.id, - security_services.RESOURCE_NAME) + security_services.RESOURCE_NAME, + ) def test_list_summary(self): - with mock.patch.object(self.manager, '_list', - mock.Mock(return_value=None)): + with mock.patch.object( + self.manager, '_list', mock.Mock(return_value=None) + ): self.manager.list(detailed=False) self.manager._list.assert_called_once_with( security_services.RESOURCES_PATH, - security_services.RESOURCES_NAME) + security_services.RESOURCES_NAME, + ) def test_list_detail(self): - with mock.patch.object(self.manager, '_list', - mock.Mock(return_value=None)): + with mock.patch.object( + self.manager, '_list', mock.Mock(return_value=None) + ): self.manager.list(detailed=True) self.manager._list.assert_called_once_with( security_services.RESOURCES_PATH + '/detail', - security_services.RESOURCES_NAME) + security_services.RESOURCES_NAME, + ) def test_list_no_filters(self): - with mock.patch.object(self.manager, '_list', - mock.Mock(return_value=None)): + with mock.patch.object( + self.manager, '_list', mock.Mock(return_value=None) + ): self.manager.list() self.manager._list.assert_called_once_with( security_services.RESOURCES_PATH + '/detail', - security_services.RESOURCES_NAME) + security_services.RESOURCES_NAME, + ) def test_list_with_filters(self): filters = {'all_tenants': 1, 'network': 'fake', 'status': 'ERROR'} - expected_postfix = ('/detail?all_tenants=1&network=fake&status=ERROR') - with mock.patch.object(self.manager, '_list', - mock.Mock(return_value=None)): + expected_postfix = '/detail?all_tenants=1&network=fake&status=ERROR' + with mock.patch.object( + self.manager, '_list', mock.Mock(return_value=None) + ): self.manager.list(search_opts=filters) self.manager._list.assert_called_once_with( security_services.RESOURCES_PATH + expected_postfix, - security_services.RESOURCES_NAME) + security_services.RESOURCES_NAME, + ) def test_update(self): security_service = 'fake service' @@ -179,13 +199,14 @@ def test_update(self): result = self.manager.update(security_service, **values) self.assertEqual( result['url'], - security_services.RESOURCE_PATH % security_service) + security_services.RESOURCE_PATH % security_service, + ) self.assertEqual( - result['resp_key'], - security_services.RESOURCE_NAME) + result['resp_key'], security_services.RESOURCE_NAME + ) self.assertEqual( - result['body'][security_services.RESOURCE_NAME], - values) + result['body'][security_services.RESOURCE_NAME], values + ) def test_update_by_object(self): security_service = self._FakeSecurityService() @@ -194,16 +215,17 @@ def test_update_by_object(self): result = self.manager.update(security_service, **values) self.assertEqual( result['url'], - security_services.RESOURCE_PATH % security_service.id) + security_services.RESOURCE_PATH % security_service.id, + ) self.assertEqual( - result['resp_key'], - security_services.RESOURCE_NAME) + result['resp_key'], security_services.RESOURCE_NAME + ) self.assertEqual( - result['body'][security_services.RESOURCE_NAME], - values) + result['body'][security_services.RESOURCE_NAME], values + ) def test_update_no_fields_specified(self): security_service = 'fake service' - self.assertRaises(exceptions.CommandError, - self.manager.update, - security_service) + self.assertRaises( + exceptions.CommandError, self.manager.update, security_service + ) diff --git a/manilaclient/tests/unit/v2/test_services.py b/manilaclient/tests/unit/v2/test_services.py index 93518fb0..e01abf08 100644 --- a/manilaclient/tests/unit/v2/test_services.py +++ b/manilaclient/tests/unit/v2/test_services.py @@ -24,15 +24,15 @@ @ddt.ddt class ServicesTest(utils.TestCase): - def _get_manager(self, microversion): version = api_versions.APIVersion(microversion) mock_microversion = mock.Mock(api_version=version) return services.ServiceManager(api=mock_microversion) def _get_resource_path(self, microversion): - if (api_versions.APIVersion(microversion) > - api_versions.APIVersion("2.6")): + if api_versions.APIVersion(microversion) > api_versions.APIVersion( + "2.6" + ): return services.RESOURCE_PATH return services.RESOURCE_PATH_LEGACY @@ -40,20 +40,21 @@ def _get_resource_path(self, microversion): def test_list(self, microversion): manager = self._get_manager(microversion) resource_path = self._get_resource_path(microversion) - with mock.patch.object(manager, '_list', - mock.Mock(return_value='fake')): + with mock.patch.object( + manager, '_list', mock.Mock(return_value='fake') + ): result = manager.list() manager._list.assert_called_once_with( - resource_path, services.RESOURCE_NAME) + resource_path, services.RESOURCE_NAME + ) self.assertEqual("fake", result) def test_list_services_with_one_search_opt(self): manager = self._get_manager("2.7") host = 'fake_host' - query_string = "?host=%s" % host - with mock.patch.object(manager, '_list', - mock.Mock(return_value=None)): + query_string = f"?host={host}" + with mock.patch.object(manager, '_list', mock.Mock(return_value=None)): manager.list({'host': host}) manager._list.assert_called_once_with( services.RESOURCE_PATH + query_string, @@ -64,9 +65,8 @@ def test_list_services_with_two_search_opts(self): manager = self._get_manager("2.7") host = 'fake_host' binary = 'fake_binary' - query_string = "?binary=%s&host=%s" % (binary, host) - with mock.patch.object(manager, '_list', - mock.Mock(return_value=None)): + query_string = f"?binary={binary}&host={host}" + with mock.patch.object(manager, '_list', mock.Mock(return_value=None)): manager.list({'binary': binary, 'host': host}) manager._list.assert_called_once_with( services.RESOURCE_PATH + query_string, diff --git a/manilaclient/tests/unit/v2/test_share_backups.py b/manilaclient/tests/unit/v2/test_share_backups.py index 9c027b75..b2f6bf4a 100644 --- a/manilaclient/tests/unit/v2/test_share_backups.py +++ b/manilaclient/tests/unit/v2/test_share_backups.py @@ -25,57 +25,62 @@ @ddt.ddt class ShareBackupsTest(utils.TestCase): - - class _FakeShareBackup(object): + class _FakeShareBackup: id = 'fake_share_backup_id' def setUp(self): - super(ShareBackupsTest, self).setUp() + super().setUp() microversion = api_versions.APIVersion("2.91") self.manager = share_backups.ShareBackupManager( - fakes.FakeClient(api_version=microversion)) + fakes.FakeClient(api_version=microversion) + ) def test_delete_str(self): with mock.patch.object(self.manager, '_delete', mock.Mock()): self.manager.delete(FAKE_BACKUP) self.manager._delete.assert_called_once_with( - share_backups.RESOURCE_PATH % FAKE_BACKUP) + share_backups.RESOURCE_PATH % FAKE_BACKUP + ) def test_delete_obj(self): backup = self._FakeShareBackup with mock.patch.object(self.manager, '_delete', mock.Mock()): self.manager.delete(backup) self.manager._delete.assert_called_once_with( - share_backups.RESOURCE_PATH % backup.id) + share_backups.RESOURCE_PATH % backup.id + ) def test_get(self): with mock.patch.object(self.manager, '_get', mock.Mock()): self.manager.get(FAKE_BACKUP) self.manager._get.assert_called_once_with( share_backups.RESOURCE_PATH % FAKE_BACKUP, - share_backups.RESOURCE_NAME) + share_backups.RESOURCE_NAME, + ) def test_restore(self): with mock.patch.object(self.manager, '_action', mock.Mock()): self.manager.restore(FAKE_BACKUP) self.manager._action.assert_called_once_with( - 'restore', FAKE_BACKUP, info=None) + 'restore', FAKE_BACKUP, info=None + ) def test_restore_to_target(self): with mock.patch.object(self.manager, '_action', mock.Mock()): self.manager.restore( - FAKE_BACKUP, - target_share_id=FAKE_TARGET_SHARE_ID + FAKE_BACKUP, target_share_id=FAKE_TARGET_SHARE_ID ) self.manager._action.assert_called_once_with( - 'restore', FAKE_BACKUP, info=FAKE_TARGET_SHARE_ID) + 'restore', FAKE_BACKUP, info=FAKE_TARGET_SHARE_ID + ) def test_list(self): with mock.patch.object(self.manager, '_list', mock.Mock()): self.manager.list() self.manager._list.assert_called_once_with( share_backups.RESOURCES_PATH + '/detail', - share_backups.RESOURCES_NAME) + share_backups.RESOURCES_NAME, + ) def test_list_with_share(self): with mock.patch.object(self.manager, '_list', mock.Mock()): @@ -83,13 +88,15 @@ def test_list_with_share(self): share_uri = '?share_id=fake_share_id' self.manager._list.assert_called_once_with( (share_backups.RESOURCES_PATH + '/detail' + share_uri), - share_backups.RESOURCES_NAME) + share_backups.RESOURCES_NAME, + ) def test_reset_state(self): with mock.patch.object(self.manager, '_action', mock.Mock()): self.manager.reset_status(FAKE_BACKUP, 'fake_status') self.manager._action.assert_called_once_with( - 'reset_status', FAKE_BACKUP, {'status': 'fake_status'}) + 'reset_status', FAKE_BACKUP, {'status': 'fake_status'} + ) def test_update(self): backup = self._FakeShareBackup @@ -97,5 +104,5 @@ def test_update(self): data = dict(name='backup1') self.manager.update(backup, **data) self.manager._update.assert_called_once_with( - share_backups.RESOURCE_PATH % backup.id, - {'share_backup': data}) + share_backups.RESOURCE_PATH % backup.id, {'share_backup': data} + ) diff --git a/manilaclient/tests/unit/v2/test_share_export_locations.py b/manilaclient/tests/unit/v2/test_share_export_locations.py index aaf8f66b..7ca9a3fd 100644 --- a/manilaclient/tests/unit/v2/test_share_export_locations.py +++ b/manilaclient/tests/unit/v2/test_share_export_locations.py @@ -32,27 +32,22 @@ @ddt.ddt class ShareExportLocationsTest(utils.TestCase): - def _get_manager(self, microversion): version = api_versions.APIVersion(microversion) mock_microversion = mock.Mock(api_version=version) - return ( - share_export_locations.ShareExportLocationManager( - api=mock_microversion) + return share_export_locations.ShareExportLocationManager( + api=mock_microversion ) def test_list_of_export_locations(self): share_id = '1234' cs.share_export_locations.list(share_id, search_opts=None) - cs.assert_called( - 'GET', '/shares/%s/export_locations' % share_id) + cs.assert_called('GET', f'/shares/{share_id}/export_locations') def test_get_single_export_location(self): share_id = '1234' el_uuid = 'fake_el_uuid' cs.share_export_locations.get(share_id, el_uuid) cs.assert_called( - 'GET', - ('/shares/%(share_id)s/export_locations/' - '%(el_uuid)s') % { - 'share_id': share_id, 'el_uuid': el_uuid}) + 'GET', (f'/shares/{share_id}/export_locations/{el_uuid}') + ) diff --git a/manilaclient/tests/unit/v2/test_share_group_snapshots.py b/manilaclient/tests/unit/v2/test_share_group_snapshots.py index d7c6269d..4629bc46 100644 --- a/manilaclient/tests/unit/v2/test_share_group_snapshots.py +++ b/manilaclient/tests/unit/v2/test_share_group_snapshots.py @@ -25,12 +25,12 @@ class ShareGroupSnapshotTest(utils.TestCase): - def setUp(self): - super(ShareGroupSnapshotTest, self).setUp() + super().setUp() self.manager = snapshots.ShareGroupSnapshotManager(fake.FakeClient()) self.share_group_snapshot = snapshots.ShareGroupSnapshot( - self.manager, {'id': 'fake_id'}) + self.manager, {'id': 'fake_id'} + ) self.fake_kwargs = {'key': 'value'} def test_repr(self): @@ -44,7 +44,8 @@ def test_update(self): self.share_group_snapshot.update(**self.fake_kwargs) mock_manager_update.assert_called_once_with( - self.share_group_snapshot, **self.fake_kwargs) + self.share_group_snapshot, **self.fake_kwargs + ) def test_delete(self): mock_manager_delete = self.mock_object(self.manager, 'delete') @@ -55,26 +56,29 @@ def test_delete(self): def test_reset_state(self): mock_manager_reset_state = self.mock_object( - self.manager, 'reset_state') + self.manager, 'reset_state' + ) self.share_group_snapshot.reset_state('fake_state') mock_manager_reset_state.assert_called_once_with( - self.share_group_snapshot, 'fake_state') + self.share_group_snapshot, 'fake_state' + ) @ddt.ddt class ShareGroupSnapshotManagerTest(utils.TestCase): - def setUp(self): - super(ShareGroupSnapshotManagerTest, self).setUp() + super().setUp() self.manager = snapshots.ShareGroupSnapshotManager(fake.FakeClient()) def test_create(self): fake_share_group_snapshot = fake.ShareGroupSnapshot() mock_create = self.mock_object( - self.manager, '_create', - mock.Mock(return_value=fake_share_group_snapshot)) + self.manager, + '_create', + mock.Mock(return_value=fake_share_group_snapshot), + ) create_args = { 'name': fake.ShareGroupSnapshot.name, 'description': fake.ShareGroupSnapshot.description, @@ -91,13 +95,16 @@ def test_create(self): }, } mock_create.assert_called_once_with( - snapshots.RESOURCES_PATH, expected_body, snapshots.RESOURCE_NAME) + snapshots.RESOURCES_PATH, expected_body, snapshots.RESOURCE_NAME + ) def test_create_minimal_args(self): fake_share_group_snapshot = fake.ShareGroupSnapshot() mock_create = self.mock_object( - self.manager, '_create', - mock.Mock(return_value=fake_share_group_snapshot)) + self.manager, + '_create', + mock.Mock(return_value=fake_share_group_snapshot), + ) result = self.manager.create(fake.ShareGroupSnapshot) @@ -108,99 +115,125 @@ def test_create_minimal_args(self): }, } mock_create.assert_called_once_with( - snapshots.RESOURCES_PATH, expected_body, snapshots.RESOURCE_NAME) + snapshots.RESOURCES_PATH, expected_body, snapshots.RESOURCE_NAME + ) def test_create_using_unsupported_microversion(self): self.manager.api.api_version = manilaclient.API_MIN_VERSION self.assertRaises( exceptions.UnsupportedVersion, - self.manager.create, fake.ShareGroupSnapshot) + self.manager.create, + fake.ShareGroupSnapshot, + ) def test_get(self): fake_share_group_snapshot = fake.ShareGroupSnapshot() mock_get = self.mock_object( - self.manager, '_get', - mock.Mock(return_value=fake_share_group_snapshot)) + self.manager, + '_get', + mock.Mock(return_value=fake_share_group_snapshot), + ) result = self.manager.get(fake.ShareGroupSnapshot.id) self.assertIs(fake_share_group_snapshot, result) mock_get.assert_called_once_with( snapshots.RESOURCE_PATH % fake.ShareGroupSnapshot.id, - snapshots.RESOURCE_NAME) + snapshots.RESOURCE_NAME, + ) def test_list(self): fake_share_group_snapshot = fake.ShareGroupSnapshot() mock_list = self.mock_object( - self.manager, '_list', - mock.Mock(return_value=[fake_share_group_snapshot])) + self.manager, + '_list', + mock.Mock(return_value=[fake_share_group_snapshot]), + ) result = self.manager.list() self.assertEqual([fake_share_group_snapshot], result) mock_list.assert_called_once_with( - snapshots.RESOURCES_PATH + '/detail', - snapshots.RESOURCES_NAME) + snapshots.RESOURCES_PATH + '/detail', snapshots.RESOURCES_NAME + ) def test_list_no_detail(self): fake_share_group_snapshot = fake.ShareGroupSnapshot() mock_list = self.mock_object( - self.manager, '_list', - mock.Mock(return_value=[fake_share_group_snapshot])) + self.manager, + '_list', + mock.Mock(return_value=[fake_share_group_snapshot]), + ) result = self.manager.list(detailed=False) self.assertEqual([fake_share_group_snapshot], result) mock_list.assert_called_once_with( - snapshots.RESOURCES_PATH, snapshots.RESOURCES_NAME) + snapshots.RESOURCES_PATH, snapshots.RESOURCES_NAME + ) def test_list_with_filters(self): fake_share_group_snapshot = fake.ShareGroupSnapshot() mock_list = self.mock_object( - self.manager, '_list', - mock.Mock(return_value=[fake_share_group_snapshot])) + self.manager, + '_list', + mock.Mock(return_value=[fake_share_group_snapshot]), + ) filters = {'all_tenants': 1, 'status': 'ERROR'} result = self.manager.list(detailed=False, search_opts=filters) self.assertEqual([fake_share_group_snapshot], result) - expected_path = (snapshots.RESOURCES_PATH + - '?all_tenants=1&status=ERROR') + expected_path = ( + snapshots.RESOURCES_PATH + '?all_tenants=1&status=ERROR' + ) mock_list.assert_called_once_with( - expected_path, snapshots.RESOURCES_NAME) + expected_path, snapshots.RESOURCES_NAME + ) def test_list_with_sorting(self): fake_share_group_snapshot = fake.ShareGroupSnapshot() mock_list = self.mock_object( - self.manager, '_list', - mock.Mock(return_value=[fake_share_group_snapshot])) + self.manager, + '_list', + mock.Mock(return_value=[fake_share_group_snapshot]), + ) result = self.manager.list( - detailed=False, sort_dir='asc', sort_key='name') + detailed=False, sort_dir='asc', sort_key='name' + ) self.assertEqual([fake_share_group_snapshot], result) expected_path = ( - snapshots.RESOURCES_PATH + '?sort_dir=asc&sort_key=name') + snapshots.RESOURCES_PATH + '?sort_dir=asc&sort_key=name' + ) mock_list.assert_called_once_with( - expected_path, snapshots.RESOURCES_NAME) + expected_path, snapshots.RESOURCES_NAME + ) - @ddt.data({'sort_key': 'name', 'sort_dir': 'invalid'}, - {'sort_key': 'invalid', 'sort_dir': 'asc'}) + @ddt.data( + {'sort_key': 'name', 'sort_dir': 'invalid'}, + {'sort_key': 'invalid', 'sort_dir': 'asc'}, + ) @ddt.unpack def test_list_with_invalid_sorting(self, sort_key, sort_dir): self.assertRaises( - ValueError, - self.manager.list, sort_dir=sort_dir, sort_key=sort_key) + ValueError, self.manager.list, sort_dir=sort_dir, sort_key=sort_key + ) def test_update(self): fake_share_group_snapshot = fake.ShareGroupSnapshot() mock_get = self.mock_object( - self.manager, '_get', - mock.Mock(return_value=fake_share_group_snapshot)) + self.manager, + '_get', + mock.Mock(return_value=fake_share_group_snapshot), + ) mock_update = self.mock_object( - self.manager, '_update', - mock.Mock(return_value=fake_share_group_snapshot)) + self.manager, + '_update', + mock.Mock(return_value=fake_share_group_snapshot), + ) update_args = { 'name': fake.ShareGroupSnapshot.name, 'description': fake.ShareGroupSnapshot.description, @@ -213,16 +246,21 @@ def test_update(self): mock_update.assert_called_once_with( snapshots.RESOURCE_PATH % fake.ShareGroupSnapshot.id, {snapshots.RESOURCE_NAME: update_args}, - snapshots.RESOURCE_NAME) + snapshots.RESOURCE_NAME, + ) def test_update_no_data(self): fake_share_group_snapshot = fake.ShareGroupSnapshot() mock_get = self.mock_object( - self.manager, '_get', - mock.Mock(return_value=fake_share_group_snapshot)) + self.manager, + '_get', + mock.Mock(return_value=fake_share_group_snapshot), + ) mock_update = self.mock_object( - self.manager, '_update', - mock.Mock(return_value=fake_share_group_snapshot)) + self.manager, + '_update', + mock.Mock(return_value=fake_share_group_snapshot), + ) update_args = {} result = self.manager.update(fake.ShareGroupSnapshot(), **update_args) @@ -230,7 +268,8 @@ def test_update_no_data(self): self.assertIs(fake_share_group_snapshot, result) mock_get.assert_called_once_with( snapshots.RESOURCE_PATH % fake.ShareGroupSnapshot.id, - snapshots.RESOURCE_NAME) + snapshots.RESOURCE_NAME, + ) self.assertFalse(mock_update.called) def test_delete(self): @@ -240,7 +279,8 @@ def test_delete(self): self.manager.delete(fake.ShareGroupSnapshot()) mock_delete.assert_called_once_with( - snapshots.RESOURCE_PATH % fake.ShareGroupSnapshot.id) + snapshots.RESOURCE_PATH % fake.ShareGroupSnapshot.id + ) self.assertFalse(mock_post.called) def test_delete_force(self): @@ -252,7 +292,8 @@ def test_delete_force(self): self.assertFalse(mock_delete.called) mock_post.assert_called_once_with( snapshots.RESOURCE_PATH_ACTION % fake.ShareGroupSnapshot.id, - body={'force_delete': None}) + body={'force_delete': None}, + ) def test_reset_state(self): mock_post = self.mock_object(self.manager.api.client, 'post') @@ -261,4 +302,5 @@ def test_reset_state(self): mock_post.assert_called_once_with( snapshots.RESOURCE_PATH_ACTION % fake.ShareGroupSnapshot.id, - body={'reset_status': {'status': 'fake_state'}}) + body={'reset_status': {'status': 'fake_state'}}, + ) diff --git a/manilaclient/tests/unit/v2/test_share_group_type_access.py b/manilaclient/tests/unit/v2/test_share_group_type_access.py index def93a10..64b4faa2 100644 --- a/manilaclient/tests/unit/v2/test_share_group_type_access.py +++ b/manilaclient/tests/unit/v2/test_share_group_type_access.py @@ -26,50 +26,58 @@ @ddt.ddt class ShareGroupTypeAccessTest(utils.TestCase): - def setUp(self): - super(ShareGroupTypeAccessTest, self).setUp() + super().setUp() self.manager = type_access.ShareGroupTypeAccessManager( - fake.FakeClient()) + fake.FakeClient() + ) fake_group_type_access_info = { - 'share_group_type_id': fake.ShareGroupTypeAccess.id} + 'share_group_type_id': fake.ShareGroupTypeAccess.id + } self.share_group_type_access = type_access.ShareGroupTypeAccess( - self.manager, fake_group_type_access_info, loaded=True) + self.manager, fake_group_type_access_info, loaded=True + ) def test_repr(self): result = str(self.share_group_type_access) self.assertEqual( - '' % fake.ShareGroupTypeAccess.id, - result) + f'', + result, + ) @ddt.ddt class ShareGroupTypeAccessManagerTest(utils.TestCase): - def setUp(self): - super(ShareGroupTypeAccessManagerTest, self).setUp() + super().setUp() self.manager = type_access.ShareGroupTypeAccessManager( - fake.FakeClient()) + fake.FakeClient() + ) def test_list(self): fake_share_group_type_access = fake.ShareGroupTypeAccess() mock_list = self.mock_object( - self.manager, '_list', - mock.Mock(return_value=[fake_share_group_type_access])) + self.manager, + '_list', + mock.Mock(return_value=[fake_share_group_type_access]), + ) result = self.manager.list(fake.ShareGroupType(), search_opts=None) self.assertEqual([fake_share_group_type_access], result) mock_list.assert_called_once_with( type_access.RESOURCE_PATH % fake.ShareGroupType.id, - type_access.RESOURCE_NAME) + type_access.RESOURCE_NAME, + ) def test_list_public(self): fake_share_group_type_access = fake.ShareGroupTypeAccess() mock_list = self.mock_object( - self.manager, '_list', - mock.Mock(return_value=[fake_share_group_type_access])) + self.manager, + '_list', + mock.Mock(return_value=[fake_share_group_type_access]), + ) fake_share_group_type = fake.ShareGroupType() fake_share_group_type.is_public = True @@ -84,7 +92,9 @@ def test_list_using_unsupported_microversion(self): self.assertRaises( exceptions.UnsupportedVersion, - self.manager.list, fake_share_group_type_access) + self.manager.list, + fake_share_group_type_access, + ) def test_add_project_access(self): mock_post = self.mock_object(self.manager.api.client, 'post') @@ -98,13 +108,15 @@ def test_add_project_access(self): } mock_post.assert_called_once_with( type_access.RESOURCE_PATH_ACTION % fake.ShareGroupType.id, - body=expected_body) + body=expected_body, + ) def test_remove_project_access(self): mock_post = self.mock_object(self.manager.api.client, 'post') self.manager.remove_project_access( - fake.ShareGroupType(), 'fake_project') + fake.ShareGroupType(), 'fake_project' + ) expected_body = { 'removeProjectAccess': { @@ -113,4 +125,5 @@ def test_remove_project_access(self): } mock_post.assert_called_once_with( type_access.RESOURCE_PATH_ACTION % fake.ShareGroupType.id, - body=expected_body) + body=expected_body, + ) diff --git a/manilaclient/tests/unit/v2/test_share_group_types.py b/manilaclient/tests/unit/v2/test_share_group_types.py index 53b86999..8a3390c2 100644 --- a/manilaclient/tests/unit/v2/test_share_group_types.py +++ b/manilaclient/tests/unit/v2/test_share_group_types.py @@ -26,9 +26,8 @@ @ddt.ddt class ShareGroupTypeTest(utils.TestCase): - def setUp(self): - super(ShareGroupTypeTest, self).setUp() + super().setUp() self.manager = types.ShareGroupTypeManager(fake.FakeClient()) self.fake_group_specs = {'key1': 'value1', 'key2': 'value2'} self.fake_share_group_type_info = { @@ -39,13 +38,15 @@ def setUp(self): 'group_specs': self.fake_group_specs, } self.share_group_type = types.ShareGroupType( - self.manager, self.fake_share_group_type_info, loaded=True) + self.manager, self.fake_share_group_type_info, loaded=True + ) def test_repr(self): result = str(self.share_group_type) self.assertEqual( - '' % fake.ShareGroupType.name, result) + f'', result + ) @ddt.data((True, True), (False, False), (None, 'N/A')) @ddt.unpack @@ -54,7 +55,8 @@ def test_is_public(self, is_public, expected): if is_public is not None: fake_share_group_type_info['is_public'] = is_public share_group_type = types.ShareGroupType( - self.manager, fake_share_group_type_info, loaded=True) + self.manager, fake_share_group_type_info, loaded=True + ) result = share_group_type.is_public @@ -70,21 +72,26 @@ def test_get_keys(self): def test_get_keys_force_api_call(self): share_group_type = types.ShareGroupType( - self.manager, self.fake_share_group_type_info, loaded=True) + self.manager, self.fake_share_group_type_info, loaded=True + ) share_group_type._group_specs = {} - self.manager.api.client.get = mock.Mock(return_value=( - None, self.fake_share_group_type_info)) + self.manager.api.client.get = mock.Mock( + return_value=(None, self.fake_share_group_type_info) + ) result = share_group_type.get_keys(prefer_resource_data=False) self.assertEqual(self.fake_group_specs, result) self.manager.api.client.get.assert_called_once_with( - types.GROUP_SPECS_RESOURCES_PATH % fake.ShareGroupType.id) + types.GROUP_SPECS_RESOURCES_PATH % fake.ShareGroupType.id + ) def test_set_keys(self): mock_manager_create = self.mock_object( - self.manager, '_create', - mock.Mock(return_value=self.fake_group_specs)) + self.manager, + '_create', + mock.Mock(return_value=self.fake_group_specs), + ) result = self.share_group_type.set_keys(self.fake_group_specs) @@ -92,47 +99,62 @@ def test_set_keys(self): expected_body = {'group_specs': self.fake_group_specs} mock_manager_create.assert_called_once_with( types.GROUP_SPECS_RESOURCES_PATH % fake.ShareGroupType.id, - expected_body, types.GROUP_SPECS_RESOURCES_NAME, return_raw=True) + expected_body, + types.GROUP_SPECS_RESOURCES_NAME, + return_raw=True, + ) def test_unset_keys(self): mock_manager_delete = self.mock_object( - self.manager, '_delete', mock.Mock(return_value=None)) + self.manager, '_delete', mock.Mock(return_value=None) + ) result = self.share_group_type.unset_keys(self.fake_group_specs.keys()) self.assertIsNone(result) - mock_manager_delete.assert_has_calls([ - mock.call(types.GROUP_SPECS_RESOURCE_PATH % - (fake.ShareGroupType.id, 'key1')), - mock.call(types.GROUP_SPECS_RESOURCE_PATH % - (fake.ShareGroupType.id, 'key2')), - ], any_order=True) + mock_manager_delete.assert_has_calls( + [ + mock.call( + types.GROUP_SPECS_RESOURCE_PATH + % (fake.ShareGroupType.id, 'key1') + ), + mock.call( + types.GROUP_SPECS_RESOURCE_PATH + % (fake.ShareGroupType.id, 'key2') + ), + ], + any_order=True, + ) def test_unset_keys_error(self): mock_manager_delete = self.mock_object( - self.manager, '_delete', mock.Mock(return_value='error')) + self.manager, '_delete', mock.Mock(return_value='error') + ) result = self.share_group_type.unset_keys( - sorted(self.fake_group_specs.keys())) + sorted(self.fake_group_specs.keys()) + ) self.assertEqual('error', result) mock_manager_delete.assert_called_once_with( - types.GROUP_SPECS_RESOURCE_PATH % (fake.ShareGroupType.id, 'key1')) + types.GROUP_SPECS_RESOURCE_PATH % (fake.ShareGroupType.id, 'key1') + ) @ddt.ddt class ShareGroupTypeManagerTest(utils.TestCase): - def setUp(self): - super(ShareGroupTypeManagerTest, self).setUp() + super().setUp() self.manager = types.ShareGroupTypeManager(fake.FakeClient()) self.fake_group_specs = {'key1': 'value1', 'key2': 'value2'} def test_create(self): fake_share_group_type = fake.ShareGroupType() mock_create = self.mock_object( - self.manager, '_create', - mock.Mock(return_value=fake_share_group_type)) + self.manager, + '_create', + mock.Mock(return_value=fake_share_group_type), + ) create_args = { 'name': fake.ShareGroupType.name, 'share_types': [fake.ShareType()], @@ -152,7 +174,8 @@ def test_create(self): }, } mock_create.assert_called_once_with( - types.RESOURCES_PATH, expected_body, types.RESOURCE_NAME) + types.RESOURCES_PATH, expected_body, types.RESOURCE_NAME + ) def test_create_no_share_type(self): create_args = { @@ -172,38 +195,45 @@ def test_create_using_unsupported_microversion(self): def test_get(self): fake_share_group_type = fake.ShareGroupType() mock_get = self.mock_object( - self.manager, '_get', - mock.Mock(return_value=fake_share_group_type)) + self.manager, '_get', mock.Mock(return_value=fake_share_group_type) + ) result = self.manager.get(fake.ShareGroupType.id) self.assertIs(fake_share_group_type, result) mock_get.assert_called_once_with( - types.RESOURCE_PATH % fake.ShareGroupType.id, types.RESOURCE_NAME) + types.RESOURCE_PATH % fake.ShareGroupType.id, types.RESOURCE_NAME + ) def test_list(self): fake_share_group_type = fake.ShareGroupType() mock_list = self.mock_object( - self.manager, '_list', - mock.Mock(return_value=[fake_share_group_type])) + self.manager, + '_list', + mock.Mock(return_value=[fake_share_group_type]), + ) result = self.manager.list(search_opts=None) self.assertEqual([fake_share_group_type], result) mock_list.assert_called_once_with( - types.RESOURCES_PATH + '?is_public=all', types.RESOURCES_NAME) + types.RESOURCES_PATH + '?is_public=all', types.RESOURCES_NAME + ) def test_list_no_public(self): fake_share_group_type = fake.ShareGroupType() mock_list = self.mock_object( - self.manager, '_list', - mock.Mock(return_value=[fake_share_group_type])) + self.manager, + '_list', + mock.Mock(return_value=[fake_share_group_type]), + ) result = self.manager.list(show_all=False) self.assertEqual([fake_share_group_type], result) mock_list.assert_called_once_with( - types.RESOURCES_PATH, types.RESOURCES_NAME) + types.RESOURCES_PATH, types.RESOURCES_NAME + ) def test_delete(self): mock_delete = self.mock_object(self.manager, '_delete') @@ -211,4 +241,5 @@ def test_delete(self): self.manager.delete(fake.ShareGroupType()) mock_delete.assert_called_once_with( - types.RESOURCE_PATH % fake.ShareGroupType.id) + types.RESOURCE_PATH % fake.ShareGroupType.id + ) diff --git a/manilaclient/tests/unit/v2/test_share_groups.py b/manilaclient/tests/unit/v2/test_share_groups.py index 9601d966..adefad2f 100644 --- a/manilaclient/tests/unit/v2/test_share_groups.py +++ b/manilaclient/tests/unit/v2/test_share_groups.py @@ -26,12 +26,12 @@ @ddt.ddt class ShareGroupTest(utils.TestCase): - def setUp(self): - super(ShareGroupTest, self).setUp() + super().setUp() self.manager = share_groups.ShareGroupManager(fake.FakeClient()) self.share_group = share_groups.ShareGroup( - self.manager, {'id': 'fake_id'}) + self.manager, {'id': 'fake_id'} + ) self.fake_kwargs = {'key': 'value'} def test_repr(self): @@ -45,7 +45,8 @@ def test_update(self): self.share_group.update(**self.fake_kwargs) mock_manager_update.assert_called_once_with( - self.share_group, **self.fake_kwargs) + self.share_group, **self.fake_kwargs + ) def test_delete(self): mock_manager_delete = self.mock_object(self.manager, 'delete') @@ -53,7 +54,8 @@ def test_delete(self): self.share_group.delete() mock_manager_delete.assert_called_once_with( - self.share_group, force=False) + self.share_group, force=False + ) @ddt.data(True, False) def test_delete_force(self, force): @@ -62,29 +64,32 @@ def test_delete_force(self, force): self.share_group.delete(force=force) mock_manager_delete.assert_called_once_with( - self.share_group, force=force) + self.share_group, force=force + ) def test_reset_state(self): mock_manager_reset_state = self.mock_object( - self.manager, 'reset_state') + self.manager, 'reset_state' + ) self.share_group.reset_state('fake_state') mock_manager_reset_state.assert_called_once_with( - self.share_group, 'fake_state') + self.share_group, 'fake_state' + ) @ddt.ddt class ShareGroupManagerTest(utils.TestCase): - def setUp(self): - super(ShareGroupManagerTest, self).setUp() + super().setUp() self.manager = share_groups.ShareGroupManager(fake.FakeClient()) def test_create(self): fake_share_group = fake.ShareGroup() mock_create = self.mock_object( - self.manager, '_create', mock.Mock(return_value=fake_share_group)) + self.manager, '_create', mock.Mock(return_value=fake_share_group) + ) create_args = { 'name': fake.ShareGroup.name, 'description': fake.ShareGroup.description, @@ -110,12 +115,14 @@ def test_create(self): mock_create.assert_called_once_with( share_groups.RESOURCES_PATH, expected_body, - share_groups.RESOURCE_NAME) + share_groups.RESOURCE_NAME, + ) def test_create_default_type(self): fake_share_group = fake.ShareGroup() mock_create = self.mock_object( - self.manager, '_create', mock.Mock(return_value=fake_share_group)) + self.manager, '_create', mock.Mock(return_value=fake_share_group) + ) create_args = { 'name': fake.ShareGroup.name, 'description': fake.ShareGroup.description, @@ -129,12 +136,14 @@ def test_create_default_type(self): mock_create.assert_called_once_with( share_groups.RESOURCES_PATH, expected_body, - share_groups.RESOURCE_NAME) + share_groups.RESOURCE_NAME, + ) def test_create_from_snapshot(self): fake_share_group = fake.ShareGroup() mock_create = self.mock_object( - self.manager, '_create', mock.Mock(return_value=fake_share_group)) + self.manager, '_create', mock.Mock(return_value=fake_share_group) + ) create_args = { 'name': fake.ShareGroup.name, 'description': fake.ShareGroup.description, @@ -156,7 +165,8 @@ def test_create_from_snapshot(self): mock_create.assert_called_once_with( share_groups.RESOURCES_PATH, expected_body, - share_groups.RESOURCE_NAME) + share_groups.RESOURCE_NAME, + ) def test_create_using_unsupported_microversion(self): self.manager.api.api_version = manilaclient.API_MIN_VERSION @@ -176,50 +186,58 @@ def test_create_invalid_arguments(self): def test_get(self): fake_share_group = fake.ShareGroup() mock_get = self.mock_object( - self.manager, '_get', mock.Mock(return_value=fake_share_group)) + self.manager, '_get', mock.Mock(return_value=fake_share_group) + ) result = self.manager.get(fake.ShareGroup.id) self.assertIs(fake_share_group, result) mock_get.assert_called_once_with( share_groups.RESOURCE_PATH % fake.ShareGroup.id, - share_groups.RESOURCE_NAME) + share_groups.RESOURCE_NAME, + ) def test_list(self): fake_share_group = fake.ShareGroup() mock_list = self.mock_object( - self.manager, '_list', mock.Mock(return_value=[fake_share_group])) + self.manager, '_list', mock.Mock(return_value=[fake_share_group]) + ) result = self.manager.list() self.assertEqual([fake_share_group], result) mock_list.assert_called_once_with( share_groups.RESOURCES_PATH + '/detail', - share_groups.RESOURCES_NAME) + share_groups.RESOURCES_NAME, + ) def test_list_no_detail(self): fake_share_group = fake.ShareGroup() mock_list = self.mock_object( - self.manager, '_list', mock.Mock(return_value=[fake_share_group])) + self.manager, '_list', mock.Mock(return_value=[fake_share_group]) + ) result = self.manager.list(detailed=False) self.assertEqual([fake_share_group], result) mock_list.assert_called_once_with( - share_groups.RESOURCES_PATH, share_groups.RESOURCES_NAME) + share_groups.RESOURCES_PATH, share_groups.RESOURCES_NAME + ) def test_list_with_filters(self): fake_share_group = fake.ShareGroup() mock_list = self.mock_object( - self.manager, '_list', mock.Mock(return_value=[fake_share_group])) + self.manager, '_list', mock.Mock(return_value=[fake_share_group]) + ) filters = {'all_tenants': 1} result = self.manager.list(detailed=False, search_opts=filters) self.assertEqual([fake_share_group], result) - expected_path = (share_groups.RESOURCES_PATH + '?all_tenants=1') + expected_path = share_groups.RESOURCES_PATH + '?all_tenants=1' mock_list.assert_called_once_with( - expected_path, share_groups.RESOURCES_NAME) + expected_path, share_groups.RESOURCES_NAME + ) @ddt.data( ('name', 'name'), @@ -230,17 +248,22 @@ def test_list_with_filters(self): def test_list_with_sorting(self, key, expected_key): fake_share_group = fake.ShareGroup() mock_list = self.mock_object( - self.manager, '_list', mock.Mock(return_value=[fake_share_group])) + self.manager, '_list', mock.Mock(return_value=[fake_share_group]) + ) result = self.manager.list( - detailed=False, sort_dir='asc', sort_key=key) + detailed=False, sort_dir='asc', sort_key=key + ) self.assertEqual([fake_share_group], result) expected_path = ( - share_groups.RESOURCES_PATH + '?sort_dir=asc&sort_key=' + - expected_key) + share_groups.RESOURCES_PATH + + '?sort_dir=asc&sort_key=' + + expected_key + ) mock_list.assert_called_once_with( - expected_path, share_groups.RESOURCES_NAME) + expected_path, share_groups.RESOURCES_NAME + ) @ddt.data( ('name', 'invalid'), @@ -249,15 +272,17 @@ def test_list_with_sorting(self, key, expected_key): @ddt.unpack def test_list_with_invalid_sorting(self, sort_key, sort_dir): self.assertRaises( - ValueError, - self.manager.list, sort_dir=sort_dir, sort_key=sort_key) + ValueError, self.manager.list, sort_dir=sort_dir, sort_key=sort_key + ) def test_update(self): fake_share_group = fake.ShareGroup() mock_get = self.mock_object( - self.manager, '_get', mock.Mock(return_value=fake_share_group)) + self.manager, '_get', mock.Mock(return_value=fake_share_group) + ) mock_update = self.mock_object( - self.manager, '_update', mock.Mock(return_value=fake_share_group)) + self.manager, '_update', mock.Mock(return_value=fake_share_group) + ) update_args = { 'name': fake.ShareGroup.name, 'description': fake.ShareGroup.description, @@ -270,14 +295,17 @@ def test_update(self): mock_update.assert_called_once_with( share_groups.RESOURCE_PATH % fake.ShareGroup.id, {share_groups.RESOURCE_NAME: update_args}, - share_groups.RESOURCE_NAME) + share_groups.RESOURCE_NAME, + ) def test_update_no_data(self): fake_share_group = fake.ShareGroup() mock_get = self.mock_object( - self.manager, '_get', mock.Mock(return_value=fake_share_group)) + self.manager, '_get', mock.Mock(return_value=fake_share_group) + ) mock_update = self.mock_object( - self.manager, '_update', mock.Mock(return_value=fake_share_group)) + self.manager, '_update', mock.Mock(return_value=fake_share_group) + ) update_args = {} result = self.manager.update(fake.ShareGroup(), **update_args) @@ -285,7 +313,8 @@ def test_update_no_data(self): self.assertIs(fake_share_group, result) mock_get.assert_called_once_with( share_groups.RESOURCE_PATH % fake.ShareGroup.id, - share_groups.RESOURCE_NAME) + share_groups.RESOURCE_NAME, + ) self.assertFalse(mock_update.called) def test_delete(self): @@ -295,7 +324,8 @@ def test_delete(self): self.manager.delete(fake.ShareGroup()) mock_delete.assert_called_once_with( - share_groups.RESOURCE_PATH % fake.ShareGroup.id) + share_groups.RESOURCE_PATH % fake.ShareGroup.id + ) self.assertFalse(mock_post.called) def test_delete_force(self): @@ -307,7 +337,8 @@ def test_delete_force(self): self.assertFalse(mock_delete.called) mock_post.assert_called_once_with( share_groups.RESOURCE_PATH_ACTION % fake.ShareGroup.id, - body={'force_delete': None}) + body={'force_delete': None}, + ) def test_reset_state(self): mock_post = self.mock_object(self.manager.api.client, 'post') @@ -316,4 +347,5 @@ def test_reset_state(self): mock_post.assert_called_once_with( share_groups.RESOURCE_PATH_ACTION % fake.ShareGroup.id, - body={'reset_status': {'status': 'fake_state'}}) + body={'reset_status': {'status': 'fake_state'}}, + ) diff --git a/manilaclient/tests/unit/v2/test_share_instance_export_locations.py b/manilaclient/tests/unit/v2/test_share_instance_export_locations.py index 4fa95565..0adb8aad 100644 --- a/manilaclient/tests/unit/v2/test_share_instance_export_locations.py +++ b/manilaclient/tests/unit/v2/test_share_instance_export_locations.py @@ -25,29 +25,32 @@ extensions = [ - extension.Extension('share_instance_export_locations', - share_instance_export_locations), + extension.Extension( + 'share_instance_export_locations', share_instance_export_locations + ), ] cs = fakes.FakeClient(extensions=extensions) @ddt.ddt class ShareInstanceExportLocationsTest(utils.TestCase): - def _get_manager(self, microversion): version = api_versions.APIVersion(microversion) mock_microversion = mock.Mock(api_version=version) return ( share_instance_export_locations.ShareInstanceExportLocationManager( - api=mock_microversion) + api=mock_microversion + ) ) def test_list_of_export_locations(self): share_instance_id = '1234' cs.share_instance_export_locations.list( - share_instance_id, search_opts=None) + share_instance_id, search_opts=None + ) cs.assert_called( - 'GET', '/share_instances/%s/export_locations' % share_instance_id) + 'GET', f'/share_instances/{share_instance_id}/export_locations' + ) def test_get_single_export_location(self): share_instance_id = '1234' @@ -55,6 +58,8 @@ def test_get_single_export_location(self): cs.share_instance_export_locations.get(share_instance_id, el_uuid) cs.assert_called( 'GET', - ('/share_instances/%(share_instance_id)s/export_locations/' - '%(el_uuid)s') % { - 'share_instance_id': share_instance_id, 'el_uuid': el_uuid}) + ( + f'/share_instances/{share_instance_id}/export_locations/' + f'{el_uuid}' + ), + ) diff --git a/manilaclient/tests/unit/v2/test_share_instances.py b/manilaclient/tests/unit/v2/test_share_instances.py index a59f19d2..2d6f44d1 100644 --- a/manilaclient/tests/unit/v2/test_share_instances.py +++ b/manilaclient/tests/unit/v2/test_share_instances.py @@ -32,7 +32,6 @@ @ddt.ddt class ShareInstancesTest(utils.TestCase): - def _get_manager(self, microversion): version = api_versions.APIVersion(microversion) mock_microversion = mock.Mock(api_version=version) @@ -42,25 +41,28 @@ def test_list(self): cs.share_instances.list(search_opts=None) cs.assert_called('GET', '/share_instances') - @ddt.data(('id', 'b4991315-eb7d-43ec-979e-5715d4399827'), - ('path', '//0.0.0.0/fake_path')) + @ddt.data( + ('id', 'b4991315-eb7d-43ec-979e-5715d4399827'), + ('path', '//0.0.0.0/fake_path'), + ) @ddt.unpack def test_list_by_export_location(self, filter_type, value): cs.share_instances.list(export_location=value) cs.assert_called( - 'GET', '/share_instances?export_location_' + - filter_type + '=' + value) + 'GET', + '/share_instances?export_location_' + filter_type + '=' + value, + ) def test_get(self): - instance = type('None', (object, ), {'id': '1234'}) + instance = type('None', (object,), {'id': '1234'}) cs.share_instances.get(instance) cs.assert_called('GET', '/share_instances/1234') @ddt.data( - ("2.6", type("InstanceUUID", (object, ), {"uuid": "1234"})), - ("2.7", type("InstanceUUID", (object, ), {"uuid": "1234"})), - ("2.6", type("InstanceID", (object, ), {"id": "1234"})), - ("2.7", type("InstanceID", (object, ), {"id": "1234"})), + ("2.6", type("InstanceUUID", (object,), {"uuid": "1234"})), + ("2.7", type("InstanceUUID", (object,), {"uuid": "1234"})), + ("2.6", type("InstanceID", (object,), {"id": "1234"})), + ("2.7", type("InstanceID", (object,), {"id": "1234"})), ("2.6", "1234"), ("2.7", "1234"), ) @@ -68,8 +70,9 @@ def test_get(self): def test_reset_instance_state(self, microversion, instance): manager = self._get_manager(microversion) state = 'available' - if (api_versions.APIVersion(microversion) > - api_versions.APIVersion("2.6")): + if api_versions.APIVersion(microversion) > api_versions.APIVersion( + "2.6" + ): action_name = "reset_status" else: action_name = "os-reset_status" @@ -78,19 +81,21 @@ def test_reset_instance_state(self, microversion, instance): manager.reset_state(instance, state) manager._action.assert_called_once_with( - action_name, instance, {"status": state}) + action_name, instance, {"status": state} + ) @ddt.data( - ("2.6", type('InstanceUUID', (object, ), {"uuid": "1234"})), + ("2.6", type('InstanceUUID', (object,), {"uuid": "1234"})), ("2.6", "1234"), - ("2.7", type('InstanceUUID', (object, ), {"uuid": "1234"})), + ("2.7", type('InstanceUUID', (object,), {"uuid": "1234"})), ("2.7", "1234"), ) @ddt.unpack def test_force_delete_share_snapshot(self, microversion, instance): manager = self._get_manager(microversion) - if (api_versions.APIVersion(microversion) > - api_versions.APIVersion("2.6")): + if api_versions.APIVersion(microversion) > api_versions.APIVersion( + "2.6" + ): action_name = "force_delete" else: action_name = "os-force_delete" @@ -111,8 +116,9 @@ def test_force_delete_share_snapshot(self, microversion, instance): @ddt.unpack def test_valid_instance_state(self, microversion, instance, state): manager = self._get_manager(microversion) - if (api_versions.APIVersion(microversion) > - api_versions.APIVersion("2.6")): + if api_versions.APIVersion(microversion) > api_versions.APIVersion( + "2.6" + ): action_name = "reset_status" else: action_name = "os-reset_status" @@ -121,4 +127,5 @@ def test_valid_instance_state(self, microversion, instance, state): manager.reset_state(instance, state) manager._action.assert_called_once_with( - action_name, instance, {"status": state}) + action_name, instance, {"status": state} + ) diff --git a/manilaclient/tests/unit/v2/test_share_network_subnets.py b/manilaclient/tests/unit/v2/test_share_network_subnets.py index 0dae0d5e..9a89d32d 100644 --- a/manilaclient/tests/unit/v2/test_share_network_subnets.py +++ b/manilaclient/tests/unit/v2/test_share_network_subnets.py @@ -24,11 +24,11 @@ @ddt.ddt class ShareNetworkSubnetTest(utils.TestCase): - def setUp(self): - super(ShareNetworkSubnetTest, self).setUp() + super().setUp() self.manager = share_network_subnets.ShareNetworkSubnetManager( - fakes.FakeClient()) + fakes.FakeClient() + ) def test_create(self): share_network_id = 'fake_share_net_id' @@ -39,7 +39,7 @@ def test_create(self): 'neutron_net_id': 'fake_net_id', 'neutron_subnet_id': 'fake_subnet_id', 'availability_zone': 'fake_availability_zone', - 'metadata': 'fake_metadata' + 'metadata': 'fake_metadata', } expected_body = {'share-network-subnet': expected_values} payload = expected_values.copy() @@ -50,11 +50,9 @@ def test_create(self): self.assertEqual(expected_url, result['url']) self.assertEqual( - share_network_subnets.RESOURCE_NAME, - result['resp_key']) - self.assertEqual( - expected_body, - result['body']) + share_network_subnets.RESOURCE_NAME, result['resp_key'] + ) + self.assertEqual(expected_body, result['body']) def test_get(self): share_network = 'fake_share_network' @@ -64,11 +62,13 @@ def test_get(self): self.manager.get(share_network, share_subnet) self.manager._get.assert_called_once_with( - share_network_subnets.RESOURCE_PATH % { + share_network_subnets.RESOURCE_PATH + % { 'share_network_id': share_network, - 'share_network_subnet_id': share_subnet + 'share_network_subnet_id': share_subnet, }, - share_network_subnets.RESOURCE_NAME) + share_network_subnets.RESOURCE_NAME, + ) def test_delete(self): share_network = 'fake_share_network' @@ -78,7 +78,9 @@ def test_delete(self): self.manager.delete(share_network, share_subnet) self.manager._delete.assert_called_once_with( - share_network_subnets.RESOURCE_PATH % { + share_network_subnets.RESOURCE_PATH + % { 'share_network_id': share_network, - 'share_network_subnet_id': share_subnet - }) + 'share_network_subnet_id': share_subnet, + } + ) diff --git a/manilaclient/tests/unit/v2/test_share_networks.py b/manilaclient/tests/unit/v2/test_share_networks.py index 3380c3dc..9a2f83b9 100644 --- a/manilaclient/tests/unit/v2/test_share_networks.py +++ b/manilaclient/tests/unit/v2/test_share_networks.py @@ -27,15 +27,14 @@ @ddt.ddt class ShareNetworkTest(utils.TestCase): - - class _FakeShareNetwork(object): + class _FakeShareNetwork: id = 'fake_share_network_id' - class _FakeSecurityService(object): + class _FakeSecurityService: id = 'fake_security_service_id' def setUp(self): - super(ShareNetworkTest, self).setUp() + super().setUp() self.manager = share_networks.ShareNetworkManager(fakes.FakeClient()) self.values = { 'nova_net_id': 'fake_nova_net_id', @@ -49,34 +48,35 @@ def setUp(self): def test_create(self, microversion): api_version = api_versions.APIVersion(microversion) values = self.values.copy() - if (api_version >= api_versions.APIVersion("2.26")): + if api_version >= api_versions.APIVersion("2.26"): del values['nova_net_id'] body_expected = {share_networks.RESOURCE_NAME: values} manager = share_networks.ShareNetworkManager( - fakes.FakeClient(api_version=api_version)) + fakes.FakeClient(api_version=api_version) + ) with mock.patch.object(manager, '_create', fakes.fake_create): result = manager.create(**values) self.assertEqual(result['url'], share_networks.RESOURCES_PATH) self.assertEqual(result['resp_key'], share_networks.RESOURCE_NAME) - self.assertEqual( - body_expected, - result['body']) + self.assertEqual(body_expected, result['body']) def test_delete_str(self): share_nw = 'fake share nw' with mock.patch.object(self.manager, '_delete', mock.Mock()): self.manager.delete(share_nw) self.manager._delete.assert_called_once_with( - share_networks.RESOURCE_PATH % share_nw) + share_networks.RESOURCE_PATH % share_nw + ) def test_delete_obj(self): share_nw = self._FakeShareNetwork() with mock.patch.object(self.manager, '_delete', mock.Mock()): self.manager.delete(share_nw) self.manager._delete.assert_called_once_with( - share_networks.RESOURCE_PATH % share_nw.id) + share_networks.RESOURCE_PATH % share_nw.id + ) def test_get(self): share_nw = 'fake share nw' @@ -84,63 +84,71 @@ def test_get(self): self.manager.get(share_nw) self.manager._get.assert_called_once_with( share_networks.RESOURCE_PATH % share_nw, - share_networks.RESOURCE_NAME) + share_networks.RESOURCE_NAME, + ) def test_list_not_detailed(self): - with mock.patch.object(self.manager, '_list', - mock.Mock(return_value=None)): + with mock.patch.object( + self.manager, '_list', mock.Mock(return_value=None) + ): self.manager.list(detailed=False) self.manager._list.assert_called_once_with( - share_networks.RESOURCES_PATH, - share_networks.RESOURCES_NAME) + share_networks.RESOURCES_PATH, share_networks.RESOURCES_NAME + ) def test_list(self): - with mock.patch.object(self.manager, '_list', - mock.Mock(return_value=None)): + with mock.patch.object( + self.manager, '_list', mock.Mock(return_value=None) + ): self.manager.list() self.manager._list.assert_called_once_with( share_networks.RESOURCES_PATH + '/detail', - share_networks.RESOURCES_NAME) + share_networks.RESOURCES_NAME, + ) def test_list_with_filters(self): filters = {'all_tenants': 1, 'status': 'ERROR'} - expected_path = ("%s/detail?all_tenants=1&status=" - "ERROR" % share_networks.RESOURCES_PATH) - - with mock.patch.object(self.manager, '_list', - mock.Mock(return_value=None)): + expected_path = ( + f"{share_networks.RESOURCES_PATH}/detail?all_tenants=1&status=" + "ERROR" + ) + + with mock.patch.object( + self.manager, '_list', mock.Mock(return_value=None) + ): self.manager.list(search_opts=filters) self.manager._list.assert_called_once_with( - expected_path, - share_networks.RESOURCES_NAME) - - @ddt.data(*itertools.product( - ["2.25", "2.26"], - ['fake share nw', _FakeShareNetwork()] - )) + expected_path, share_networks.RESOURCES_NAME + ) + + @ddt.data( + *itertools.product( + ["2.25", "2.26"], ['fake share nw', _FakeShareNetwork()] + ) + ) @ddt.unpack def test_update_share_network(self, microversion, share_nw): api_version = api_versions.APIVersion(microversion) values = self.values.copy() - if (api_version >= api_versions.APIVersion("2.26")): + if api_version >= api_versions.APIVersion("2.26"): del values['nova_net_id'] body_expected = {share_networks.RESOURCE_NAME: values} manager = share_networks.ShareNetworkManager( - fakes.FakeClient(api_version=api_version)) + fakes.FakeClient(api_version=api_version) + ) with mock.patch.object(manager, '_update', fakes.fake_update): result = manager.update(share_nw, **values) id = share_nw.id if hasattr(share_nw, 'id') else share_nw - self.assertEqual(result['url'], - share_networks.RESOURCE_PATH % id) + self.assertEqual(result['url'], share_networks.RESOURCE_PATH % id) self.assertEqual(result['resp_key'], share_networks.RESOURCE_NAME) self.assertEqual(result['body'], body_expected) def test_update_with_exception(self): share_nw = 'fake share nw' - self.assertRaises(exceptions.CommandError, - self.manager.update, - share_nw) + self.assertRaises( + exceptions.CommandError, self.manager.update, share_nw + ) def test_add_security_service(self): security_service = 'fake security service' @@ -152,9 +160,8 @@ def test_add_security_service(self): with mock.patch.object(self.manager, '_action', mock.Mock()): self.manager.add_security_service(share_nw, security_service) self.manager._action.assert_called_once_with( - expected_path, - share_nw, - expected_body) + expected_path, share_nw, expected_body + ) def test_add_security_service_to_share_nw_object(self): security_service = self._FakeSecurityService() @@ -166,9 +173,8 @@ def test_add_security_service_to_share_nw_object(self): with mock.patch.object(self.manager, '_action', mock.Mock()): self.manager.add_security_service(share_nw, security_service) self.manager._action.assert_called_once_with( - expected_path, - share_nw, - expected_body) + expected_path, share_nw, expected_body + ) def test_remove_security_service(self): security_service = 'fake security service' @@ -182,15 +188,15 @@ def test_remove_security_service(self): with mock.patch.object(self.manager, '_create', mock.Mock()): self.manager.remove_security_service(share_nw, security_service) self.manager._create.assert_called_once_with( - expected_path, - expected_body, - share_networks.RESOURCE_NAME) + expected_path, expected_body, share_networks.RESOURCE_NAME + ) def test_remove_security_service_from_share_nw_object(self): security_service = self._FakeSecurityService() share_nw = self._FakeShareNetwork() - expected_path = ((share_networks.RESOURCE_PATH + - '/action') % share_nw.id) + expected_path = ( + share_networks.RESOURCE_PATH + '/action' + ) % share_nw.id expected_body = { 'remove_security_service': { 'security_service_id': security_service.id, @@ -199,9 +205,8 @@ def test_remove_security_service_from_share_nw_object(self): with mock.patch.object(self.manager, '_create', mock.Mock()): self.manager.remove_security_service(share_nw, security_service) self.manager._create.assert_called_once_with( - expected_path, - expected_body, - share_networks.RESOURCE_NAME) + expected_path, expected_body, share_networks.RESOURCE_NAME + ) def test_update_share_network_security_service(self): current_security_service = self._FakeSecurityService() @@ -212,16 +217,16 @@ def test_update_share_network_security_service(self): expected_body = { 'current_service_id': current_security_service.id, - 'new_service_id': new_security_service.id + 'new_service_id': new_security_service.id, } with mock.patch.object(self.manager, '_action', mock.Mock()): self.manager.update_share_network_security_service( - share_nw, current_security_service, new_security_service) + share_nw, current_security_service, new_security_service + ) self.manager._action.assert_called_once_with( - expected_path, - share_nw, - expected_body) + expected_path, share_nw, expected_body + ) def test_share_network_reset_state(self): share_nw = self._FakeShareNetwork() @@ -233,12 +238,10 @@ def test_share_network_reset_state(self): } with mock.patch.object(self.manager, '_action', mock.Mock()): - self.manager.reset_state( - share_nw, state) + self.manager.reset_state(share_nw, state) self.manager._action.assert_called_once_with( - expected_path, - share_nw, - expected_body) + expected_path, share_nw, expected_body + ) def test_share_network_security_service_update_check(self): current_security_service = self._FakeSecurityService() @@ -250,16 +253,16 @@ def test_share_network_security_service_update_check(self): expected_body = { 'current_service_id': current_security_service.id, 'new_service_id': new_security_service.id, - 'reset_operation': False + 'reset_operation': False, } with mock.patch.object(self.manager, '_action', mock.Mock()): self.manager.update_share_network_security_service_check( - share_nw, current_security_service, new_security_service) + share_nw, current_security_service, new_security_service + ) self.manager._action.assert_called_once_with( - expected_path, - share_nw, - expected_body) + expected_path, share_nw, expected_body + ) def test_add_security_service_check(self): current_security_service = self._FakeSecurityService() @@ -269,16 +272,16 @@ def test_add_security_service_check(self): expected_body = { 'security_service_id': current_security_service.id, - 'reset_operation': False + 'reset_operation': False, } with mock.patch.object(self.manager, '_action', mock.Mock()): self.manager.add_security_service_check( - share_nw, current_security_service, False) + share_nw, current_security_service, False + ) self.manager._action.assert_called_once_with( - expected_path, - share_nw, - expected_body) + expected_path, share_nw, expected_body + ) def test_share_network_subnet_create_check(self): share_nw = self._FakeShareNetwork() @@ -288,14 +291,15 @@ def test_share_network_subnet_create_check(self): expected_body = { 'neutron_net_id': self.values['neutron_net_id'], 'neutron_subnet_id': self.values['neutron_subnet_id'], - 'reset_operation': False + 'reset_operation': False, } with mock.patch.object(self.manager, '_action', mock.Mock()): self.manager.share_network_subnet_create_check( - share_nw, self.values['neutron_net_id'], - self.values['neutron_subnet_id']) - self.manager._action.assert_called_once_with( - expected_path, share_nw, - expected_body) + self.values['neutron_net_id'], + self.values['neutron_subnet_id'], + ) + self.manager._action.assert_called_once_with( + expected_path, share_nw, expected_body + ) diff --git a/manilaclient/tests/unit/v2/test_share_replica_export_locations.py b/manilaclient/tests/unit/v2/test_share_replica_export_locations.py index ff21dd70..c42617c3 100644 --- a/manilaclient/tests/unit/v2/test_share_replica_export_locations.py +++ b/manilaclient/tests/unit/v2/test_share_replica_export_locations.py @@ -26,26 +26,28 @@ @ddt.ddt class ShareReplicaExportLocationsTest(utils.TestCase): - def _get_manager(self, microversion): version = api_versions.APIVersion(microversion) mock_microversion = mock.Mock(api_version=version) return ( share_replica_export_locations.ShareReplicaExportLocationManager( - api=mock_microversion) + api=mock_microversion + ) ) def test_list_share_replica_export_locations(self): share_replica_id = '1234' cs.share_replica_export_locations.list(share_replica_id) cs.assert_called( - 'GET', '/share-replicas/%s/export-locations' % share_replica_id) + 'GET', f'/share-replicas/{share_replica_id}/export-locations' + ) def test_get_share_replica_export_location(self): share_replica_id = '1234' el_uuid = 'fake_el_uuid' cs.share_replica_export_locations.get(share_replica_id, el_uuid) - url = ('/share-replicas/%(share_replica_id)s/export-locations/' - '%(el_uuid)s') + url = ( + '/share-replicas/%(share_replica_id)s/export-locations/%(el_uuid)s' + ) payload = {'share_replica_id': share_replica_id, 'el_uuid': el_uuid} cs.assert_called('GET', url % payload) diff --git a/manilaclient/tests/unit/v2/test_share_replicas.py b/manilaclient/tests/unit/v2/test_share_replicas.py index 7cbc0b73..52ce16c5 100644 --- a/manilaclient/tests/unit/v2/test_share_replicas.py +++ b/manilaclient/tests/unit/v2/test_share_replicas.py @@ -28,19 +28,21 @@ @ddt.ddt class ShareReplicasTest(utils.TestCase): - - class _FakeShareReplica(object): + class _FakeShareReplica: id = 'fake_share_replica_id' def setUp(self): - super(ShareReplicasTest, self).setUp() + super().setUp() microversion = api_versions.APIVersion("2.67") self.manager = share_replicas.ShareReplicaManager( - fakes.FakeClient(api_version=microversion)) - - @ddt.data("2.11", - constants.REPLICA_PRE_GRADUATION_VERSION, - constants.REPLICA_GRADUATION_VERSION) + fakes.FakeClient(api_version=microversion) + ) + + @ddt.data( + "2.11", + constants.REPLICA_PRE_GRADUATION_VERSION, + constants.REPLICA_GRADUATION_VERSION, + ) def test_create(self, microversion): api_version = api_versions.APIVersion(microversion) values = { @@ -49,7 +51,8 @@ def test_create(self, microversion): } manager = share_replicas.ShareReplicaManager( - fakes.FakeClient(api_version=api_version)) + fakes.FakeClient(api_version=api_version) + ) with mock.patch.object(manager, '_create', fakes.fake_create): result = manager.create(**values) @@ -69,7 +72,8 @@ def test_create_with_share_network(self, microversion): } manager = share_replicas.ShareReplicaManager( - fakes.FakeClient(api_version=api_version)) + fakes.FakeClient(api_version=api_version) + ) with mock.patch.object(manager, '_create', fakes.fake_create): result = manager.create(**values) @@ -84,40 +88,46 @@ def test_delete_str(self): with mock.patch.object(self.manager, '_delete', mock.Mock()): self.manager.delete(FAKE_REPLICA) self.manager._delete.assert_called_once_with( - share_replicas.RESOURCE_PATH % FAKE_REPLICA) + share_replicas.RESOURCE_PATH % FAKE_REPLICA + ) def test_delete_obj(self): replica = self._FakeShareReplica with mock.patch.object(self.manager, '_delete', mock.Mock()): self.manager.delete(replica) self.manager._delete.assert_called_once_with( - share_replicas.RESOURCE_PATH % replica.id) + share_replicas.RESOURCE_PATH % replica.id + ) def test_delete_with_force(self): with mock.patch.object(self.manager, '_action', mock.Mock()): self.manager.delete(FAKE_REPLICA, force=True) self.manager._action.assert_called_once_with( - 'force_delete', FAKE_REPLICA) + 'force_delete', FAKE_REPLICA + ) def test_get(self): with mock.patch.object(self.manager, '_get', mock.Mock()): self.manager.get(FAKE_REPLICA) self.manager._get.assert_called_once_with( share_replicas.RESOURCE_PATH % FAKE_REPLICA, - share_replicas.RESOURCE_NAME) + share_replicas.RESOURCE_NAME, + ) def test_promote(self): with mock.patch.object(self.manager, '_action', mock.Mock()): self.manager.promote(FAKE_REPLICA) self.manager._action.assert_called_once_with( - 'promote', FAKE_REPLICA) + 'promote', FAKE_REPLICA + ) def test_list(self): with mock.patch.object(self.manager, '_list', mock.Mock()): self.manager.list(search_opts=None) self.manager._list.assert_called_once_with( share_replicas.RESOURCES_PATH + '/detail', - share_replicas.RESOURCES_NAME) + share_replicas.RESOURCES_NAME, + ) def test_list_with_share(self): with mock.patch.object(self.manager, '_list', mock.Mock()): @@ -125,13 +135,15 @@ def test_list_with_share(self): share_uri = '?share_id=share_id' self.manager._list.assert_called_once_with( (share_replicas.RESOURCES_PATH + '/detail' + share_uri), - share_replicas.RESOURCES_NAME) + share_replicas.RESOURCES_NAME, + ) def test_resync(self): with mock.patch.object(self.manager, '_action', mock.Mock()): self.manager.resync(FAKE_REPLICA) self.manager._action.assert_called_once_with( - 'resync', FAKE_REPLICA) + 'resync', FAKE_REPLICA + ) @ddt.data('reset_status', 'reset_replica_state') def test_reset_state_actions(self, action): @@ -140,4 +152,5 @@ def test_reset_state_actions(self, action): with mock.patch.object(self.manager, '_action', mock.Mock()): method(FAKE_REPLICA, 'some_status') self.manager._action.assert_called_once_with( - action, FAKE_REPLICA, {attr: 'some_status'}) + action, FAKE_REPLICA, {attr: 'some_status'} + ) diff --git a/manilaclient/tests/unit/v2/test_share_servers.py b/manilaclient/tests/unit/v2/test_share_servers.py index 3850424d..09f645ab 100644 --- a/manilaclient/tests/unit/v2/test_share_servers.py +++ b/manilaclient/tests/unit/v2/test_share_servers.py @@ -24,7 +24,7 @@ from manilaclient.v2 import share_servers -class FakeShareServer(object): +class FakeShareServer: _info = { "backend_details": { "fake_key1": "fake_value1", @@ -34,9 +34,8 @@ class FakeShareServer(object): class ShareServerTest(utils.TestCase): - def setUp(self): - super(ShareServerTest, self).setUp() + super().setUp() self.share_server_id = 'foo' self.share_network = 'bar' info = { @@ -44,11 +43,12 @@ def setUp(self): 'share_network_name': self.share_network, } self.resource_class = share_servers.ShareServer( - manager=self, info=info) + manager=self, info=info + ) def test_get_repr_of_share_server(self): self.assertIn( - 'ShareServer: %s' % self.share_server_id, + f'ShareServer: {self.share_server_id}', repr(self.resource_class), ) @@ -65,24 +65,25 @@ def test_get_nonexistent_share_network_name(self): except AttributeError: pass else: - raise Exception("Expected exception 'AttributeError' " - "has not been raised.") + raise Exception( + "Expected exception 'AttributeError' has not been raised." + ) @ddt.ddt class ShareServerManagerTest(utils.TestCase): - def setUp(self): - super(ShareServerManagerTest, self).setUp() + super().setUp() self.manager = share_servers.ShareServerManager(api=fakes.FakeClient()) def test_list(self): - with mock.patch.object(self.manager, '_list', - mock.Mock(return_value=None)): + with mock.patch.object( + self.manager, '_list', mock.Mock(return_value=None) + ): self.manager.list() self.manager._list.assert_called_once_with( - share_servers.RESOURCES_PATH, - share_servers.RESOURCES_NAME) + share_servers.RESOURCES_PATH, share_servers.RESOURCES_NAME + ) @ddt.data(None, {}, {'opt1': 'fake_opt1', 'opt12': 'fake_opt2'}) def test_manage(self, driver_options): @@ -99,52 +100,65 @@ def test_manage(self, driver_options): 'driver_options': driver_options, 'share_network_subnet_id': share_network_subnet_id, } - with mock.patch.object(self.manager, '_create', - mock.Mock(return_value='fake')): + with mock.patch.object( + self.manager, '_create', mock.Mock(return_value='fake') + ): result = self.manager.manage( - host, share_network_id, identifier, + host, + share_network_id, + identifier, driver_options=driver_options, - share_network_subnet_id=share_network_subnet_id) + share_network_subnet_id=share_network_subnet_id, + ) self.manager._create.assert_called_once_with( share_servers.RESOURCES_PATH + '/manage', - {'share_server': expected_body}, 'share_server' + {'share_server': expected_body}, + 'share_server', ) self.assertEqual('fake', result) @ddt.data(True, False) def test_unmanage(self, force): share_server = {'id': 'fake'} - with mock.patch.object(self.manager, '_action', - mock.Mock(return_value='fake')): + with mock.patch.object( + self.manager, '_action', mock.Mock(return_value='fake') + ): result = self.manager.unmanage(share_server, force) self.manager._action.assert_called_once_with( - "unmanage", share_server, {'force': force}) + "unmanage", share_server, {'force': force} + ) self.assertEqual('fake', result) def test_reset_state(self): share_server = {'id': 'fake'} state = constants.STATUS_AVAILABLE - with mock.patch.object(self.manager, '_action', - mock.Mock(return_value='fake')): + with mock.patch.object( + self.manager, '_action', mock.Mock(return_value='fake') + ): result = self.manager.reset_state(share_server, state) self.manager._action.assert_called_once_with( - "reset_status", share_server, {"status": state}) + "reset_status", share_server, {"status": state} + ) self.assertEqual('fake', result) - @ddt.data(("reset_status", {"status": constants.STATUS_AVAILABLE}), - ("unmanage", {"id": "fake_id"})) + @ddt.data( + ("reset_status", {"status": constants.STATUS_AVAILABLE}), + ("unmanage", {"id": "fake_id"}), + ) @ddt.unpack def test__action(self, action, info): action = "" share_server = {"id": 'fake_id'} - expected_url = '/share-servers/%s/action' % share_server['id'] + expected_url = '/share-servers/{}/action'.format(share_server['id']) expected_body = {action: info} - with mock.patch.object(self.manager.api.client, 'post', - mock.Mock(return_value='fake')): - self.mock_object(base, 'getid', - mock.Mock(return_value=share_server['id'])) + with mock.patch.object( + self.manager.api.client, 'post', mock.Mock(return_value='fake') + ): + self.mock_object( + base, 'getid', mock.Mock(return_value=share_server['id']) + ) result = self.manager._action(action, share_server, info) self.manager.api.client.post.assert_called_once_with( expected_url, body=expected_body @@ -153,9 +167,10 @@ def test__action(self, action, info): def test_list_with_one_search_opt(self): host = 'fake_host' - query_string = "?host=%s" % host - with mock.patch.object(self.manager, '_list', - mock.Mock(return_value=None)): + query_string = f"?host={host}" + with mock.patch.object( + self.manager, '_list', mock.Mock(return_value=None) + ): self.manager.list({'host': host}) self.manager._list.assert_called_once_with( share_servers.RESOURCES_PATH + query_string, @@ -165,9 +180,10 @@ def test_list_with_one_search_opt(self): def test_list_with_two_search_opts(self): host = 'fake_host' status = 'fake_status' - query_string = "?host=%s&status=%s" % (host, status) - with mock.patch.object(self.manager, '_list', - mock.Mock(return_value=None)): + query_string = f"?host={host}&status={status}" + with mock.patch.object( + self.manager, '_list', mock.Mock(return_value=None) + ): self.manager.list({'host': host, 'status': status}) self.manager._list.assert_called_once_with( share_servers.RESOURCES_PATH + query_string, @@ -179,28 +195,33 @@ def test_delete(self): with mock.patch.object(self.manager, '_delete', mock.Mock()): self.manager.delete(share_server_id) self.manager._delete.assert_called_once_with( - share_servers.RESOURCE_PATH % share_server_id) + share_servers.RESOURCE_PATH % share_server_id + ) def test_get(self): server = FakeShareServer() - with mock.patch.object(self.manager, '_get', - mock.Mock(return_value=server)): + with mock.patch.object( + self.manager, '_get', mock.Mock(return_value=server) + ): share_server_id = 'fake_share_server_id' self.manager.get(share_server_id) self.manager._get.assert_called_once_with( - "%s/%s" % (share_servers.RESOURCES_PATH, share_server_id), - share_servers.RESOURCE_NAME) + f"{share_servers.RESOURCES_PATH}/{share_server_id}", + share_servers.RESOURCE_NAME, + ) for key in ["details:fake_key1", "details:fake_key2"]: self.assertIn(key, list(server._info)) def test_details(self): - with mock.patch.object(self.manager, '_get', - mock.Mock(return_value=None)): + with mock.patch.object( + self.manager, '_get', mock.Mock(return_value=None) + ): share_server_id = 'fake_share_server_id' self.manager.details(share_server_id) self.manager._get.assert_called_once_with( - "%s/%s/details" % (share_servers.RESOURCES_PATH, - share_server_id), 'details') + f"{share_servers.RESOURCES_PATH}/{share_server_id}/details", + 'details', + ) def test_migration_check(self): share_server = "fake_share_server" @@ -214,19 +235,27 @@ def test_migration_check(self): 'preserve_snapshots': True, } - with mock.patch.object(self.manager, "_action", - mock.Mock(return_value=['200', returned])): + with mock.patch.object( + self.manager, "_action", mock.Mock(return_value=['200', returned]) + ): result = self.manager.migration_check( - share_server, host, writable=True, nondisruptive=True, - preserve_snapshots=True) + share_server, + host, + writable=True, + nondisruptive=True, + preserve_snapshots=True, + ) self.manager._action.assert_called_once_with( - 'migration_check', share_server, { + 'migration_check', + share_server, + { "host": host, "writable": True, "nondisruptive": True, "preserve_snapshots": True, "new_share_network_id": None, - }) + }, + ) self.assertEqual(returned, result) @@ -235,19 +264,27 @@ def test_migration_start(self): host = "fake_host" returned = "fake" - with mock.patch.object(self.manager, "_action", - mock.Mock(return_value=returned)): + with mock.patch.object( + self.manager, "_action", mock.Mock(return_value=returned) + ): result = self.manager.migration_start( - share_server, host, writable=True, nondisruptive=True, - preserve_snapshots=True) + share_server, + host, + writable=True, + nondisruptive=True, + preserve_snapshots=True, + ) self.manager._action.assert_called_once_with( - 'migration_start', share_server, { + 'migration_start', + share_server, + { "host": host, "writable": True, "nondisruptive": True, "preserve_snapshots": True, "new_share_network_id": None, - }) + }, + ) self.assertEqual(returned, result) @@ -255,24 +292,28 @@ def test_migration_complete(self): share_server = "fake_share_server" returned = "fake" - with mock.patch.object(self.manager, "_action", - mock.Mock(return_value=['200', returned])): + with mock.patch.object( + self.manager, "_action", mock.Mock(return_value=['200', returned]) + ): result = self.manager.migration_complete(share_server) self.manager._action.assert_called_once_with( - "migration_complete", share_server) + "migration_complete", share_server + ) self.assertEqual(returned, result) def test_migration_get_progress(self): share_server = "fake_share_server" returned = "fake" - with mock.patch.object(self.manager, "_action", - mock.Mock(return_value=['200', returned])): + with mock.patch.object( + self.manager, "_action", mock.Mock(return_value=['200', returned]) + ): result = self.manager.migration_get_progress(share_server) self.manager._action.assert_called_once_with( - "migration_get_progress", share_server) + "migration_get_progress", share_server + ) self.assertEqual(returned, result) def test_reset_task_state(self): @@ -280,22 +321,26 @@ def test_reset_task_state(self): state = "fake_state" returned = "fake" - with mock.patch.object(self.manager, "_action", - mock.Mock(return_value=returned)): + with mock.patch.object( + self.manager, "_action", mock.Mock(return_value=returned) + ): result = self.manager.reset_task_state(share_server, state) self.manager._action.assert_called_once_with( - "reset_task_state", share_server, {'task_state': state}) + "reset_task_state", share_server, {'task_state': state} + ) self.assertEqual(returned, result) def test_migration_cancel(self): share_server = "fake_share_server" returned = "fake" - with mock.patch.object(self.manager, "_action", - mock.Mock(return_value=returned)): + with mock.patch.object( + self.manager, "_action", mock.Mock(return_value=returned) + ): result = self.manager.migration_cancel(share_server) self.manager._action.assert_called_once_with( - "migration_cancel", share_server) + "migration_cancel", share_server + ) self.assertEqual(returned, result) diff --git a/manilaclient/tests/unit/v2/test_share_snapshot_export_locations.py b/manilaclient/tests/unit/v2/test_share_snapshot_export_locations.py index 4c248177..fc02d75c 100644 --- a/manilaclient/tests/unit/v2/test_share_snapshot_export_locations.py +++ b/manilaclient/tests/unit/v2/test_share_snapshot_export_locations.py @@ -21,8 +21,9 @@ extensions = [ - extension.Extension('share_snapshot_export_locations', - share_snapshot_export_locations), + extension.Extension( + 'share_snapshot_export_locations', share_snapshot_export_locations + ), ] cs = fakes.FakeClient(extensions=extensions) @@ -31,15 +32,12 @@ class ShareSnapshotExportLocationsTest(utils.TestCase): def test_list_snapshot(self): snapshot_id = '1234' cs.share_snapshot_export_locations.list(snapshot_id, search_opts=None) - cs.assert_called( - 'GET', '/snapshots/%s/export-locations' % snapshot_id) + cs.assert_called('GET', f'/snapshots/{snapshot_id}/export-locations') def test_get_snapshot(self): snapshot_id = '1234' el_id = 'fake_el_id' cs.share_snapshot_export_locations.get(el_id, snapshot_id) cs.assert_called( - 'GET', - ('/snapshots/%(snapshot_id)s/export-locations/' - '%(el_id)s') % { - 'snapshot_id': snapshot_id, 'el_id': el_id}) + 'GET', (f'/snapshots/{snapshot_id}/export-locations/{el_id}') + ) diff --git a/manilaclient/tests/unit/v2/test_share_snapshot_instance_export_locations.py b/manilaclient/tests/unit/v2/test_share_snapshot_instance_export_locations.py index 686093c2..fa829640 100644 --- a/manilaclient/tests/unit/v2/test_share_snapshot_instance_export_locations.py +++ b/manilaclient/tests/unit/v2/test_share_snapshot_instance_export_locations.py @@ -21,8 +21,10 @@ extensions = [ - extension.Extension('share_snapshot_export_locations', - share_snapshot_instance_export_locations), + extension.Extension( + 'share_snapshot_export_locations', + share_snapshot_instance_export_locations, + ), ] cs = fakes.FakeClient(extensions=extensions) @@ -31,18 +33,23 @@ class ShareSnapshotInstanceExportLocationsTest(utils.TestCase): def test_list_snapshot_instance(self): snapshot_instance_id = '1234' cs.share_snapshot_instance_export_locations.list( - snapshot_instance_id, search_opts=None) + snapshot_instance_id, search_opts=None + ) cs.assert_called( - 'GET', '/snapshot-instances/%s/export-locations' - % snapshot_instance_id) + 'GET', + f'/snapshot-instances/{snapshot_instance_id}/export-locations', + ) def test_get_snapshot_instance(self): snapshot_instance_id = '1234' el_id = 'fake_el_id' cs.share_snapshot_instance_export_locations.get( - el_id, snapshot_instance_id) + el_id, snapshot_instance_id + ) cs.assert_called( 'GET', - ('/snapshot-instances/%(snapshot_id)s/export-locations/' - '%(el_id)s') % { - 'snapshot_id': snapshot_instance_id, 'el_id': el_id}) + ( + f'/snapshot-instances/{snapshot_instance_id}/export-locations/' + f'{el_id}' + ), + ) diff --git a/manilaclient/tests/unit/v2/test_share_snapshot_instances.py b/manilaclient/tests/unit/v2/test_share_snapshot_instances.py index 1738c2e4..33e5be9e 100644 --- a/manilaclient/tests/unit/v2/test_share_snapshot_instances.py +++ b/manilaclient/tests/unit/v2/test_share_snapshot_instances.py @@ -33,13 +33,13 @@ @ddt.ddt class SnapshotInstancesTest(utils.TestCase): - def setUp(self): - super(SnapshotInstancesTest, self).setUp() + super().setUp() microversion = api_versions.APIVersion("2.19") mock_microversion = mock.Mock(api_version=microversion) self.manager = share_snapshot_instances.ShareSnapshotInstanceManager( - api=mock_microversion) + api=mock_microversion + ) @ddt.data(True, False) def test_list(self, detailed): @@ -60,14 +60,17 @@ def test_list_with_snapshot(self, detailed): self.mock_object(self.manager, '_list', mock.Mock()) self.manager.list(detailed=detailed, snapshot='snapshot_id') self.manager._list.assert_called_once_with( - (url + '?snapshot_id=snapshot_id'), 'snapshot_instances',) + (url + '?snapshot_id=snapshot_id'), + 'snapshot_instances', + ) def test_get(self): self.mock_object(self.manager, '_get', mock.Mock()) self.manager.get('fake_snapshot_instance') self.manager._get.assert_called_once_with( '/snapshot-instances/' + 'fake_snapshot_instance', - 'snapshot_instance') + 'snapshot_instance', + ) def test_reset_instance_state(self): state = 'available' @@ -75,7 +78,8 @@ def test_reset_instance_state(self): self.mock_object(self.manager, '_action', mock.Mock()) self.manager.reset_state('fake_instance', state) self.manager._action.assert_called_once_with( - "reset_status", 'fake_instance', {"status": state}) + "reset_status", 'fake_instance', {"status": state} + ) @ddt.data('get', 'list', 'reset_state') def test_upsupported_microversion(self, method_name): @@ -90,7 +94,9 @@ def test_upsupported_microversion(self, method_name): microversion = api_versions.APIVersion(microversion) mock_microversion = mock.Mock(api_version=microversion) manager = share_snapshot_instances.ShareSnapshotInstanceManager( - api=mock_microversion) + api=mock_microversion + ) method = getattr(manager, method_name) - self.assertRaises(exceptions.UnsupportedVersion, - method, **arguments) + self.assertRaises( + exceptions.UnsupportedVersion, method, **arguments + ) diff --git a/manilaclient/tests/unit/v2/test_share_snapshots.py b/manilaclient/tests/unit/v2/test_share_snapshots.py index bd8a525c..9fe29cab 100644 --- a/manilaclient/tests/unit/v2/test_share_snapshots.py +++ b/manilaclient/tests/unit/v2/test_share_snapshots.py @@ -34,7 +34,6 @@ @ddt.ddt class ShareSnapshotsTest(utils.TestCase): - def _get_manager(self, microversion): version = api_versions.APIVersion(microversion) mock_microversion = mock.Mock(api_version=version) @@ -45,27 +44,29 @@ def test_create_share_snapshot(self): cs.assert_called('POST', '/snapshots') @ddt.data( - type('SnapshotUUID', (object, ), {'uuid': '1234'}), - type('SnapshotID', (object, ), {'id': '1234'}), - '1234') + type('SnapshotUUID', (object,), {'uuid': '1234'}), + type('SnapshotID', (object,), {'id': '1234'}), + '1234', + ) def test_get_share_snapshot(self, snapshot): snapshot = cs.share_snapshots.get(snapshot) cs.assert_called('GET', '/snapshots/1234') @ddt.data( - type('SnapshotUUID', (object, ), {'uuid': '1234'}), - type('SnapshotID', (object, ), {'id': '1234'}), - '1234') + type('SnapshotUUID', (object,), {'uuid': '1234'}), + type('SnapshotID', (object,), {'id': '1234'}), + '1234', + ) def test_update_share_snapshot(self, snapshot): data = dict(foo='bar', quuz='foobar') snapshot = cs.share_snapshots.update(snapshot, **data) cs.assert_called('PUT', '/snapshots/1234', {'snapshot': data}) @ddt.data( - ("2.6", type('SnapshotUUID', (object, ), {'uuid': '1234'})), - ("2.7", type('SnapshotUUID', (object, ), {'uuid': '1234'})), - ("2.6", type('SnapshotID', (object, ), {'id': '1234'})), - ("2.7", type('SnapshotID', (object, ), {'id': '1234'})), + ("2.6", type('SnapshotUUID', (object,), {'uuid': '1234'})), + ("2.7", type('SnapshotUUID', (object,), {'uuid': '1234'})), + ("2.6", type('SnapshotID', (object,), {'id': '1234'})), + ("2.7", type('SnapshotID', (object,), {'id': '1234'})), ("2.6", "1234"), ("2.7", "1234"), ) @@ -73,8 +74,9 @@ def test_update_share_snapshot(self, snapshot): def test_reset_snapshot_state(self, microversion, snapshot): manager = self._get_manager(microversion) state = 'available' - if (api_versions.APIVersion(microversion) > - api_versions.APIVersion("2.6")): + if api_versions.APIVersion(microversion) > api_versions.APIVersion( + "2.6" + ): action_name = "reset_status" else: action_name = "os-reset_status" @@ -83,7 +85,8 @@ def test_reset_snapshot_state(self, microversion, snapshot): manager.reset_state(snapshot, state) manager._action.assert_called_once_with( - action_name, snapshot, {"status": state}) + action_name, snapshot, {"status": state} + ) def test_delete_share_snapshot(self): snapshot = cs.share_snapshots.get(1234) @@ -91,16 +94,17 @@ def test_delete_share_snapshot(self): cs.assert_called('DELETE', '/snapshots/1234') @ddt.data( - ("2.6", type('SnapshotUUID', (object, ), {"uuid": "1234"})), + ("2.6", type('SnapshotUUID', (object,), {"uuid": "1234"})), ("2.6", "1234"), - ("2.7", type('SnapshotUUID', (object, ), {"uuid": "1234"})), + ("2.7", type('SnapshotUUID', (object,), {"uuid": "1234"})), ("2.7", "1234"), ) @ddt.unpack def test_force_delete_share_snapshot(self, microversion, snapshot): manager = self._get_manager(microversion) - if (api_versions.APIVersion(microversion) > - api_versions.APIVersion("2.6")): + if api_versions.APIVersion(microversion) > api_versions.APIVersion( + "2.6" + ): action_name = "force_delete" else: action_name = "os-force_delete" @@ -118,16 +122,19 @@ def test_list_share_snapshots_index_with_search_opts(self): search_opts = {'fake_str': 'fake_str_value', 'fake_int': 1} cs.share_snapshots.list(detailed=False, search_opts=search_opts) cs.assert_called( - 'GET', '/snapshots?fake_int=1&fake_str=fake_str_value') + 'GET', '/snapshots?fake_int=1&fake_str=fake_str_value' + ) def test_list_share_snapshots_sort_by_asc_and_share_id(self): cs.share_snapshots.list( - detailed=False, sort_key='share_id', sort_dir='asc') + detailed=False, sort_key='share_id', sort_dir='asc' + ) cs.assert_called('GET', '/snapshots?sort_dir=asc&sort_key=share_id') def test_list_share_snapshots_sort_by_desc_and_status(self): cs.share_snapshots.list( - detailed=False, sort_key='status', sort_dir='desc') + detailed=False, sort_key='status', sort_dir='desc' + ) cs.assert_called('GET', '/snapshots?sort_dir=desc&sort_key=status') def test_list_share_snapshots_by_improper_direction(self): @@ -144,10 +151,10 @@ def test_list_share_snapshots_detail_with_count(self): search_opts = { 'with_count': 'True', } - snapshots, count = cs.share_snapshots.list(detailed=True, - search_opts=search_opts) - cs.assert_called( - 'GET', '/snapshots/detail?with_count=True') + snapshots, count = cs.share_snapshots.list( + detailed=True, search_opts=search_opts + ) + cs.assert_called('GET', '/snapshots/detail?with_count=True') self.assertEqual(2, count) self.assertEqual(1, len(snapshots)) @@ -168,16 +175,21 @@ def test_manage_snapshot(self): mock_microversion = mock.Mock(api_version=version) manager = share_snapshots.ShareSnapshotManager(api=mock_microversion) - with mock.patch.object(manager, "_create", - mock.Mock(return_value="fake")): - - result = manager.manage(share_id, provider_location, - driver_options=driver_options, - name=name, description=description) + with mock.patch.object( + manager, "_create", mock.Mock(return_value="fake") + ): + result = manager.manage( + share_id, + provider_location, + driver_options=driver_options, + name=name, + description=description, + ) self.assertEqual(manager._create.return_value, result) manager._create.assert_called_once_with( - "/snapshots/manage", {"snapshot": expected_body}, "snapshot") + "/snapshots/manage", {"snapshot": expected_body}, "snapshot" + ) def test_unmanage_snapshot(self): snapshot = "fake_snapshot" @@ -185,8 +197,9 @@ def test_unmanage_snapshot(self): mock_microversion = mock.Mock(api_version=version) manager = share_snapshots.ShareSnapshotManager(api=mock_microversion) - with mock.patch.object(manager, "_action", - mock.Mock(return_value="fake")): + with mock.patch.object( + manager, "_action", mock.Mock(return_value="fake") + ): result = manager.unmanage(snapshot) manager._action.assert_called_once_with("unmanage", snapshot) @@ -202,13 +215,16 @@ def test_allow_access(self): mock_microversion = mock.Mock(api_version=version) manager = share_snapshots.ShareSnapshotManager(api=mock_microversion) - with mock.patch.object(manager, "_action", - mock.Mock(return_value=access)): + with mock.patch.object( + manager, "_action", mock.Mock(return_value=access) + ): result = manager.allow(snapshot, access_type, access_to) self.assertEqual("fake", result) manager._action.assert_called_once_with( - "allow_access", snapshot, - {'access_type': access_type, 'access_to': access_to}) + "allow_access", + snapshot, + {'access_type': access_type, 'access_to': access_to}, + ) def test_deny_access(self): snapshot = "fake_snapshot" @@ -221,7 +237,8 @@ def test_deny_access(self): with mock.patch.object(manager, "_action"): manager.deny(snapshot, access_id) manager._action.assert_called_once_with( - "deny_access", snapshot, {'access_id': access_id}) + "deny_access", snapshot, {'access_id': access_id} + ) def test_access_list(self): cs.share_snapshots.access_list(1234) @@ -233,23 +250,27 @@ def test_get_metadata(self): def test_set_metadata(self): cs.share_snapshots.set_metadata(1234, {'k1': 'v2'}) - cs.assert_called('POST', '/snapshots/1234/metadata', - {'metadata': {'k1': 'v2'}}) + cs.assert_called( + 'POST', '/snapshots/1234/metadata', {'metadata': {'k1': 'v2'}} + ) @ddt.data( - type('SnapshotUUID', (object, ), {'uuid': '1234'}), - type('SnapshotID', (object, ), {'id': '1234'}), - '1234') + type('SnapshotUUID', (object,), {'uuid': '1234'}), + type('SnapshotID', (object,), {'id': '1234'}), + '1234', + ) def test_delete_metadata(self, snapshot): keys = ['key1'] cs.share_snapshots.delete_metadata(snapshot, keys) cs.assert_called('DELETE', '/snapshots/1234/metadata/key1') @ddt.data( - type('SnapshotUUID', (object, ), {'uuid': '1234'}), - type('SnapshotID', (object, ), {'id': '1234'}), - '1234') + type('SnapshotUUID', (object,), {'uuid': '1234'}), + type('SnapshotID', (object,), {'id': '1234'}), + '1234', + ) def test_metadata_update_all(self, snapshot): cs.share_snapshots.update_all_metadata(snapshot, {'k1': 'v1'}) - cs.assert_called('PUT', '/snapshots/1234/metadata', - {'metadata': {'k1': 'v1'}}) + cs.assert_called( + 'PUT', '/snapshots/1234/metadata', {'metadata': {'k1': 'v1'}} + ) diff --git a/manilaclient/tests/unit/v2/test_share_transfers.py b/manilaclient/tests/unit/v2/test_share_transfers.py index 6cec52b5..54a6a640 100644 --- a/manilaclient/tests/unit/v2/test_share_transfers.py +++ b/manilaclient/tests/unit/v2/test_share_transfers.py @@ -22,29 +22,29 @@ class ShareTransfersTest(utils.TestCase): - def test_create(self): cs.transfers.create('1234') - cs.assert_called('POST', '/%s' % TRANSFER_URL, - body={'transfer': {'share_id': '1234', - 'name': None}}) + cs.assert_called( + 'POST', + f'/{TRANSFER_URL}', + body={'transfer': {'share_id': '1234', 'name': None}}, + ) def test_get(self): transfer_id = '5678' cs.transfers.get(transfer_id) - cs.assert_called('GET', '/%s/%s' % (TRANSFER_URL, transfer_id)) + cs.assert_called('GET', f'/{TRANSFER_URL}/{transfer_id}') def test_list(self): cs.transfers.list() - cs.assert_called('GET', '/%s/detail' % TRANSFER_URL) + cs.assert_called('GET', f'/{TRANSFER_URL}/detail') def test_delete(self): cs.transfers.delete('5678') - cs.assert_called('DELETE', '/%s/5678' % TRANSFER_URL) + cs.assert_called('DELETE', f'/{TRANSFER_URL}/5678') def test_accept(self): transfer_id = '5678' auth_key = '12345' cs.transfers.accept(transfer_id, auth_key) - cs.assert_called('POST', - '/%s/%s/accept' % (TRANSFER_URL, transfer_id)) + cs.assert_called('POST', f'/{TRANSFER_URL}/{transfer_id}/accept') diff --git a/manilaclient/tests/unit/v2/test_shares.py b/manilaclient/tests/unit/v2/test_shares.py index 43e57140..1ee49411 100644 --- a/manilaclient/tests/unit/v2/test_shares.py +++ b/manilaclient/tests/unit/v2/test_shares.py @@ -35,10 +35,9 @@ @ddt.ddt class SharesTest(utils.TestCase): - # Testcases for class Share def setUp(self): - super(SharesTest, self).setUp() + super().setUp() self.share = shares.Share(None, {'id': 1}) self.share.manager = mock.Mock() @@ -50,7 +49,8 @@ def test_share_allow_access(self): self.share.allow(access_type, access_to, access_level) self.share.manager.allow.assert_called_once_with( - self.share, access_type, access_to, access_level) + self.share, access_type, access_to, access_level + ) # Testcases for class ShareManager @@ -73,9 +73,10 @@ def test_create_share_with_protocol(self, protocol): cs.assert_called('POST', '/shares', {'share': expected}) @ddt.data( - type('ShareNetworkUUID', (object, ), {'uuid': 'fake_nw'}), - type('ShareNetworkID', (object, ), {'id': 'fake_nw'}), - 'fake_nw') + type('ShareNetworkUUID', (object,), {'uuid': 'fake_nw'}), + type('ShareNetworkID', (object,), {'id': 'fake_nw'}), + 'fake_nw', + ) def test_create_share_with_share_network(self, share_network): expected = { 'size': 1, @@ -94,9 +95,10 @@ def test_create_share_with_share_network(self, share_network): cs.assert_called('POST', '/shares', {'share': expected}) @ddt.data( - type('ShareTypeUUID', (object, ), {'uuid': 'fake_st'}), - type('ShareTypeID', (object, ), {'id': 'fake_st'}), - 'fake_st') + type('ShareTypeUUID', (object,), {'uuid': 'fake_st'}), + type('ShareTypeID', (object,), {'id': 'fake_st'}), + 'fake_st', + ) def test_create_share_with_share_type(self, share_type): expected = { 'size': 1, @@ -114,13 +116,14 @@ def test_create_share_with_share_type(self, share_type): cs.shares.create('nfs', 1, share_type=share_type) cs.assert_called('POST', '/shares', {'share': expected}) - @ddt.data({'is_public': True, - 'availability_zone': 'nova'}, - {'is_public': False, - 'availability_zone': 'fake_azzzzz'}) + @ddt.data( + {'is_public': True, 'availability_zone': 'nova'}, + {'is_public': False, 'availability_zone': 'fake_azzzzz'}, + ) @ddt.unpack - def test_create_share_with_all_params_defined(self, is_public, - availability_zone): + def test_create_share_with_all_params_defined( + self, is_public, availability_zone + ): body = { 'share': { 'is_public': is_public, @@ -136,12 +139,15 @@ def test_create_share_with_all_params_defined(self, is_public, 'scheduler_hints': {}, } } - cs.shares.create('nfs', 1, is_public=is_public, - availability_zone=availability_zone) + cs.shares.create( + 'nfs', 1, is_public=is_public, availability_zone=availability_zone + ) cs.assert_called('POST', '/shares', body) - @ddt.data({'mount_point_name': 'fake_mount_pt1'}, - {'mount_point_name': 'fake_mount_pt2'}) + @ddt.data( + {'mount_point_name': 'fake_mount_pt1'}, + {'mount_point_name': 'fake_mount_pt2'}, + ) @ddt.unpack def test_create_share_with_mount_point_name(self, mount_point_name): body = { @@ -163,8 +169,10 @@ def test_create_share_with_mount_point_name(self, mount_point_name): cs.shares.create('nfs', 1, mount_point_name=mount_point_name) cs.assert_called('POST', '/shares', body) - @ddt.data({'encryption_key_ref': 'fake_key1'}, - {'encryption_key_ref': 'fake_key2'}) + @ddt.data( + {'encryption_key_ref': 'fake_key1'}, + {'encryption_key_ref': 'fake_key2'}, + ) @ddt.unpack def test_create_share_with_encryption_key_ref(self, encryption_key_ref): body = { @@ -187,17 +195,19 @@ def test_create_share_with_encryption_key_ref(self, encryption_key_ref): cs.assert_called('POST', '/shares', body) @ddt.data( - type('ShareUUID', (object, ), {'uuid': '1234'}), - type('ShareID', (object, ), {'id': '1234'}), - '1234') + type('ShareUUID', (object,), {'uuid': '1234'}), + type('ShareID', (object,), {'id': '1234'}), + '1234', + ) def test_get_share(self, share): share = cs.shares.get(share) cs.assert_called('GET', '/shares/1234') @ddt.data( - type('ShareUUID', (object, ), {'uuid': '1234'}), - type('ShareID', (object, ), {'id': '1234'}), - '1234') + type('ShareUUID', (object,), {'uuid': '1234'}), + type('ShareID', (object,), {'id': '1234'}), + '1234', + ) def test_get_update(self, share): data = dict(foo='bar', quuz='foobar') share = cs.shares.update(share, **data) @@ -228,8 +238,13 @@ def test_restore_share(self): ("2.49", "/shares/manage", False, '1234'), ) @ddt.unpack - def test_manage_share(self, microversion, resource_path, is_public=False, - share_server_id=None): + def test_manage_share( + self, + microversion, + resource_path, + is_public=False, + share_server_id=None, + ): service_host = "fake_service_host" protocol = "fake_protocol" export_path = "fake_export_path" @@ -254,44 +269,73 @@ def test_manage_share(self, microversion, resource_path, is_public=False, mock_microversion = mock.Mock(api_version=version) manager = shares.ShareManager(api=mock_microversion) - with mock.patch.object(manager, "_create", - mock.Mock(return_value="fake")): + with mock.patch.object( + manager, "_create", mock.Mock(return_value="fake") + ): if version < api_versions.APIVersion('2.8'): result = manager.manage( - service_host, protocol, export_path, driver_options, - share_type, name, description) - elif (api_versions.APIVersion('2.8') <= version - < api_versions.APIVersion('2.49')): + service_host, + protocol, + export_path, + driver_options, + share_type, + name, + description, + ) + elif ( + api_versions.APIVersion('2.8') + <= version + < api_versions.APIVersion('2.49') + ): result = manager.manage( - service_host, protocol, export_path, driver_options, - share_type, name, description, is_public) + service_host, + protocol, + export_path, + driver_options, + share_type, + name, + description, + is_public, + ) else: result = manager.manage( - service_host, protocol, export_path, driver_options, - share_type, name, description, is_public, share_server_id) + service_host, + protocol, + export_path, + driver_options, + share_type, + name, + description, + is_public, + share_server_id, + ) self.assertEqual(manager._create.return_value, result) manager._create.assert_called_once_with( - resource_path, {"share": expected_body}, "share") + resource_path, {"share": expected_body}, "share" + ) @ddt.data( - type("ShareUUID", (object, ), {"uuid": "1234"}), - type("ShareID", (object, ), {"id": "1234"}), - "1234") + type("ShareUUID", (object,), {"uuid": "1234"}), + type("ShareID", (object,), {"id": "1234"}), + "1234", + ) def test_unmanage_share_v2_6(self, share): version = api_versions.APIVersion("2.6") mock_microversion = mock.Mock(api_version=version) manager = shares.ShareManager(api=mock_microversion) - with mock.patch.object(manager, "_action", - mock.Mock(return_value="fake")): + with mock.patch.object( + manager, "_action", mock.Mock(return_value="fake") + ): result = manager.unmanage(share) self.assertFalse(manager._action.called) self.assertNotEqual("fake", result) self.assertEqual(manager.api.client.post.return_value, result) manager.api.client.post.assert_called_once_with( - "/os-share-unmanage/1234/unmanage") + "/os-share-unmanage/1234/unmanage" + ) def test_unmanage_share_v2_7(self): share = "fake_share" @@ -299,41 +343,44 @@ def test_unmanage_share_v2_7(self): mock_microversion = mock.Mock(api_version=version) manager = shares.ShareManager(api=mock_microversion) - with mock.patch.object(manager, "_action", - mock.Mock(return_value="fake")): + with mock.patch.object( + manager, "_action", mock.Mock(return_value="fake") + ): result = manager.unmanage(share) manager._action.assert_called_once_with("unmanage", share) self.assertEqual("fake", result) def test_revert_to_snapshot(self): - share = 'fake_share' snapshot = 'fake_snapshot' version = api_versions.APIVersion("2.27") mock_microversion = mock.Mock(api_version=version) manager = shares.ShareManager(api=mock_microversion) mock_action = self.mock_object( - manager, '_action', mock.Mock(return_value='fake')) + manager, '_action', mock.Mock(return_value='fake') + ) result = manager.revert_to_snapshot(share, snapshot) self.assertEqual('fake', result) mock_action.assert_called_once_with( - 'revert', 'fake_share', info={'snapshot_id': 'fake_snapshot'}) + 'revert', 'fake_share', info={'snapshot_id': 'fake_snapshot'} + ) def test_revert_to_snapshot_not_supported(self): - share = 'fake_share' snapshot = 'fake_snapshot' version = api_versions.APIVersion("2.26") mock_microversion = mock.Mock(api_version=version) manager = shares.ShareManager(api=mock_microversion) - self.assertRaises(client_exceptions.UnsupportedVersion, - manager.revert_to_snapshot, - share, - snapshot) + self.assertRaises( + client_exceptions.UnsupportedVersion, + manager.revert_to_snapshot, + share, + snapshot, + ) @ddt.data( ("2.6", "os-force_delete"), @@ -346,8 +393,9 @@ def test_force_delete_share(self, microversion, action_name): mock_microversion = mock.Mock(api_version=version) manager = shares.ShareManager(api=mock_microversion) - with mock.patch.object(manager, "_action", - mock.Mock(return_value="fake")): + with mock.patch.object( + manager, "_action", mock.Mock(return_value="fake") + ): result = manager.force_delete(share) manager._action.assert_called_once_with(action_name, share) @@ -371,22 +419,35 @@ def test_list_shares_index_diff_api_version(self, microversion): 'is_soft_deleted': 'True', } - with mock.patch.object(manager, "do_list", - mock.Mock(return_value="fake")): + with mock.patch.object( + manager, "do_list", mock.Mock(return_value="fake") + ): manager.list(detailed=False, search_opts=search_opts3) if version >= api_versions.APIVersion('2.69'): manager.do_list.assert_called_once_with( - detailed=False, search_opts=search_opts3, - sort_key=None, sort_dir=None, return_raw=False) + detailed=False, + search_opts=search_opts3, + sort_key=None, + sort_dir=None, + return_raw=False, + ) elif version >= api_versions.APIVersion('2.35'): manager.do_list.assert_called_once_with( - detailed=False, search_opts=search_opts2, - sort_key=None, sort_dir=None, return_raw=False) + detailed=False, + search_opts=search_opts2, + sort_key=None, + sort_dir=None, + return_raw=False, + ) else: manager.do_list.assert_called_once_with( - detailed=False, search_opts=search_opts1, - sort_key=None, sort_dir=None, return_raw=False) + detailed=False, + search_opts=search_opts1, + sort_key=None, + sort_dir=None, + return_raw=False, + ) def test_list_shares_index_with_search_opts(self): search_opts = { @@ -399,27 +460,45 @@ def test_list_shares_index_with_search_opts(self): cs.assert_called( 'GET', '/shares?description~=fake_description&fake_int=1&' - 'fake_str=fake_str_value&is_public=True&name~=fake_name') + 'fake_str=fake_str_value&is_public=True&name~=fake_name', + ) - @ddt.data(('id', 'b4991315-eb7d-43ec-979e-5715d4399827', True), - ('id', 'b4991315-eb7d-43ec-979e-5715d4399827', False), - ('path', 'fake_path', False), - ('path', 'fake_path', True)) + @ddt.data( + ('id', 'b4991315-eb7d-43ec-979e-5715d4399827', True), + ('id', 'b4991315-eb7d-43ec-979e-5715d4399827', False), + ('path', 'fake_path', False), + ('path', 'fake_path', True), + ) @ddt.unpack - def test_list_shares_index_with_export_location(self, filter_type, - value, detailed): + def test_list_shares_index_with_export_location( + self, filter_type, value, detailed + ): search_opts = { 'export_location': value, } cs.shares.list(detailed=detailed, search_opts=search_opts) if detailed: cs.assert_called( - 'GET', ('/shares/detail?export_location_' + filter_type + - '=' + value + '&is_public=True')) + 'GET', + ( + '/shares/detail?export_location_' + + filter_type + + '=' + + value + + '&is_public=True' + ), + ) else: cs.assert_called( - 'GET', ('/shares?export_location_' + filter_type + '=' - + value + '&is_public=True')) + 'GET', + ( + '/shares?export_location_' + + filter_type + + '=' + + value + + '&is_public=True' + ), + ) @ddt.data(True, False) def test_list_shares_index_with_is_soft_deleted(self, detailed): @@ -429,12 +508,13 @@ def test_list_shares_index_with_is_soft_deleted(self, detailed): cs.shares.list(detailed=detailed, search_opts=search_opts) if detailed: cs.assert_called( - 'GET', ('/shares/detail?is_public=True' - + '&is_soft_deleted=True')) + 'GET', + ('/shares/detail?is_public=True' + '&is_soft_deleted=True'), + ) else: cs.assert_called( - 'GET', ('/shares?is_public=True' - + '&is_soft_deleted=True')) + 'GET', ('/shares?is_public=True' + '&is_soft_deleted=True') + ) def test_list_shares_detailed(self): search_opts = { @@ -442,7 +522,8 @@ def test_list_shares_detailed(self): } shares, count = cs.shares.list(detailed=True, search_opts=search_opts) cs.assert_called( - 'GET', '/shares/detail?is_public=True&with_count=True') + 'GET', '/shares/detail?is_public=True&with_count=True' + ) self.assertEqual(2, count) self.assertEqual(4, len(shares)) @@ -458,22 +539,26 @@ def test_list_shares_detailed_with_search_opts(self): cs.shares.list(detailed=True, search_opts=search_opts) cs.assert_called( 'GET', - '/shares/detail?fake_int=1&fake_str=fake_str_value&is_public=True') + '/shares/detail?fake_int=1&fake_str=fake_str_value&is_public=True', + ) def test_list_shares_sort_by_asc_and_host_key(self): cs.shares.list(detailed=False, sort_key='host', sort_dir='asc') - cs.assert_called('GET', - '/shares?is_public=True&sort_dir=asc&sort_key=host') + cs.assert_called( + 'GET', '/shares?is_public=True&sort_dir=asc&sort_key=host' + ) def test_list_shares_sort_by_desc_and_size_key(self): cs.shares.list(detailed=False, sort_key='size', sort_dir='desc') - cs.assert_called('GET', - '/shares?is_public=True&sort_dir=desc&sort_key=size') + cs.assert_called( + 'GET', '/shares?is_public=True&sort_dir=desc&sort_key=size' + ) def test_list_shares_filter_by_share_network_alias(self): cs.shares.list(detailed=False, sort_key='share_network') - cs.assert_called('GET', - '/shares?is_public=True&sort_key=share_network_id') + cs.assert_called( + 'GET', '/shares?is_public=True&sort_key=share_network_id' + ) def test_list_shares_filter_by_snapshot_alias(self): cs.shares.list(detailed=False, sort_key='snapshot') @@ -481,8 +566,9 @@ def test_list_shares_filter_by_snapshot_alias(self): def test_list_shares_filter_by_share_type_alias(self): cs.shares.list(detailed=False, sort_key='share_type') - cs.assert_called('GET', - '/shares?is_public=True&sort_key=share_type_id') + cs.assert_called( + 'GET', '/shares?is_public=True&sort_key=share_type_id' + ) def test_list_shares_by_improper_direction(self): self.assertRaises(ValueError, cs.shares.list, sort_dir='fake') @@ -491,54 +577,131 @@ def test_list_shares_by_improper_key(self): self.assertRaises(ValueError, cs.shares.list, sort_key='fake') @ddt.data( - {'access_to': '127.0.0.1', 'access_type': 'ip', - 'action_name': 'os-allow_access', 'microversion': '2.0'}, - {'access_to': '1' * 4, 'access_type': 'user', - 'action_name': 'os-allow_access', 'microversion': '2.0'}, - {'access_to': '1' * 255, 'access_type': 'user', - 'action_name': 'os-allow_access', 'microversion': '2.0'}, - {'access_to': 'fake${.-_\'`}', 'access_type': 'user', - 'action_name': 'os-allow_access', 'microversion': '2.0'}, - {'access_to': 'MYDOMAIN-Administrator', 'access_type': 'user', - 'action_name': 'os-allow_access', 'microversion': '2.0'}, - {'access_to': 'test group name', 'access_type': 'user', - 'action_name': 'os-allow_access', 'microversion': '2.0'}, - {'access_to': 'x', 'access_type': 'cert', - 'action_name': 'os-allow_access', 'microversion': '2.0'}, - {'access_to': 'x' * 64, 'access_type': 'cert', - 'action_name': 'os-allow_access', 'microversion': '2.0'}, - {'access_to': 'tenant.example.com', 'access_type': 'cert', - 'action_name': 'os-allow_access', 'microversion': '2.0'}, - {'access_to': '127.0.0.1', 'access_type': 'ip', - 'action_name': 'allow_access', 'microversion': '2.7'}, - {'access_to': 'test group name', 'access_type': 'user', - 'action_name': 'allow_access', 'microversion': '2.7'}, - {'access_to': 'alice', 'access_type': 'cephx', - 'action_name': 'allow_access', 'microversion': '2.13'}, - {'access_to': 'alice_bob', 'access_type': 'cephx', - 'action_name': 'allow_access', 'microversion': '2.13'}, - {'access_to': 'alice bob', 'access_type': 'cephx', - 'action_name': 'allow_access', 'microversion': '2.13'}, - {'access_to': 'test group name', 'access_type': 'user', - 'action_name': 'allow_access', 'microversion': '2.13'}, - {'access_to': 'AD80:0000:0000:0000:ABAA:0000:00C2:0002', - 'access_type': 'ip', 'action_name': 'allow_access', - 'microversion': '2.38'}, - {'access_to': 'AD80::/36', - 'access_type': 'ip', 'action_name': 'allow_access', - 'microversion': '2.38'}, - {'access_to': 'AD80:ABAA::/128', - 'access_type': 'ip', 'action_name': 'allow_access', - 'microversion': '2.38'}, - {'access_to': 'ad80::abaa:0:c2:2', - 'access_type': 'ip', 'action_name': 'allow_access', - 'microversion': '2.38'}, - {'access_to': 'test group name', 'access_type': 'user', - 'action_name': 'allow_access', 'microversion': '2.38'}, + { + 'access_to': '127.0.0.1', + 'access_type': 'ip', + 'action_name': 'os-allow_access', + 'microversion': '2.0', + }, + { + 'access_to': '1' * 4, + 'access_type': 'user', + 'action_name': 'os-allow_access', + 'microversion': '2.0', + }, + { + 'access_to': '1' * 255, + 'access_type': 'user', + 'action_name': 'os-allow_access', + 'microversion': '2.0', + }, + { + 'access_to': 'fake${.-_\'`}', + 'access_type': 'user', + 'action_name': 'os-allow_access', + 'microversion': '2.0', + }, + { + 'access_to': 'MYDOMAIN-Administrator', + 'access_type': 'user', + 'action_name': 'os-allow_access', + 'microversion': '2.0', + }, + { + 'access_to': 'test group name', + 'access_type': 'user', + 'action_name': 'os-allow_access', + 'microversion': '2.0', + }, + { + 'access_to': 'x', + 'access_type': 'cert', + 'action_name': 'os-allow_access', + 'microversion': '2.0', + }, + { + 'access_to': 'x' * 64, + 'access_type': 'cert', + 'action_name': 'os-allow_access', + 'microversion': '2.0', + }, + { + 'access_to': 'tenant.example.com', + 'access_type': 'cert', + 'action_name': 'os-allow_access', + 'microversion': '2.0', + }, + { + 'access_to': '127.0.0.1', + 'access_type': 'ip', + 'action_name': 'allow_access', + 'microversion': '2.7', + }, + { + 'access_to': 'test group name', + 'access_type': 'user', + 'action_name': 'allow_access', + 'microversion': '2.7', + }, + { + 'access_to': 'alice', + 'access_type': 'cephx', + 'action_name': 'allow_access', + 'microversion': '2.13', + }, + { + 'access_to': 'alice_bob', + 'access_type': 'cephx', + 'action_name': 'allow_access', + 'microversion': '2.13', + }, + { + 'access_to': 'alice bob', + 'access_type': 'cephx', + 'action_name': 'allow_access', + 'microversion': '2.13', + }, + { + 'access_to': 'test group name', + 'access_type': 'user', + 'action_name': 'allow_access', + 'microversion': '2.13', + }, + { + 'access_to': 'AD80:0000:0000:0000:ABAA:0000:00C2:0002', + 'access_type': 'ip', + 'action_name': 'allow_access', + 'microversion': '2.38', + }, + { + 'access_to': 'AD80::/36', + 'access_type': 'ip', + 'action_name': 'allow_access', + 'microversion': '2.38', + }, + { + 'access_to': 'AD80:ABAA::/128', + 'access_type': 'ip', + 'action_name': 'allow_access', + 'microversion': '2.38', + }, + { + 'access_to': 'ad80::abaa:0:c2:2', + 'access_type': 'ip', + 'action_name': 'allow_access', + 'microversion': '2.38', + }, + { + 'access_to': 'test group name', + 'access_type': 'user', + 'action_name': 'allow_access', + 'microversion': '2.38', + }, ) @ddt.unpack - def test_allow_access_to_share(self, access_to, access_type, - action_name, microversion): + def test_allow_access_to_share( + self, access_to, access_type, action_name, microversion + ): access = ('foo', {'access': 'bar'}) access_level = 'fake_access_level' share = 'fake_share' @@ -546,56 +709,69 @@ def test_allow_access_to_share(self, access_to, access_type, mock_microversion = mock.Mock(api_version=version) manager = shares.ShareManager(api=mock_microversion) - with mock.patch.object(manager, '_action', - mock.Mock(return_value=access)): + with mock.patch.object( + manager, '_action', mock.Mock(return_value=access) + ): result = manager.allow(share, access_type, access_to, access_level) manager._action.assert_called_once_with( - action_name, share, {'access_level': access_level, - 'access_type': access_type, - 'access_to': access_to}) + action_name, + share, + { + 'access_level': access_level, + 'access_type': access_type, + 'access_to': access_to, + }, + ) self.assertEqual('bar', result) @ddt.data( - {'access_to': 'localhost', 'access_type': 'ip', - 'microversion': '2.0'}, - {'access_to': '127.0.0.*', 'access_type': 'ip', - 'microversion': '2.0'}, - {'access_to': '127.0.0.0/33', 'access_type': 'ip', - 'microversion': '2.0'}, - {'access_to': '127.0.0.256', 'access_type': 'ip', - 'microversion': '2.0'}, - {'access_to': '1', 'access_type': 'user', - 'microversion': '2.0'}, - {'access_to': '1' * 3, 'access_type': 'user', - 'microversion': '2.0'}, - {'access_to': '1' * 256, 'access_type': 'user', - 'microversion': '2.0'}, - {'access_to': 'root+=', 'access_type': 'user', - 'microversion': '2.0'}, - {'access_to': '', 'access_type': 'cert', - 'microversion': '2.0'}, - {'access_to': ' ', 'access_type': 'cert', - 'microversion': '2.0'}, - {'access_to': 'x' * 65, 'access_type': 'cert', - 'microversion': '2.0'}, - {'access_to': 'alice', 'access_type': 'cephx', - 'microversion': '2.0'}, - {'access_to': '', 'access_type': 'cephx', - 'microversion': '2.13'}, - {'access_to': u"bj\u00F6rn", 'access_type': 'cephx', - 'microversion': '2.13'}, - {'access_to': "AD80:0000:0000:0000:ABAA:0000:00C2:0002/65", - 'access_type': 'ip', 'microversion': '2.38'}, - {'access_to': "AD80:0000:0000:0000:ABAA:0000:00C2:0002*32", - 'access_type': 'ip', 'microversion': '2.38'}, - {'access_to': "AD80:0000:0000:0000:ABAA:0000:00C2:0002", - 'access_type': 'ip', 'microversion': '2.37'}, + {'access_to': 'localhost', 'access_type': 'ip', 'microversion': '2.0'}, + {'access_to': '127.0.0.*', 'access_type': 'ip', 'microversion': '2.0'}, + { + 'access_to': '127.0.0.0/33', + 'access_type': 'ip', + 'microversion': '2.0', + }, + { + 'access_to': '127.0.0.256', + 'access_type': 'ip', + 'microversion': '2.0', + }, + {'access_to': '1', 'access_type': 'user', 'microversion': '2.0'}, + {'access_to': '1' * 3, 'access_type': 'user', 'microversion': '2.0'}, + {'access_to': '1' * 256, 'access_type': 'user', 'microversion': '2.0'}, + {'access_to': 'root+=', 'access_type': 'user', 'microversion': '2.0'}, + {'access_to': '', 'access_type': 'cert', 'microversion': '2.0'}, + {'access_to': ' ', 'access_type': 'cert', 'microversion': '2.0'}, + {'access_to': 'x' * 65, 'access_type': 'cert', 'microversion': '2.0'}, + {'access_to': 'alice', 'access_type': 'cephx', 'microversion': '2.0'}, + {'access_to': '', 'access_type': 'cephx', 'microversion': '2.13'}, + { + 'access_to': "bj\u00f6rn", + 'access_type': 'cephx', + 'microversion': '2.13', + }, + { + 'access_to': "AD80:0000:0000:0000:ABAA:0000:00C2:0002/65", + 'access_type': 'ip', + 'microversion': '2.38', + }, + { + 'access_to': "AD80:0000:0000:0000:ABAA:0000:00C2:0002*32", + 'access_type': 'ip', + 'microversion': '2.38', + }, + { + 'access_to': "AD80:0000:0000:0000:ABAA:0000:00C2:0002", + 'access_type': 'ip', + 'microversion': '2.37', + }, ) @ddt.unpack - def test_allow_access_to_share_error_invalid_access(self, access_to, - access_type, - microversion): + def test_allow_access_to_share_error_invalid_access( + self, access_to, access_type, microversion + ): access = ('foo', {'access': 'bar'}) access_level = 'fake_access_level' share = 'fake_share' @@ -603,10 +779,17 @@ def test_allow_access_to_share_error_invalid_access(self, access_to, mock_microversion = mock.Mock(api_version=version) manager = shares.ShareManager(api=mock_microversion) - with mock.patch.object(manager, '_action', - mock.Mock(return_value=access)): - self.assertRaises(exceptions.CommandError, manager.allow, - share, access_type, access_to, access_level) + with mock.patch.object( + manager, '_action', mock.Mock(return_value=access) + ): + self.assertRaises( + exceptions.CommandError, + manager.allow, + share, + access_type, + access_to, + access_level, + ) manager._action.assert_not_called() @@ -622,12 +805,14 @@ def test_deny_access_to_share(self, microversion, action_name): mock_microversion = mock.Mock(api_version=version) manager = shares.ShareManager(api=mock_microversion) - with mock.patch.object(manager, "_action", - mock.Mock(return_value="fake")): + with mock.patch.object( + manager, "_action", mock.Mock(return_value="fake") + ): result = manager.deny(share, access_id) manager._action.assert_called_once_with( - action_name, share, {"access_id": access_id}) + action_name, share, {"access_id": access_id} + ) self.assertEqual("fake", result) def test_get_metadata(self): @@ -636,26 +821,30 @@ def test_get_metadata(self): def test_set_metadata(self): cs.shares.set_metadata(1234, {'k1': 'v2'}) - cs.assert_called('POST', '/shares/1234/metadata', - {'metadata': {'k1': 'v2'}}) + cs.assert_called( + 'POST', '/shares/1234/metadata', {'metadata': {'k1': 'v2'}} + ) @ddt.data( - type('ShareUUID', (object, ), {'uuid': '1234'}), - type('ShareID', (object, ), {'id': '1234'}), - '1234') + type('ShareUUID', (object,), {'uuid': '1234'}), + type('ShareID', (object,), {'id': '1234'}), + '1234', + ) def test_delete_metadata(self, share): keys = ['key1'] cs.shares.delete_metadata(share, keys) cs.assert_called('DELETE', '/shares/1234/metadata/key1') @ddt.data( - type('ShareUUID', (object, ), {'uuid': '1234'}), - type('ShareID', (object, ), {'id': '1234'}), - '1234') + type('ShareUUID', (object,), {'uuid': '1234'}), + type('ShareID', (object,), {'id': '1234'}), + '1234', + ) def test_metadata_update_all(self, share): cs.shares.update_all_metadata(share, {'k1': 'v1'}) - cs.assert_called('PUT', '/shares/1234/metadata', - {'metadata': {'k1': 'v1'}}) + cs.assert_called( + 'PUT', '/shares/1234/metadata', {'metadata': {'k1': 'v1'}} + ) @ddt.data( ("2.6", "os-reset_status"), @@ -669,12 +858,14 @@ def test_reset_share_state(self, microversion, action_name): mock_microversion = mock.Mock(api_version=version) manager = shares.ShareManager(api=mock_microversion) - with mock.patch.object(manager, "_action", - mock.Mock(return_value="fake")): + with mock.patch.object( + manager, "_action", mock.Mock(return_value="fake") + ): result = manager.reset_state(share, state) manager._action.assert_called_once_with( - action_name, share, {"status": state}) + action_name, share, {"status": state} + ) self.assertEqual("fake", result) @ddt.data( @@ -690,17 +881,19 @@ def test_extend_share(self, microversion, action_name, force): mock_microversion = mock.Mock(api_version=version) manager = shares.ShareManager(api=mock_microversion) - with mock.patch.object(manager, "_action", - mock.Mock(return_value="fake")): + with mock.patch.object( + manager, "_action", mock.Mock(return_value="fake") + ): if not force: result = manager.extend(share, size) manager._action.assert_called_once_with( - action_name, share, {"new_size": size}) + action_name, share, {"new_size": size} + ) else: result = manager.extend(share, size, force=force) manager._action.assert_called_once_with( - action_name, share, {"new_size": size, - "force": "true"}) + action_name, share, {"new_size": size, "force": "true"} + ) self.assertEqual("fake", result) @ddt.data( @@ -715,16 +908,18 @@ def test_shrink_share(self, microversion, action_name): mock_microversion = mock.Mock(api_version=version) manager = shares.ShareManager(api=mock_microversion) - with mock.patch.object(manager, "_action", - mock.Mock(return_value="fake")): + with mock.patch.object( + manager, "_action", mock.Mock(return_value="fake") + ): result = manager.shrink(share, size) manager._action.assert_called_once_with( - action_name, share, {"new_size": size}) + action_name, share, {"new_size": size} + ) self.assertEqual("fake", result) def test_list_share_instances(self): - share = type('ShareID', (object, ), {'id': '1234'}) + share = type('ShareID', (object,), {'id': '1234'}) cs.shares.list_instances(share) cs.assert_called('GET', '/shares/1234/instances') @@ -733,16 +928,25 @@ def test_migration_start(self): host = "fake_host" version = api_versions.APIVersion('2.29') manager = shares.ShareManager( - api=fakes.FakeClient(api_version=version)) + api=fakes.FakeClient(api_version=version) + ) - with mock.patch.object(manager, "_action", - mock.Mock(return_value="fake")): + with mock.patch.object( + manager, "_action", mock.Mock(return_value="fake") + ): result = manager.migration_start( - share, host, force_host_assisted_migration=True, - preserve_metadata=True, writable=True, nondisruptive=True, - preserve_snapshots=True) + share, + host, + force_host_assisted_migration=True, + preserve_metadata=True, + writable=True, + nondisruptive=True, + preserve_snapshots=True, + ) manager._action.assert_called_once_with( - 'migration_start', share, { + 'migration_start', + share, + { "host": host, "force_host_assisted_migration": True, "preserve_metadata": True, @@ -751,7 +955,8 @@ def test_migration_start(self): "preserve_snapshots": True, "new_share_network_id": None, "new_share_type_id": None, - }) + }, + ) self.assertEqual("fake", result) @@ -759,24 +964,28 @@ def test_migration_complete(self): share = "fake_share" manager = shares.ShareManager(api=fakes.FakeClient()) - with mock.patch.object(manager, "_action", - mock.Mock(return_value="fake")): + with mock.patch.object( + manager, "_action", mock.Mock(return_value="fake") + ): result = manager.migration_complete(share) manager._action.assert_called_once_with( - "migration_complete", share) + "migration_complete", share + ) self.assertEqual("fake", result) def test_migration_get_progress(self): share = "fake_share" manager = shares.ShareManager(api=fakes.FakeClient()) - with mock.patch.object(manager, "_action", - mock.Mock(return_value="fake")): + with mock.patch.object( + manager, "_action", mock.Mock(return_value="fake") + ): result = manager.migration_get_progress(share) manager._action.assert_called_once_with( - "migration_get_progress", share) + "migration_get_progress", share + ) self.assertEqual("fake", result) def test_reset_task_state(self): @@ -784,22 +993,24 @@ def test_reset_task_state(self): state = "fake_state" manager = shares.ShareManager(api=fakes.FakeClient()) - with mock.patch.object(manager, "_action", - mock.Mock(return_value="fake")): + with mock.patch.object( + manager, "_action", mock.Mock(return_value="fake") + ): result = manager.reset_task_state(share, state) manager._action.assert_called_once_with( - "reset_task_state", share, {'task_state': state}) + "reset_task_state", share, {'task_state': state} + ) self.assertEqual("fake", result) def test_migration_cancel(self): share = "fake_share" manager = shares.ShareManager(api=fakes.FakeClient()) - with mock.patch.object(manager, "_action", - mock.Mock(return_value="fake")): + with mock.patch.object( + manager, "_action", mock.Mock(return_value="fake") + ): result = manager.migration_cancel(share) - manager._action.assert_called_once_with( - "migration_cancel", share) + manager._action.assert_called_once_with("migration_cancel", share) self.assertEqual("fake", result) diff --git a/manilaclient/tests/unit/v2/test_shell.py b/manilaclient/tests/unit/v2/test_shell.py index 41343d9b..5a0d04e8 100644 --- a/manilaclient/tests/unit/v2/test_shell.py +++ b/manilaclient/tests/unit/v2/test_shell.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2013 OpenStack Foundation # Copyright 2014 Mirantis, Inc. # All Rights Reserved. @@ -49,7 +48,6 @@ @ddt.ddt class ShellTest(test_utils.TestCase): - FAKE_ENV = { 'MANILA_USERNAME': 'username', 'MANILA_PASSWORD': 'password', @@ -60,10 +58,11 @@ class ShellTest(test_utils.TestCase): # Patch os.environ to avoid required auth info. def setUp(self): """Run before each test.""" - super(ShellTest, self).setUp() + super().setUp() for var in self.FAKE_ENV: - self.useFixture(fixtures.EnvironmentVariable(var, - self.FAKE_ENV[var])) + self.useFixture( + fixtures.EnvironmentVariable(var, self.FAKE_ENV[var]) + ) self.mock_completion() self.shell = shell.OpenStackManilaShell() @@ -96,13 +95,14 @@ def tearDown(self): # testing a SystemExit to be thrown and object self.shell has # no time to get instantatiated which is OK in this case, so # we make sure the method is there before launching it. - if hasattr(self.shell, 'cs') and hasattr(self.shell.cs, - 'clear_callstack'): + if hasattr(self.shell, 'cs') and hasattr( + self.shell.cs, 'clear_callstack' + ): self.shell.cs.clear_callstack() # HACK(bcwaldon): replace this when we start using stubs client.get_client_class = self.old_get_client_class - super(ShellTest, self).tearDown() + super().tearDown() def run_command(self, cmd, version=None): if version: @@ -114,10 +114,12 @@ def run_command(self, cmd, version=None): def assert_called(self, method, url, body=None, **kwargs): return self.shell.cs.assert_called(method, url, body, **kwargs) - def assert_called_anytime(self, method, url, body=None, - clear_callstack=True): + def assert_called_anytime( + self, method, url, body=None, clear_callstack=True + ): return self.shell.cs.assert_called_anytime( - method, url, body, clear_callstack=clear_callstack) + method, url, body, clear_callstack=clear_callstack + ) def test_availability_zone_list(self): self.run_command('availability-zone-list') @@ -128,7 +130,8 @@ def test_availability_zone_list_select_column(self): self.run_command('availability-zone-list --columns id,name') self.assert_called('GET', '/availability-zones') cliutils.print_list.assert_called_once_with( - mock.ANY, fields=['Id', 'Name']) + mock.ANY, fields=['Id', 'Name'] + ) def test_service_list(self): self.run_command('service-list') @@ -139,21 +142,24 @@ def test_service_list_select_column(self): self.run_command('service-list --columns id,host') self.assert_called('GET', '/services') cliutils.print_list.assert_called_once_with( - mock.ANY, fields=['Id', 'Host']) + mock.ANY, fields=['Id', 'Host'] + ) def test_service_enable(self): self.run_command('service-enable foo_host@bar_backend manila-share') self.assert_called( 'PUT', '/services/enable', - {'host': 'foo_host@bar_backend', 'binary': 'manila-share'}) + {'host': 'foo_host@bar_backend', 'binary': 'manila-share'}, + ) def test_service_disable(self): self.run_command('service-disable foo_host@bar_backend manila-share') self.assert_called( 'PUT', '/services/disable', - {'host': 'foo_host@bar_backend', 'binary': 'manila-share'}) + {'host': 'foo_host@bar_backend', 'binary': 'manila-share'}, + ) def test_list(self): self.run_command('list') @@ -165,8 +171,8 @@ def test_list_select_column(self): self.run_command('list --column id,name') self.assert_called('GET', '/shares/detail') cliutils.print_list.assert_called_once_with( - mock.ANY, - ['Id', 'Name'], sortby_index=None) + mock.ANY, ['Id', 'Name'], sortby_index=None + ) def test_list_sort_by_name(self): self.run_command('list --sort_key name') @@ -188,25 +194,36 @@ def test_list_all_tenants_only_key(self): self.assert_called('GET', '/shares/detail?all_tenants=1') cliutils.print_list.assert_called_once_with( mock.ANY, - ['ID', 'Name', 'Size', 'Share Proto', 'Status', 'Is Public', - 'Share Type Name', 'Host', 'Availability Zone', 'Project ID'], - sortby_index=None) + [ + 'ID', + 'Name', + 'Size', + 'Share Proto', + 'Status', + 'Is Public', + 'Share Type Name', + 'Host', + 'Availability Zone', + 'Project ID', + ], + sortby_index=None, + ) @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_list_select_column_and_all_tenants(self): self.run_command('list --columns ID,Name --all-tenants') self.assert_called('GET', '/shares/detail?all_tenants=1') cliutils.print_list.assert_called_once_with( - mock.ANY, - ['Id', 'Name'], sortby_index=None) + mock.ANY, ['Id', 'Name'], sortby_index=None + ) @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_list_select_column_and_public(self): self.run_command('list --columns ID,Name --public') self.assert_called('GET', '/shares/detail?is_public=True') cliutils.print_list.assert_called_once_with( - mock.ANY, - ['Id', 'Name'], sortby_index=None) + mock.ANY, ['Id', 'Name'], sortby_index=None + ) def test_list_all_tenants_key_and_value_1(self): for separator in self.separators: @@ -220,38 +237,41 @@ def test_list_all_tenants_key_and_value_0(self): def test_list_filter_by_share_server_and_its_aliases(self): aliases = [ - '--share-server-id', '--share-server_id', - '--share_server-id', '--share_server_id', + '--share-server-id', + '--share-server_id', + '--share_server-id', + '--share_server_id', ] for alias in aliases: for separator in self.separators: self.run_command('list ' + alias + separator + '1234') self.assert_called( - 'GET', '/shares/detail?share_server_id=1234') + 'GET', '/shares/detail?share_server_id=1234' + ) def test_list_filter_by_metadata(self): self.run_command('list --metadata key=value') # /shares/detail?metadata={'key': 'value'} self.assert_called( - 'GET', '/shares/detail?metadata=' - '%7B%27key%27%3A+%27value%27%7D') + 'GET', '/shares/detail?metadata=%7B%27key%27%3A+%27value%27%7D' + ) def test_list_filter_by_metadata_with_multiple_key_values(self): - self.run_command('list --metadata key1=value1 ' - 'key2=value2 key3=value3') + self.run_command('list --metadata key1=value1 key2=value2 key3=value3') # /shares/detail?metadata={'key1': 'value1', # 'key2': 'value2', 'key3': 'value3'} self.assert_called( - 'GET', '/shares/detail?metadata=' - '%7B%27key1%27%3A+%27value1%27%2C+%27key2%27%3A+' - '%27value2%27%2C+%27key3%27%3A+%27value3%27%7D') + 'GET', + '/shares/detail?metadata=' + '%7B%27key1%27%3A+%27value1%27%2C+%27key2%27%3A+' + '%27value2%27%2C+%27key3%27%3A+%27value3%27%7D', + ) @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_list_filter_by_metadata_with_empty_metadata(self): self.run_command('list --metadata \'\'') - self.assert_called( - 'GET', '/shares/detail') + self.assert_called('GET', '/shares/detail') cliutils.print_list.assert_called() args, _ = cliutils.print_list.call_args shares = args[0] @@ -262,8 +282,7 @@ def test_list_filter_by_metadata_with_empty_metadata(self): def test_list_filter_by_metadata_set_to_None(self): self.run_command('list --metadata None') - self.assert_called( - 'GET', '/shares/detail') + self.assert_called('GET', '/shares/detail') cliutils.print_list.assert_called() args, _ = cliutils.print_list.call_args shares = args[0] @@ -276,15 +295,14 @@ def test_list_filter_by_metadata_with_one_empty_of_many_metadata(self): self.run_command('list --metadata key=value \'\'') # /shares/detail?metadata={'key': 'value'} self.assert_called( - 'GET', '/shares/detail?metadata=' - '%7B%27key%27%3A+%27value%27%7D') + 'GET', '/shares/detail?metadata=%7B%27key%27%3A+%27value%27%7D' + ) @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_list_filter_by_metadata_with_no_metadata(self): self.run_command('list --metadata') # /shares/detail - self.assert_called( - 'GET', '/shares/detail') + self.assert_called('GET', '/shares/detail') cliutils.print_list.assert_called() args, _ = cliutils.print_list.call_args shares = args[0] @@ -292,7 +310,10 @@ def test_list_filter_by_metadata_with_no_metadata(self): self.assertEqual(len(shares), 4) def test_list_filter_by_extra_specs_and_its_aliases(self): - aliases = ['--extra-specs', '--extra_specs', ] + aliases = [ + '--extra-specs', + '--extra_specs', + ] for alias in aliases: self.run_command('list ' + alias + ' key=value') self.assert_called( @@ -303,50 +324,52 @@ def test_list_filter_by_extra_specs_and_its_aliases(self): def test_list_filter_by_share_type_and_its_aliases(self): fake_st = type('Empty', (object,), {'id': 'fake_st'}) aliases = [ - '--share-type', '--share_type', '--share-type-id', - '--share-type_id', '--share_type-id', '--share_type_id', + '--share-type', + '--share_type', + '--share-type-id', + '--share-type_id', + '--share_type-id', + '--share_type_id', ] for alias in aliases: for separator in self.separators: with mock.patch.object( - apiclient_utils, - 'find_resource', - mock.Mock(return_value=fake_st)): + apiclient_utils, + 'find_resource', + mock.Mock(return_value=fake_st), + ): self.run_command('list ' + alias + separator + fake_st.id) self.assert_called( - 'GET', '/shares/detail?share_type_id=' + fake_st.id) + 'GET', '/shares/detail?share_type_id=' + fake_st.id + ) def test_list_filter_by_inexact_name(self): for separator in self.separators: - self.run_command('list --name~' + separator + - 'fake_name') - self.assert_called( - 'GET', - '/shares/detail?name~=fake_name') + self.run_command('list --name~' + separator + 'fake_name') + self.assert_called('GET', '/shares/detail?name~=fake_name') def test_list_filter_by_inexact_description(self): for separator in self.separators: - self.run_command('list --description~' + separator + - 'fake_description') + self.run_command( + 'list --description~' + separator + 'fake_description' + ) self.assert_called( - 'GET', - '/shares/detail?description~=fake_description') + 'GET', '/shares/detail?description~=fake_description' + ) def test_list_filter_by_inexact_unicode_name(self): for separator in self.separators: - self.run_command('list --name~' + separator + - u'ффф') + self.run_command('list --name~' + separator + 'ффф') self.assert_called( - 'GET', - '/shares/detail?name~=%D1%84%D1%84%D1%84') + 'GET', '/shares/detail?name~=%D1%84%D1%84%D1%84' + ) def test_list_filter_by_inexact_unicode_description(self): for separator in self.separators: - self.run_command('list --description~' + separator + - u'ффф') + self.run_command('list --description~' + separator + 'ффф') self.assert_called( - 'GET', - '/shares/detail?description~=%D1%84%D1%84%D1%84') + 'GET', '/shares/detail?description~=%D1%84%D1%84%D1%84' + ) def test_list_filter_by_share_type_not_found(self): for separator in self.separators: @@ -393,8 +416,11 @@ def test_list_with_sort_key_verify_keys(self): key = 'share_network_id' if key == 'share_network' else key key = 'snapshot_id' if key == 'snapshot' else key key = 'share_type_id' if key == 'share_type' else key - key = ('availability_zone_id' if key == 'availability_zone' - else key) + key = ( + 'availability_zone_id' + if key == 'availability_zone' + else key + ) self.assert_called('GET', '/shares/detail?sort_key=' + key) def test_list_with_fake_sort_key(self): @@ -408,12 +434,14 @@ def test_list_filter_by_snapshot(self): fake_s = type('Empty', (object,), {'id': 'fake_snapshot_id'}) for separator in self.separators: with mock.patch.object( - apiclient_utils, - 'find_resource', - mock.Mock(return_value=fake_s)): + apiclient_utils, + 'find_resource', + mock.Mock(return_value=fake_s), + ): self.run_command('list --snapshot' + separator + fake_s.id) self.assert_called( - 'GET', '/shares/detail?snapshot_id=' + fake_s.id) + 'GET', '/shares/detail?snapshot_id=' + fake_s.id + ) def test_list_filter_by_snapshot_not_found(self): self.assertRaises( @@ -428,38 +456,46 @@ def test_list_filter_by_host(self): self.run_command('list --host' + separator + 'fake_host') self.assert_called('GET', '/shares/detail?host=fake_host') - @ddt.data(('id', 'b4991315-eb7d-43ec-979e-5715d4399827'), - ('path', 'fake_path')) + @ddt.data( + ('id', 'b4991315-eb7d-43ec-979e-5715d4399827'), ('path', 'fake_path') + ) @ddt.unpack def test_share_list_filter_by_export_location(self, filter_type, value): for separator in self.separators: self.run_command('list --export_location' + separator + value) self.assert_called( 'GET', - '/shares/detail?export_location_' + filter_type + '=' + value) + '/shares/detail?export_location_' + filter_type + '=' + value, + ) @ddt.data('list', 'share-instance-list') def test_share_or_instance_list_filter_by_export_location_version_invalid( - self, cmd): + self, cmd + ): self.assertRaises( exceptions.CommandError, self.run_command, cmd + ' --export_location=fake', - '2.34' + '2.34', ) def test_list_filter_by_share_network(self): - aliases = ['--share-network', '--share_network', ] + aliases = [ + '--share-network', + '--share_network', + ] fake_sn = type('Empty', (object,), {'id': 'fake_share_network_id'}) for alias in aliases: for separator in self.separators: with mock.patch.object( - apiclient_utils, - 'find_resource', - mock.Mock(return_value=fake_sn)): + apiclient_utils, + 'find_resource', + mock.Mock(return_value=fake_sn), + ): self.run_command('list ' + alias + separator + fake_sn.id) self.assert_called( - 'GET', '/shares/detail?share_network_id=' + fake_sn.id) + 'GET', '/shares/detail?share_network_id=' + fake_sn.id + ) def test_list_filter_by_share_network_not_found(self): self.assertRaises( @@ -485,7 +521,7 @@ def test_list_filter_with_count_invalid_version(self, value): exceptions.CommandError, self.run_command, 'list --count ' + value, - version='2.41' + version='2.41', ) @mock.patch.object(cliutils, 'print_list', mock.Mock()) @@ -495,8 +531,17 @@ def test_share_instance_list(self): self.assert_called('GET', '/share_instances') cliutils.print_list.assert_called_once_with( mock.ANY, - ['ID', 'Share ID', 'Host', 'Status', 'Availability Zone', - 'Share Network ID', 'Share Server ID', 'Share Type ID']) + [ + 'ID', + 'Share ID', + 'Host', + 'Status', + 'Availability Zone', + 'Share Network ID', + 'Share Server ID', + 'Share Type ID', + ], + ) @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_share_instance_list_select_column(self): @@ -504,25 +549,34 @@ def test_share_instance_list_select_column(self): self.assert_called('GET', '/share_instances') cliutils.print_list.assert_called_once_with( - mock.ANY, - ['Id', 'Host', 'Status']) + mock.ANY, ['Id', 'Host', 'Status'] + ) @mock.patch.object(cliutils, 'print_list', mock.Mock()) - @ddt.data(('id', 'b4991315-eb7d-43ec-979e-5715d4399827'), - ('path', 'fake_path')) + @ddt.data( + ('id', 'b4991315-eb7d-43ec-979e-5715d4399827'), ('path', 'fake_path') + ) @ddt.unpack - def test_share_instance_list_filter_by_export_location(self, filter_type, - value): + def test_share_instance_list_filter_by_export_location( + self, filter_type, value + ): for separator in self.separators: - self.run_command('share-instance-list --export_location' + - separator + value) + self.run_command( + 'share-instance-list --export_location' + separator + value + ) self.assert_called( 'GET', - ('/share_instances?export_location_' + - filter_type + '=' + value)) + ( + '/share_instances?export_location_' + + filter_type + + '=' + + value + ), + ) - @mock.patch.object(apiclient_utils, 'find_resource', - mock.Mock(return_value='fake')) + @mock.patch.object( + apiclient_utils, 'find_resource', mock.Mock(return_value='fake') + ) def test_share_instance_list_with_share(self): self.run_command('share-instance-list --share-id=fake') self.assert_called('GET', '/shares/fake/instances') @@ -542,92 +596,128 @@ def test_share_instance_export_location_list(self): self.run_command('share-instance-export-location-list 1234') self.assert_called_anytime( - 'GET', '/share_instances/1234/export_locations') + 'GET', '/share_instances/1234/export_locations' + ) @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_share_instance_export_location_list_with_columns(self): self.run_command( - 'share-instance-export-location-list 1234 --columns uuid,path') + 'share-instance-export-location-list 1234 --columns uuid,path' + ) self.assert_called_anytime( - 'GET', '/share_instances/1234/export_locations') + 'GET', '/share_instances/1234/export_locations' + ) cliutils.print_list.assert_called_once_with(mock.ANY, ['Uuid', 'Path']) def test_share_instance_export_location_show(self): self.run_command( - 'share-instance-export-location-show 1234 fake_el_uuid') + 'share-instance-export-location-show 1234 fake_el_uuid' + ) self.assert_called_anytime( - 'GET', '/share_instances/1234/export_locations/fake_el_uuid') + 'GET', '/share_instances/1234/export_locations/fake_el_uuid' + ) def test_share_instance_reset_state(self): self.run_command('share-instance-reset-state 1234') expected = {'reset_status': {'status': 'available'}} - self.assert_called('POST', '/share_instances/1234/action', - body=expected) + self.assert_called( + 'POST', '/share_instances/1234/action', body=expected + ) def test_share_instance_force_delete(self): manager_mock = mock.Mock() share_instance = share_instances.ShareInstance( - manager_mock, {'id': 'fake'}, True) + manager_mock, {'id': 'fake'}, True + ) - with mock.patch.object(shell_v2, '_find_share_instance', - mock.Mock(return_value=share_instance)): + with mock.patch.object( + shell_v2, + '_find_share_instance', + mock.Mock(return_value=share_instance), + ): self.run_command('share-instance-force-delete 1234') manager_mock.force_delete.assert_called_once_with(share_instance) - @ddt.data(('share_instance_xyz', ), ('share_instance_abc', - 'share_instance_xyz')) + @ddt.data( + ('share_instance_xyz',), ('share_instance_abc', 'share_instance_xyz') + ) def test_share_instance_force_delete_wait(self, instances_to_delete): fake_manager = mock.Mock() fake_instances = [ share_instances.ShareInstance(fake_manager, {'id': '1234'}) for instance in instances_to_delete ] - instance_not_found_error = ("Delete for instance %s failed: No " - "instance with a name or " - "ID of '%s' exists.") + instance_not_found_error = ( + "Delete for instance %s failed: No " + "instance with a name or " + "ID of '%s' exists." + ) instances_are_not_found_errors = [ exceptions.CommandError( - instance_not_found_error % (instance, instance)) + instance_not_found_error % (instance, instance) + ) for instance in instances_to_delete ] self.mock_object( - shell_v2, '_find_share_instance', - mock.Mock(side_effect=( - fake_instances + instances_are_not_found_errors))) + shell_v2, + '_find_share_instance', + mock.Mock( + side_effect=(fake_instances + instances_are_not_found_errors) + ), + ) self.run_command( - 'share-instance-force-delete %s --wait' % ' '.join( - instances_to_delete)) - shell_v2._find_share_instance.assert_has_calls([ - mock.call(self.shell.cs, instance) for instance in - instances_to_delete - ]) - fake_manager.force_delete.assert_has_calls([ - mock.call(instance) for instance in fake_instances]) - self.assertEqual(len(instances_to_delete), - fake_manager.force_delete.call_count) + 'share-instance-force-delete %s --wait' + % ' '.join(instances_to_delete) + ) + shell_v2._find_share_instance.assert_has_calls( + [ + mock.call(self.shell.cs, instance) + for instance in instances_to_delete + ] + ) + fake_manager.force_delete.assert_has_calls( + [mock.call(instance) for instance in fake_instances] + ) + self.assertEqual( + len(instances_to_delete), fake_manager.force_delete.call_count + ) def test_type_show_details(self): self.run_command('type-show 1234') self.assert_called_anytime('GET', '/types/1234') @mock.patch.object(cliutils, 'print_list', mock.Mock()) - @ddt.data(*itertools.product( - ('type-list --columns id,is_default', 'type-list --columns id,name', - 'type-list --columns is_default', 'type-list'), - {'2.45', '2.46', api_versions.MAX_VERSION})) + @ddt.data( + *itertools.product( + ( + 'type-list --columns id,is_default', + 'type-list --columns id,name', + 'type-list --columns is_default', + 'type-list', + ), + {'2.45', '2.46', api_versions.MAX_VERSION}, + ) + ) @ddt.unpack def test_type_list(self, command, version): self.run_command(command, version=version) - columns_requested = ['ID', 'Name', 'visibility', - 'is_default', 'required_extra_specs', - 'optional_extra_specs', 'Description'] + columns_requested = [ + 'ID', + 'Name', + 'visibility', + 'is_default', + 'required_extra_specs', + 'optional_extra_specs', + 'Description', + ] if 'columns' in command: columns_requested = command.split('--columns ')[1].split(',') - is_default_in_api = (api_versions.APIVersion(version) >= - api_versions.APIVersion('2.46')) + is_default_in_api = api_versions.APIVersion( + version + ) >= api_versions.APIVersion('2.46') if not is_default_in_api and 'is_default' in columns_requested: self.assert_called('GET', '/types/default') @@ -636,7 +726,8 @@ def test_type_list(self, command, version): self.assert_called('GET', '/types') cliutils.print_list.assert_called_with( - mock.ANY, columns_requested, mock.ANY) + mock.ANY, columns_requested, mock.ANY + ) @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_type_list_select_column(self): @@ -644,9 +735,8 @@ def test_type_list_select_column(self): self.assert_called('GET', '/types') cliutils.print_list.assert_called_once_with( - mock.ANY, - ['id', 'name'], - mock.ANY) + mock.ANY, ['id', 'name'], mock.ANY + ) def test_type_list_all(self): self.run_command('type-list --all') @@ -660,12 +750,12 @@ def test_type_create_with_access(self, public): 'extra_specs': { 'driver_handles_share_servers': False, }, - 'share_type_access:is_public': public + 'share_type_access:is_public': public, } } self.run_command( - 'type-create test-type-3 false --is-public %s' % - str(public)) + 'type-create test-type-3 false --is-public %s' % str(public) + ) self.assert_called('POST', '/types', body=expected) def test_type_access_list(self): @@ -701,12 +791,13 @@ def test_list_with_public_shares(self): 'Share Type Name', 'Host', 'Availability Zone', - 'Project ID' + 'Project ID', ] self.run_command('list --public') self.assert_called('GET', '/shares/detail?is_public=True') - cliutils.print_list.assert_called_with(mock.ANY, listed_fields, - sortby_index=None) + cliutils.print_list.assert_called_with( + mock.ANY, listed_fields, sortby_index=None + ) def test_show(self): self.run_command('show 1234') @@ -714,112 +805,125 @@ def test_show(self): def test_share_export_location_list(self): self.run_command('share-export-location-list 1234') - self.assert_called_anytime( - 'GET', '/shares/1234/export_locations') + self.assert_called_anytime('GET', '/shares/1234/export_locations') @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_share_export_location_list_with_columns(self): self.run_command('share-export-location-list 1234 --columns uuid,path') - self.assert_called_anytime( - 'GET', '/shares/1234/export_locations') + self.assert_called_anytime('GET', '/shares/1234/export_locations') cliutils.print_list.assert_called_once_with(mock.ANY, ['Uuid', 'Path']) def test_share_export_location_show(self): self.run_command('share-export-location-show 1234 fake_el_uuid') self.assert_called_anytime( - 'GET', '/shares/1234/export_locations/fake_el_uuid') - - @ddt.data({'cmd_args': '--driver_options opt1=opt1 opt2=opt2' - ' --share_type fake_share_type', - 'valid_params': { - 'driver_options': {'opt1': 'opt1', 'opt2': 'opt2'}, - 'share_type': 'fake_share_type', - 'share_server_id': None, - }}, - {'cmd_args': '--share_type fake_share_type', - 'valid_params': { - 'driver_options': {}, - 'share_type': 'fake_share_type', - 'share_server_id': None, - }}, - {'cmd_args': '', - 'valid_params': { - 'driver_options': {}, - 'share_type': None, - 'share_server_id': None, - }}, - {'cmd_args': '--public' - ' --wait', - 'valid_params': { - 'driver_options': {}, - 'share_type': None, - 'share_server_id': None, - }, - 'is_public': True, - 'version': '--os-share-api-version 2.8', - }, - {'cmd_args': '', - 'valid_params': { - 'driver_options': {}, - 'share_type': None, - 'share_server_id': None, - }, - 'is_public': False, - 'version': '--os-share-api-version 2.8', - }, - {'cmd_args': '--driver_options opt1=opt1 opt2=opt2' - ' --share_type fake_share_type' - ' --wait', - 'valid_params': { - 'driver_options': {'opt1': 'opt1', 'opt2': 'opt2'}, - 'share_type': 'fake_share_type', - 'share_server_id': None, - }, - 'version': '--os-share-api-version 2.49', - }, - {'cmd_args': '--driver_options opt1=opt1 opt2=opt2' - ' --share_type fake_share_type' - ' --share_server_id fake_server', - 'valid_params': { - 'driver_options': {'opt1': 'opt1', 'opt2': 'opt2'}, - 'share_type': 'fake_share_type', - 'share_server_id': 'fake_server', - }, - 'version': '--os-share-api-version 2.49', - }, - {'cmd_args': '--driver_options opt1=opt1 opt2=opt2' - ' --share_type fake_share_type' - ' --share_server_id fake_server' - ' --wait', - 'valid_params': { - 'driver_options': {'opt1': 'opt1', 'opt2': 'opt2'}, - 'share_type': 'fake_share_type', - 'share_server_id': 'fake_server', - }}, - ) - @ddt.unpack - def test_manage(self, cmd_args, valid_params, is_public=False, - version=None): - share_to_be_managed = shares.Share( - 'fake_share', { - 'id': 'fake' - } + 'GET', '/shares/1234/export_locations/fake_el_uuid' ) + + @ddt.data( + { + 'cmd_args': '--driver_options opt1=opt1 opt2=opt2' + ' --share_type fake_share_type', + 'valid_params': { + 'driver_options': {'opt1': 'opt1', 'opt2': 'opt2'}, + 'share_type': 'fake_share_type', + 'share_server_id': None, + }, + }, + { + 'cmd_args': '--share_type fake_share_type', + 'valid_params': { + 'driver_options': {}, + 'share_type': 'fake_share_type', + 'share_server_id': None, + }, + }, + { + 'cmd_args': '', + 'valid_params': { + 'driver_options': {}, + 'share_type': None, + 'share_server_id': None, + }, + }, + { + 'cmd_args': '--public --wait', + 'valid_params': { + 'driver_options': {}, + 'share_type': None, + 'share_server_id': None, + }, + 'is_public': True, + 'version': '--os-share-api-version 2.8', + }, + { + 'cmd_args': '', + 'valid_params': { + 'driver_options': {}, + 'share_type': None, + 'share_server_id': None, + }, + 'is_public': False, + 'version': '--os-share-api-version 2.8', + }, + { + 'cmd_args': '--driver_options opt1=opt1 opt2=opt2' + ' --share_type fake_share_type' + ' --wait', + 'valid_params': { + 'driver_options': {'opt1': 'opt1', 'opt2': 'opt2'}, + 'share_type': 'fake_share_type', + 'share_server_id': None, + }, + 'version': '--os-share-api-version 2.49', + }, + { + 'cmd_args': '--driver_options opt1=opt1 opt2=opt2' + ' --share_type fake_share_type' + ' --share_server_id fake_server', + 'valid_params': { + 'driver_options': {'opt1': 'opt1', 'opt2': 'opt2'}, + 'share_type': 'fake_share_type', + 'share_server_id': 'fake_server', + }, + 'version': '--os-share-api-version 2.49', + }, + { + 'cmd_args': '--driver_options opt1=opt1 opt2=opt2' + ' --share_type fake_share_type' + ' --share_server_id fake_server' + ' --wait', + 'valid_params': { + 'driver_options': {'opt1': 'opt1', 'opt2': 'opt2'}, + 'share_type': 'fake_share_type', + 'share_server_id': 'fake_server', + }, + }, + ) + @ddt.unpack + def test_manage( + self, cmd_args, valid_params, is_public=False, version=None + ): + share_to_be_managed = shares.Share('fake_share', {'id': 'fake'}) self.mock_object( - shell_v2, '_wait_for_resource_status', - mock.Mock(return_value=share_to_be_managed) + shell_v2, + '_wait_for_resource_status', + mock.Mock(return_value=share_to_be_managed), ) if version is not None: - self.run_command(version - + ' manage fake_service fake_protocol ' - + ' fake_export_path ' - + cmd_args) + self.run_command( + version + + ' manage fake_service fake_protocol ' + + ' fake_export_path ' + + cmd_args + ) else: - self.run_command(' manage fake_service fake_protocol ' - + ' fake_export_path ' - + cmd_args) + self.run_command( + ' manage fake_service fake_protocol ' + + ' fake_export_path ' + + cmd_args + ) expected = { 'share': { 'service_host': 'fake_service', @@ -837,8 +941,11 @@ def test_manage(self, cmd_args, valid_params, is_public=False, if '--wait' in cmd_args: shell_v2._wait_for_resource_status.assert_called_once_with( - self.shell.cs, share_to_be_managed, resource_type='share', - expected_status='available') + self.shell.cs, + share_to_be_managed, + resource_type='share', + expected_status='available', + ) else: shell_v2._wait_for_resource_status.assert_not_called() @@ -851,106 +958,127 @@ def test_manage_invalid_param_share_server_id(self): + ' fake_export_path ' + ' --driver_options opt1=opt1 opt2=opt2' + ' --share_type fake_share_type' - + ' --share_server_id fake_server') + + ' --share_server_id fake_server', + ) def test_share_server_manage_unsupported_version(self): self.assertRaises( exceptions.UnsupportedVersion, self.run_command, - '--os-share-api-version 2.48 ' + - 'share-server-manage fake_host fake_share_net_id fake_id') + '--os-share-api-version 2.48 ' + + 'share-server-manage fake_host fake_share_net_id fake_id', + ) def test_share_server_manage_invalid_param_subnet_id(self): self.assertRaises( exceptions.CommandError, self.run_command, - '--os-share-api-version 2.49 ' + - 'share-server-manage fake_host fake_share_net_id fake_id ' + - '--share-network-subnet fake_subnet_id') - - @ddt.data({'driver_args': '--driver_options opt1=opt1 opt2=opt2', - 'valid_params': { - 'driver_options': {'opt1': 'opt1', 'opt2': 'opt2'}, - }}, - {'driver_args': '--driver_options opt1=opt1 opt2=opt2', - 'subnet_id': 'fake_subnet_1', - 'valid_params': { - 'driver_options': {'opt1': 'opt1', 'opt2': 'opt2'}, - }}, - {'driver_args': '--driver_options opt1=opt1 opt2=opt2', - 'valid_params': { - 'driver_options': {'opt1': 'opt1', 'opt2': 'opt2'}, - }, - 'version': '2.51', - }, - {'driver_args': '--driver_options opt1=opt1 opt2=opt2', - 'subnet_id': 'fake_subnet_1', - 'valid_params': { - 'driver_options': {'opt1': 'opt1', 'opt2': 'opt2'}, - }, - 'version': '2.51', - }, - {'driver_args': "", - 'valid_params': { - 'driver_options': {} - }, - 'version': '2.51', - }, - {'driver_args': '--driver_options opt1=opt1 opt2=opt2', - 'valid_params': { - 'driver_options': {'opt1': 'opt1', 'opt2': 'opt2'}, - }, - 'version': '2.49', - }, - {'driver_args': '', - 'valid_params': { - 'driver_options': {}, - }, - 'network_id': 'fake_network_id', - 'version': '2.49', - }, - {'driver_args': "", - 'valid_params': { - 'driver_options': {} - }, - 'version': '2.49', - }, - ) + '--os-share-api-version 2.49 ' + + 'share-server-manage fake_host fake_share_net_id fake_id ' + + '--share-network-subnet fake_subnet_id', + ) + + @ddt.data( + { + 'driver_args': '--driver_options opt1=opt1 opt2=opt2', + 'valid_params': { + 'driver_options': {'opt1': 'opt1', 'opt2': 'opt2'}, + }, + }, + { + 'driver_args': '--driver_options opt1=opt1 opt2=opt2', + 'subnet_id': 'fake_subnet_1', + 'valid_params': { + 'driver_options': {'opt1': 'opt1', 'opt2': 'opt2'}, + }, + }, + { + 'driver_args': '--driver_options opt1=opt1 opt2=opt2', + 'valid_params': { + 'driver_options': {'opt1': 'opt1', 'opt2': 'opt2'}, + }, + 'version': '2.51', + }, + { + 'driver_args': '--driver_options opt1=opt1 opt2=opt2', + 'subnet_id': 'fake_subnet_1', + 'valid_params': { + 'driver_options': {'opt1': 'opt1', 'opt2': 'opt2'}, + }, + 'version': '2.51', + }, + { + 'driver_args': "", + 'valid_params': {'driver_options': {}}, + 'version': '2.51', + }, + { + 'driver_args': '--driver_options opt1=opt1 opt2=opt2', + 'valid_params': { + 'driver_options': {'opt1': 'opt1', 'opt2': 'opt2'}, + }, + 'version': '2.49', + }, + { + 'driver_args': '', + 'valid_params': { + 'driver_options': {}, + }, + 'network_id': 'fake_network_id', + 'version': '2.49', + }, + { + 'driver_args': "", + 'valid_params': {'driver_options': {}}, + 'version': '2.49', + }, + ) @ddt.unpack - def test_share_server_manage_wait(self, driver_args, valid_params, - version=None, network_id=None, - subnet_id=None): + def test_share_server_manage_wait( + self, + driver_args, + valid_params, + version=None, + network_id=None, + subnet_id=None, + ): fake_manager = mock.Mock() - subnet_support = (version is None or - api_versions.APIVersion(version) >= - api_versions.APIVersion('2.51')) + subnet_support = version is None or api_versions.APIVersion( + version + ) >= api_versions.APIVersion('2.51') network_id = '3456' if network_id is None else network_id fake_share_network = share_networks.ShareNetwork( - fake_manager, {'id': network_id, 'uuid': network_id}) + fake_manager, {'id': network_id, 'uuid': network_id} + ) self.mock_object( - shell_v2, '_find_share_network', - mock.Mock(return_value=fake_share_network)) + shell_v2, + '_find_share_network', + mock.Mock(return_value=fake_share_network), + ) fake_share_server = share_servers.ShareServer( - fake_manager, {'id': 'fake'}) + fake_manager, {'id': 'fake'} + ) self.mock_object( - shell_v2, '_find_share_server', - mock.Mock(return_value=fake_share_server)) + shell_v2, + '_find_share_server', + mock.Mock(return_value=fake_share_server), + ) - self.mock_object( - shell_v2, '_wait_for_resource_status', - mock.Mock() - ) - command = ('share-server-manage ' - '%(host)s ' - '%(share_network_id)s ' - '%(identifier)s ' - '%(driver_args)s ' % { - 'host': 'fake_host', - 'share_network_id': fake_share_network.id, - 'identifier': '88-as-23-f3-45', - 'driver_args': driver_args, - }) + self.mock_object(shell_v2, '_wait_for_resource_status', mock.Mock()) + command = ( + 'share-server-manage ' + '%(host)s ' + '%(share_network_id)s ' + '%(identifier)s ' + '%(driver_args)s ' + % { + 'host': 'fake_host', + 'share_network_id': fake_share_network.id, + 'identifier': '88-as-23-f3-45', + 'driver_args': driver_args, + } + ) command += '--share-network-subnet %s' % subnet_id if subnet_id else '' self.run_command(command, version=version) @@ -960,7 +1088,7 @@ def test_share_server_manage_wait(self, driver_args, valid_params, 'host': 'fake_host', 'share_network_id': fake_share_network.id, 'identifier': '88-as-23-f3-45', - 'driver_options': driver_args + 'driver_options': driver_args, } } if subnet_support: @@ -969,14 +1097,25 @@ def test_share_server_manage_wait(self, driver_args, valid_params, self.assert_called('POST', '/share-servers/manage', body=expected) - shell_v2._wait_for_resource_status.assert_has_calls([ - mock.call(self.shell.cs, fake_share_server, - resource_type='share_server', expected_status='active') - ]) + shell_v2._wait_for_resource_status.assert_has_calls( + [ + mock.call( + self.shell.cs, + fake_share_server, + resource_type='share_server', + expected_status='active', + ) + ] + ) - @ddt.data(constants.STATUS_ERROR, constants.STATUS_ACTIVE, - constants.STATUS_MANAGE_ERROR, constants.STATUS_UNMANAGE_ERROR, - constants.STATUS_DELETING, constants.STATUS_CREATING) + @ddt.data( + constants.STATUS_ERROR, + constants.STATUS_ACTIVE, + constants.STATUS_MANAGE_ERROR, + constants.STATUS_UNMANAGE_ERROR, + constants.STATUS_DELETING, + constants.STATUS_CREATING, + ) def test_share_server_reset_state(self, status): self.run_command('share-server-reset-state 1234 --state %s ' % status) expected = {'reset_status': {'status': status}} @@ -988,86 +1127,121 @@ def test_unmanage(self, wait_option): api = mock.Mock(api_version=version) manager = shares.ShareManager(api=api) fake_share = shares.Share( - manager, { + manager, + { 'id': 'xyzzyspoon', 'api_version': version, 'status': 'available', - } + }, + ) + share_not_found_error = ( + "ERROR: No share with a name or ID of '%s' exists." ) - share_not_found_error = ("ERROR: No share with " - "a name or ID of '%s' exists.") share_not_found_error = exceptions.CommandError( share_not_found_error % (fake_share.id) ) self.mock_object( - shell_v2, '_find_share', - mock.Mock(side_effect=([fake_share, fake_share, fake_share, - share_not_found_error]))) + shell_v2, + '_find_share', + mock.Mock( + side_effect=( + [fake_share, fake_share, fake_share, share_not_found_error] + ) + ), + ) self.mock_object( - shares.ShareManager, 'get', - mock.Mock(return_value=fake_share)) + shares.ShareManager, 'get', mock.Mock(return_value=fake_share) + ) self.run_command('unmanage %s xyzzyspoon' % wait_option) expected_get_share_calls = 4 if wait_option else 1 shell_v2._find_share.assert_has_calls( - [mock.call(self.shell.cs, fake_share.id)] * - expected_get_share_calls + [mock.call(self.shell.cs, fake_share.id)] + * expected_get_share_calls ) uri = '/shares/%s/action' % fake_share.id api.client.post.assert_called_once_with(uri, body={'unmanage': None}) def test_share_server_unmanage(self): self.run_command('share-server-unmanage 1234') - self.assert_called('POST', '/share-servers/1234/action', - body={'unmanage': {'force': False}}) + self.assert_called( + 'POST', + '/share-servers/1234/action', + body={'unmanage': {'force': False}}, + ) def test_share_server_unmanage_force(self): self.run_command('share-server-unmanage 1234 --force') - self.assert_called('POST', '/share-servers/1234/action', - body={'unmanage': {'force': True}}) + self.assert_called( + 'POST', + '/share-servers/1234/action', + body={'unmanage': {'force': True}}, + ) @mock.patch.object(shell_v2, '_wait_for_resource_status', mock.Mock()) def test_share_server_unmanage_wait(self): self.run_command('share-server-unmanage 1234 --wait') - self.assert_called('POST', '/share-servers/1234/action', - body={'unmanage': {'force': False}}, pos=-2) + self.assert_called( + 'POST', + '/share-servers/1234/action', + body={'unmanage': {'force': False}}, + pos=-2, + ) expected_share_server = shell_v2._find_share_server( - self.shell.cs, '1234') + self.shell.cs, '1234' + ) shell_v2._wait_for_resource_status.assert_called_once_with( - self.shell.cs, expected_share_server, - resource_type='share_server', expected_status='unmanaged') + self.shell.cs, + expected_share_server, + resource_type='share_server', + expected_status='unmanaged', + ) @mock.patch.object(shell_v2, '_wait_for_resource_status', mock.Mock()) def test_share_server_unmanage_wait_with_force(self): self.run_command('share-server-unmanage 1234 --force --wait') - self.assert_called('POST', '/share-servers/1234/action', - body={'unmanage': {'force': True}}, pos=-2) + self.assert_called( + 'POST', + '/share-servers/1234/action', + body={'unmanage': {'force': True}}, + pos=-2, + ) expected_share_server = shell_v2._find_share_server( - self.shell.cs, '1234') + self.shell.cs, '1234' + ) shell_v2._wait_for_resource_status.assert_called_once_with( - self.shell.cs, expected_share_server, - resource_type='share_server', expected_status='unmanaged') - - @ddt.data({'cmd_args': '--driver_options opt1=opt1 opt2=opt2', - 'valid_params': { - 'driver_options': {'opt1': 'opt1', 'opt2': 'opt2'}, - }}, - {'cmd_args': '', - 'valid_params': { - 'driver_options': {}, - }}, - ) + self.shell.cs, + expected_share_server, + resource_type='share_server', + expected_status='unmanaged', + ) + + @ddt.data( + { + 'cmd_args': '--driver_options opt1=opt1 opt2=opt2', + 'valid_params': { + 'driver_options': {'opt1': 'opt1', 'opt2': 'opt2'}, + }, + }, + { + 'cmd_args': '', + 'valid_params': { + 'driver_options': {}, + }, + }, + ) @ddt.unpack @mock.patch.object(shell_v2, '_find_share', mock.Mock()) @mock.patch.object(shell_v2, '_wait_for_resource_status', mock.Mock()) def test_snapshot_manage(self, cmd_args, valid_params): share_containing_snapshot = shares.Share('fake_share', {'id': '1234'}) shell_v2._find_share.return_value = share_containing_snapshot - self.run_command('snapshot-manage fake_share fake_provider_location ' - + cmd_args) + self.run_command( + 'snapshot-manage fake_share fake_provider_location ' + cmd_args + ) expected = { 'snapshot': { 'share_id': '1234', @@ -1087,8 +1261,9 @@ def test_snapshot_manage_with_wait(self): share_containing_snapshot = shares.Share('fake_share', {'id': '1234'}) shell_v2._find_share.return_value = share_containing_snapshot cmd_args = '--wait --driver_options opt1=opt1 opt2=opt2' - self.run_command('snapshot-manage fake_share fake_provider_location ' - + cmd_args) + self.run_command( + 'snapshot-manage fake_share fake_provider_location ' + cmd_args + ) expected = { 'snapshot': { 'share_id': '1234', @@ -1102,11 +1277,13 @@ def test_snapshot_manage_with_wait(self): self.assert_called('POST', '/snapshots/manage', body=expected) shell_v2._find_share.assert_has_calls( - [mock.call(self.shell.cs, 'fake_share')]) + [mock.call(self.shell.cs, 'fake_share')] + ) self.assertEqual(1, shell_v2._find_share.call_count) # _wait_for_resource_status should be triggered once shell_v2._wait_for_resource_status.assert_called_once_with( - self.shell.cs, mock.ANY, 'available', resource_type='snapshot') + self.shell.cs, mock.ANY, 'available', resource_type='snapshot' + ) @mock.patch.object(shell_v2, '_find_share', mock.Mock()) @mock.patch.object(shell_v2, '_wait_for_resource_status', mock.Mock()) @@ -1115,8 +1292,9 @@ def test_snapshot_unmanage(self): shell_v2._find_share.return_value = share_containing_snapshot self.run_command('snapshot-unmanage 1234') - self.assert_called('POST', '/snapshots/1234/action', - body={'unmanage': None}) + self.assert_called( + 'POST', '/snapshots/1234/action', body={'unmanage': None} + ) self.assertEqual(0, shell_v2._wait_for_resource_status.call_count) @mock.patch.object(shell_v2, '_find_share', mock.Mock()) @@ -1126,54 +1304,69 @@ def test_snapshot_unmanage_with_wait(self): shell_v2._find_share.return_value = share_containing_snapshot self.run_command('snapshot-unmanage 1234 --wait') - self.assert_called('POST', '/snapshots/1234/action', - body={'unmanage': None}) + self.assert_called( + 'POST', '/snapshots/1234/action', body={'unmanage': None} + ) expected_snapshot = shell_v2._find_share_snapshot( - self.shell.cs, '1234') + self.shell.cs, '1234' + ) # _wait_for_resource_status should be trigerred once shell_v2._wait_for_resource_status.assert_called_once_with( - self.shell.cs, expected_snapshot, 'deleted', - resource_type='snapshot') + self.shell.cs, + expected_snapshot, + 'deleted', + resource_type='snapshot', + ) @mock.patch.object(shell_v2, '_wait_for_share_status', mock.Mock()) def test_revert_to_snapshot(self): - fake_share_snapshot = type( - 'FakeShareSnapshot', (object,), {'id': '5678', 'share_id': '1234'}) + 'FakeShareSnapshot', (object,), {'id': '5678', 'share_id': '1234'} + ) self.mock_object( - shell_v2, '_find_share_snapshot', - mock.Mock(return_value=fake_share_snapshot)) + shell_v2, + '_find_share_snapshot', + mock.Mock(return_value=fake_share_snapshot), + ) self.run_command('revert-to-snapshot 5678') - self.assert_called('POST', '/shares/1234/action', - body={'revert': {'snapshot_id': '5678'}}) + self.assert_called( + 'POST', + '/shares/1234/action', + body={'revert': {'snapshot_id': '5678'}}, + ) # _wait_for_share_status should not be trigerred self.assertEqual(0, shell_v2._wait_for_share_status.call_count) @mock.patch.object(shell_v2, '_wait_for_share_status', mock.Mock()) def test_revert_to_snapshot_with_wait(self): - fake_share_snapshot = type( - 'FakeShareSnapshot', (object,), {'id': '5678', 'share_id': '1234'}) + 'FakeShareSnapshot', (object,), {'id': '5678', 'share_id': '1234'} + ) self.mock_object( - shell_v2, '_find_share_snapshot', - mock.Mock(return_value=fake_share_snapshot)) + shell_v2, + '_find_share_snapshot', + mock.Mock(return_value=fake_share_snapshot), + ) self.run_command('revert-to-snapshot 5678 --wait') - self.assert_called('POST', '/shares/1234/action', - body={'revert': {'snapshot_id': '5678'}}) + self.assert_called( + 'POST', + '/shares/1234/action', + body={'revert': {'snapshot_id': '5678'}}, + ) # _wait_for_share_status should be trigerred once shell_v2._wait_for_share_status.assert_called_once_with( - self.shell.cs, mock.ANY) + self.shell.cs, mock.ANY + ) def test_delete(self): self.run_command('delete 1234') self.assert_called('DELETE', '/shares/1234') - @ddt.data( - '--group sg1313', '--share-group sg1313', '--share_group sg1313') + @ddt.data('--group sg1313', '--share-group sg1313', '--share_group sg1313') @mock.patch.object(shell_v2, '_find_share_group', mock.Mock()) def test_delete_with_share_group(self, sg_cmd): fake_sg = type('FakeShareGroup', (object,), {'id': sg_cmd.split()[-1]}) @@ -1186,60 +1379,67 @@ def test_delete_with_share_group(self, sg_cmd): def test_delete_not_found(self): self.assertRaises( - exceptions.CommandError, - self.run_command, - 'delete fake-not-found' + exceptions.CommandError, self.run_command, 'delete fake-not-found' ) - @ddt.data(('share_xyz', ), ('share_abc', 'share_xyz')) + @ddt.data(('share_xyz',), ('share_abc', 'share_xyz')) def test_delete_wait(self, shares_to_delete): fake_shares = [ - shares.Share('fake', {'id': share}) - for share in shares_to_delete + shares.Share('fake', {'id': share}) for share in shares_to_delete ] - share_not_found_error = ("Delete for share %s failed: No share with " - "a name or ID of '%s' exists.") + share_not_found_error = ( + "Delete for share %s failed: No share with " + "a name or ID of '%s' exists." + ) shares_are_not_found_errors = [ exceptions.CommandError(share_not_found_error % (share, share)) for share in shares_to_delete ] self.mock_object( - shell_v2, '_find_share', - mock.Mock(side_effect=(fake_shares + shares_are_not_found_errors))) + shell_v2, + '_find_share', + mock.Mock(side_effect=(fake_shares + shares_are_not_found_errors)), + ) self.run_command('delete %s --wait' % ' '.join(shares_to_delete)) - shell_v2._find_share.assert_has_calls([ - mock.call(self.shell.cs, share) for share in shares_to_delete - ]) + shell_v2._find_share.assert_has_calls( + [mock.call(self.shell.cs, share) for share in shares_to_delete] + ) for share in fake_shares: uri = '/shares/%s' % share.id self.assert_called_anytime('DELETE', uri, clear_callstack=False) - @ddt.data(('share_xyz', ), ('share_abc', 'share_xyz')) + @ddt.data(('share_xyz',), ('share_abc', 'share_xyz')) def test_force_delete_wait(self, shares_to_delete): fake_manager = mock.Mock() fake_shares = [ shares.Share(fake_manager, {'id': '1234'}) for share in shares_to_delete ] - share_not_found_error = ("Delete for share %s failed: No share with " - "a name or ID of '%s' exists.") + share_not_found_error = ( + "Delete for share %s failed: No share with " + "a name or ID of '%s' exists." + ) shares_are_not_found_errors = [ exceptions.CommandError(share_not_found_error % (share, share)) for share in shares_to_delete ] self.mock_object( - shell_v2, '_find_share', - mock.Mock(side_effect=(fake_shares + shares_are_not_found_errors))) + shell_v2, + '_find_share', + mock.Mock(side_effect=(fake_shares + shares_are_not_found_errors)), + ) self.run_command('force-delete %s --wait' % ' '.join(shares_to_delete)) - shell_v2._find_share.assert_has_calls([ - mock.call(self.shell.cs, share) for share in shares_to_delete - ]) - fake_manager.force_delete.assert_has_calls([ - mock.call(share) for share in fake_shares]) - self.assertEqual(len(shares_to_delete), - fake_manager.force_delete.call_count) + shell_v2._find_share.assert_has_calls( + [mock.call(self.shell.cs, share) for share in shares_to_delete] + ) + fake_manager.force_delete.assert_has_calls( + [mock.call(share) for share in fake_shares] + ) + self.assertEqual( + len(shares_to_delete), fake_manager.force_delete.call_count + ) def test_soft_delete(self): self.run_command('soft-delete 1234') @@ -1260,8 +1460,8 @@ def test_snapshot_list_select_column(self): self.run_command('snapshot-list --columns id,name') self.assert_called('GET', '/snapshots/detail') cliutils.print_list.assert_called_once_with( - mock.ANY, - ['Id', 'Name'], sortby_index=None) + mock.ANY, ['Id', 'Name'], sortby_index=None + ) @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_list_snapshots_all_tenants_only_key(self): @@ -1270,13 +1470,13 @@ def test_list_snapshots_all_tenants_only_key(self): cliutils.print_list.assert_called_once_with( mock.ANY, ['ID', 'Share ID', 'Status', 'Name', 'Share Size', 'Project ID'], - sortby_index=None) + sortby_index=None, + ) def test_list_snapshots_all_tenants_key_and_value_1(self): for separator in self.separators: self.run_command('snapshot-list --all-tenants' + separator + '1') - self.assert_called( - 'GET', '/snapshots/detail?all_tenants=1') + self.assert_called('GET', '/snapshots/detail?all_tenants=1') def test_list_snapshots_all_tenants_key_and_value_0(self): for separator in self.separators: @@ -1286,22 +1486,19 @@ def test_list_snapshots_all_tenants_key_and_value_0(self): def test_list_snapshots_filter_by_name(self): for separator in self.separators: self.run_command('snapshot-list --name' + separator + '1234') - self.assert_called( - 'GET', '/snapshots/detail?name=1234') + self.assert_called('GET', '/snapshots/detail?name=1234') def test_list_snapshots_filter_by_status(self): for separator in self.separators: self.run_command('snapshot-list --status' + separator + '1234') - self.assert_called( - 'GET', '/snapshots/detail?status=1234') + self.assert_called('GET', '/snapshots/detail?status=1234') def test_list_snapshots_filter_by_share_id(self): aliases = ['--share_id', '--share-id'] for alias in aliases: for separator in self.separators: self.run_command('snapshot-list ' + alias + separator + '1234') - self.assert_called( - 'GET', '/snapshots/detail?share_id=1234') + self.assert_called('GET', '/snapshots/detail?share_id=1234') def test_list_snapshots_only_used(self): for separator in self.separators: @@ -1321,46 +1518,42 @@ def test_list_snapshots_any(self): def test_list_snapshots_with_limit(self): for separator in self.separators: self.run_command('snapshot-list --limit' + separator + '50') - self.assert_called( - 'GET', '/snapshots/detail?limit=50') + self.assert_called('GET', '/snapshots/detail?limit=50') def test_list_snapshots_with_offset(self): for separator in self.separators: self.run_command('snapshot-list --offset' + separator + '50') - self.assert_called( - 'GET', '/snapshots/detail?offset=50') + self.assert_called('GET', '/snapshots/detail?offset=50') def test_list_snapshots_filter_by_inexact_name(self): for separator in self.separators: - self.run_command('snapshot-list --name~' + separator + - 'fake_name') - self.assert_called( - 'GET', - '/snapshots/detail?name~=fake_name') + self.run_command('snapshot-list --name~' + separator + 'fake_name') + self.assert_called('GET', '/snapshots/detail?name~=fake_name') def test_list_snapshots_filter_by_inexact_description(self): for separator in self.separators: - self.run_command('snapshot-list --description~' + separator + - 'fake_description') + self.run_command( + 'snapshot-list --description~' + separator + 'fake_description' + ) self.assert_called( - 'GET', - '/snapshots/detail?description~=fake_description') + 'GET', '/snapshots/detail?description~=fake_description' + ) def test_list_snapshots_filter_by_inexact_unicode_name(self): for separator in self.separators: - self.run_command('snapshot-list --name~' + separator + - u'ффф') + self.run_command('snapshot-list --name~' + separator + 'ффф') self.assert_called( - 'GET', - '/snapshots/detail?name~=%D1%84%D1%84%D1%84') + 'GET', '/snapshots/detail?name~=%D1%84%D1%84%D1%84' + ) def test_list_snapshots_filter_by_inexact_unicode_description(self): for separator in self.separators: - self.run_command('snapshot-list --description~' + separator + - u'ффф') + self.run_command( + 'snapshot-list --description~' + separator + 'ффф' + ) self.assert_called( - 'GET', - '/snapshots/detail?description~=%D1%84%D1%84%D1%84') + 'GET', '/snapshots/detail?description~=%D1%84%D1%84%D1%84' + ) def test_list_snapshots_with_sort_dir_verify_keys(self): aliases = ['--sort_dir', '--sort-dir'] @@ -1368,10 +1561,11 @@ def test_list_snapshots_with_sort_dir_verify_keys(self): for key in constants.SORT_DIR_VALUES: for separator in self.separators: self.run_command( - 'snapshot-list ' + alias + separator + key) + 'snapshot-list ' + alias + separator + key + ) self.assert_called( - 'GET', - '/snapshots/detail?sort_dir=' + key) + 'GET', '/snapshots/detail?sort_dir=' + key + ) def test_list_snapshots_with_fake_sort_dir(self): self.assertRaises( @@ -1386,10 +1580,11 @@ def test_list_snapshots_with_sort_key_verify_keys(self): for key in constants.SNAPSHOT_SORT_KEY_VALUES: for separator in self.separators: self.run_command( - 'snapshot-list ' + alias + separator + key) + 'snapshot-list ' + alias + separator + key + ) self.assert_called( - 'GET', - '/snapshots/detail?sort_key=' + key) + 'GET', '/snapshots/detail?sort_key=' + key + ) def test_list_snapshots_with_fake_sort_key(self): self.assertRaises( @@ -1414,7 +1609,7 @@ def test_list_snapshots_filter_with_count_invalid_version(self, value): exceptions.CommandError, self.run_command, 'snapshot-list --count ' + value, - version='2.78' + version='2.78', ) @mock.patch.object(cliutils, 'print_list', mock.Mock()) @@ -1423,7 +1618,8 @@ def test_extra_specs_list(self): self.assert_called('GET', '/types?is_public=all') cliutils.print_list.assert_called_once_with( - mock.ANY, ['ID', 'Name', 'all_extra_specs'], mock.ANY) + mock.ANY, ['ID', 'Name', 'all_extra_specs'], mock.ANY + ) @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_extra_specs_list_select_column(self): @@ -1431,7 +1627,8 @@ def test_extra_specs_list_select_column(self): self.assert_called('GET', '/types?is_public=all') cliutils.print_list.assert_called_once_with( - mock.ANY, ['id', 'name'], mock.ANY) + mock.ANY, ['id', 'name'], mock.ANY + ) @ddt.data('fake', 'FFFalse', 'trueee') def test_type_create_invalid_dhss_value(self, value): @@ -1446,19 +1643,24 @@ def test_type_create_duplicate_dhss(self, value): self.assertRaises( exceptions.CommandError, self.run_command, - 'type-create test ' + value + - ' --extra-specs driver_handles_share_servers=' + value, + 'type-create test ' + + value + + ' --extra-specs driver_handles_share_servers=' + + value, ) - @ddt.data(*itertools.product( - ['snapshot_support', 'create_share_from_snapshot_support'], - ['True', 'False']) + @ddt.data( + *itertools.product( + ['snapshot_support', 'create_share_from_snapshot_support'], + ['True', 'False'], + ) ) @ddt.unpack def test_type_create_duplicate_switch_and_extra_spec(self, key, value): - - cmd = ('type-create test True --%(key)s %(value)s --extra-specs ' - '%(key)s=%(value)s' % {'key': key, 'value': value}) + cmd = ( + 'type-create test True --%(key)s %(value)s --extra-specs ' + '%(key)s=%(value)s' % {'key': key, 'value': value} + ) self.assertRaises(exceptions.CommandError, self.run_command, cmd) @@ -1466,15 +1668,16 @@ def test_type_create_duplicate_extra_spec_key(self): self.assertRaises( exceptions.CommandError, self.run_command, - 'type-create test True --extra-specs' - ' a=foo1 a=foo2', + 'type-create test True --extra-specs a=foo1 a=foo2', ) @ddt.unpack - @ddt.data({'expected_bool': True, 'text': 'true'}, - {'expected_bool': True, 'text': '1'}, - {'expected_bool': False, 'text': 'false'}, - {'expected_bool': False, 'text': '0'}) + @ddt.data( + {'expected_bool': True, 'text': 'true'}, + {'expected_bool': True, 'text': '1'}, + {'expected_bool': False, 'text': 'false'}, + {'expected_bool': False, 'text': '0'}, + ) def test_type_create(self, expected_bool, text): expected = { "share_type": { @@ -1482,7 +1685,7 @@ def test_type_create(self, expected_bool, text): "share_type_access:is_public": True, "extra_specs": { "driver_handles_share_servers": expected_bool, - } + }, } } @@ -1498,11 +1701,13 @@ def test_type_create_with_description(self): "share_type_access:is_public": True, "extra_specs": { "driver_handles_share_servers": False, - } + }, } } - self.run_command('type-create test false ' - '--description test_description', version='2.41') + self.run_command( + 'type-create test false --description test_description', + version='2.41', + ) self.assert_called('POST', '/types', body=expected) @@ -1512,15 +1717,21 @@ def test_type_create_invalid_description_version(self, version): exceptions.CommandError, self.run_command, 'type-create test false --description test_description', - version=version + version=version, ) @ddt.unpack @ddt.data( - *([{'expected_bool': True, 'text': v} - for v in ('true', 'True', '1', 'TRUE', 'tRuE')] + - [{'expected_bool': False, 'text': v} - for v in ('false', 'False', '0', 'FALSE', 'fAlSe')]) + *( + [ + {'expected_bool': True, 'text': v} + for v in ('true', 'True', '1', 'TRUE', 'tRuE') + ] + + [ + {'expected_bool': False, 'text': v} + for v in ('false', 'False', '0', 'FALSE', 'fAlSe') + ] + ) ) def test_type_create_with_snapshot_support(self, expected_bool, text): expected = { @@ -1530,7 +1741,7 @@ def test_type_create_with_snapshot_support(self, expected_bool, text): "extra_specs": { "snapshot_support": expected_bool, "driver_handles_share_servers": False, - } + }, } } self.run_command('type-create test false --snapshot-support ' + text) @@ -1538,14 +1749,21 @@ def test_type_create_with_snapshot_support(self, expected_bool, text): self.assert_called('POST', '/types', body=expected) @ddt.unpack - @ddt.data({'expected_bool': True, - 'snapshot_text': 'true', - 'replication_type': 'readable'}, - {'expected_bool': False, - 'snapshot_text': 'false', - 'replication_type': 'writable'}) - def test_create_with_extra_specs(self, expected_bool, snapshot_text, - replication_type): + @ddt.data( + { + 'expected_bool': True, + 'snapshot_text': 'true', + 'replication_type': 'readable', + }, + { + 'expected_bool': False, + 'snapshot_text': 'false', + 'replication_type': 'writable', + }, + ) + def test_create_with_extra_specs( + self, expected_bool, snapshot_text, replication_type + ): expected = { "share_type": { "name": "test", @@ -1554,25 +1772,36 @@ def test_create_with_extra_specs(self, expected_bool, snapshot_text, "driver_handles_share_servers": False, "snapshot_support": expected_bool, "replication_type": replication_type, - } + }, } } - self.run_command('type-create test false --extra-specs' - ' snapshot_support=' + snapshot_text + - ' replication_type=' + replication_type) + self.run_command( + 'type-create test false --extra-specs' + ' snapshot_support=' + + snapshot_text + + ' replication_type=' + + replication_type + ) self.assert_called('POST', '/types', body=expected) @ddt.unpack @ddt.data( - *([{'expected_bool': True, 'text': v} - for v in ('true', 'True', '1', 'TRUE', 'tRuE')] + - [{'expected_bool': False, 'text': v} - for v in ('false', 'False', '0', 'FALSE', 'fAlSe')]) + *( + [ + {'expected_bool': True, 'text': v} + for v in ('true', 'True', '1', 'TRUE', 'tRuE') + ] + + [ + {'expected_bool': False, 'text': v} + for v in ('false', 'False', '0', 'FALSE', 'fAlSe') + ] + ) ) def test_type_create_with_create_share_from_snapshot_support( - self, expected_bool, text): + self, expected_bool, text + ): expected = { "share_type": { "name": "test", @@ -1581,12 +1810,14 @@ def test_type_create_with_create_share_from_snapshot_support( "driver_handles_share_servers": False, "snapshot_support": True, "create_share_from_snapshot_support": expected_bool, - } + }, } } - self.run_command('type-create test false --snapshot-support true ' - '--create-share-from-snapshot-support ' + text) + self.run_command( + 'type-create test false --snapshot-support true ' + '--create-share-from-snapshot-support ' + text + ) self.assert_called('POST', '/types', body=expected) @@ -1608,13 +1839,20 @@ def test_type_create_invalid_extra_spec_value(self, value): @ddt.unpack @ddt.data( - *([{'expected_bool': True, 'text': v} - for v in ('true', 'True', '1', 'TRUE', 'tRuE')] + - [{'expected_bool': False, 'text': v} - for v in ('false', 'False', '0', 'FALSE', 'fAlSe')]) + *( + [ + {'expected_bool': True, 'text': v} + for v in ('true', 'True', '1', 'TRUE', 'tRuE') + ] + + [ + {'expected_bool': False, 'text': v} + for v in ('false', 'False', '0', 'FALSE', 'fAlSe') + ] + ) ) def test_type_create_with_revert_to_snapshot_support( - self, expected_bool, text): + self, expected_bool, text + ): expected = { "share_type": { "name": "test", @@ -1623,12 +1861,14 @@ def test_type_create_with_revert_to_snapshot_support( "driver_handles_share_servers": False, "snapshot_support": True, "revert_to_snapshot_support": expected_bool, - } + }, } } - self.run_command('type-create test false --snapshot-support true ' - '--revert-to-snapshot-support ' + text) + self.run_command( + 'type-create test false --snapshot-support true ' + '--revert-to-snapshot-support ' + text + ) self.assert_called('POST', '/types', body=expected) @@ -1642,13 +1882,20 @@ def test_type_create_invalid_revert_to_snapshot_support_value(self, value): @ddt.unpack @ddt.data( - *([{'expected_bool': True, 'text': v} - for v in ('true', 'True', '1', 'TRUE', 'tRuE')] + - [{'expected_bool': False, 'text': v} - for v in ('false', 'False', '0', 'FALSE', 'fAlSe')]) - ) + *( + [ + {'expected_bool': True, 'text': v} + for v in ('true', 'True', '1', 'TRUE', 'tRuE') + ] + + [ + {'expected_bool': False, 'text': v} + for v in ('false', 'False', '0', 'FALSE', 'fAlSe') + ] + ) + ) def test_type_create_with_mount_snapshot_support( - self, expected_bool, text): + self, expected_bool, text + ): expected = { "share_type": { "name": "test", @@ -1658,13 +1905,15 @@ def test_type_create_with_mount_snapshot_support( "snapshot_support": True, "revert_to_snapshot_support": False, "mount_snapshot_support": expected_bool, - } + }, } } - self.run_command('type-create test false --snapshot-support true ' - '--revert-to-snapshot-support false ' - '--mount-snapshot-support ' + text) + self.run_command( + 'type-create test false --snapshot-support true ' + '--revert-to-snapshot-support false ' + '--mount-snapshot-support ' + text + ) self.assert_called('POST', '/types', body=expected) @@ -1689,33 +1938,42 @@ def test_update(self, alias): # update is_public attr valid_is_public_values = strutils.TRUE_STRINGS + strutils.FALSE_STRINGS for is_public in valid_is_public_values: - self.run_command('update 1234 %(alias)s %(value)s' % { - 'alias': alias, - 'value': is_public}) + self.run_command( + 'update 1234 %(alias)s %(value)s' + % {'alias': alias, 'value': is_public} + ) expected = { 'share': { - 'is_public': strutils.bool_from_string(is_public, - strict=True), + 'is_public': strutils.bool_from_string( + is_public, strict=True + ), }, } self.assert_called('PUT', '/shares/1234', body=expected) for invalid_val in ['truebar', 'bartrue']: - self.assertRaises(ValueError, self.run_command, - 'update 1234 %(alias)s %(value)s' % { - 'alias': alias, - 'value': invalid_val}) + self.assertRaises( + ValueError, + self.run_command, + 'update 1234 %(alias)s %(value)s' + % {'alias': alias, 'value': invalid_val}, + ) # update all attributes - self.run_command('update 1234 --name new-name ' - '--description=new-description ' - '%s True' % alias) - expected = {'share': { - 'display_name': 'new-name', - 'display_description': 'new-description', - 'is_public': True, - }} + self.run_command( + 'update 1234 --name new-name ' + '--description=new-description ' + '%s True' % alias + ) + expected = { + 'share': { + 'display_name': 'new-name', + 'display_description': 'new-description', + 'is_public': True, + } + } self.assert_called('PUT', '/shares/1234', body=expected) - self.assertRaises(exceptions.CommandError, - self.run_command, 'update 1234') + self.assertRaises( + exceptions.CommandError, self.run_command, 'update 1234' + ) def test_rename_snapshot(self): # basic rename with positional arguments @@ -1723,27 +1981,33 @@ def test_rename_snapshot(self): expected = {'snapshot': {'display_name': 'new-name'}} self.assert_called('PUT', '/snapshots/1234', body=expected) # change description only - self.run_command('snapshot-rename 1234 ' - '--description=new-description') + self.run_command('snapshot-rename 1234 --description=new-description') expected = {'snapshot': {'display_description': 'new-description'}} self.assert_called('PUT', '/snapshots/1234', body=expected) # snapshot-rename and change description - self.run_command('snapshot-rename 1234 new-name ' - '--description=new-description') - expected = {'snapshot': { - 'display_name': 'new-name', - 'display_description': 'new-description', - }} + self.run_command( + 'snapshot-rename 1234 new-name --description=new-description' + ) + expected = { + 'snapshot': { + 'display_name': 'new-name', + 'display_description': 'new-description', + } + } self.assert_called('PUT', '/snapshots/1234', body=expected) # noop, the only all will be the lookup - self.assertRaises(exceptions.CommandError, - self.run_command, 'snapshot-rename 1234') + self.assertRaises( + exceptions.CommandError, self.run_command, 'snapshot-rename 1234' + ) def test_set_metadata_set(self): self.run_command('metadata 1234 set key1=val1 key2=val2') - self.assert_called('POST', '/shares/1234/metadata', - {'metadata': {'key1': 'val1', 'key2': 'val2'}}) + self.assert_called( + 'POST', + '/shares/1234/metadata', + {'metadata': {'key1': 'val1', 'key2': 'val2'}}, + ) def test_set_metadata_delete_dict(self): self.run_command('metadata 1234 unset key1=val1 key2=val2') @@ -1757,12 +2021,15 @@ def test_set_metadata_delete_keys(self): def test_share_metadata_update_all(self): self.run_command('metadata-update-all 1234 key1=val1 key2=val2') - self.assert_called('PUT', '/shares/1234/metadata', - {'metadata': {'key1': 'val1', 'key2': 'val2'}}) + self.assert_called( + 'PUT', + '/shares/1234/metadata', + {'metadata': {'key1': 'val1', 'key2': 'val2'}}, + ) def test_extract_metadata(self): # mimic the result of argparse's parse_args() method - class Arguments(object): + class Arguments: def __init__(self, metadata=None): if metadata is None: metadata = [] @@ -1774,7 +2041,7 @@ def __init__(self, metadata=None): (["key"], {"key": None}), (["k1=v1", "k2=v2"], {"k1": "v1", "k2": "v2"}), (["k1=v1", "k2"], {"k1": "v1", "k2": None}), - (["k1", "k2=v2"], {"k1": None, "k2": "v2"}) + (["k1", "k2=v2"], {"k1": None, "k2": "v2"}), ] for input in inputs: @@ -1784,26 +2051,35 @@ def __init__(self, metadata=None): @ddt.data('--wait', '') def test_extend_with_wait_option(self, wait_option): available_share = shares.Share( - 'fake', {'id': '1234', 'status': 'available'}) - share_to_extend = shares.Share('fake', {'id': '1234', - 'status': 'extending'}) + 'fake', {'id': '1234', 'status': 'available'} + ) + share_to_extend = shares.Share( + 'fake', {'id': '1234', 'status': 'extending'} + ) fake_shares = [ - available_share, share_to_extend, share_to_extend, available_share + available_share, + share_to_extend, + share_to_extend, + available_share, ] - self.mock_object(shell_v2, '_find_share', - mock.Mock(side_effect=fake_shares)) + self.mock_object( + shell_v2, '_find_share', mock.Mock(side_effect=fake_shares) + ) expected_extend_body = {'extend': {'new_size': 77}} self.run_command('extend 1234 77 %s' % wait_option) - self.assert_called_anytime('POST', '/shares/1234/action', - body=expected_extend_body, - clear_callstack=False) + self.assert_called_anytime( + 'POST', + '/shares/1234/action', + body=expected_extend_body, + clear_callstack=False, + ) if wait_option: shell_v2._find_share.assert_has_calls( - [mock.call(self.shell.cs, '1234')] * 4) + [mock.call(self.shell.cs, '1234')] * 4 + ) self.assertEqual(4, shell_v2._find_share.call_count) else: - shell_v2._find_share.assert_called_with( - self.shell.cs, '1234') + shell_v2._find_share.assert_called_with(self.shell.cs, '1234') self.assertEqual(2, shell_v2._find_share.call_count) def test_reset_state(self): @@ -1814,26 +2090,35 @@ def test_reset_state(self): @ddt.data('--wait', '') def test_shrink_with_wait_option(self, wait_option): available_share = shares.Share( - 'fake', {'id': '1234', 'status': 'available'}) - share_to_shrink = shares.Share('fake', {'id': '1234', - 'status': 'shrinking'}) + 'fake', {'id': '1234', 'status': 'available'} + ) + share_to_shrink = shares.Share( + 'fake', {'id': '1234', 'status': 'shrinking'} + ) fake_shares = [ - available_share, share_to_shrink, share_to_shrink, available_share + available_share, + share_to_shrink, + share_to_shrink, + available_share, ] - self.mock_object(shell_v2, '_find_share', - mock.Mock(side_effect=fake_shares)) + self.mock_object( + shell_v2, '_find_share', mock.Mock(side_effect=fake_shares) + ) expected_shrink_body = {'shrink': {'new_size': 77}} self.run_command('shrink 1234 77 %s' % wait_option) - self.assert_called_anytime('POST', '/shares/1234/action', - body=expected_shrink_body, - clear_callstack=False) + self.assert_called_anytime( + 'POST', + '/shares/1234/action', + body=expected_shrink_body, + clear_callstack=False, + ) if wait_option: shell_v2._find_share.assert_has_calls( - [mock.call(self.shell.cs, '1234')] * 4) + [mock.call(self.shell.cs, '1234')] * 4 + ) self.assertEqual(4, shell_v2._find_share.call_count) else: - shell_v2._find_share.assert_called_with( - self.shell.cs, '1234') + shell_v2._find_share.assert_called_with(self.shell.cs, '1234') self.assertEqual(2, shell_v2._find_share.call_count) def test_reset_state_with_flag(self): @@ -1857,10 +2142,13 @@ def test_snapshot_reset_state_with_flag(self): {'--description': 'fake_description'}, {'--neutron_net_id': 'fake_neutron_net_id'}, {'--neutron_subnet_id': 'fake_neutron_subnet_id'}, - {'--description': 'fake_description', - '--name': 'fake_name', - '--neutron_net_id': 'fake_neutron_net_id', - '--neutron_subnet_id': 'fake_neutron_subnet_id'}) + { + '--description': 'fake_description', + '--name': 'fake_name', + '--neutron_net_id': 'fake_neutron_net_id', + '--neutron_subnet_id': 'fake_neutron_subnet_id', + }, + ) def test_share_network_create(self, data): cmd = 'share-network-create' for k, v in data.items(): @@ -1873,34 +2161,43 @@ def test_share_network_create(self, data): @ddt.data( {'data': {'--name': 'fake_name'}}, {'data': {'--description': 'fake_description'}}, - {'data': {'--neutron_net_id': 'fake_neutron_net_id'}, - 'version': '2.49', - }, - {'data': {'--neutron_subnet_id': 'fake_neutron_subnet_id'}, - 'version': '2.49', - }, - {'data': { - '--description': 'fake_description', - '--name': 'fake_name', - '--neutron_net_id': 'fake_neutron_net_id', - '--neutron_subnet_id': 'fake_neutron_subnet_id'}, - 'version': '2.49', - }, + { + 'data': {'--neutron_net_id': 'fake_neutron_net_id'}, + 'version': '2.49', + }, + { + 'data': {'--neutron_subnet_id': 'fake_neutron_subnet_id'}, + 'version': '2.49', + }, + { + 'data': { + '--description': 'fake_description', + '--name': 'fake_name', + '--neutron_net_id': 'fake_neutron_net_id', + '--neutron_subnet_id': 'fake_neutron_subnet_id', + }, + 'version': '2.49', + }, {'data': {'--name': '""'}}, {'data': {'--description': '""'}}, - {'data': {'--neutron_net_id': '""'}, - 'version': '2.49', - }, - {'data': {'--neutron_subnet_id': '""'}, - 'version': '2.49', - }, - {'data': { - '--description': '""', - '--name': '""', - '--neutron_net_id': '""', - '--neutron_subnet_id': '""'}, - 'version': '2.49', - }) + { + 'data': {'--neutron_net_id': '""'}, + 'version': '2.49', + }, + { + 'data': {'--neutron_subnet_id': '""'}, + 'version': '2.49', + }, + { + 'data': { + '--description': '""', + '--name': '""', + '--neutron_net_id': '""', + '--neutron_subnet_id': '""', + }, + 'version': '2.49', + }, + ) def test_share_network_update(self, data, version=None): cmd = 'share-network-update 1111' expected = dict() @@ -1921,8 +2218,8 @@ def test_share_network_list(self): '/share-networks/detail', ) cliutils.print_list.assert_called_once_with( - mock.ANY, - fields=['id', 'name']) + mock.ANY, fields=['id', 'name'] + ) @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_share_network_list_select_column(self): @@ -1931,9 +2228,7 @@ def test_share_network_list_select_column(self): 'GET', '/share-networks/detail', ) - cliutils.print_list.assert_called_once_with( - mock.ANY, - fields=['Id']) + cliutils.print_list.assert_called_once_with(mock.ANY, fields=['Id']) @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_share_network_list_all_tenants(self): @@ -1943,8 +2238,8 @@ def test_share_network_list_all_tenants(self): '/share-networks/detail?all_tenants=1', ) cliutils.print_list.assert_called_once_with( - mock.ANY, - fields=['id', 'name']) + mock.ANY, fields=['id', 'name'] + ) @mock.patch.object(cliutils, 'print_list', mock.Mock()) @mock.patch.object(shell_v2, '_find_security_service', mock.Mock()) @@ -1952,17 +2247,18 @@ def test_share_network_list_filter_by_security_service(self): ss = type('FakeSecurityService', (object,), {'id': 'fake-ss-id'}) shell_v2._find_security_service.return_value = ss for command in ['--security_service', '--security-service']: - self.run_command('share-network-list %(command)s %(ss_id)s' % - {'command': command, - 'ss_id': ss.id}) + self.run_command( + 'share-network-list %(command)s %(ss_id)s' + % {'command': command, 'ss_id': ss.id} + ) self.assert_called( 'GET', '/share-networks/detail?security_service_id=%s' % ss.id, ) shell_v2._find_security_service.assert_called_with(mock.ANY, ss.id) cliutils.print_list.assert_called_with( - mock.ANY, - fields=['id', 'name']) + mock.ANY, fields=['id', 'name'] + ) @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_share_network_list_project_id_aliases(self): @@ -1973,8 +2269,8 @@ def test_share_network_list_project_id_aliases(self): '/share-networks/detail?project_id=1234', ) cliutils.print_list.assert_called_with( - mock.ANY, - fields=['id', 'name']) + mock.ANY, fields=['id', 'name'] + ) @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_share_network_list_created_before_aliases(self): @@ -1985,8 +2281,8 @@ def test_share_network_list_created_before_aliases(self): '/share-networks/detail?created_before=2001-01-01', ) cliutils.print_list.assert_called_with( - mock.ANY, - fields=['id', 'name']) + mock.ANY, fields=['id', 'name'] + ) @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_share_network_list_created_since_aliases(self): @@ -1997,34 +2293,42 @@ def test_share_network_list_created_since_aliases(self): '/share-networks/detail?created_since=2001-01-01', ) cliutils.print_list.assert_called_with( - mock.ANY, - fields=['id', 'name']) + mock.ANY, fields=['id', 'name'] + ) @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_share_network_list_neutron_net_id_aliases(self): - for command in ['--neutron-net-id', '--neutron-net_id', - '--neutron_net-id', '--neutron_net_id']: + for command in [ + '--neutron-net-id', + '--neutron-net_id', + '--neutron_net-id', + '--neutron_net_id', + ]: self.run_command('share-network-list %s fake-id' % command) self.assert_called( 'GET', '/share-networks/detail?neutron_net_id=fake-id', ) cliutils.print_list.assert_called_with( - mock.ANY, - fields=['id', 'name']) + mock.ANY, fields=['id', 'name'] + ) @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_share_network_list_neutron_subnet_id_aliases(self): - for command in ['--neutron-subnet-id', '--neutron-subnet_id', - '--neutron_subnet-id', '--neutron_subnet_id']: + for command in [ + '--neutron-subnet-id', + '--neutron-subnet_id', + '--neutron_subnet-id', + '--neutron_subnet_id', + ]: self.run_command('share-network-list %s fake-id' % command) self.assert_called( 'GET', '/share-networks/detail?neutron_subnet_id=fake-id', ) cliutils.print_list.assert_called_with( - mock.ANY, - fields=['id', 'name']) + mock.ANY, fields=['id', 'name'] + ) @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_share_network_list_network_type_aliases(self): @@ -2035,8 +2339,8 @@ def test_share_network_list_network_type_aliases(self): '/share-networks/detail?network_type=local', ) cliutils.print_list.assert_called_with( - mock.ANY, - fields=['id', 'name']) + mock.ANY, fields=['id', 'name'] + ) @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_share_network_list_segmentation_id_aliases(self): @@ -2047,8 +2351,8 @@ def test_share_network_list_segmentation_id_aliases(self): '/share-networks/detail?segmentation_id=1234', ) cliutils.print_list.assert_called_with( - mock.ANY, - fields=['id', 'name']) + mock.ANY, fields=['id', 'name'] + ) @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_share_network_list_ip_version_aliases(self): @@ -2059,8 +2363,8 @@ def test_share_network_list_ip_version_aliases(self): '/share-networks/detail?ip_version=4', ) cliutils.print_list.assert_called_with( - mock.ANY, - fields=['id', 'name']) + mock.ANY, fields=['id', 'name'] + ) @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_share_network_list_all_filters(self): @@ -2080,62 +2384,71 @@ def test_share_network_list_all_filters(self): } command_str = 'share-network-list' for key, value in filters.items(): - command_str += ' --%(key)s=%(value)s' % {'key': key, - 'value': value} + command_str += ' --%(key)s=%(value)s' % { + 'key': key, + 'value': value, + } self.run_command(command_str) - query = utils.safe_urlencode(sorted([(k.replace('-', '_'), v) for - (k, v) in filters.items()])) + query = utils.safe_urlencode( + sorted([(k.replace('-', '_'), v) for (k, v) in filters.items()]) + ) self.assert_called( 'GET', '/share-networks/detail?%s' % query, ) cliutils.print_list.assert_called_once_with( - mock.ANY, - fields=['id', 'name']) + mock.ANY, fields=['id', 'name'] + ) def test_share_network_list_filter_by_inexact_name(self): for separator in self.separators: - self.run_command('share-network-list --name~' + separator + - 'fake_name') - self.assert_called( - 'GET', - '/share-networks/detail?name~=fake_name') + self.run_command( + 'share-network-list --name~' + separator + 'fake_name' + ) + self.assert_called('GET', '/share-networks/detail?name~=fake_name') def test_share_network_list_filter_by_inexact_description(self): for separator in self.separators: - self.run_command('share-network-list --description~' + separator + - 'fake_description') + self.run_command( + 'share-network-list --description~' + + separator + + 'fake_description' + ) self.assert_called( - 'GET', - '/share-networks/detail?description~=fake_description') + 'GET', '/share-networks/detail?description~=fake_description' + ) def test_share_network_list_filter_by_inexact_unicode_name(self): for separator in self.separators: - self.run_command('share-network-list --name~' + separator + - u'ффф') + self.run_command('share-network-list --name~' + separator + 'ффф') self.assert_called( - 'GET', - '/share-networks/detail?name~=%D1%84%D1%84%D1%84') + 'GET', '/share-networks/detail?name~=%D1%84%D1%84%D1%84' + ) def test_share_network_list_filter_by_inexact_unicode_description(self): for separator in self.separators: - self.run_command('share-network-list --description~' + separator + - u'ффф') + self.run_command( + 'share-network-list --description~' + separator + 'ффф' + ) self.assert_called( - 'GET', - '/share-networks/detail?description~=%D1%84%D1%84%D1%84') + 'GET', '/share-networks/detail?description~=%D1%84%D1%84%D1%84' + ) def test_share_network_security_service_add(self): - self.run_command('share-network-security-service-add fake_share_nw ' - 'fake_security_service') + self.run_command( + 'share-network-security-service-add fake_share_nw ' + 'fake_security_service' + ) self.assert_called( 'POST', '/share-networks/1234/action', ) def test_share_network_security_service_remove(self): - self.run_command('share-network-security-service-remove fake_share_nw ' - 'fake_security_service') + self.run_command( + 'share-network-security-service-remove fake_share_nw ' + 'fake_security_service' + ) self.assert_called( 'POST', '/share-networks/1234/action', @@ -2143,15 +2456,17 @@ def test_share_network_security_service_remove(self): @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_share_network_security_service_list_select_column(self): - self.run_command('share-network-security-service-list ' - 'fake_share_nw --column id,name') + self.run_command( + 'share-network-security-service-list ' + 'fake_share_nw --column id,name' + ) self.assert_called( 'GET', '/security-services/detail?share_network_id=1234', ) cliutils.print_list.assert_called_once_with( - mock.ANY, - fields=['Id', 'Name']) + mock.ANY, fields=['Id', 'Name'] + ) def test_share_network_security_service_list_by_name(self): self.run_command('share-network-security-service-list fake_share_nw') @@ -2183,18 +2498,26 @@ def test_share_network_security_service_list_by_id(self): @ddt.data( {}, - {'--neutron_net_id': 'fake_neutron_net_id', - '--neutron_subnet_id': 'fake_neutron_subnet_id'}, + { + '--neutron_net_id': 'fake_neutron_net_id', + '--neutron_subnet_id': 'fake_neutron_subnet_id', + }, {'--availability-zone': 'fake_availability_zone_id'}, - {'--neutron_net_id': 'fake_neutron_net_id', - '--neutron_subnet_id': 'fake_neutron_subnet_id', - '--availability-zone': 'fake_availability_zone_id'}) + { + '--neutron_net_id': 'fake_neutron_net_id', + '--neutron_subnet_id': 'fake_neutron_subnet_id', + '--availability-zone': 'fake_availability_zone_id', + }, + ) def test_share_network_subnet_add(self, data): fake_share_network = type( - 'FakeShareNetwork', (object,), {'id': '1234'}) + 'FakeShareNetwork', (object,), {'id': '1234'} + ) self.mock_object( - shell_v2, '_find_share_network', - mock.Mock(return_value=fake_share_network)) + shell_v2, + '_find_share_network', + mock.Mock(return_value=fake_share_network), + ) cmd = 'share-network-subnet-create' for k, v in data.items(): @@ -2203,61 +2526,69 @@ def test_share_network_subnet_add(self, data): self.run_command(cmd) shell_v2._find_share_network.assert_called_once_with( - mock.ANY, fake_share_network.id) + mock.ANY, fake_share_network.id + ) self.assert_called('POST', '/share-networks/1234/subnets') @ddt.data( {'--neutron_net_id': 'fake_neutron_net_id'}, {'--neutron_subnet_id': 'fake_neutron_subnet_id'}, - {'--neutron_net_id': 'fake_neutron_net_id', - '--availability-zone': 'fake_availability_zone_id'}, - {'--neutron_subnet_id': 'fake_neutron_subnet_id', - '--availability-zone': 'fake_availability_zone_id'}) + { + '--neutron_net_id': 'fake_neutron_net_id', + '--availability-zone': 'fake_availability_zone_id', + }, + { + '--neutron_subnet_id': 'fake_neutron_subnet_id', + '--availability-zone': 'fake_availability_zone_id', + }, + ) def test_share_network_subnet_add_invalid_param(self, data): cmd = 'share-network-subnet-create' for k, v in data.items(): cmd += ' ' + k + ' ' + v cmd += ' fake_network_id' - self.assertRaises( - exceptions.CommandError, - self.run_command, - cmd) + self.assertRaises(exceptions.CommandError, self.run_command, cmd) def test_share_network_subnet_add_invalid_share_network(self): cmd = 'share-network-subnet-create not-found-id' - self.assertRaises( - exceptions.CommandError, - self.run_command, - cmd) + self.assertRaises(exceptions.CommandError, self.run_command, cmd) - @ddt.data(('fake_subnet1', ), - ('fake_subnet1', 'fake_subnet2')) + @ddt.data(('fake_subnet1',), ('fake_subnet1', 'fake_subnet2')) def test_share_network_subnet_delete(self, subnet_ids): fake_share_network = type( - 'FakeShareNetwork', (object,), {'id': '1234'}) + 'FakeShareNetwork', (object,), {'id': '1234'} + ) self.mock_object( - shell_v2, '_find_share_network', - mock.Mock(return_value=fake_share_network)) + shell_v2, + '_find_share_network', + mock.Mock(return_value=fake_share_network), + ) fake_share_network_subnets = [ share_network_subnets.ShareNetworkSubnet( - 'fake', {'id': subnet_id}, True) + 'fake', {'id': subnet_id}, True + ) for subnet_id in subnet_ids ] self.run_command( - 'share-network-subnet-delete %(network_id)s %(subnet_ids)s' % { + 'share-network-subnet-delete %(network_id)s %(subnet_ids)s' + % { 'network_id': fake_share_network.id, - 'subnet_ids': ' '.join(subnet_ids) - }) + 'subnet_ids': ' '.join(subnet_ids), + } + ) shell_v2._find_share_network.assert_called_once_with( - mock.ANY, fake_share_network.id) + mock.ANY, fake_share_network.id + ) for subnet in fake_share_network_subnets: self.assert_called_anytime( - 'DELETE', '/share-networks/1234/subnets/%s' % subnet.id, - clear_callstack=False) + 'DELETE', + '/share-networks/1234/subnets/%s' % subnet.id, + clear_callstack=False, + ) def test_share_network_subnet_delete_invalid_share_network(self): command = 'share-network-subnet-delete %(net_id)s %(subnet_id)s' % { @@ -2265,41 +2596,42 @@ def test_share_network_subnet_delete_invalid_share_network(self): 'subnet_id': '1234', } - self.assertRaises( - exceptions.CommandError, - self.run_command, - command) + self.assertRaises(exceptions.CommandError, self.run_command, command) def test_share_network_subnet_delete_invalid_share_network_subnet(self): fake_share_network = type( - 'FakeShareNetwork', (object,), {'id': '1234'}) + 'FakeShareNetwork', (object,), {'id': '1234'} + ) self.mock_object( - shell_v2, '_find_share_network', - mock.Mock(return_value=fake_share_network)) + shell_v2, + '_find_share_network', + mock.Mock(return_value=fake_share_network), + ) command = 'share-network-subnet-delete %(net_id)s %(subnet_id)s' % { 'net_id': fake_share_network.id, 'subnet_id': 'not-found-id', } - self.assertRaises( - exceptions.CommandError, - self.run_command, - command) + self.assertRaises(exceptions.CommandError, self.run_command, command) @mock.patch.object(cliutils, 'print_dict', mock.Mock()) def test_share_network_subnet_show(self): fake_share_network = type( - 'FakeShareNetwork', (object,), {'id': '1234'}) + 'FakeShareNetwork', (object,), {'id': '1234'} + ) self.mock_object( - shell_v2, '_find_share_network', - mock.Mock(return_value=fake_share_network)) + shell_v2, + '_find_share_network', + mock.Mock(return_value=fake_share_network), + ) args = { 'share_net_id': fake_share_network.id, 'subnet_id': 'fake_subnet_id', } self.run_command( - 'share-network-subnet-show %(share_net_id)s %(subnet_id)s' % args) + 'share-network-subnet-show %(share_net_id)s %(subnet_id)s' % args + ) self.assert_called( 'GET', @@ -2313,18 +2645,15 @@ def test_share_network_subnet_show_invalid_share_network(self): 'subnet_id': 1234, } - self.assertRaises( - exceptions.CommandError, - self.run_command, - command) + self.assertRaises(exceptions.CommandError, self.run_command, command) @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_share_server_list_select_column(self): self.run_command('share-server-list --columns id,host,status') self.assert_called('GET', '/share-servers') cliutils.print_list.assert_called_once_with( - mock.ANY, - fields=['Id', 'Host', 'Status']) + mock.ANY, fields=['Id', 'Host', 'Status'] + ) def test_create_share(self): # Use only required fields @@ -2343,10 +2672,12 @@ def test_create_public_share(self): def test_create_with_share_network(self): # Except required fields added share network sn = "fake-share-network" - with mock.patch.object(shell_v2, "_find_share_network", - mock.Mock(return_value=sn)): - self.run_command("create nfs 1 --share-type test_type " - "--share-network %s" % sn) + with mock.patch.object( + shell_v2, "_find_share_network", mock.Mock(return_value=sn) + ): + self.run_command( + "create nfs 1 --share-type test_type --share-network %s" % sn + ) expected = self.create_share_body.copy() expected['share']['share_network_id'] = sn expected['share']['share_type'] = 'test_type' @@ -2355,8 +2686,10 @@ def test_create_with_share_network(self): def test_create_with_metadata(self): # Except required fields added metadata - self.run_command("create nfs 1 --metadata key1=value1 key2=value2 " - "--share-type test_type") + self.run_command( + "create nfs 1 --metadata key1=value1 key2=value2 " + "--share-type test_type" + ) expected = self.create_share_body.copy() expected['share']['metadata'] = {"key1": "value1", "key2": "value2"} expected['share']['share_type'] = 'test_type' @@ -2367,18 +2700,22 @@ def test_create_with_wait(self): expected = self.create_share_body.copy() expected['share']['share_type'] = 'test_type' self.assert_called_anytime( - "POST", "/shares", body=expected, clear_callstack=False) + "POST", "/shares", body=expected, clear_callstack=False + ) self.assert_called("GET", "/shares/1234") def test_create_share_with_no_existing_share_type(self): self.assertRaises( - exceptions.CommandError, self.run_command, "create nfs 1") + exceptions.CommandError, self.run_command, "create nfs 1" + ) @ddt.data('None', 'NONE', 'none') def test_create_share_with_the_name_none(self, name): self.assertRaises( - exceptions.CommandError, self.run_command, - "create nfs 1 --name %s --share-type test_type" % name) + exceptions.CommandError, + self.run_command, + "create nfs 1 --name %s --share-type test_type" % name, + ) def test_allow_access_cert(self): self.run_command("access-allow 1234 cert client.example.com") @@ -2393,13 +2730,17 @@ def test_allow_access_cert(self): def test_allow_access_cert_error_gt64(self): common_name = 'x' * 65 - self.assertRaises(exceptions.CommandError, self.run_command, - ("access-allow 1234 cert %s" % common_name)) + self.assertRaises( + exceptions.CommandError, + self.run_command, + ("access-allow 1234 cert %s" % common_name), + ) def test_allow_access_cert_error_zero(self): cmd = mock.Mock() - cmd.split = mock.Mock(side_effect=lambda: ['access-allow', '1234', - 'cert', '']) + cmd.split = mock.Mock( + side_effect=lambda: ['access-allow', '1234', 'cert', ''] + ) self.assertRaises(exceptions.CommandError, self.run_command, cmd) @@ -2407,8 +2748,9 @@ def test_allow_access_cert_error_zero(self): def test_allow_access_cert_error_whitespace(self): cmd = mock.Mock() - cmd.split = mock.Mock(side_effect=lambda: ['access-allow', '1234', - 'cert', ' ']) + cmd.split = mock.Mock( + side_effect=lambda: ['access-allow', '1234', 'cert', ' '] + ) self.assertRaises(exceptions.CommandError, self.run_command, cmd) @@ -2427,9 +2769,11 @@ def test_allow_access_with_access_level(self): for alias in aliases: for s in self.separators: self.run_command( - "access-allow " + alias + s + "ro 1111 ip 10.0.0.6") - self.assert_called("POST", "/shares/1111/action", - body=expected) + "access-allow " + alias + s + "ro 1111 ip 10.0.0.6" + ) + self.assert_called( + "POST", "/shares/1111/action", body=expected + ) def test_allow_access_with_valid_access_levels(self): expected = { @@ -2442,13 +2786,16 @@ def test_allow_access_with_valid_access_levels(self): for level in ['rw', 'ro']: expected["allow_access"]['access_level'] = level self.run_command( - "access-allow --access-level " + level + " 1111 ip 10.0.0.6") - self.assert_called("POST", "/shares/1111/action", - body=expected) + "access-allow --access-level " + level + " 1111 ip 10.0.0.6" + ) + self.assert_called("POST", "/shares/1111/action", body=expected) def test_allow_access_with_invalid_access_level(self): - self.assertRaises(SystemExit, self.run_command, - "access-allow --access-level fake 1111 ip 10.0.0.6") + self.assertRaises( + SystemExit, + self.run_command, + "access-allow --access-level fake 1111 ip 10.0.0.6", + ) def test_allow_access_with_metadata(self): expected = { @@ -2461,7 +2808,8 @@ def test_allow_access_with_metadata(self): self.run_command( "access-allow 2222 ip 10.0.0.6 --metadata key1=v1 key2=v2", - version="2.45") + version="2.45", + ) self.assert_called("POST", "/shares/2222/action", body=expected) def test_set_access_metadata(self): @@ -2472,15 +2820,14 @@ def test_set_access_metadata(self): } } self.run_command( - "access-metadata 9999 set key1=v1 key2=v2", - version="2.45") - self.assert_called("PUT", "/share-access-rules/9999/metadata", - body=expected) + "access-metadata 9999 set key1=v1 key2=v2", version="2.45" + ) + self.assert_called( + "PUT", "/share-access-rules/9999/metadata", body=expected + ) def test_unset_access_metadata(self): - self.run_command( - "access-metadata 9999 unset key1", - version="2.45") + self.run_command("access-metadata 9999 unset key1", version="2.45") self.assert_called("DELETE", "/share-access-rules/9999/metadata/key1") @ddt.data("1.0", "2.0", "2.44") @@ -2499,17 +2846,25 @@ def test_access_list(self, version): version = api_versions.APIVersion(version) cliutils.print_list.assert_called_with( mock.ANY, - ['id', 'access_type', 'access_to', 'access_level', 'state', - 'access_key', 'created_at', 'updated_at']) + [ + 'id', + 'access_type', + 'access_to', + 'access_level', + 'state', + 'access_key', + 'created_at', + 'updated_at', + ], + ) @mock.patch.object(cliutils, 'print_list', mock.Mock()) @ddt.data(*set(["2.44", "2.45", api_versions.MAX_VERSION])) def test_access_list_select_column(self, version): - self.run_command("access-list 1111 --columns id,access_type", - version=version) - cliutils.print_list.assert_called_with( - mock.ANY, - ['Id', 'Access_Type']) + self.run_command( + "access-list 1111 --columns id,access_type", version=version + ) + cliutils.print_list.assert_called_with(mock.ANY, ['Id', 'Access_Type']) @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_snapshot_access_list(self): @@ -2517,7 +2872,8 @@ def test_snapshot_access_list(self): self.assert_called('GET', '/snapshots/1234/access-list') cliutils.print_list.assert_called_with( - mock.ANY, ['id', 'access_type', 'access_to', 'state']) + mock.ANY, ['id', 'access_type', 'access_to', 'state'] + ) @mock.patch.object(cliutils, 'print_dict', mock.Mock()) def test_snapshot_access_allow(self): @@ -2525,7 +2881,8 @@ def test_snapshot_access_allow(self): self.assert_called('POST', '/snapshots/1234/action') cliutils.print_dict.assert_called_with( - {'access_type': 'ip', 'access_to': '1.1.1.1'}) + {'access_type': 'ip', 'access_to': '1.1.1.1'} + ) @ddt.data(*set(["2.45", api_versions.MAX_VERSION])) def test_allow_access_wait(self, version): @@ -2535,21 +2892,40 @@ def test_allow_access_wait(self, version): fake_share = mock.Mock() fake_share.name = 'fake_share' fake_share.allow = mock.Mock(return_value=fake_access_rule) - self.mock_object(shell_v2, '_wait_for_resource_status', - mock.Mock(return_value=fake_access)) - self.mock_object(share_access_rules.ShareAccessRuleManager, 'get', - mock.Mock(return_value=fake_access_rule)) - with mock.patch.object(apiclient_utils, 'find_resource', - mock.Mock(return_value=fake_share)): - is_default_in_api = (api_versions.APIVersion(version) >= - api_versions.APIVersion('2.45')) + self.mock_object( + shell_v2, + '_wait_for_resource_status', + mock.Mock(return_value=fake_access), + ) + self.mock_object( + share_access_rules.ShareAccessRuleManager, + 'get', + mock.Mock(return_value=fake_access_rule), + ) + with mock.patch.object( + apiclient_utils, + 'find_resource', + mock.Mock(return_value=fake_share), + ): + is_default_in_api = api_versions.APIVersion( + version + ) >= api_versions.APIVersion('2.45') if is_default_in_api: - self.run_command("access-allow fake_share ip 10.0.0.1 --wait", - version=version) - shell_v2._wait_for_resource_status.assert_has_calls([ - mock.call(self.shell.cs, fake_access_rule, - resource_type='share_access_rule', - expected_status='active', status_attr='state')]) + self.run_command( + "access-allow fake_share ip 10.0.0.1 --wait", + version=version, + ) + shell_v2._wait_for_resource_status.assert_has_calls( + [ + mock.call( + self.shell.cs, + fake_access_rule, + resource_type='share_access_rule', + expected_status='active', + status_attr='state', + ) + ] + ) def test_snapshot_access_deny(self): self.run_command("snapshot-access-deny 1234 fake_id") @@ -2560,34 +2936,37 @@ def test_snapshot_access_deny(self): def test_snapshot_export_location_list(self): self.run_command('snapshot-export-location-list 1234') - self.assert_called( - 'GET', '/snapshots/1234/export-locations') + self.assert_called('GET', '/snapshots/1234/export-locations') @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_snapshot_instance_export_location_list(self): self.run_command('snapshot-instance-export-location-list 1234') - self.assert_called( - 'GET', '/snapshot-instances/1234/export-locations') + self.assert_called('GET', '/snapshot-instances/1234/export-locations') @mock.patch.object(cliutils, 'print_dict', mock.Mock()) def test_snapshot_instance_export_location_show(self): - self.run_command('snapshot-instance-export-location-show 1234 ' - 'fake_el_id') + self.run_command( + 'snapshot-instance-export-location-show 1234 fake_el_id' + ) self.assert_called( - 'GET', '/snapshot-instances/1234/export-locations/fake_el_id') + 'GET', '/snapshot-instances/1234/export-locations/fake_el_id' + ) cliutils.print_dict.assert_called_once_with( - {'path': '/fake_path', 'id': 'fake_id'}) + {'path': '/fake_path', 'id': 'fake_id'} + ) @mock.patch.object(cliutils, 'print_dict', mock.Mock()) def test_snapshot_export_location_show(self): self.run_command('snapshot-export-location-show 1234 fake_el_id') - self.assert_called('GET', - '/snapshots/1234/export-locations/fake_el_id') + self.assert_called( + 'GET', '/snapshots/1234/export-locations/fake_el_id' + ) cliutils.print_dict.assert_called_once_with( - {'path': '/fake_path', 'id': 'fake_id'}) + {'path': '/fake_path', 'id': 'fake_id'} + ) @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_security_service_list(self): @@ -2597,8 +2976,8 @@ def test_security_service_list(self): '/security-services', ) cliutils.print_list.assert_called_once_with( - mock.ANY, - fields=['id', 'name', 'status', 'type']) + mock.ANY, fields=['id', 'name', 'status', 'type'] + ) @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_security_service_list_select_column(self): @@ -2608,28 +2987,30 @@ def test_security_service_list_select_column(self): '/security-services', ) cliutils.print_list.assert_called_once_with( - mock.ANY, - fields=['Name', 'Type']) + mock.ANY, fields=['Name', 'Type'] + ) @mock.patch.object(cliutils, 'print_list', mock.Mock()) @mock.patch.object(shell_v2, '_find_share_network', mock.Mock()) def test_security_service_list_filter_share_network(self): - class FakeShareNetwork(object): + class FakeShareNetwork: id = 'fake-sn-id' + sn = FakeShareNetwork() shell_v2._find_share_network.return_value = sn for command in ['--share-network', '--share_network']: - self.run_command('security-service-list %(command)s %(sn_id)s' % - {'command': command, - 'sn_id': sn.id}) + self.run_command( + 'security-service-list %(command)s %(sn_id)s' + % {'command': command, 'sn_id': sn.id} + ) self.assert_called( 'GET', '/security-services?share_network_id=%s' % sn.id, ) shell_v2._find_share_network.assert_called_with(mock.ANY, sn.id) cliutils.print_list.assert_called_with( - mock.ANY, - fields=['id', 'name', 'status', 'type']) + mock.ANY, fields=['id', 'name', 'status', 'type'] + ) @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_security_service_list_detailed(self): @@ -2639,8 +3020,8 @@ def test_security_service_list_detailed(self): '/security-services/detail', ) cliutils.print_list.assert_called_once_with( - mock.ANY, - fields=['id', 'name', 'status', 'type', 'share_networks']) + mock.ANY, fields=['id', 'name', 'status', 'type', 'share_networks'] + ) @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_security_service_list_all_tenants(self): @@ -2650,8 +3031,8 @@ def test_security_service_list_all_tenants(self): '/security-services?all_tenants=1', ) cliutils.print_list.assert_called_once_with( - mock.ANY, - fields=['id', 'name', 'status', 'type']) + mock.ANY, fields=['id', 'name', 'status', 'type'] + ) @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_security_service_list_all_filters(self): @@ -2669,8 +3050,10 @@ def test_security_service_list_all_filters(self): } command_str = 'security-service-list' for key, value in filters.items(): - command_str += ' --%(key)s=%(value)s' % {'key': key, - 'value': value} + command_str += ' --%(key)s=%(value)s' % { + 'key': key, + 'value': value, + } self.run_command(command_str) self.assert_called( 'GET', @@ -2679,8 +3062,8 @@ def test_security_service_list_all_filters(self): '&status=new&type=ldap&user=fake-user', ) cliutils.print_list.assert_called_once_with( - mock.ANY, - fields=['id', 'name', 'status', 'type']) + mock.ANY, fields=['id', 'name', 'status', 'type'] + ) @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_security_service_list_filter_by_dns_ip_alias(self): @@ -2690,8 +3073,8 @@ def test_security_service_list_filter_by_dns_ip_alias(self): '/security-services?dns_ip=1.1.1.1', ) cliutils.print_list.assert_called_once_with( - mock.ANY, - fields=['id', 'name', 'status', 'type']) + mock.ANY, fields=['id', 'name', 'status', 'type'] + ) @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_security_service_list_filter_by_ou_alias(self): @@ -2701,8 +3084,8 @@ def test_security_service_list_filter_by_ou_alias(self): '/security-services?ou=fake-ou', ) cliutils.print_list.assert_called_once_with( - mock.ANY, - fields=['id', 'name', 'status', 'type']) + mock.ANY, fields=['id', 'name', 'status', 'type'] + ) @ddt.data( {'--name': 'fake_name'}, @@ -2713,14 +3096,16 @@ def test_security_service_list_filter_by_ou_alias(self): {'--server': 'fake_server'}, {'--user': 'fake_user'}, {'--password': 'fake_password'}, - {'--name': 'fake_name', - '--description': 'fake_description', - '--dns-ip': 'fake_dns_ip', - '--ou': 'fake_ou', - '--domain': 'fake_domain', - '--server': 'fake_server', - '--user': 'fake_user', - '--password': 'fake_password'}, + { + '--name': 'fake_name', + '--description': 'fake_description', + '--dns-ip': 'fake_dns_ip', + '--ou': 'fake_ou', + '--domain': 'fake_domain', + '--server': 'fake_server', + '--user': 'fake_user', + '--password': 'fake_password', + }, {'--name': '""'}, {'--description': '""'}, {'--dns-ip': '""'}, @@ -2729,14 +3114,17 @@ def test_security_service_list_filter_by_ou_alias(self): {'--server': '""'}, {'--user': '""'}, {'--password': '""'}, - {'--name': '""', - '--description': '""', - '--dns-ip': '""', - '--ou': '""', - '--domain': '""', - '--server': '""', - '--user': '""', - '--password': '""'},) + { + '--name': '""', + '--description': '""', + '--dns-ip': '""', + '--ou': '""', + '--domain': '""', + '--server': '""', + '--user': '""', + '--password': '""', + }, + ) def test_security_service_update(self, data): cmd = 'security-service-update 1111' expected = dict() @@ -2757,8 +3145,8 @@ def test_pool_list(self): '/scheduler-stats/pools?backend=.%2A&host=.%2A&pool=.%2A', ) cliutils.print_list.assert_called_with( - mock.ANY, - fields=["Name", "Host", "Backend", "Pool"]) + mock.ANY, fields=["Name", "Host", "Backend", "Pool"] + ) @mock.patch.object(cliutils, 'print_dict', mock.Mock()) def test_quota_show(self): @@ -2791,7 +3179,8 @@ def test_quota_show_with_user_id(self): @mock.patch('manilaclient.common.cliutils.print_dict') def test_quota_show_with_share_type(self, share_type_id, mock_print_dict): self.run_command( - 'quota-show --tenant 1234 --share_type %s' % share_type_id) + 'quota-show --tenant 1234 --share_type %s' % share_type_id + ) self.assert_called( 'GET', @@ -2823,13 +3212,19 @@ def test_quota_update(self, cmd, expected_body): @ddt.data( "quota-update 1234 --share-groups 13 --share-type foo", "quota-update 1234 --share-group-snapshots 14 --share-type bar", - ("quota-update 1234 --share-groups 13 --share-type foo " - "--share-group-snapshots 14"), + ( + "quota-update 1234 --share-groups 13 --share-type foo " + "--share-group-snapshots 14" + ), "--os-share-api-version 2.39 quota-update 1234 --share-groups 13", - ("--os-share-api-version 2.39 quota-update 1234 " - "--share-group-snapshots 13"), - ("--os-share-api-version 2.38 quota-update 1234 --shares 5 " - "--share-type foo"), + ( + "--os-share-api-version 2.39 quota-update 1234 " + "--share-group-snapshots 13" + ), + ( + "--os-share-api-version 2.38 quota-update 1234 --shares 5 " + "--share-type foo" + ), ) def test_quota_update_with_wrong_combinations(self, cmd): self.assertRaises(exceptions.CommandError, self.run_command, cmd) @@ -2842,7 +3237,8 @@ def test_pool_list_with_detail(self): '/scheduler-stats/pools/detail?backend=.%2A&host=.%2A&pool=.%2A', ) cliutils.print_dict.assert_called_with( - {'name': 'host1@backend1#pool2', 'qos': False}) + {'name': 'host1@backend1#pool2', 'qos': False} + ) @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_pool_list_select_column(self): @@ -2852,18 +3248,26 @@ def test_pool_list_select_column(self): '/scheduler-stats/pools/detail?backend=.%2A&host=.%2A&pool=.%2A', ) cliutils.print_list.assert_called_with( - mock.ANY, - fields=["Name", "Host"]) - - @ddt.data(({"key1": "value1", - "key2": "value2"}, - {"key1": "value1", - "key2": "value2"}), - ({"key1": {"key11": "value11", "key12": "value12"}, - "key2": {"key21": "value21"}}, - {"key1": "key11 = value11\nkey12 = value12", - "key2": "key21 = value21"}), - ({}, {})) + mock.ANY, fields=["Name", "Host"] + ) + + @ddt.data( + ( + {"key1": "value1", "key2": "value2"}, + {"key1": "value1", "key2": "value2"}, + ), + ( + { + "key1": {"key11": "value11", "key12": "value12"}, + "key2": {"key21": "value21"}, + }, + { + "key1": "key11 = value11\nkey12 = value12", + "key2": "key21 = value21", + }, + ), + ({}, {}), + ) @ddt.unpack @mock.patch.object(cliutils, 'print_dict', mock.Mock()) def test_quota_set_pretty_show(self, value, expected): @@ -2872,12 +3276,19 @@ def test_quota_set_pretty_show(self, value, expected): shell_v2._quota_set_pretty_show(fake_quota_set) cliutils.print_dict.assert_called_with(expected) - @ddt.data('--share-type test_type', '--share_type test_type', - '--share-type-id 0123456789', '--share_type_id 0123456789') + @ddt.data( + '--share-type test_type', + '--share_type test_type', + '--share-type-id 0123456789', + '--share_type_id 0123456789', + ) @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_pool_list_with_filters(self, param): - cmd = ('pool-list --host host1 --backend backend1 --pool pool1' + ' ' + - param) + cmd = ( + 'pool-list --host host1 --backend backend1 --pool pool1' + + ' ' + + param + ) self.run_command(cmd) self.assert_called( 'GET', @@ -2885,8 +3296,8 @@ def test_pool_list_with_filters(self, param): 'pool=pool1&share_type=%s' % param.split()[-1], ) cliutils.print_list.assert_called_with( - mock.ANY, - fields=["Name", "Host", "Backend", "Pool"]) + mock.ANY, fields=["Name", "Host", "Backend", "Pool"] + ) @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_api_version(self): @@ -2895,7 +3306,8 @@ def test_api_version(self): cliutils.print_list.assert_called_with( mock.ANY, ['ID', 'Status', 'Version', 'Min_version'], - field_labels=['ID', 'Status', 'Version', 'Minimum Version']) + field_labels=['ID', 'Status', 'Version', 'Minimum Version'], + ) @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_share_group_list(self): @@ -2903,8 +3315,10 @@ def test_share_group_list(self): self.assert_called('GET', '/share-groups/detail') cliutils.print_list.assert_called_once_with( - mock.ANY, fields=('ID', 'Name', 'Status', 'Description'), - sortby_index=None) + mock.ANY, + fields=('ID', 'Name', 'Status', 'Description'), + sortby_index=None, + ) @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_share_group_list_select_column(self): @@ -2912,78 +3326,97 @@ def test_share_group_list_select_column(self): self.assert_called('GET', '/share-groups/detail') cliutils.print_list.assert_called_once_with( - mock.ANY, fields=['Id', 'Name', 'Description'], sortby_index=None) + mock.ANY, fields=['Id', 'Name', 'Description'], sortby_index=None + ) def test_share_group_list_filter_by_inexact_name(self): for separator in self.separators: - self.run_command('share-group-list --name~' + separator + - 'fake_name') - self.assert_called( - 'GET', - '/share-groups/detail?name~=fake_name') + self.run_command( + 'share-group-list --name~' + separator + 'fake_name' + ) + self.assert_called('GET', '/share-groups/detail?name~=fake_name') def test_share_group_list_filter_by_inexact_description(self): for separator in self.separators: - self.run_command('share-group-list --description~' + separator + - 'fake_description') + self.run_command( + 'share-group-list --description~' + + separator + + 'fake_description' + ) self.assert_called( - 'GET', - '/share-groups/detail?description~=fake_description') + 'GET', '/share-groups/detail?description~=fake_description' + ) def test_share_group_list_filter_by_inexact_unicode_name(self): for separator in self.separators: - self.run_command('share-group-list --name~' + separator + - u'ффф') + self.run_command('share-group-list --name~' + separator + 'ффф') self.assert_called( - 'GET', - '/share-groups/detail?name~=%D1%84%D1%84%D1%84') + 'GET', '/share-groups/detail?name~=%D1%84%D1%84%D1%84' + ) def test_share_group_list_filter_by_inexact_unicode_description(self): for separator in self.separators: - self.run_command('share-group-list --description~' + separator + - u'ффф') + self.run_command( + 'share-group-list --description~' + separator + 'ффф' + ) self.assert_called( - 'GET', - '/share-groups/detail?description~=%D1%84%D1%84%D1%84') + 'GET', '/share-groups/detail?description~=%D1%84%D1%84%D1%84' + ) def test_share_group_show(self): fake_manager = mock.Mock() fake_share_group = share_groups.ShareGroup( - fake_manager, {'id': '1234'}) + fake_manager, {'id': '1234'} + ) self.mock_object( - shell_v2, '_find_share_group', - mock.Mock(side_effect=[fake_share_group])) + shell_v2, + '_find_share_group', + mock.Mock(side_effect=[fake_share_group]), + ) self.run_command('share-group-show 1234') shell_v2._find_share_group.assert_has_calls( - [mock.call(self.shell.cs, "1234")]) + [mock.call(self.shell.cs, "1234")] + ) def test_share_group_create_wait(self): fake_manager = mock.Mock() fake_share_type1 = share_types.ShareType( - fake_manager, {'name': '1234', 'uuid': '1234'}) + fake_manager, {'name': '1234', 'uuid': '1234'} + ) fake_share_type2 = share_types.ShareType( - fake_manager, {'name': '5678', 'uuid': '5678'}) + fake_manager, {'name': '5678', 'uuid': '5678'} + ) fake_share_group_type = share_group_types.ShareGroupType( - fake_manager, {'name': 'fake_sg', 'uuid': '2345'}) + fake_manager, {'name': 'fake_sg', 'uuid': '2345'} + ) fake_share_network = share_networks.ShareNetwork( - fake_manager, {'id': '3456', 'uuid': '3456'}) + fake_manager, {'id': '3456', 'uuid': '3456'} + ) fake_share_group = share_groups.ShareGroup( - fake_manager, {'id': 'fake-sg-id', 'name': 'fake_sg'}) + fake_manager, {'id': 'fake-sg-id', 'name': 'fake_sg'} + ) self.mock_object( - shell_v2, '_find_share_type', - mock.Mock(side_effect=[fake_share_type1, fake_share_type2])) + shell_v2, + '_find_share_type', + mock.Mock(side_effect=[fake_share_type1, fake_share_type2]), + ) self.mock_object( - shell_v2, '_find_share_group_type', - mock.Mock(side_effect=[fake_share_group_type])) + shell_v2, + '_find_share_group_type', + mock.Mock(side_effect=[fake_share_group_type]), + ) self.mock_object( - shell_v2, '_find_share_network', - mock.Mock(side_effect=[fake_share_network])) + shell_v2, + '_find_share_network', + mock.Mock(side_effect=[fake_share_network]), + ) self.mock_object( - shell_v2, '_wait_for_resource_status', - mock.Mock(side_effect=[fake_share_group]) + shell_v2, + '_wait_for_resource_status', + mock.Mock(side_effect=[fake_share_group]), ) self.run_command( @@ -2991,20 +3424,23 @@ def test_share_group_create_wait(self): '--share-types 1234,5678 ' '--share-group-type fake_sg ' '--share-network 3456 ' - '--availability-zone fake_az --wait') + '--availability-zone fake_az --wait' + ) - shell_v2._find_share_type.assert_has_calls([ - mock.call(self.shell.cs, '1234'), - mock.call(self.shell.cs, '5678') - ]) + shell_v2._find_share_type.assert_has_calls( + [ + mock.call(self.shell.cs, '1234'), + mock.call(self.shell.cs, '5678'), + ] + ) - shell_v2._find_share_group_type.assert_has_calls([ - mock.call(self.shell.cs, 'fake_sg') - ]) + shell_v2._find_share_group_type.assert_has_calls( + [mock.call(self.shell.cs, 'fake_sg')] + ) - shell_v2._find_share_network.assert_has_calls([ - mock.call(self.shell.cs, '3456') - ]) + shell_v2._find_share_network.assert_has_calls( + [mock.call(self.shell.cs, '3456')] + ) expected = { 'share_group': { @@ -3018,11 +3454,16 @@ def test_share_group_create_wait(self): } self.assert_called('POST', '/share-groups', body=expected) - shell_v2._wait_for_resource_status.assert_has_calls([ - mock.call(self.shell.cs, fake_share_group, - resource_type='share_group', - expected_status='available') - ]) + shell_v2._wait_for_resource_status.assert_has_calls( + [ + mock.call( + self.shell.cs, + fake_share_group, + resource_type='share_group', + expected_status='available', + ) + ] + ) @ddt.data( '--name fake_name --availability-zone fake_az', @@ -3040,18 +3481,26 @@ def test_share_group_create_invalid_args(self): fake_share_type_1 = type('FakeShareType1', (object,), {'id': '1234'}) fake_share_type_2 = type('FakeShareType2', (object,), {'id': '5678'}) self.mock_object( - shell_v2, '_find_share_type', - mock.Mock(side_effect=[fake_share_type_1, fake_share_type_2])) + shell_v2, + '_find_share_type', + mock.Mock(side_effect=[fake_share_type_1, fake_share_type_2]), + ) fake_share_group_type = type( - 'FakeShareGroupType', (object,), {'id': '2345'}) + 'FakeShareGroupType', (object,), {'id': '2345'} + ) self.mock_object( - shell_v2, '_find_share_group_type', - mock.Mock(return_value=fake_share_group_type)) + shell_v2, + '_find_share_group_type', + mock.Mock(return_value=fake_share_group_type), + ) fake_share_group_snapshot = type( - 'FakeShareGroupSnapshot', (object,), {'id': '3456'}) + 'FakeShareGroupSnapshot', (object,), {'id': '3456'} + ) self.mock_object( - shell_v2, '_find_share_group_snapshot', - mock.Mock(return_value=fake_share_group_snapshot)) + shell_v2, + '_find_share_group_snapshot', + mock.Mock(return_value=fake_share_group_snapshot), + ) self.assertRaises( ValueError, @@ -3060,86 +3509,116 @@ def test_share_group_create_invalid_args(self): '--description my_group --share-types 1234,5678 ' '--share-group-type fake_sg_type ' '--source-share-group-snapshot fake_share_group_snapshot ' - '--availability-zone fake_az') + '--availability-zone fake_az', + ) @ddt.data( ('--name new-name', {'name': 'new-name'}), ('--description new-description', {'description': 'new-description'}), - ('--name new-name --description new-description', - {'name': 'new-name', 'description': 'new-description'}), + ( + '--name new-name --description new-description', + {'name': 'new-name', 'description': 'new-description'}, + ), ) @ddt.unpack def test_share_group_update(self, cmd, expected_body): fake_manager = mock.Mock() fake_share_group = share_groups.ShareGroup( - fake_manager, {'uuid': '1234', 'id': '1234'}) + fake_manager, {'uuid': '1234', 'id': '1234'} + ) self.mock_object( - shell_v2, '_find_share_group', - mock.Mock(side_effect=[fake_share_group])) + shell_v2, + '_find_share_group', + mock.Mock(side_effect=[fake_share_group]), + ) self.run_command('share-group-update 1234 %s' % cmd) shell_v2._find_share_group.assert_has_calls( - [mock.call(self.shell.cs, '1234')]) + [mock.call(self.shell.cs, '1234')] + ) expected = {'share_group': expected_body} self.assert_called('PUT', '/share-groups/1234', body=expected) def test_try_update_share_group_without_data(self): self.assertRaises( exceptions.CommandError, - self.run_command, 'share-group-update 1234') + self.run_command, + 'share-group-update 1234', + ) - @ddt.data(('share_group_xyz', ), ('share_group_abc', 'share_group_xyz')) + @ddt.data(('share_group_xyz',), ('share_group_abc', 'share_group_xyz')) def test_share_group_delete_wait(self, share_group_to_delete): fake_manager = mock.Mock() fake_share_group = [ share_groups.ShareGroup(fake_manager, {'id': share_group}) for share_group in share_group_to_delete ] - share_group_not_found_error = ("Delete for share group %s " - "failed: No group with a " - "name or ID of '%s' exists.") + share_group_not_found_error = ( + "Delete for share group %s " + "failed: No group with a " + "name or ID of '%s' exists." + ) share_group_are_not_found_errors = [ exceptions.CommandError( - share_group_not_found_error % (share_group, share_group)) + share_group_not_found_error % (share_group, share_group) + ) for share_group in share_group_to_delete ] self.mock_object( - shell_v2, '_find_share_group', - mock.Mock(side_effect=( - fake_share_group + share_group_are_not_found_errors))) - self.mock_object( - shell_v2, '_wait_for_resource_status', - mock.Mock() + shell_v2, + '_find_share_group', + mock.Mock( + side_effect=( + fake_share_group + share_group_are_not_found_errors + ) + ), ) + self.mock_object(shell_v2, '_wait_for_resource_status', mock.Mock()) self.run_command( - 'share-group-delete %s --wait' % ' '.join( - share_group_to_delete)) - shell_v2._find_share_group.assert_has_calls([ - mock.call(self.shell.cs, share_group) for share_group in - share_group_to_delete - ]) - fake_manager.delete.assert_has_calls([ - mock.call(share_group, - force=False) for share_group in fake_share_group]) - shell_v2._wait_for_resource_status.assert_has_calls([ - mock.call(self.shell.cs, share_group, - resource_type='share_group', expected_status='deleted') - for share_group in fake_share_group - ]) + 'share-group-delete %s --wait' % ' '.join(share_group_to_delete) + ) + shell_v2._find_share_group.assert_has_calls( + [ + mock.call(self.shell.cs, share_group) + for share_group in share_group_to_delete + ] + ) + fake_manager.delete.assert_has_calls( + [ + mock.call(share_group, force=False) + for share_group in fake_share_group + ] + ) + shell_v2._wait_for_resource_status.assert_has_calls( + [ + mock.call( + self.shell.cs, + share_group, + resource_type='share_group', + expected_status='deleted', + ) + for share_group in fake_share_group + ] + ) def test_share_group_delete_force(self): fake_manager = mock.Mock() fake_share_group = share_groups.ShareGroup( - fake_manager, {'id': 'fake-group'}) + fake_manager, {'id': 'fake-group'} + ) self.mock_object( - shell_v2, '_find_share_group', - mock.Mock(side_effect=[fake_share_group])) + shell_v2, + '_find_share_group', + mock.Mock(side_effect=[fake_share_group]), + ) self.run_command('share-group-delete --force fake-group') shell_v2._find_share_group.assert_has_calls( - [mock.call(self.shell.cs, "fake-group")]) + [mock.call(self.shell.cs, "fake-group")] + ) fake_manager.delete.assert_has_calls( - [mock.call(fake_share_group, force=True)]) + [mock.call(fake_share_group, force=True)] + ) self.assertEqual(1, fake_manager.delete.call_count) @mock.patch.object(shell_v2, '_find_share_group', mock.Mock()) @@ -3148,7 +3627,9 @@ def test_share_group_delete_all_fail(self): self.assertRaises( exceptions.CommandError, - self.run_command, 'share-group-delete fake-group') + self.run_command, + 'share-group-delete fake-group', + ) @mock.patch.object(shell_v2, '_find_share_group', mock.Mock()) def test_share_group_reset_state_with_flag(self): @@ -3158,8 +3639,10 @@ def test_share_group_reset_state_with_flag(self): self.run_command('share-group-reset-state --state error 1234') self.assert_called( - 'POST', '/share-groups/1234/action', - {'reset_status': {'status': 'error'}}) + 'POST', + '/share-groups/1234/action', + {'reset_status': {'status': 'error'}}, + ) @ddt.data( 'fake-sg-id', @@ -3189,8 +3672,11 @@ def test_share_group_snapshot_create_with_wait(self): self.assert_called('POST', '/share-group-snapshots') # _wait_for_resource_status should be triggered once shell_v2._wait_for_resource_status.assert_called_once_with( - self.shell.cs, mock.ANY, resource_type='share_group_snapshot', - expected_status='available') + self.shell.cs, + mock.ANY, + resource_type='share_group_snapshot', + expected_status='available', + ) @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_share_group_snapshot_list(self): @@ -3198,8 +3684,10 @@ def test_share_group_snapshot_list(self): self.assert_called('GET', '/share-group-snapshots/detail') cliutils.print_list.assert_called_once_with( - mock.ANY, fields=('id', 'name', 'status', 'description'), - sortby_index=None) + mock.ANY, + fields=('id', 'name', 'status', 'description'), + sortby_index=None, + ) @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_share_group_snapshot_list_select_column(self): @@ -3207,27 +3695,32 @@ def test_share_group_snapshot_list_select_column(self): self.assert_called('GET', '/share-group-snapshots/detail') cliutils.print_list.assert_called_once_with( - mock.ANY, fields=['Id', 'Name'], sortby_index=None) + mock.ANY, fields=['Id', 'Name'], sortby_index=None + ) def test_share_group_snapshot_list_all_tenants_only_key(self): self.run_command('share-group-snapshot-list --all-tenants') self.assert_called( - 'GET', '/share-group-snapshots/detail?all_tenants=1') + 'GET', '/share-group-snapshots/detail?all_tenants=1' + ) def test_share_group_snapshot_list_all_tenants_key_and_value_1(self): for separator in self.separators: self.run_command( - 'share-group-snapshot-list --all-tenants' + separator + '1') + 'share-group-snapshot-list --all-tenants' + separator + '1' + ) self.assert_called( - 'GET', '/share-group-snapshots/detail?all_tenants=1') + 'GET', '/share-group-snapshots/detail?all_tenants=1' + ) def test_share_group_snapshot_list_with_filters(self): self.run_command('share-group-snapshot-list --limit 10 --offset 0') self.assert_called( - 'GET', '/share-group-snapshots/detail?limit=10&offset=0') + 'GET', '/share-group-snapshots/detail?limit=10&offset=0' + ) def test_share_group_snapshot_show(self): self.run_command('share-group-snapshot-show 1234') @@ -3243,23 +3736,28 @@ def test_share_group_snapshot_list_members_select_column(self): self.mock_object(cliutils, 'print_list') self.run_command( - 'share-group-snapshot-list-members 1234 --columns id,size') + 'share-group-snapshot-list-members 1234 --columns id,size' + ) self.assert_called('GET', '/share-group-snapshots/1234') cliutils.print_list.assert_called_once_with( - mock.ANY, fields=['Id', 'Size']) + mock.ANY, fields=['Id', 'Size'] + ) @mock.patch.object(shell_v2, '_find_share_group_snapshot', mock.Mock()) def test_share_group_snapshot_reset_state(self): fake_sg_snapshot = type( - 'FakeShareGroupSnapshot', (object,), {'id': '1234'}) + 'FakeShareGroupSnapshot', (object,), {'id': '1234'} + ) shell_v2._find_share_group_snapshot.return_value = fake_sg_snapshot self.run_command('share-group-snapshot-reset-state 1234') self.assert_called( - 'POST', '/share-group-snapshots/1234/action', - {'reset_status': {'status': 'available'}}) + 'POST', + '/share-group-snapshots/1234/action', + {'reset_status': {'status': 'available'}}, + ) @mock.patch.object(shell_v2, '_find_share_group_snapshot', mock.Mock()) def test_share_group_snapshot_reset_state_with_flag(self): @@ -3267,17 +3765,22 @@ def test_share_group_snapshot_reset_state_with_flag(self): shell_v2._find_share_group_snapshot.return_value = fake_sg_snapshot self.run_command( - 'share-group-snapshot-reset-state --state creating 1234') + 'share-group-snapshot-reset-state --state creating 1234' + ) self.assert_called( - 'POST', '/share-group-snapshots/1234/action', - {'reset_status': {'status': 'creating'}}) + 'POST', + '/share-group-snapshots/1234/action', + {'reset_status': {'status': 'creating'}}, + ) @ddt.data( ('--name new-name', {'name': 'new-name'}), ('--description new-description', {'description': 'new-description'}), - ('--name new-name --description new-description', - {'name': 'new-name', 'description': 'new-description'}), + ( + '--name new-name --description new-description', + {'name': 'new-name', 'description': 'new-description'}, + ), ) @ddt.unpack def test_share_group_snapshot_update(self, cmd, expected_body): @@ -3289,7 +3792,9 @@ def test_share_group_snapshot_update(self, cmd, expected_body): def test_try_update_share_group_snapshot_without_data(self): self.assertRaises( exceptions.CommandError, - self.run_command, 'share-group-snapshot-update 1234') + self.run_command, + 'share-group-snapshot-update 1234', + ) @mock.patch.object(shell_v2, '_find_share_group_snapshot', mock.Mock()) @mock.patch.object(shell_v2, '_wait_for_resource_status', mock.Mock()) @@ -3308,14 +3813,18 @@ def test_share_group_snapshot_delete_with_wait(self): fake_sg_snapshot = type('FakeSGSnapshot', (object,), {'id': '1234'}) shell_v2._find_share_group_snapshot.return_value = fake_sg_snapshot - self.run_command('share-group-snapshot-delete fake-group-snapshot' - ' --wait') + self.run_command( + 'share-group-snapshot-delete fake-group-snapshot --wait' + ) self.assert_called('DELETE', '/share-group-snapshots/1234') # _wait_for_resource_status should be triggered once shell_v2._wait_for_resource_status.assert_called_once_with( - self.shell.cs, mock.ANY, resource_type='share_group_snapshot', - expected_status='deleted') + self.shell.cs, + mock.ANY, + resource_type='share_group_snapshot', + expected_status='deleted', + ) @mock.patch.object(shell_v2, '_find_share_group_snapshot', mock.Mock()) def test_share_group_snapshot_delete_force(self): @@ -3323,45 +3832,63 @@ def test_share_group_snapshot_delete_force(self): shell_v2._find_share_group_snapshot.return_value = fake_sg_snapshot self.run_command( - 'share-group-snapshot-delete --force fake-sg-snapshot') + 'share-group-snapshot-delete --force fake-sg-snapshot' + ) self.assert_called( - 'POST', '/share-group-snapshots/1234/action', - {'force_delete': None}) + 'POST', + '/share-group-snapshots/1234/action', + {'force_delete': None}, + ) def test_share_group_snapshot_delete_all_fail(self): self.mock_object( - shell_v2, '_find_share_group_snapshot', - mock.Mock(side_effect=Exception)) + shell_v2, + '_find_share_group_snapshot', + mock.Mock(side_effect=Exception), + ) self.assertRaises( exceptions.CommandError, - self.run_command, 'share-group-snapshot-delete fake-sg-snapshot') + self.run_command, + 'share-group-snapshot-delete fake-sg-snapshot', + ) - @ddt.data(*itertools.product( - ('--columns id,is_default', '--columns id,name', - '--columns is_default', ''), - {'2.45', '2.46', api_versions.MAX_VERSION})) + @ddt.data( + *itertools.product( + ( + '--columns id,is_default', + '--columns id,name', + '--columns is_default', + '', + ), + {'2.45', '2.46', api_versions.MAX_VERSION}, + ) + ) @ddt.unpack def test_share_group_type_list(self, command_args, version): self.mock_object(shell_v2, '_print_share_group_type_list') command = 'share-group-type-list ' + command_args columns_requested = command_args.split('--columns ')[-1] or None - is_default_in_api = (api_versions.APIVersion(version) >= - api_versions.APIVersion('2.46')) + is_default_in_api = api_versions.APIVersion( + version + ) >= api_versions.APIVersion('2.46') self.run_command(command, version=version) - if (not is_default_in_api and - (not columns_requested or 'is_default' in columns_requested)): + if not is_default_in_api and ( + not columns_requested or 'is_default' in columns_requested + ): self.assert_called('GET', '/share-group-types/default') self.assert_called_anytime('GET', '/share-group-types') else: self.assert_called('GET', '/share-group-types') shell_v2._print_share_group_type_list.assert_called_once_with( - mock.ANY, default_share_group_type=mock.ANY, - columns=columns_requested) + mock.ANY, + default_share_group_type=mock.ANY, + columns=columns_requested, + ) def test_share_group_type_list_select_column(self): self.mock_object(shell_v2, '_print_share_group_type_list') @@ -3370,7 +3897,8 @@ def test_share_group_type_list_select_column(self): self.assert_called('GET', '/share-group-types') shell_v2._print_share_group_type_list.assert_called_once_with( - mock.ANY, default_share_group_type=mock.ANY, columns='id,name') + mock.ANY, default_share_group_type=mock.ANY, columns='id,name' + ) def test_share_group_type_list_all(self): self.run_command('share-group-type-list --all') @@ -3386,15 +3914,18 @@ def test_share_group_specs_list(self, args_cmd, expected_columns): self.assert_called('GET', '/share-group-types?is_public=all') shell_v2._print_type_and_extra_specs_list.assert_called_once_with( - mock.ANY, columns=mock.ANY) + mock.ANY, columns=mock.ANY + ) @ddt.data(True, False) def test_share_group_type_create_with_access_and_group_specs(self, public): fake_share_type_1 = type('FakeShareType', (object,), {'id': '1234'}) fake_share_type_2 = type('FakeShareType', (object,), {'id': '5678'}) self.mock_object( - shell_v2, '_find_share_type', - mock.Mock(side_effect=[fake_share_type_1, fake_share_type_2])) + shell_v2, + '_find_share_type', + mock.Mock(side_effect=[fake_share_type_1, fake_share_type_2]), + ) expected = { 'share_group_type': { 'name': 'test-group-type-1', @@ -3407,16 +3938,20 @@ def test_share_group_type_create_with_access_and_group_specs(self, public): self.run_command( 'share-group-type-create test-group-type-1 ' 'type1,type2 --is-public %s --group-specs ' - 'spec1=value1' % str(public)) + 'spec1=value1' % str(public) + ) self.assert_called_anytime('POST', '/share-group-types', body=expected) def test_share_group_type_delete(self): fake_share_group_type = type( - 'FakeShareGroupType', (object,), {'id': '1234'}) + 'FakeShareGroupType', (object,), {'id': '1234'} + ) self.mock_object( - shell_v2, '_find_share_group_type', - mock.Mock(return_value=fake_share_group_type)) + shell_v2, + '_find_share_group_type', + mock.Mock(return_value=fake_share_group_type), + ) self.run_command('share-group-type-delete test-group-type-1') @@ -3424,12 +3959,20 @@ def test_share_group_type_delete(self): def test_share_group_type_key_set(self): fake_share_group_type = type( - 'FakeShareGroupType', (object,), - {'id': '1234', 'is_public': False, 'set_keys': mock.Mock(), - 'unset_keys': mock.Mock()}) + 'FakeShareGroupType', + (object,), + { + 'id': '1234', + 'is_public': False, + 'set_keys': mock.Mock(), + 'unset_keys': mock.Mock(), + }, + ) self.mock_object( - shell_v2, '_find_share_group_type', - mock.Mock(return_value=fake_share_group_type)) + shell_v2, + '_find_share_group_type', + mock.Mock(return_value=fake_share_group_type), + ) self.run_command('share-group-type-key fake_sg_type set key1=value1') @@ -3437,12 +3980,20 @@ def test_share_group_type_key_set(self): def test_share_group_type_key_unset(self): fake_share_group_type = type( - 'FakeShareGroupType', (object,), - {'id': '1234', 'is_public': False, 'set_keys': mock.Mock(), - 'unset_keys': mock.Mock()}) + 'FakeShareGroupType', + (object,), + { + 'id': '1234', + 'is_public': False, + 'set_keys': mock.Mock(), + 'unset_keys': mock.Mock(), + }, + ) self.mock_object( - shell_v2, '_find_share_group_type', - mock.Mock(return_value=fake_share_group_type)) + shell_v2, + '_find_share_group_type', + mock.Mock(return_value=fake_share_group_type), + ) self.run_command('share-group-type-key fake_group_type unset key1') @@ -3450,11 +4001,13 @@ def test_share_group_type_key_unset(self): def test_share_group_type_access_list(self): fake_share_group_type = type( - 'FakeShareGroupType', (object,), - {'id': '1234', 'is_public': False}) + 'FakeShareGroupType', (object,), {'id': '1234', 'is_public': False} + ) self.mock_object( - shell_v2, '_find_share_group_type', - mock.Mock(return_value=fake_share_group_type)) + shell_v2, + '_find_share_group_type', + mock.Mock(return_value=fake_share_group_type), + ) self.run_command('share-group-type-access-list 1234') @@ -3462,43 +4015,53 @@ def test_share_group_type_access_list(self): def test_share_group_type_access_list_public(self): fake_share_group_type = type( - 'FakeShareGroupType', (object,), - {'id': '1234', 'is_public': True}) + 'FakeShareGroupType', (object,), {'id': '1234', 'is_public': True} + ) self.mock_object( - shell_v2, '_find_share_group_type', - mock.Mock(return_value=fake_share_group_type)) + shell_v2, + '_find_share_group_type', + mock.Mock(return_value=fake_share_group_type), + ) self.assertRaises( exceptions.CommandError, - self.run_command, 'share-group-type-access-list 1234') + self.run_command, + 'share-group-type-access-list 1234', + ) def test_share_group_type_access_add_project(self): fake_share_group_type = type( - 'FakeShareGroupType', (object,), - {'id': '1234', 'is_public': False}) + 'FakeShareGroupType', (object,), {'id': '1234', 'is_public': False} + ) self.mock_object( - shell_v2, '_find_share_group_type', - mock.Mock(return_value=fake_share_group_type)) + shell_v2, + '_find_share_group_type', + mock.Mock(return_value=fake_share_group_type), + ) expected = {'addProjectAccess': {'project': '101'}} self.run_command('share-group-type-access-add 1234 101') self.assert_called( - 'POST', '/share-group-types/1234/action', body=expected) + 'POST', '/share-group-types/1234/action', body=expected + ) def test_share_group_type_access_remove_project(self): fake_share_group_type = type( - 'FakeShareGroupType', (object,), - {'id': '1234', 'is_public': False}) + 'FakeShareGroupType', (object,), {'id': '1234', 'is_public': False} + ) self.mock_object( - shell_v2, '_find_share_group_type', - mock.Mock(return_value=fake_share_group_type)) + shell_v2, + '_find_share_group_type', + mock.Mock(return_value=fake_share_group_type), + ) expected = {'removeProjectAccess': {'project': '101'}} self.run_command('share-group-type-access-remove 1234 101') self.assert_called( - 'POST', '/share-group-types/1234/action', body=expected) + 'POST', '/share-group-types/1234/action', body=expected + ) @ddt.data( {'--shares': 5}, @@ -3508,18 +4071,23 @@ def test_share_group_type_access_remove_project(self): {'--snapshot_gigabytes': 5}, {'--share-networks': 5}, {'--share_networks': 5}, - {'--shares': 5, - '--snapshots': 5, - '--gigabytes': 5, - '--snapshot-gigabytes': 5, - '--share-networks': 5}, - {'--shares': 5, - '--snapshots': 5, - '--gigabytes': 5, - '--snapshot-gigabytes': 5, - '--share-networks': 5, - '--share-groups': 5, - '--share-group-snapshots': 5}) + { + '--shares': 5, + '--snapshots': 5, + '--gigabytes': 5, + '--snapshot-gigabytes': 5, + '--share-networks': 5, + }, + { + '--shares': 5, + '--snapshots': 5, + '--gigabytes': 5, + '--snapshot-gigabytes': 5, + '--share-networks': 5, + '--share-groups': 5, + '--share-group-snapshots': 5, + }, + ) def test_quota_class_update(self, data): cmd = 'quota-class-update test' expected = dict() @@ -3536,7 +4104,6 @@ def test_quota_class_update(self, data): @mock.patch.object(shell_v2, '_find_share_replica', mock.Mock()) @mock.patch.object(shell_v2, '_wait_for_resource_status', mock.Mock()) def test_share_replica_delete_force(self, force): - fake_replica = type('FakeShareReplica', (object,), {'id': '1234'}) shell_v2._find_share_replica.return_value = fake_replica @@ -3544,8 +4111,11 @@ def test_share_replica_delete_force(self, force): self.run_command('share-replica-delete fake-replica ' + force) if force: - self.assert_called('POST', '/share-replicas/1234/action', - body={'force_delete': None}) + self.assert_called( + 'POST', + '/share-replicas/1234/action', + body={'force_delete': None}, + ) else: self.assert_called('DELETE', '/share-replicas/1234') self.assertEqual(0, shell_v2._wait_for_resource_status.call_count) @@ -3553,7 +4123,6 @@ def test_share_replica_delete_force(self, force): @mock.patch.object(shell_v2, '_find_share_replica', mock.Mock()) @mock.patch.object(shell_v2, '_wait_for_resource_status', mock.Mock()) def test_share_replica_delete_with_wait(self): - fake_replica = type('FakeShareReplica', (object,), {'id': '1234'}) shell_v2._find_share_replica.return_value = fake_replica @@ -3563,19 +4132,22 @@ def test_share_replica_delete_with_wait(self): # _wait_for_resource_status should be triggered once shell_v2._wait_for_resource_status.assert_called_once_with( - self.shell.cs, mock.ANY, resource_type='share_replica', - expected_status='deleted') + self.shell.cs, + mock.ANY, + resource_type='share_replica', + expected_status='deleted', + ) @ddt.data([1, 0], [1, 1], [2, 0], [2, 1], [2, 2]) @ddt.unpack @mock.patch.object(shell_v2, '_find_share_replica', mock.Mock()) def test_share_replica_delete_errors(self, replica_count, replica_errors): - class StubbedReplicaFindError(Exception): """Error in find share replica stub""" + pass - class StubbedFindWithErrors(object): + class StubbedFindWithErrors: def __init__(self, existing_replicas): self.existing_replicas = existing_replicas @@ -3593,7 +4165,8 @@ def __call__(self, cs, replica): all_replicas.append(replica) shell_v2._find_share_replica.side_effect = StubbedFindWithErrors( - existing_replicas) + existing_replicas + ) cmd = 'share-replica-delete %s' % ' '.join(all_replicas) if replica_count == replica_errors: @@ -3601,26 +4174,27 @@ def __call__(self, cs, replica): else: self.run_command(cmd) for replica in existing_replicas: - self.assert_called_anytime('DELETE', - '/share-replicas/' + replica, - clear_callstack=False) + self.assert_called_anytime( + 'DELETE', + '/share-replicas/' + replica, + clear_callstack=False, + ) def test_share_replica_list_all(self): - self.run_command('share-replica-list') self.assert_called('GET', '/share-replicas/detail') @mock.patch.object(shell_v2, '_find_share', mock.Mock()) def test_share_replica_list_for_share(self): - fshare = type('FakeShare', (object,), {'id': 'fake-share-id'}) shell_v2._find_share.return_value = fshare cmd = 'share-replica-list --share-id %s' self.run_command(cmd % fshare.id) self.assert_called( - 'GET', '/share-replicas/detail?share_id=fake-share-id') + 'GET', '/share-replicas/detail?share_id=fake-share-id' + ) @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_share_replica_list_select_column(self): @@ -3628,8 +4202,7 @@ def test_share_replica_list_select_column(self): self.assert_called('GET', '/share-replicas/detail') - cliutils.print_list.assert_called_once_with( - mock.ANY, ['Id', 'Status']) + cliutils.print_list.assert_called_once_with(mock.ANY, ['Id', 'Status']) @ddt.data( 'fake-share-id --az fake-az', @@ -3638,7 +4211,6 @@ def test_share_replica_list_select_column(self): @mock.patch.object(shell_v2, '_find_share', mock.Mock()) @mock.patch.object(shell_v2, '_wait_for_resource_status', mock.Mock()) def test_share_replica_create(self, data): - fshare = type('FakeShare', (object,), {'id': 'fake-share-id'}) shell_v2._find_share.return_value = fshare @@ -3653,12 +4225,13 @@ def test_share_replica_create(self, data): @mock.patch.object(shell_v2, '_find_share', mock.Mock()) @mock.patch.object(shell_v2, '_wait_for_resource_status', mock.Mock()) def test_share_replica_create_with_wait(self): - fshare = type('FakeShare', (object,), {'id': 'fake-share-id'}) shell_v2._find_share.return_value = fshare - cmd = ('share-replica-create fake-share-id ' - '--availability-zone fake-az --wait') + cmd = ( + 'share-replica-create fake-share-id ' + '--availability-zone fake-az --wait' + ) self.run_command(cmd) @@ -3666,11 +4239,13 @@ def test_share_replica_create_with_wait(self): self.assert_called('POST', '/share-replicas') # _wait_for_resource_status should be triggered once shell_v2._wait_for_resource_status.assert_called_once_with( - self.shell.cs, mock.ANY, resource_type='share_replica', - expected_status='available') + self.shell.cs, + mock.ANY, + resource_type='share_replica', + expected_status='available', + ) def test_share_replica_show(self): - self.run_command('share-replica-show 5678') self.assert_called_anytime('GET', '/share-replicas/5678') @@ -3680,12 +4255,17 @@ def test_share_replica_show(self): def test_share_replica_promote_quiesce_wait_time(self): fake_replica = type('FakeShareReplica', (object,), {'id': '1234'}) shell_v2._find_share_replica.return_value = fake_replica - cmd = ('share-replica-promote ' + fake_replica.id + - ' --quiesce-wait-time 5') + cmd = ( + 'share-replica-promote ' + + fake_replica.id + + ' --quiesce-wait-time 5' + ) self.run_command(cmd) self.assert_called( - 'POST', '/share-replicas/1234/action', - body={'promote': {'quiesce_wait_time': '5'}}) + 'POST', + '/share-replicas/1234/action', + body={'promote': {'quiesce_wait_time': '5'}}, + ) self.assertEqual(0, shell_v2._wait_for_resource_status.call_count) @mock.patch.object(shell_v2, '_find_share_replica', mock.Mock()) @@ -3693,14 +4273,17 @@ def test_share_replica_promote_quiesce_wait_time(self): def test_share_replica_promote_with_wait_(self): fake_replica = type('FakeShareReplica', (object,), {'id': '1234'}) shell_v2._find_share_replica.return_value = fake_replica - cmd = ('share-replica-promote ' + fake_replica.id + ' --wait') + cmd = 'share-replica-promote ' + fake_replica.id + ' --wait' self.run_command(cmd) - self.assert_called( - 'POST', '/share-replicas/1234/action') + self.assert_called('POST', '/share-replicas/1234/action') # _wait_for_resource_status should be triggered once shell_v2._wait_for_resource_status.assert_called_once_with( - self.shell.cs, mock.ANY, resource_type='share_replica', - expected_status='active', status_attr='replica_state') + self.shell.cs, + mock.ANY, + resource_type='share_replica', + expected_status='active', + status_attr='replica_state', + ) @ddt.data('promote', 'resync') @mock.patch.object(shell_v2, '_find_share_replica', mock.Mock()) @@ -3712,8 +4295,10 @@ def test_share_replica_actions(self, action): self.run_command(cmd) self.assert_called( - 'POST', '/share-replicas/1234/action', - body={action.replace('-', '_'): None}) + 'POST', + '/share-replicas/1234/action', + body={action.replace('-', '_'): None}, + ) @mock.patch.object(shell_v2, '_find_share_replica', mock.Mock()) @mock.patch.object(cliutils, 'print_list', mock.Mock()) @@ -3724,18 +4309,21 @@ def test_share_replica_export_location_list(self, columns): cmd = 'share-replica-export-location-list ' + fake_replica.id if columns is not None: cmd = cmd + ' --columns=%s' % columns - expected_columns = list(map(lambda x: x.strip().title(), - columns.split(","))) + expected_columns = list( + map(lambda x: x.strip().title(), columns.split(",")) + ) else: expected_columns = [ - 'ID', 'Availability Zone', 'Replica State', - 'Preferred', 'Path' + 'ID', + 'Availability Zone', + 'Replica State', + 'Preferred', + 'Path', ] self.run_command(cmd) - self.assert_called( - 'GET', '/share-replicas/1234/export-locations') + self.assert_called('GET', '/share-replicas/1234/export-locations') cliutils.print_list.assert_called_with(mock.ANY, expected_columns) @mock.patch.object(shell_v2, '_find_share_replica', mock.Mock()) @@ -3743,9 +4331,11 @@ def test_share_replica_export_location_show(self): fake_replica = type('FakeShareReplica', (object,), {'id': '1234'}) shell_v2._find_share_replica.return_value = fake_replica self.run_command( - 'share-replica-export-location-show 1234 fake-el-uuid') + 'share-replica-export-location-show 1234 fake-el-uuid' + ) self.assert_called( - 'GET', '/share-replicas/1234/export-locations/fake-el-uuid') + 'GET', '/share-replicas/1234/export-locations/fake-el-uuid' + ) @ddt.data('reset-state', 'reset-replica-state') @mock.patch.object(shell_v2, '_find_share_replica', mock.Mock()) @@ -3760,12 +4350,15 @@ def test_share_replica_reset_state_cmds(self, action): shell_v2._find_share_replica.return_value = fake_replica cmd = 'share-replica-%(action)s %(resource)s --state %(state)s' - self.run_command(cmd % { - 'action': action, 'resource': 1234, 'state': 'xyzzyspoon!'}) + self.run_command( + cmd % {'action': action, 'resource': 1234, 'state': 'xyzzyspoon!'} + ) self.assert_called( - 'POST', '/share-replicas/1234/action', - body={action_name: {attr: 'xyzzyspoon!'}}) + 'POST', + '/share-replicas/1234/action', + body={action_name: {attr: 'xyzzyspoon!'}}, + ) def test_snapshot_instance_list_all(self): self.run_command('snapshot-instance-list') @@ -3779,53 +4372,60 @@ def test_snapshot_instance_list_all_detail(self): def test_snapshot_instance_list_select_column(self): self.run_command('snapshot-instance-list --columns id,status') self.assert_called('GET', '/snapshot-instances') - cliutils.print_list.assert_called_once_with( - mock.ANY, ['Id', 'Status']) + cliutils.print_list.assert_called_once_with(mock.ANY, ['Id', 'Status']) @mock.patch.object(shell_v2, '_find_share_snapshot', mock.Mock()) def test_snapshot_instance_list_for_snapshot(self): - fsnapshot = type('FakeSnapshot', (object,), - {'id': 'fake-snapshot-id'}) + fsnapshot = type('FakeSnapshot', (object,), {'id': 'fake-snapshot-id'}) shell_v2._find_share_snapshot.return_value = fsnapshot cmd = 'snapshot-instance-list --snapshot %s' self.run_command(cmd % fsnapshot.id) self.assert_called( - 'GET', '/snapshot-instances?snapshot_id=fake-snapshot-id') + 'GET', '/snapshot-instances?snapshot_id=fake-snapshot-id' + ) def test_snapshot_instance_show(self): self.run_command('snapshot-instance-show 1234') - self.assert_called_anytime('GET', '/snapshot-instances/1234', - clear_callstack=False) - self.assert_called_anytime('GET', - '/snapshot-instances/1234/export-locations') + self.assert_called_anytime( + 'GET', '/snapshot-instances/1234', clear_callstack=False + ) + self.assert_called_anytime( + 'GET', '/snapshot-instances/1234/export-locations' + ) def test_snapshot_instance_reset_state(self): self.run_command('snapshot-instance-reset-state 1234') expected = {'reset_status': {'status': 'available'}} - self.assert_called('POST', '/snapshot-instances/1234/action', - body=expected) + self.assert_called( + 'POST', '/snapshot-instances/1234/action', body=expected + ) def test_migration_start(self): - command = ("migration-start --force-host-assisted-migration True " - "--new-share-network 1111 --new-share-type 1 1234 " - "host@backend#pool --writable False --nondisruptive True " - "--preserve-metadata False --preserve-snapshots True") + command = ( + "migration-start --force-host-assisted-migration True " + "--new-share-network 1111 --new-share-type 1 1234 " + "host@backend#pool --writable False --nondisruptive True " + "--preserve-metadata False --preserve-snapshots True" + ) self.run_command(command) - expected = {'migration_start': { - 'host': 'host@backend#pool', - 'force_host_assisted_migration': 'True', - 'preserve_metadata': 'False', - 'writable': 'False', - 'nondisruptive': 'True', - 'preserve_snapshots': 'True', - 'new_share_network_id': 1111, - 'new_share_type_id': 1, - }} + expected = { + 'migration_start': { + 'host': 'host@backend#pool', + 'force_host_assisted_migration': 'True', + 'preserve_metadata': 'False', + 'writable': 'False', + 'nondisruptive': 'True', + 'preserve_snapshots': 'True', + 'new_share_network_id': 1111, + 'new_share_type_id': 1, + } + } self.assert_called('POST', '/shares/1234/action', body=expected) - @ddt.data('migration-complete', 'migration-get-progress', - 'migration-cancel') + @ddt.data( + 'migration-complete', 'migration-get-progress', 'migration-cancel' + ) def test_migration_others(self, method): command = ' '.join((method, '1234')) self.run_command(command) @@ -3834,53 +4434,62 @@ def test_migration_others(self, method): @ddt.data('migration_error', 'migration_success', None) def test_reset_task_state(self, param): - command = ' '.join(('reset-task-state --state', str(param), - '1234')) + command = ' '.join(('reset-task-state --state', str(param), '1234')) self.run_command(command) expected = {'reset_task_state': {'task_state': param}} self.assert_called('POST', '/shares/1234/action', body=expected) - @ddt.data(('fake_security_service1', ), - ('fake_security_service1', 'fake_security_service2')) + @ddt.data( + ('fake_security_service1',), + ('fake_security_service1', 'fake_security_service2'), + ) def test_security_service_delete(self, ss_ids): fake_security_services = [ security_services.SecurityService('fake', {'id': ss_id}, True) for ss_id in ss_ids ] self.mock_object( - shell_v2, '_find_security_service', - mock.Mock(side_effect=fake_security_services)) + shell_v2, + '_find_security_service', + mock.Mock(side_effect=fake_security_services), + ) self.run_command('security-service-delete %s' % ' '.join(ss_ids)) - shell_v2._find_security_service.assert_has_calls([ - mock.call(self.shell.cs, ss_id) for ss_id in ss_ids - ]) + shell_v2._find_security_service.assert_has_calls( + [mock.call(self.shell.cs, ss_id) for ss_id in ss_ids] + ) for ss in fake_security_services: self.assert_called_anytime( - 'DELETE', '/security-services/%s' % ss.id, - clear_callstack=False) + 'DELETE', + '/security-services/%s' % ss.id, + clear_callstack=False, + ) - @ddt.data(('fake_share_network1', ), - ('fake_share_network1', 'fake_share_network1')) + @ddt.data( + ('fake_share_network1',), + ('fake_share_network1', 'fake_share_network1'), + ) def test_share_network_delete(self, sn_ids): fake_share_networks = [ share_networks.ShareNetwork('fake', {'id': sn_id}, True) for sn_id in sn_ids ] self.mock_object( - shell_v2, '_find_share_network', - mock.Mock(side_effect=fake_share_networks)) + shell_v2, + '_find_share_network', + mock.Mock(side_effect=fake_share_networks), + ) self.run_command('share-network-delete %s' % ' '.join(sn_ids)) - shell_v2._find_share_network.assert_has_calls([ - mock.call(self.shell.cs, sn_id) for sn_id in sn_ids - ]) + shell_v2._find_share_network.assert_has_calls( + [mock.call(self.shell.cs, sn_id) for sn_id in sn_ids] + ) for sn in fake_share_networks: self.assert_called_anytime( - 'DELETE', '/share-networks/%s' % sn.id, - clear_callstack=False) + 'DELETE', '/share-networks/%s' % sn.id, clear_callstack=False + ) @mock.patch.object(shell_v2, '_find_share', mock.Mock()) @mock.patch.object(shell_v2, '_wait_for_snapshot_status', mock.Mock()) @@ -3889,12 +4498,13 @@ def test_snapshot_create(self): shell_v2._find_share.return_value = share_to_create_snapshot self.run_command( - 'snapshot-create fake_share --name testshare1snapshot') + 'snapshot-create fake_share --name testshare1snapshot' + ) - shell_v2._find_share.assert_has_calls([ - mock.call(self.shell.cs, 'fake_share')]) - self.assert_called_anytime( - 'POST', '/snapshots', clear_callstack=False) + shell_v2._find_share.assert_has_calls( + [mock.call(self.shell.cs, 'fake_share')] + ) + self.assert_called_anytime('POST', '/snapshots', clear_callstack=False) # _wait_for_snapshot_status should not be trigerred self.assertEqual(0, shell_v2._wait_for_snapshot_status.call_count) @@ -3905,145 +4515,183 @@ def test_snapshot_create_with_wait(self): shell_v2._find_share.return_value = share_to_create_snapshot self.run_command( - 'snapshot-create fake_share --name testshare1snapshot --wait') + 'snapshot-create fake_share --name testshare1snapshot --wait' + ) - shell_v2._find_share.assert_has_calls([ - mock.call(self.shell.cs, 'fake_share')]) - self.assert_called_anytime( - 'POST', '/snapshots', clear_callstack=False) + shell_v2._find_share.assert_has_calls( + [mock.call(self.shell.cs, 'fake_share')] + ) + self.assert_called_anytime('POST', '/snapshots', clear_callstack=False) # _wait_for_snapshot_status should be trigerred once shell_v2._wait_for_snapshot_status.assert_called_once_with( - self.shell.cs, mock.ANY, expected_status='available') + self.shell.cs, mock.ANY, expected_status='available' + ) - @ddt.data(('fake_snapshot1', ), ('fake_snapshot1', 'fake_snapshot2')) + @ddt.data(('fake_snapshot1',), ('fake_snapshot1', 'fake_snapshot2')) def test_snapshot_delete(self, snapshot_ids): fake_snapshots = [ share_snapshots.ShareSnapshot('fake', {'id': snapshot_id}, True) for snapshot_id in snapshot_ids ] self.mock_object( - shell_v2, '_find_share_snapshot', - mock.Mock(side_effect=fake_snapshots)) + shell_v2, + '_find_share_snapshot', + mock.Mock(side_effect=fake_snapshots), + ) self.run_command('snapshot-delete %s' % ' '.join(snapshot_ids)) - shell_v2._find_share_snapshot.assert_has_calls([ - mock.call(self.shell.cs, s_id) for s_id in snapshot_ids - ]) + shell_v2._find_share_snapshot.assert_has_calls( + [mock.call(self.shell.cs, s_id) for s_id in snapshot_ids] + ) for snapshot in fake_snapshots: self.assert_called_anytime( - 'DELETE', '/snapshots/%s' % snapshot.id, - clear_callstack=False) + 'DELETE', '/snapshots/%s' % snapshot.id, clear_callstack=False + ) @mock.patch.object(shell_v2, '_find_share_snapshot', mock.Mock()) @mock.patch.object(shell_v2, '_wait_for_snapshot_status', mock.Mock()) def test_snapshot_delete_with_wait(self): fake_snapshot = share_snapshots.ShareSnapshot( - 'fake', {'id': 'fake_snapshot1'}, True) + 'fake', {'id': 'fake_snapshot1'}, True + ) shell_v2._find_share_snapshot.return_value = fake_snapshot self.run_command('snapshot-delete fake_snapshot1 --wait') - shell_v2._find_share_snapshot.assert_has_calls([ - mock.call(self.shell.cs, 'fake_snapshot1')]) + shell_v2._find_share_snapshot.assert_has_calls( + [mock.call(self.shell.cs, 'fake_snapshot1')] + ) self.assert_called_anytime( - 'DELETE', '/snapshots/fake_snapshot1', clear_callstack=False) + 'DELETE', '/snapshots/fake_snapshot1', clear_callstack=False + ) # _wait_for_resource_status should be trigerred once shell_v2._wait_for_snapshot_status.assert_called_once_with( - self.shell.cs, 'fake_snapshot1', expected_status='deleted') + self.shell.cs, 'fake_snapshot1', expected_status='deleted' + ) - @ddt.data(('snapshot_xyz', ), ('snapshot_abc', 'snapshot_xyz')) + @ddt.data(('snapshot_xyz',), ('snapshot_abc', 'snapshot_xyz')) def test_snapshot_force_delete_wait(self, snapshots_to_delete): fake_manager = mock.Mock() fake_snapshots = [ share_snapshots.ShareSnapshot(fake_manager, {'id': '1234'}) for snapshot in snapshots_to_delete ] - snapshot_not_found_error = ("Delete for snapshot %s failed: No " - "snapshot with a name or " - "ID of '%s' exists.") + snapshot_not_found_error = ( + "Delete for snapshot %s failed: No " + "snapshot with a name or " + "ID of '%s' exists." + ) snapshots_are_not_found_errors = [ exceptions.CommandError( - snapshot_not_found_error % (snapshot, snapshot)) + snapshot_not_found_error % (snapshot, snapshot) + ) for snapshot in snapshots_to_delete ] self.mock_object( - shell_v2, '_find_share_snapshot', - mock.Mock(side_effect=( - fake_snapshots + snapshots_are_not_found_errors))) + shell_v2, + '_find_share_snapshot', + mock.Mock( + side_effect=(fake_snapshots + snapshots_are_not_found_errors) + ), + ) self.run_command( - 'snapshot-force-delete %s --wait' % ' '.join( - snapshots_to_delete)) - shell_v2._find_share_snapshot.assert_has_calls([ - mock.call(self.shell.cs, snapshot) for snapshot in - snapshots_to_delete - ]) - fake_manager.force_delete.assert_has_calls([ - mock.call(snapshot) for snapshot in fake_snapshots]) - self.assertEqual(len(snapshots_to_delete), - fake_manager.force_delete.call_count) - - @ddt.data(('fake_type1', ), ('fake_type1', 'fake_type2')) + 'snapshot-force-delete %s --wait' % ' '.join(snapshots_to_delete) + ) + shell_v2._find_share_snapshot.assert_has_calls( + [ + mock.call(self.shell.cs, snapshot) + for snapshot in snapshots_to_delete + ] + ) + fake_manager.force_delete.assert_has_calls( + [mock.call(snapshot) for snapshot in fake_snapshots] + ) + self.assertEqual( + len(snapshots_to_delete), fake_manager.force_delete.call_count + ) + + @ddt.data(('fake_type1',), ('fake_type1', 'fake_type2')) def test_share_type_delete(self, type_ids): fake_share_types = [ share_types.ShareType('fake', {'id': type_id}, True) for type_id in type_ids ] self.mock_object( - shell_v2, '_find_share_type', - mock.Mock(side_effect=fake_share_types)) + shell_v2, + '_find_share_type', + mock.Mock(side_effect=fake_share_types), + ) self.run_command('type-delete %s' % ' '.join(type_ids)) - shell_v2._find_share_type.assert_has_calls([ - mock.call(self.shell.cs, t_id) for t_id in type_ids - ]) + shell_v2._find_share_type.assert_has_calls( + [mock.call(self.shell.cs, t_id) for t_id in type_ids] + ) for fake_share_type in fake_share_types: self.assert_called_anytime( - 'DELETE', '/types/%s' % fake_share_type.id, - clear_callstack=False) + 'DELETE', + '/types/%s' % fake_share_type.id, + clear_callstack=False, + ) - @ddt.data(('share_server_xyz', ), ('share_server_abc', 'share_server_xyz')) + @ddt.data(('share_server_xyz',), ('share_server_abc', 'share_server_xyz')) def test_share_server_delete_wait(self, share_servers_to_delete): fake_manager = mock.Mock() fake_share_servers = [ share_servers.ShareServer(fake_manager, {'id': '1234'}) for share_server in share_servers_to_delete ] - share_server_not_found_error = ("Delete for share server %s " - "failed: No server with a " - "name or ID of '%s' exists.") + share_server_not_found_error = ( + "Delete for share server %s " + "failed: No server with a " + "name or ID of '%s' exists." + ) share_servers_are_not_found_errors = [ - exceptions.CommandError(share_server_not_found_error - % (share_server, share_server)) + exceptions.CommandError( + share_server_not_found_error % (share_server, share_server) + ) for share_server in share_servers_to_delete ] self.mock_object( - shell_v2, '_find_share_server', mock.Mock( - side_effect=(fake_share_servers + - share_servers_are_not_found_errors))) - - self.mock_object( - shell_v2, '_wait_for_resource_status', - mock.Mock() + shell_v2, + '_find_share_server', + mock.Mock( + side_effect=( + fake_share_servers + share_servers_are_not_found_errors + ) + ), ) - self.run_command('share-server-delete %s --wait' % ' ' - .join(share_servers_to_delete)) + self.mock_object(shell_v2, '_wait_for_resource_status', mock.Mock()) - shell_v2._find_share_server.assert_has_calls([ - mock.call(self.shell.cs, share_server) - for share_server in share_servers_to_delete - ]) - fake_manager.delete.assert_has_calls([ - mock.call(share_server) for share_server in fake_share_servers]) - shell_v2._wait_for_resource_status.assert_has_calls([ - mock.call(self.shell.cs, share_server, - resource_type='share_server', expected_status='deleted') - for share_server in fake_share_servers - ]) - self.assertEqual(len(share_servers_to_delete), - fake_manager.delete.call_count) + self.run_command( + 'share-server-delete %s --wait' % ' '.join(share_servers_to_delete) + ) + + shell_v2._find_share_server.assert_has_calls( + [ + mock.call(self.shell.cs, share_server) + for share_server in share_servers_to_delete + ] + ) + fake_manager.delete.assert_has_calls( + [mock.call(share_server) for share_server in fake_share_servers] + ) + shell_v2._wait_for_resource_status.assert_has_calls( + [ + mock.call( + self.shell.cs, + share_server, + resource_type='share_server', + expected_status='deleted', + ) + for share_server in fake_share_servers + ] + ) + self.assertEqual( + len(share_servers_to_delete), fake_manager.delete.call_count + ) @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_message_list(self): @@ -4051,9 +4699,18 @@ def test_message_list(self): self.assert_called('GET', '/messages') cliutils.print_list.assert_called_once_with( - mock.ANY, fields=['ID', 'Resource Type', 'Resource ID', - 'Action ID', 'User Message', 'Detail ID', - 'Created At'], sortby_index=None) + mock.ANY, + fields=[ + 'ID', + 'Resource Type', + 'Resource ID', + 'Action ID', + 'User Message', + 'Detail ID', + 'Created At', + ], + sortby_index=None, + ) @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_share_message_list_created_before_aliases(self): @@ -4077,24 +4734,26 @@ def test_message_list_select_column(self): self.assert_called('GET', '/messages') cliutils.print_list.assert_called_once_with( - mock.ANY, fields=['Id', 'Resource_Type'], sortby_index=None) + mock.ANY, fields=['Id', 'Resource_Type'], sortby_index=None + ) def test_message_list_with_filters(self): self.run_command('message-list --limit 10 --offset 0') - self.assert_called( - 'GET', '/messages?limit=10&offset=0') + self.assert_called('GET', '/messages?limit=10&offset=0') def test_message_show(self): self.run_command('message-show 1234') self.assert_called('GET', '/messages/1234') - @ddt.data(('1234', ), - ('1234_error', ), - ('1234_error', '5678'), - ('1234', '5678_error'), - ('1234', '5678')) + @ddt.data( + ('1234',), + ('1234_error',), + ('1234_error', '5678'), + ('1234', '5678_error'), + ('1234', '5678'), + ) def test_message_delete(self, ids): fake_messages = dict() for mid in ids: @@ -4108,8 +4767,10 @@ def _find_message_with_errors(cs, mid): return fake_messages[mid] self.mock_object( - shell_v2, '_find_message', - mock.Mock(side_effect=_find_message_with_errors)) + shell_v2, + '_find_message', + mock.Mock(side_effect=_find_message_with_errors), + ) cmd = 'message-delete %s' % ' '.join(ids) @@ -4118,34 +4779,36 @@ def _find_message_with_errors(cs, mid): else: self.run_command(cmd) - shell_v2._find_message.assert_has_calls([ - mock.call(self.shell.cs, mid) for mid in ids - ]) + shell_v2._find_message.assert_has_calls( + [mock.call(self.shell.cs, mid) for mid in ids] + ) for fake_message in fake_messages.values(): self.assert_called_anytime( - 'DELETE', '/messages/%s' % fake_message.id, - clear_callstack=False) - - @ddt.data(('share-network-list', ' --description~', - '/share-networks/', '2.35'), - ('share-network-list', ' --name~', - '/share-networks/', '2.35'), - ('share-group-list', ' --description~', - '/share-groups/', '2.35'), - ('share-group-list', ' --name~', '/share-groups/', '2.35'), - ('list', ' --description~', '/shares/', '2.35'), - ('list', ' --name~', '/shares/', '2.35'), - ('snapshot-list', ' --description~', '/snapshots/', '2.35'), - ('snapshot-list', ' --name~', '/snapshots/', '2.35')) + 'DELETE', + '/messages/%s' % fake_message.id, + clear_callstack=False, + ) + + @ddt.data( + ('share-network-list', ' --description~', '/share-networks/', '2.35'), + ('share-network-list', ' --name~', '/share-networks/', '2.35'), + ('share-group-list', ' --description~', '/share-groups/', '2.35'), + ('share-group-list', ' --name~', '/share-groups/', '2.35'), + ('list', ' --description~', '/shares/', '2.35'), + ('list', ' --name~', '/shares/', '2.35'), + ('snapshot-list', ' --description~', '/snapshots/', '2.35'), + ('snapshot-list', ' --name~', '/snapshots/', '2.35'), + ) @ddt.unpack def test_list_filter_by_inexact_version_not_support( - self, cmd, option, url, version): + self, cmd, option, url, version + ): for separator in self.separators: self.assertRaises( exceptions.CommandError, self.run_command, cmd + option + separator + 'fake', - version=version + version=version, ) def test_share_server_unmanage_all_fail(self): @@ -4153,36 +4816,38 @@ def test_share_server_unmanage_all_fail(self): cmd = '--os-share-api-version 2.49' cmd += ' share-server-unmanage' cmd += ' 2345 5678 9999' - self.assertRaises(exceptions.CommandError, - self.run_command, cmd) + self.assertRaises(exceptions.CommandError, self.run_command, cmd) def test_share_server_unmanage_some_fail(self): # 5678 and 9999 throw exception self.run_command('share-server-unmanage 1234 5678 9999') expected = {'unmanage': {'force': False}} - self.assert_called('POST', '/share-servers/1234/action', - body=expected) + self.assert_called('POST', '/share-servers/1234/action', body=expected) @ddt.data('migration-start', 'migration-check') def test_share_server_migration_start_and_check(self, method): - command = ("share-server-%s " - "1234 host@backend --new-share-network 1111 " - "--writable False --nondisruptive True " - "--preserve-snapshots True" % - method) + command = ( + "share-server-%s " + "1234 host@backend --new-share-network 1111 " + "--writable False --nondisruptive True " + "--preserve-snapshots True" % method + ) self.run_command(command) method = method.replace('-', '_') - expected = {method: { - 'host': 'host@backend', - 'writable': 'False', - 'nondisruptive': 'True', - 'preserve_snapshots': 'True', - 'new_share_network_id': 1111 - }} + expected = { + method: { + 'host': 'host@backend', + 'writable': 'False', + 'nondisruptive': 'True', + 'preserve_snapshots': 'True', + 'new_share_network_id': 1111, + } + } self.assert_called('POST', '/share-servers/1234/action', body=expected) - @ddt.data('migration-complete', 'migration-get-progress', - 'migration-cancel') + @ddt.data( + 'migration-complete', 'migration-get-progress', 'migration-cancel' + ) def test_share_server_migration_others(self, method): command = 'share-server-' + ' '.join((method, '1234')) self.run_command(command) @@ -4191,9 +4856,9 @@ def test_share_server_migration_others(self, method): @ddt.data('migration_error', 'migration_success', None) def test_share_server_reset_task_state(self, param): - command = ' '.join(('share-server-reset-task-state --state', - str(param), - '1234')) + command = ' '.join( + ('share-server-reset-task-state --state', str(param), '1234') + ) self.run_command(command) expected = {'reset_task_state': {'task_state': param}} self.assert_called('POST', '/share-servers/1234/action', body=expected) diff --git a/manilaclient/tests/unit/v2/test_type_access.py b/manilaclient/tests/unit/v2/test_type_access.py index 50f0e8ce..0b727aa0 100644 --- a/manilaclient/tests/unit/v2/test_type_access.py +++ b/manilaclient/tests/unit/v2/test_type_access.py @@ -27,12 +27,10 @@ @ddt.ddt class TypeAccessTest(utils.TestCase): - def _get_share_type_access_manager(self, microversion): version = api_versions.APIVersion(microversion) mock_microversion = mock.Mock(api_version=version) - return share_type_access.ShareTypeAccessManager( - api=mock_microversion) + return share_type_access.ShareTypeAccessManager(api=mock_microversion) @ddt.data( ("1.0", "os-share-type-access"), @@ -48,12 +46,14 @@ def test_list(self, microversion, action_name): share_type.is_public = False manager = self._get_share_type_access_manager(microversion) - with mock.patch.object(manager, '_list', - mock.Mock(return_value=fake_access_list)): + with mock.patch.object( + manager, '_list', mock.Mock(return_value=fake_access_list) + ): access = manager.list(share_type=share_type, search_opts=None) manager._list.assert_called_once_with( - "/types/3/%s" % action_name, "share_type_access") + f"/types/3/{action_name}", "share_type_access" + ) self.assertEqual(fake_access_list, access) @ddt.data("1.0", "2.0", "2.6", "2.7") @@ -63,8 +63,9 @@ def test_list_public(self, microversion): share_type.is_public = True manager = self._get_share_type_access_manager(microversion) - with mock.patch.object(manager, '_list', - mock.Mock(return_value='fake')): + with mock.patch.object( + manager, '_list', mock.Mock(return_value='fake') + ): access = manager.list(share_type=share_type) self.assertFalse(manager._list.called) @@ -75,21 +76,25 @@ def test_add_project_access(self, microversion): share_type = mock.Mock() manager = self._get_share_type_access_manager(microversion) - with mock.patch.object(manager, '_action', - mock.Mock(return_value='fake_action')): + with mock.patch.object( + manager, '_action', mock.Mock(return_value='fake_action') + ): manager.add_project_access(share_type, PROJECT_UUID) manager._action.assert_called_once_with( - 'addProjectAccess', share_type, {'project': PROJECT_UUID}) + 'addProjectAccess', share_type, {'project': PROJECT_UUID} + ) @ddt.data("1.0", "2.0", "2.6", "2.7") def test_remove_project_access(self, microversion): share_type = mock.Mock() manager = self._get_share_type_access_manager(microversion) - with mock.patch.object(manager, '_action', - mock.Mock(return_value='fake_action')): + with mock.patch.object( + manager, '_action', mock.Mock(return_value='fake_action') + ): manager.remove_project_access(share_type, PROJECT_UUID) manager._action.assert_called_once_with( - 'removeProjectAccess', share_type, {'project': PROJECT_UUID}) + 'removeProjectAccess', share_type, {'project': PROJECT_UUID} + ) diff --git a/manilaclient/tests/unit/v2/test_types.py b/manilaclient/tests/unit/v2/test_types.py index dfcd4018..369adb8f 100644 --- a/manilaclient/tests/unit/v2/test_types.py +++ b/manilaclient/tests/unit/v2/test_types.py @@ -32,7 +32,6 @@ def get_valid_type_create_data_2_0(): - public = [True, False] dhss = [True, False] snapshot = [None, True, False] @@ -44,16 +43,17 @@ def get_valid_type_create_data_2_0(): def get_valid_type_create_data_2_24(): - public = [True, False] dhss = [True, False] snapshot = [None] create_from_snapshot = [None] extra_specs = [None, {'replication_type': 'writable', 'foo': 'bar'}] - snapshot_none_combos = list(itertools.product(public, dhss, snapshot, - create_from_snapshot, - extra_specs)) + snapshot_none_combos = list( + itertools.product( + public, dhss, snapshot, create_from_snapshot, extra_specs + ) + ) public = [True, False] dhss = [True, False] @@ -61,9 +61,11 @@ def get_valid_type_create_data_2_24(): create_from_snapshot = [True, False, None] extra_specs = [None, {'replication_type': 'readable', 'foo': 'bar'}] - snapshot_true_combos = list(itertools.product(public, dhss, snapshot, - create_from_snapshot, - extra_specs)) + snapshot_true_combos = list( + itertools.product( + public, dhss, snapshot, create_from_snapshot, extra_specs + ) + ) public = [True, False] dhss = [True, False] @@ -71,15 +73,16 @@ def get_valid_type_create_data_2_24(): create_from_snapshot = [False, None] extra_specs = [None, {'replication_type': 'dr', 'foo': 'bar'}] - snapshot_false_combos = list(itertools.product(public, dhss, snapshot, - create_from_snapshot, - extra_specs)) + snapshot_false_combos = list( + itertools.product( + public, dhss, snapshot, create_from_snapshot, extra_specs + ) + ) return snapshot_none_combos + snapshot_true_combos + snapshot_false_combos def get_valid_type_create_data_2_27(): - public = [True, False] dhss = [True, False] snapshot = [None] @@ -87,10 +90,16 @@ def get_valid_type_create_data_2_27(): revert_to_snapshot = [None] extra_specs = [None, {'replication_type': 'writable', 'foo': 'bar'}] - snapshot_none_combos = list(itertools.product(public, dhss, snapshot, - create_from_snapshot, - revert_to_snapshot, - extra_specs)) + snapshot_none_combos = list( + itertools.product( + public, + dhss, + snapshot, + create_from_snapshot, + revert_to_snapshot, + extra_specs, + ) + ) public = [True, False] dhss = [True, False] @@ -99,10 +108,16 @@ def get_valid_type_create_data_2_27(): revert_to_snapshot = [True, False, None] extra_specs = [None, {'replication_type': 'readable', 'foo': 'bar'}] - snapshot_true_combos = list(itertools.product(public, dhss, snapshot, - create_from_snapshot, - revert_to_snapshot, - extra_specs)) + snapshot_true_combos = list( + itertools.product( + public, + dhss, + snapshot, + create_from_snapshot, + revert_to_snapshot, + extra_specs, + ) + ) public = [True, False] dhss = [True, False] @@ -111,17 +126,22 @@ def get_valid_type_create_data_2_27(): revert_to_snapshot = [False, None] extra_specs = [None, {'replication_type': 'dr', 'foo': 'bar'}] - snapshot_false_combos = list(itertools.product(public, dhss, snapshot, - create_from_snapshot, - revert_to_snapshot, - extra_specs)) + snapshot_false_combos = list( + itertools.product( + public, + dhss, + snapshot, + create_from_snapshot, + revert_to_snapshot, + extra_specs, + ) + ) return snapshot_none_combos + snapshot_true_combos + snapshot_false_combos @ddt.ddt class TypesTest(utils.TestCase): - def _get_share_types_manager(self, microversion): version = api_versions.APIVersion(microversion) mock_microversion = mock.Mock(api_version=version) @@ -165,16 +185,18 @@ def test_list_types_search_by_extra_specs(self): @ddt.data(*get_valid_type_create_data_2_0()) @ddt.unpack def test_create_2_7(self, is_public, dhss, snapshot, extra_specs): - extra_specs = copy.copy(extra_specs) manager = self._get_share_types_manager("2.7") self.mock_object(manager, '_create', mock.Mock(return_value="fake")) result = manager.create( - 'test-type-3', spec_driver_handles_share_servers=dhss, - spec_snapshot_support=snapshot, extra_specs=extra_specs, - is_public=is_public) + 'test-type-3', + spec_driver_handles_share_servers=dhss, + spec_snapshot_support=snapshot, + extra_specs=extra_specs, + is_public=is_public, + ) if extra_specs is None: extra_specs = {} @@ -190,54 +212,68 @@ def test_create_2_7(self, is_public, dhss, snapshot, extra_specs): } expected_body["share_type"]["extra_specs"][ - "driver_handles_share_servers"] = dhss + "driver_handles_share_servers" + ] = dhss expected_body["share_type"]["extra_specs"]['snapshot_support'] = ( - True if snapshot is None else snapshot) + True if snapshot is None else snapshot + ) manager._create.assert_called_once_with( - "/types", expected_body, "share_type") + "/types", expected_body, "share_type" + ) self.assertEqual("fake", result) - def _add_standard_extra_specs_to_dict(self, extra_specs, - create_from_snapshot=None, - revert_to_snapshot=None, - mount_snapshot=None): - + def _add_standard_extra_specs_to_dict( + self, + extra_specs, + create_from_snapshot=None, + revert_to_snapshot=None, + mount_snapshot=None, + ): # Short-circuit checks to allow for extra specs to be (and remain) None - if all(spec is None for spec in [ - create_from_snapshot, revert_to_snapshot, mount_snapshot]): + if all( + spec is None + for spec in [ + create_from_snapshot, + revert_to_snapshot, + mount_snapshot, + ] + ): return extra_specs extra_specs = extra_specs or {} if create_from_snapshot is not None: extra_specs['create_share_from_snapshot_support'] = ( - create_from_snapshot) + create_from_snapshot + ) if revert_to_snapshot is not None: - extra_specs['revert_to_snapshot_support'] = ( - revert_to_snapshot) + extra_specs['revert_to_snapshot_support'] = revert_to_snapshot if mount_snapshot is not None: - extra_specs['mount_snapshot_support'] = ( - mount_snapshot) + extra_specs['mount_snapshot_support'] = mount_snapshot return extra_specs @ddt.data(*get_valid_type_create_data_2_24()) @ddt.unpack - def test_create_2_24(self, is_public, dhss, snapshot, create_from_snapshot, - extra_specs): - + def test_create_2_24( + self, is_public, dhss, snapshot, create_from_snapshot, extra_specs + ): extra_specs = copy.copy(extra_specs) extra_specs = self._add_standard_extra_specs_to_dict( - extra_specs, create_from_snapshot=create_from_snapshot) + extra_specs, create_from_snapshot=create_from_snapshot + ) manager = self._get_share_types_manager("2.24") self.mock_object(manager, '_create', mock.Mock(return_value="fake")) result = manager.create( - 'test-type-3', spec_driver_handles_share_servers=dhss, + 'test-type-3', + spec_driver_handles_share_servers=dhss, spec_snapshot_support=snapshot, - extra_specs=extra_specs, is_public=is_public) + extra_specs=extra_specs, + is_public=is_public, + ) expected_extra_specs = dict(extra_specs or {}) expected_extra_specs["driver_handles_share_servers"] = dhss @@ -248,11 +284,13 @@ def test_create_2_24(self, is_public, dhss, snapshot, create_from_snapshot, expected_extra_specs["snapshot_support"] = snapshot if create_from_snapshot is None: - expected_extra_specs.pop("create_share_from_snapshot_support", - None) + expected_extra_specs.pop( + "create_share_from_snapshot_support", None + ) else: expected_extra_specs["create_share_from_snapshot_support"] = ( - create_from_snapshot) + create_from_snapshot + ) expected_body = { "share_type": { @@ -263,26 +301,38 @@ def test_create_2_24(self, is_public, dhss, snapshot, create_from_snapshot, } manager._create.assert_called_once_with( - "/types", expected_body, "share_type") + "/types", expected_body, "share_type" + ) self.assertEqual("fake", result) @ddt.data(*get_valid_type_create_data_2_27()) @ddt.unpack - def test_create_2_27(self, is_public, dhss, snapshot, create_from_snapshot, - revert_to_snapshot, extra_specs): - + def test_create_2_27( + self, + is_public, + dhss, + snapshot, + create_from_snapshot, + revert_to_snapshot, + extra_specs, + ): extra_specs = copy.copy(extra_specs) extra_specs = self._add_standard_extra_specs_to_dict( - extra_specs, create_from_snapshot=create_from_snapshot, - revert_to_snapshot=revert_to_snapshot) + extra_specs, + create_from_snapshot=create_from_snapshot, + revert_to_snapshot=revert_to_snapshot, + ) manager = self._get_share_types_manager("2.27") self.mock_object(manager, '_create', mock.Mock(return_value="fake")) result = manager.create( - 'test-type-3', spec_driver_handles_share_servers=dhss, + 'test-type-3', + spec_driver_handles_share_servers=dhss, spec_snapshot_support=snapshot, - extra_specs=extra_specs, is_public=is_public) + extra_specs=extra_specs, + is_public=is_public, + ) expected_extra_specs = dict(extra_specs or {}) expected_extra_specs["driver_handles_share_servers"] = dhss @@ -293,17 +343,20 @@ def test_create_2_27(self, is_public, dhss, snapshot, create_from_snapshot, expected_extra_specs["snapshot_support"] = snapshot if create_from_snapshot is None: - expected_extra_specs.pop("create_share_from_snapshot_support", - None) + expected_extra_specs.pop( + "create_share_from_snapshot_support", None + ) else: expected_extra_specs["create_share_from_snapshot_support"] = ( - create_from_snapshot) + create_from_snapshot + ) if revert_to_snapshot is None: expected_extra_specs.pop("revert_to_snapshot_support", None) else: expected_extra_specs["revert_to_snapshot_support"] = ( - revert_to_snapshot) + revert_to_snapshot + ) expected_body = { "share_type": { @@ -314,27 +367,42 @@ def test_create_2_27(self, is_public, dhss, snapshot, create_from_snapshot, } manager._create.assert_called_once_with( - "/types", expected_body, "share_type") + "/types", expected_body, "share_type" + ) self.assertEqual("fake", result) @ddt.data( - (False, False, True, {'snapshot_support': True, - 'replication_type': 'fake_repl_type'}), - (False, False, False, {'snapshot_support': False, - 'replication_type': 'fake_repl_type'}), - (False, False, True, {'snapshot_support': False, - 'replication_type': 'fake_repl_type'}), - (False, False, False, {'snapshot_support': True, - 'replication_type': 'fake_repl_type'}), - + ( + False, + False, + True, + {'snapshot_support': True, 'replication_type': 'fake_repl_type'}, + ), + ( + False, + False, + False, + {'snapshot_support': False, 'replication_type': 'fake_repl_type'}, + ), + ( + False, + False, + True, + {'snapshot_support': False, 'replication_type': 'fake_repl_type'}, + ), + ( + False, + False, + False, + {'snapshot_support': True, 'replication_type': 'fake_repl_type'}, + ), (False, True, None, {'driver_handles_share_servers': True}), (False, False, None, {'driver_handles_share_servers': True}), (False, None, None, {'driver_handles_share_servers': True}), (False, None, None, {'driver_handles_share_servers': None}), ) @ddt.unpack - def test_create_error_2_7(self, is_public, dhss, snapshot, - extra_specs): + def test_create_error_2_7(self, is_public, dhss, snapshot, extra_specs): manager = self._get_share_types_manager("2.7") self.mock_object(manager, '_create', mock.Mock(return_value="fake")) @@ -345,20 +413,27 @@ def test_create_error_2_7(self, is_public, dhss, snapshot, spec_driver_handles_share_servers=dhss, spec_snapshot_support=snapshot, extra_specs=extra_specs, - is_public=is_public) + is_public=is_public, + ) @ddt.data( (False, True, None, None, {'driver_handles_share_servers': True}), - (False, False, False, False, {'snapshot_support': True, - 'replication_type': 'fake_repl_type'}), + ( + False, + False, + False, + False, + {'snapshot_support': True, 'replication_type': 'fake_repl_type'}, + ), ) @ddt.unpack - def test_create_error_2_24(self, is_public, dhss, snapshot, - create_from_snapshot, extra_specs): - + def test_create_error_2_24( + self, is_public, dhss, snapshot, create_from_snapshot, extra_specs + ): extra_specs = copy.copy(extra_specs) extra_specs = self._add_standard_extra_specs_to_dict( - extra_specs, create_from_snapshot=create_from_snapshot) + extra_specs, create_from_snapshot=create_from_snapshot + ) manager = self._get_share_types_manager("2.24") self.mock_object(manager, '_create', mock.Mock(return_value="fake")) @@ -370,7 +445,8 @@ def test_create_error_2_24(self, is_public, dhss, snapshot, spec_driver_handles_share_servers=dhss, spec_snapshot_support=snapshot, extra_specs=extra_specs, - is_public=is_public) + is_public=is_public, + ) @ddt.data( ("2.6", True), @@ -384,20 +460,22 @@ def test_create_error_2_24(self, is_public, dhss, snapshot, ) @ddt.unpack def test_create_with_default_values(self, microversion, dhss): - manager = self._get_share_types_manager(microversion) self.mock_object(manager, '_create', mock.Mock(return_value="fake")) description = 'test description' - if (api_versions.APIVersion(microversion) >= - api_versions.APIVersion("2.41")): + if api_versions.APIVersion(microversion) >= api_versions.APIVersion( + "2.41" + ): result = manager.create( - 'test-type-3', dhss, description=description) + 'test-type-3', dhss, description=description + ) else: result = manager.create('test-type-3', dhss) - if (api_versions.APIVersion(microversion) > - api_versions.APIVersion("2.6")): + if api_versions.APIVersion(microversion) > api_versions.APIVersion( + "2.6" + ): is_public_keyname = "share_type_access:is_public" else: is_public_keyname = "os-share-type-access:is_public" @@ -409,27 +487,30 @@ def test_create_with_default_values(self, microversion, dhss): "extra_specs": { "driver_handles_share_servers": dhss, "snapshot_support": True, - } + }, } } - if (api_versions.APIVersion(microversion) >= - api_versions.APIVersion("2.24")): + if api_versions.APIVersion(microversion) >= api_versions.APIVersion( + "2.24" + ): del expected_body['share_type']['extra_specs']['snapshot_support'] - if (api_versions.APIVersion(microversion) >= - api_versions.APIVersion("2.41")): + if api_versions.APIVersion(microversion) >= api_versions.APIVersion( + "2.41" + ): expected_body['share_type']['description'] = description manager._create.assert_called_once_with( - "/types", expected_body, "share_type") + "/types", expected_body, "share_type" + ) self.assertEqual("fake", result) def test_set_key(self): t = cs.share_types.get(1) t.set_keys({'k': 'v'}) - cs.assert_called('POST', - '/types/1/extra_specs', - {'extra_specs': {'k': 'v'}}) + cs.assert_called( + 'POST', '/types/1/extra_specs', {'extra_specs': {'k': 'v'}} + ) def test_unset_keys(self): t = cs.share_types.get(1) @@ -451,11 +532,11 @@ def test_update(self, microversion): is_public_key_name: is_public, } } - result = manager.update( - share_type, name, is_public, description) + result = manager.update(share_type, name, is_public, description) expected_body['share_type']['description'] = description manager._update.assert_called_once_with( - "/types/%s" % share_type, expected_body, "share_type") + f"/types/{share_type}", expected_body, "share_type" + ) self.assertEqual("fake", result) def test_delete(self): @@ -466,33 +547,38 @@ def test_get_keys_from_resource_data(self): manager = mock.Mock() manager.api.client.get = mock.Mock(return_value=(200, {})) valid_extra_specs = {'test': 'test'} - share_type = share_types.ShareType(mock.Mock(), - {'extra_specs': valid_extra_specs, - 'name': 'test'}, - loaded=True) + share_type = share_types.ShareType( + mock.Mock(), + {'extra_specs': valid_extra_specs, 'name': 'test'}, + loaded=True, + ) actual_result = share_type.get_keys() self.assertEqual(actual_result, valid_extra_specs) self.assertEqual(manager.api.client.get.call_count, 0) - @ddt.data({'prefer_resource_data': True, - 'resource_extra_specs': {}}, - {'prefer_resource_data': False, - 'resource_extra_specs': {'fake': 'fake'}}, - {'prefer_resource_data': False, - 'resource_extra_specs': {}}) + @ddt.data( + {'prefer_resource_data': True, 'resource_extra_specs': {}}, + { + 'prefer_resource_data': False, + 'resource_extra_specs': {'fake': 'fake'}, + }, + {'prefer_resource_data': False, 'resource_extra_specs': {}}, + ) @ddt.unpack - def test_get_keys_from_api(self, prefer_resource_data, - resource_extra_specs): + def test_get_keys_from_api( + self, prefer_resource_data, resource_extra_specs + ): manager = mock.Mock() valid_extra_specs = {'test': 'test'} manager.api.client.get = mock.Mock( - return_value=(200, {'extra_specs': valid_extra_specs})) + return_value=(200, {'extra_specs': valid_extra_specs}) + ) info = { 'name': 'test', 'uuid': 'fake', - 'extra_specs': resource_extra_specs + 'extra_specs': resource_extra_specs, } share_type = share_types.ShareType(manager, info, loaded=True) diff --git a/manilaclient/utils.py b/manilaclient/utils.py index 8dcc477b..fae3bb99 100644 --- a/manilaclient/utils.py +++ b/manilaclient/utils.py @@ -13,8 +13,9 @@ from urllib import parse -class HookableMixin(object): +class HookableMixin: """Mixin so classes can register and run hooks.""" + _hooks_map = {} @classmethod @@ -44,7 +45,7 @@ def safe_issubclass(*args): def get_function_name(func): - return "%s.%s" % (func.__module__, func.__qualname__) + return f"{func.__module__}.{func.__qualname__}" def safe_urlencode(params_dict): diff --git a/manilaclient/v1/__init__.py b/manilaclient/v1/__init__.py index 56c143be..44787d62 100644 --- a/manilaclient/v1/__init__.py +++ b/manilaclient/v1/__init__.py @@ -20,7 +20,7 @@ from manilaclient import v2 -class MovedModule(object): +class MovedModule: def __init__(self, new_module): self.new_module = new_module diff --git a/manilaclient/v1/client.py b/manilaclient/v1/client.py index 67acc3b5..9f82b427 100644 --- a/manilaclient/v1/client.py +++ b/manilaclient/v1/client.py @@ -34,9 +34,10 @@ from manilaclient.v2 import shares -@removals.removed_class("Client", message="Please use 'v2.Client' instead", - removal_version='2.0.0') -class Client(object): +@removals.removed_class( + "Client", message="Please use 'v2.Client' instead", removal_version='2.0.0' +) +class Client: """Top-level object to access the OpenStack Manila API. Create an instance with your creds:: @@ -66,26 +67,42 @@ class Client(object): >>> client.shares.list() ... """ - def __init__(self, username=None, project_id=None, auth_url=None, - insecure=False, timeout=None, tenant_id=None, - project_name=None, region_name=None, - endpoint_type='publicURL', extensions=None, - service_type=constants.V1_SERVICE_TYPE, service_name=None, - retries=None, http_log_debug=False, input_auth_token=None, - session=None, auth=None, cacert=None, - service_catalog_url=None, user_agent='python-manilaclient', - use_keyring=False, force_new_token=False, - cached_token_lifetime=300, - api_version=manilaclient.API_DEPRECATED_VERSION, - user_id=None, - user_domain_id=None, - user_domain_name=None, - project_domain_id=None, - project_domain_name=None, - cert=None, - password=None, - **kwargs): + def __init__( + self, + username=None, + project_id=None, + auth_url=None, + insecure=False, + timeout=None, + tenant_id=None, + project_name=None, + region_name=None, + endpoint_type='publicURL', + extensions=None, + service_type=constants.V1_SERVICE_TYPE, + service_name=None, + retries=None, + http_log_debug=False, + input_auth_token=None, + session=None, + auth=None, + cacert=None, + service_catalog_url=None, + user_agent='python-manilaclient', + use_keyring=False, + force_new_token=False, + cached_token_lifetime=300, + api_version=manilaclient.API_DEPRECATED_VERSION, + user_id=None, + user_domain_id=None, + user_domain_name=None, + project_domain_id=None, + project_domain_name=None, + cert=None, + password=None, + **kwargs, + ): self.username = username self.password = password self.tenant_id = tenant_id or project_id @@ -112,8 +129,10 @@ def __init__(self, username=None, project_id=None, auth_url=None, self.cached_token_lifetime = cached_token_lifetime if input_auth_token and not service_catalog_url: - msg = ("For token-based authentication you should " - "provide 'input_auth_token' and 'service_catalog_url'.") + msg = ( + "For token-based authentication you should " + "provide 'input_auth_token' and 'service_catalog_url'." + ) raise exceptions.ClientException(msg) self.project_id = tenant_id if tenant_id is not None else project_id @@ -131,7 +150,8 @@ def __init__(self, username=None, project_id=None, auth_url=None, interface=endpoint_type, service_type=service_type, service_name=service_name, - region_name=region_name) + region_name=region_name, + ) input_auth_token = self.keystone_client.session.get_token(auth) else: @@ -143,38 +163,43 @@ def __init__(self, username=None, project_id=None, auth_url=None, if session and not service_catalog_url: service_catalog_url = self.keystone_client.session.get_endpoint( - auth, interface=endpoint_type, - service_type=service_type) + auth, interface=endpoint_type, service_type=service_type + ) elif not service_catalog_url: catalog = self.keystone_client.service_catalog.get_endpoints( - service_type) + service_type + ) for catalog_entry in catalog.get(service_type, []): - if (catalog_entry.get("interface") == ( - endpoint_type.lower().split("url")[0]) or - catalog_entry.get(endpoint_type)): - if (region_name and not region_name == ( - catalog_entry.get( - "region", - catalog_entry.get("region_id")))): + if catalog_entry.get("interface") == ( + endpoint_type.lower().split("url")[0] + ) or catalog_entry.get(endpoint_type): + if region_name and not region_name == ( + catalog_entry.get( + "region", catalog_entry.get("region_id") + ) + ): continue service_catalog_url = catalog_entry.get( - "url", catalog_entry.get(endpoint_type)) + "url", catalog_entry.get(endpoint_type) + ) break if not service_catalog_url: raise RuntimeError("Could not find Manila endpoint in catalog") self.api_version = api_version - self.client = httpclient.HTTPClient(service_catalog_url, - input_auth_token, - user_agent, - insecure=insecure, - cacert=cacert, - cert=cert, - timeout=timeout, - retries=retries, - http_log_debug=http_log_debug, - api_version=self.api_version) + self.client = httpclient.HTTPClient( + service_catalog_url, + input_auth_token, + user_agent, + insecure=insecure, + cacert=cacert, + cert=cert, + timeout=timeout, + retries=retries, + http_log_debug=http_log_debug, + api_version=self.api_version, + ) self.limits = limits.LimitsManager(self) self.services = services.ServiceManager(self) @@ -217,7 +242,8 @@ def _get_keystone_client(self): if not auth_url: raise exceptions.CommandError( 'Unable to determine the Keystone version to authenticate ' - 'with using the given auth_url.') + 'with using the given auth_url.' + ) keystone_client = ks_client.Client( session=ks_session, @@ -232,7 +258,8 @@ def _get_keystone_client(self): project_name=self.project_name, project_domain_name=self.project_domain_name, project_domain_id=self.project_domain_id, - region_name=self.region_name) + region_name=self.region_name, + ) keystone_client.authenticate() return keystone_client diff --git a/manilaclient/v1/contrib/list_extensions.py b/manilaclient/v1/contrib/list_extensions.py index 7c9508cd..d6fc3156 100644 --- a/manilaclient/v1/contrib/list_extensions.py +++ b/manilaclient/v1/contrib/list_extensions.py @@ -22,10 +22,11 @@ "Module manilaclient.v1.contrib.list_extensions is deprecated " "(taken as a basis for manilaclient.v2.contrib.list_extensions). " "The preferable way to get a client class or object is to use " - "the manilaclient.client module.") + "the manilaclient.client module." +) -class MovedModule(object): +class MovedModule: def __init__(self, new_module): self.new_module = new_module @@ -34,4 +35,5 @@ def __getattr__(self, attr): sys.modules["manilaclient.v1.contrib.list_extensions"] = MovedModule( - list_extensions) + list_extensions +) diff --git a/manilaclient/v1/limits.py b/manilaclient/v1/limits.py index 06c55766..6632a065 100644 --- a/manilaclient/v1/limits.py +++ b/manilaclient/v1/limits.py @@ -19,13 +19,15 @@ from manilaclient.v2 import limits -warnings.warn("Module manilaclient.v1.limits is deprecated (taken as a basis " - "for manilaclient.v2.limits). " - "The preferable way to get a client class or object is to use " - "the manilaclient.client module.") +warnings.warn( + "Module manilaclient.v1.limits is deprecated (taken as a basis " + "for manilaclient.v2.limits). " + "The preferable way to get a client class or object is to use " + "the manilaclient.client module." +) -class MovedModule(object): +class MovedModule: def __init__(self, new_module): self.new_module = new_module diff --git a/manilaclient/v1/quota_classes.py b/manilaclient/v1/quota_classes.py index 32e22a00..a404a8da 100644 --- a/manilaclient/v1/quota_classes.py +++ b/manilaclient/v1/quota_classes.py @@ -19,13 +19,15 @@ from manilaclient.v2 import quota_classes -warnings.warn("Module manilaclient.v1.quota_classes is deprecated (taken as " - "a basis for manilaclient.v2.quota_classes). " - "The preferable way to get a client class or object is to use " - "the manilaclient.client module.") +warnings.warn( + "Module manilaclient.v1.quota_classes is deprecated (taken as " + "a basis for manilaclient.v2.quota_classes). " + "The preferable way to get a client class or object is to use " + "the manilaclient.client module." +) -class MovedModule(object): +class MovedModule: def __init__(self, new_module): self.new_module = new_module diff --git a/manilaclient/v1/quotas.py b/manilaclient/v1/quotas.py index d0b79b6a..a7961521 100644 --- a/manilaclient/v1/quotas.py +++ b/manilaclient/v1/quotas.py @@ -19,13 +19,15 @@ from manilaclient.v2 import quotas -warnings.warn("Module manilaclient.v1.quotas is deprecated (taken as " - "a basis for manilaclient.v2.quotas). " - "The preferable way to get a client class or object is to use " - "the manilaclient.client module.") +warnings.warn( + "Module manilaclient.v1.quotas is deprecated (taken as " + "a basis for manilaclient.v2.quotas). " + "The preferable way to get a client class or object is to use " + "the manilaclient.client module." +) -class MovedModule(object): +class MovedModule: def __init__(self, new_module): self.new_module = new_module diff --git a/manilaclient/v1/scheduler_stats.py b/manilaclient/v1/scheduler_stats.py index d30a96d4..3c9fae89 100644 --- a/manilaclient/v1/scheduler_stats.py +++ b/manilaclient/v1/scheduler_stats.py @@ -19,13 +19,15 @@ from manilaclient.v2 import scheduler_stats -warnings.warn("Module manilaclient.v1.scheduler_stats is deprecated (taken as " - "a basis for manilaclient.v2.scheduler_stats). " - "The preferable way to get a client class or object is to use " - "the manilaclient.client module.") +warnings.warn( + "Module manilaclient.v1.scheduler_stats is deprecated (taken as " + "a basis for manilaclient.v2.scheduler_stats). " + "The preferable way to get a client class or object is to use " + "the manilaclient.client module." +) -class MovedModule(object): +class MovedModule: def __init__(self, new_module): self.new_module = new_module diff --git a/manilaclient/v1/security_services.py b/manilaclient/v1/security_services.py index 1819b055..a456ed1f 100644 --- a/manilaclient/v1/security_services.py +++ b/manilaclient/v1/security_services.py @@ -19,13 +19,15 @@ from manilaclient.v2 import security_services -warnings.warn("Module manilaclient.v1.security_services is deprecated (taken " - "as a basis for manilaclient.v2.security_services). " - "The preferable way to get a client class or object is to use " - "the manilaclient.client module.") +warnings.warn( + "Module manilaclient.v1.security_services is deprecated (taken " + "as a basis for manilaclient.v2.security_services). " + "The preferable way to get a client class or object is to use " + "the manilaclient.client module." +) -class MovedModule(object): +class MovedModule: def __init__(self, new_module): self.new_module = new_module @@ -33,5 +35,6 @@ def __getattr__(self, attr): return getattr(self.new_module, attr) -sys.modules[ - "manilaclient.v1.security_services"] = MovedModule(security_services) +sys.modules["manilaclient.v1.security_services"] = MovedModule( + security_services +) diff --git a/manilaclient/v1/services.py b/manilaclient/v1/services.py index 7dfbc10c..e6f16937 100644 --- a/manilaclient/v1/services.py +++ b/manilaclient/v1/services.py @@ -19,13 +19,15 @@ from manilaclient.v2 import services -warnings.warn("Module manilaclient.v1.services is deprecated (taken as " - "a basis for manilaclient.v2.services). " - "The preferable way to get a client class or object is to use " - "the manilaclient.client module.") +warnings.warn( + "Module manilaclient.v1.services is deprecated (taken as " + "a basis for manilaclient.v2.services). " + "The preferable way to get a client class or object is to use " + "the manilaclient.client module." +) -class MovedModule(object): +class MovedModule: def __init__(self, new_module): self.new_module = new_module diff --git a/manilaclient/v1/share_networks.py b/manilaclient/v1/share_networks.py index 076fbd30..4c5a346e 100644 --- a/manilaclient/v1/share_networks.py +++ b/manilaclient/v1/share_networks.py @@ -19,13 +19,15 @@ from manilaclient.v2 import share_networks -warnings.warn("Module manilaclient.v1.share_networks is deprecated (taken as " - "a basis for manilaclient.v2.share_networks). " - "The preferable way to get a client class or object is to use " - "the manilaclient.client module.") +warnings.warn( + "Module manilaclient.v1.share_networks is deprecated (taken as " + "a basis for manilaclient.v2.share_networks). " + "The preferable way to get a client class or object is to use " + "the manilaclient.client module." +) -class MovedModule(object): +class MovedModule: def __init__(self, new_module): self.new_module = new_module diff --git a/manilaclient/v1/share_servers.py b/manilaclient/v1/share_servers.py index 7440b915..d136a33f 100644 --- a/manilaclient/v1/share_servers.py +++ b/manilaclient/v1/share_servers.py @@ -19,13 +19,15 @@ from manilaclient.v2 import share_servers -warnings.warn("Module manilaclient.v1.share_servers is deprecated (taken as " - "a basis for manilaclient.v2.share_servers). " - "The preferable way to get a client class or object is to use " - "the manilaclient.client module.") +warnings.warn( + "Module manilaclient.v1.share_servers is deprecated (taken as " + "a basis for manilaclient.v2.share_servers). " + "The preferable way to get a client class or object is to use " + "the manilaclient.client module." +) -class MovedModule(object): +class MovedModule: def __init__(self, new_module): self.new_module = new_module diff --git a/manilaclient/v1/share_snapshots.py b/manilaclient/v1/share_snapshots.py index 96070a40..71192371 100644 --- a/manilaclient/v1/share_snapshots.py +++ b/manilaclient/v1/share_snapshots.py @@ -19,13 +19,15 @@ from manilaclient.v2 import share_snapshots -warnings.warn("Module manilaclient.v1.share_snapshots is deprecated (taken as " - "a basis for manilaclient.v2.share_snapshots). " - "The preferable way to get a client class or object is to use " - "the manilaclient.client module.") +warnings.warn( + "Module manilaclient.v1.share_snapshots is deprecated (taken as " + "a basis for manilaclient.v2.share_snapshots). " + "The preferable way to get a client class or object is to use " + "the manilaclient.client module." +) -class MovedModule(object): +class MovedModule: def __init__(self, new_module): self.new_module = new_module diff --git a/manilaclient/v1/share_type_access.py b/manilaclient/v1/share_type_access.py index 2da0873f..e4614a7e 100644 --- a/manilaclient/v1/share_type_access.py +++ b/manilaclient/v1/share_type_access.py @@ -19,13 +19,15 @@ from manilaclient.v2 import share_type_access -warnings.warn("Module manilaclient.v1.share_type_access is deprecated (taken " - "as a basis for manilaclient.v2.share_type_access). " - "The preferable way to get a client class or object is to use " - "the manilaclient.client module.") +warnings.warn( + "Module manilaclient.v1.share_type_access is deprecated (taken " + "as a basis for manilaclient.v2.share_type_access). " + "The preferable way to get a client class or object is to use " + "the manilaclient.client module." +) -class MovedModule(object): +class MovedModule: def __init__(self, new_module): self.new_module = new_module @@ -33,5 +35,6 @@ def __getattr__(self, attr): return getattr(self.new_module, attr) -sys.modules[ - "manilaclient.v1.share_type_access"] = MovedModule(share_type_access) +sys.modules["manilaclient.v1.share_type_access"] = MovedModule( + share_type_access +) diff --git a/manilaclient/v1/share_types.py b/manilaclient/v1/share_types.py index 793766f7..b3f64220 100644 --- a/manilaclient/v1/share_types.py +++ b/manilaclient/v1/share_types.py @@ -19,13 +19,15 @@ from manilaclient.v2 import share_types -warnings.warn("Module manilaclient.v1.share_types is deprecated (taken as " - "a basis for manilaclient.v2.share_types). " - "The preferable way to get a client class or object is to use " - "the manilaclient.client module.") +warnings.warn( + "Module manilaclient.v1.share_types is deprecated (taken as " + "a basis for manilaclient.v2.share_types). " + "The preferable way to get a client class or object is to use " + "the manilaclient.client module." +) -class MovedModule(object): +class MovedModule: def __init__(self, new_module): self.new_module = new_module diff --git a/manilaclient/v1/shares.py b/manilaclient/v1/shares.py index cc007fb9..79dd5e56 100644 --- a/manilaclient/v1/shares.py +++ b/manilaclient/v1/shares.py @@ -19,13 +19,15 @@ from manilaclient.v2 import shares -warnings.warn("Module manilaclient.v1.shares is deprecated (taken as " - "a basis for manilaclient.v2.shares). " - "The preferable way to get a client class or object is to use " - "the manilaclient.client module.") +warnings.warn( + "Module manilaclient.v1.shares is deprecated (taken as " + "a basis for manilaclient.v2.shares). " + "The preferable way to get a client class or object is to use " + "the manilaclient.client module." +) -class MovedModule(object): +class MovedModule: def __init__(self, new_module): self.new_module = new_module diff --git a/manilaclient/v2/__init__.py b/manilaclient/v2/__init__.py index c5fa79a7..a2e057d9 100644 --- a/manilaclient/v2/__init__.py +++ b/manilaclient/v2/__init__.py @@ -14,4 +14,4 @@ # License for the specific language governing permissions and limitations # under the License. -from manilaclient.v2.client import Client # noqa +from manilaclient.v2.client import Client # noqa diff --git a/manilaclient/v2/availability_zones.py b/manilaclient/v2/availability_zones.py index 52555e0d..ccb1cbf5 100644 --- a/manilaclient/v2/availability_zones.py +++ b/manilaclient/v2/availability_zones.py @@ -22,13 +22,13 @@ class AvailabilityZone(base.Resource): - def __repr__(self): - return "" % self.id + return f"" class AvailabilityZoneManager(base.Manager): """Manage :class:`Service` resources.""" + resource_class = AvailabilityZone @api_versions.wraps("1.0", "2.6") diff --git a/manilaclient/v2/client.py b/manilaclient/v2/client.py index af534529..000d1568 100644 --- a/manilaclient/v2/client.py +++ b/manilaclient/v2/client.py @@ -51,7 +51,7 @@ from manilaclient.v2 import shares -class Client(object): +class Client: """Top-level object to access the OpenStack Manila API. Create an instance with your creds:: @@ -81,26 +81,42 @@ class Client(object): >>> client.shares.list() ... """ - def __init__(self, username=None, project_id=None, auth_url=None, - insecure=False, timeout=None, tenant_id=None, - project_name=None, region_name=None, - endpoint_type='publicURL', extensions=None, - service_type=constants.V2_SERVICE_TYPE, service_name=None, - retries=None, http_log_debug=False, input_auth_token=None, - session=None, auth=None, cacert=None, - service_catalog_url=None, user_agent='python-manilaclient', - use_keyring=False, force_new_token=False, - cached_token_lifetime=300, - api_version=manilaclient.API_MIN_VERSION, - user_id=None, - user_domain_id=None, - user_domain_name=None, - project_domain_id=None, - project_domain_name=None, - cert=None, - password=None, - **kwargs): + def __init__( + self, + username=None, + project_id=None, + auth_url=None, + insecure=False, + timeout=None, + tenant_id=None, + project_name=None, + region_name=None, + endpoint_type='publicURL', + extensions=None, + service_type=constants.V2_SERVICE_TYPE, + service_name=None, + retries=None, + http_log_debug=False, + input_auth_token=None, + session=None, + auth=None, + cacert=None, + service_catalog_url=None, + user_agent='python-manilaclient', + use_keyring=False, + force_new_token=False, + cached_token_lifetime=300, + api_version=manilaclient.API_MIN_VERSION, + user_id=None, + user_domain_id=None, + user_domain_name=None, + project_domain_id=None, + project_domain_name=None, + cert=None, + password=None, + **kwargs, + ): self.username = username self.password = password self.tenant_id = tenant_id or project_id @@ -127,8 +143,10 @@ def __init__(self, username=None, project_id=None, auth_url=None, self.cached_token_lifetime = cached_token_lifetime if input_auth_token and not service_catalog_url: - msg = ("For token-based authentication you should " - "provide 'input_auth_token' and 'service_catalog_url'.") + msg = ( + "For token-based authentication you should " + "provide 'input_auth_token' and 'service_catalog_url'." + ) raise exceptions.ClientException(msg) self.project_id = tenant_id if tenant_id is not None else project_id @@ -146,7 +164,8 @@ def __init__(self, username=None, project_id=None, auth_url=None, interface=endpoint_type, service_type=service_type, service_name=service_name, - region_name=region_name) + region_name=region_name, + ) input_auth_token = self.keystone_client.session.get_token(auth) else: @@ -158,41 +177,50 @@ def __init__(self, username=None, project_id=None, auth_url=None, if session and not service_catalog_url: service_catalog_url = self.keystone_client.session.get_endpoint( - auth, interface=endpoint_type, - service_type=service_type, region_name=region_name) + auth, + interface=endpoint_type, + service_type=service_type, + region_name=region_name, + ) elif not service_catalog_url: catalog = self.keystone_client.service_catalog.get_endpoints( - service_type) + service_type + ) for catalog_entry in catalog.get(service_type, []): - if (catalog_entry.get("interface") == ( - endpoint_type.lower().split("url")[0]) or - catalog_entry.get(endpoint_type)): - if (region_name and not region_name == ( - catalog_entry.get( - "region", - catalog_entry.get("region_id")))): + if catalog_entry.get("interface") == ( + endpoint_type.lower().split("url")[0] + ) or catalog_entry.get(endpoint_type): + if region_name and not region_name == ( + catalog_entry.get( + "region", catalog_entry.get("region_id") + ) + ): continue service_catalog_url = catalog_entry.get( - "url", catalog_entry.get(endpoint_type)) + "url", catalog_entry.get(endpoint_type) + ) break if not service_catalog_url: raise RuntimeError("Could not find Manila endpoint in catalog") self.api_version = api_version - self.client = httpclient.HTTPClient(service_catalog_url, - input_auth_token, - user_agent, - insecure=insecure, - cacert=cacert, - cert=cert, - timeout=timeout, - retries=retries, - http_log_debug=http_log_debug, - api_version=self.api_version) + self.client = httpclient.HTTPClient( + service_catalog_url, + input_auth_token, + user_agent, + insecure=insecure, + cacert=cacert, + cert=cert, + timeout=timeout, + retries=retries, + http_log_debug=http_log_debug, + api_version=self.api_version, + ) self.availability_zones = availability_zones.AvailabilityZoneManager( - self) + self + ) self.limits = limits.LimitsManager(self) self.transfers = share_transfers.ShareTransferManager(self) self.messages = messages.MessageManager(self) @@ -200,7 +228,8 @@ def __init__(self, username=None, project_id=None, auth_url=None, self.security_services = security_services.SecurityServiceManager(self) self.share_networks = share_networks.ShareNetworkManager(self) self.share_network_subnets = ( - share_network_subnets.ShareNetworkSubnetManager(self)) + share_network_subnets.ShareNetworkSubnetManager(self) + ) self.quota_classes = quota_classes.QuotaClassSetManager(self) self.quotas = quotas.QuotaSetManager(self) @@ -209,26 +238,34 @@ def __init__(self, username=None, project_id=None, auth_url=None, self.shares = shares.ShareManager(self) self.share_export_locations = ( - share_export_locations.ShareExportLocationManager(self)) + share_export_locations.ShareExportLocationManager(self) + ) self.share_groups = share_groups.ShareGroupManager(self) self.share_group_snapshots = ( - share_group_snapshots.ShareGroupSnapshotManager(self)) + share_group_snapshots.ShareGroupSnapshotManager(self) + ) self.share_group_type_access = ( - share_group_type_access.ShareGroupTypeAccessManager(self)) + share_group_type_access.ShareGroupTypeAccessManager(self) + ) self.share_group_types = share_group_types.ShareGroupTypeManager(self) self.share_instances = share_instances.ShareInstanceManager(self) self.share_instance_export_locations = ( share_instance_export_locations.ShareInstanceExportLocationManager( - self)) + self + ) + ) self.share_snapshots = share_snapshots.ShareSnapshotManager(self) self.share_snapshot_instances = ( - share_snapshot_instances.ShareSnapshotInstanceManager(self)) + share_snapshot_instances.ShareSnapshotInstanceManager(self) + ) self.share_snapshot_export_locations = ( share_snapshot_export_locations.ShareSnapshotExportLocationManager( - self)) - self.share_snapshot_instance_export_locations = ( - share_snapshot_instance_export_locations. - ShareSnapshotInstanceExportLocationManager(self)) + self + ) + ) + self.share_snapshot_instance_export_locations = share_snapshot_instance_export_locations.ShareSnapshotInstanceExportLocationManager( + self + ) self.share_types = share_types.ShareTypeManager(self) self.share_type_access = share_type_access.ShareTypeAccessManager(self) @@ -236,10 +273,13 @@ def __init__(self, username=None, project_id=None, auth_url=None, self.share_replicas = share_replicas.ShareReplicaManager(self) self.share_replica_export_locations = ( share_replica_export_locations.ShareReplicaExportLocationManager( - self)) + self + ) + ) self.pools = scheduler_stats.PoolManager(self) - self.share_access_rules = ( - share_access_rules.ShareAccessRuleManager(self)) + self.share_access_rules = share_access_rules.ShareAccessRuleManager( + self + ) self.share_backups = share_backups.ShareBackupManager(self) self._load_extensions(extensions) @@ -267,7 +307,8 @@ def _get_keystone_client(self): if not auth_url: raise exceptions.CommandError( 'Unable to determine the Keystone version to authenticate ' - 'with using the given auth_url.') + 'with using the given auth_url.' + ) keystone_client = ks_client.Client( session=ks_session, @@ -282,7 +323,8 @@ def _get_keystone_client(self): project_name=self.project_name, project_domain_name=self.project_domain_name, project_domain_id=self.project_domain_id, - region_name=self.region_name) + region_name=self.region_name, + ) keystone_client.authenticate() return keystone_client diff --git a/manilaclient/v2/limits.py b/manilaclient/v2/limits.py index 1a46cf67..9cfb93a4 100644 --- a/manilaclient/v2/limits.py +++ b/manilaclient/v2/limits.py @@ -25,7 +25,7 @@ def __repr__(self): @property def absolute(self): - for (name, value) in list(self._info['absolute'].items()): + for name, value in list(self._info['absolute'].items()): yield AbsoluteLimit(name, value) @property @@ -34,16 +34,21 @@ def rate(self): uri = group['uri'] regex = group['regex'] for rate in group['limit']: - yield RateLimit(rate['verb'], uri, regex, rate['value'], - rate['remaining'], rate['unit'], - rate['next-available']) - - -class RateLimit(object): + yield RateLimit( + rate['verb'], + uri, + regex, + rate['value'], + rate['remaining'], + rate['unit'], + rate['next-available'], + ) + + +class RateLimit: """Data model that represents a flattened view of a single rate limit.""" - def __init__(self, verb, uri, regex, value, remain, - unit, next_available): + def __init__(self, verb, uri, regex, value, remain, unit, next_available): self.verb = verb self.uri = uri self.regex = regex @@ -54,19 +59,21 @@ def __init__(self, verb, uri, regex, value, remain, self.next_available = next_available def __eq__(self, other): - return (self.uri == other.uri and - self.regex == other.regex and - self.value == other.value and - self.verb == other.verb and - self.remain == other.remain and - self.unit == other.unit and - self.next_available == other.next_available) + return ( + self.uri == other.uri + and self.regex == other.regex + and self.value == other.value + and self.verb == other.verb + and self.remain == other.remain + and self.unit == other.unit + and self.next_available == other.next_available + ) def __repr__(self): - return "" % (self.verb, self.uri) + return f"" -class AbsoluteLimit(object): +class AbsoluteLimit: """Data model that represents a single absolute limit.""" def __init__(self, name, value): @@ -77,7 +84,7 @@ def __eq__(self, other): return self.value == other.value and self.name == other.name def __repr__(self): - return "" % (self.name) + return f"" class LimitsManager(base.Manager): diff --git a/manilaclient/v2/messages.py b/manilaclient/v2/messages.py index ef54250d..7b638d78 100644 --- a/manilaclient/v2/messages.py +++ b/manilaclient/v2/messages.py @@ -11,6 +11,7 @@ # under the License. """Asynchronous User Message interface.""" + from manilaclient import api_versions from manilaclient import base from manilaclient.common import constants @@ -25,7 +26,7 @@ class Message(base.Resource): NAME_ATTR = 'id' def __repr__(self): - return "" % self.id + return f"" def delete(self): """Delete this message.""" @@ -34,6 +35,7 @@ def delete(self): class MessageManager(base.ManagerWithFind): """Manage :class:`Message` resources.""" + resource_class = Message @api_versions.wraps('2.37') @@ -59,15 +61,20 @@ def list(self, search_opts=None, sort_key=None, sort_dir=None): search_opts['sort_key'] = sort_key else: raise ValueError( - 'sort_key must be one of the following: %s.' - % ', '.join(constants.MESSAGE_SORT_KEY_VALUES)) + 'sort_key must be one of the following: {}.'.format( + ', '.join(constants.MESSAGE_SORT_KEY_VALUES) + ) + ) if sort_dir is not None: if sort_dir in constants.SORT_DIR_VALUES: search_opts['sort_dir'] = sort_dir else: - raise ValueError('sort_dir must be one of the following: %s.' - % ', '.join(constants.SORT_DIR_VALUES)) + raise ValueError( + 'sort_dir must be one of the following: {}.'.format( + ', '.join(constants.SORT_DIR_VALUES) + ) + ) query_string = self._build_query_string(search_opts) diff --git a/manilaclient/v2/quota_classes.py b/manilaclient/v2/quota_classes.py index 4acc972b..338a0579 100644 --- a/manilaclient/v2/quota_classes.py +++ b/manilaclient/v2/quota_classes.py @@ -22,7 +22,6 @@ class QuotaClassSet(base.Resource): - @property def id(self): """Needed by base.Resource to self-refresh and be indexed.""" @@ -38,24 +37,28 @@ class QuotaClassSetManager(base.ManagerWithFind): @api_versions.wraps("1.0", "2.6") def get(self, class_name): return self._get( - "%(resource_path)s/%(class_name)s" % { - "resource_path": RESOURCE_PATH_LEGACY, - "class_name": class_name}, - "quota_class_set") + f"{RESOURCE_PATH_LEGACY}/{class_name}", "quota_class_set" + ) @api_versions.wraps("2.7") # noqa def get(self, class_name): # noqa - return self._get( - "%(resource_path)s/%(class_name)s" % { - "resource_path": RESOURCE_PATH, "class_name": class_name}, - "quota_class_set") - - def _do_update(self, class_name, shares=None, gigabytes=None, - snapshots=None, snapshot_gigabytes=None, - share_networks=None, share_replicas=None, - replica_gigabytes=None, per_share_gigabytes=None, - share_groups=None, share_group_snapshots=None, - resource_path=RESOURCE_PATH): + return self._get(f"{RESOURCE_PATH}/{class_name}", "quota_class_set") + + def _do_update( + self, + class_name, + shares=None, + gigabytes=None, + snapshots=None, + snapshot_gigabytes=None, + share_networks=None, + share_replicas=None, + replica_gigabytes=None, + per_share_gigabytes=None, + share_groups=None, + share_group_snapshots=None, + resource_path=RESOURCE_PATH, + ): body = { 'quota_class_set': { 'class_name': class_name, @@ -76,64 +79,126 @@ def _do_update(self, class_name, shares=None, gigabytes=None, if body['quota_class_set'][key] is None: body['quota_class_set'].pop(key) - self._update( - "%(resource_path)s/%(class_name)s" % { - "resource_path": resource_path, - "class_name": class_name}, - body) + self._update(f"{resource_path}/{class_name}", body) @api_versions.wraps("1.0", "2.6") - def update(self, class_name, shares=None, gigabytes=None, - snapshots=None, snapshot_gigabytes=None, share_networks=None): + def update( + self, + class_name, + shares=None, + gigabytes=None, + snapshots=None, + snapshot_gigabytes=None, + share_networks=None, + ): return self._do_update( - class_name, shares=shares, gigabytes=gigabytes, - snapshots=snapshots, snapshot_gigabytes=snapshot_gigabytes, - share_networks=share_networks, resource_path=RESOURCE_PATH_LEGACY) + class_name, + shares=shares, + gigabytes=gigabytes, + snapshots=snapshots, + snapshot_gigabytes=snapshot_gigabytes, + share_networks=share_networks, + resource_path=RESOURCE_PATH_LEGACY, + ) @api_versions.wraps("2.7", "2.39") # noqa - def update(self, class_name, shares=None, gigabytes=None, # noqa - snapshots=None, snapshot_gigabytes=None, share_networks=None): + def update( # noqa + self, + class_name, + shares=None, + gigabytes=None, + snapshots=None, + snapshot_gigabytes=None, + share_networks=None, + ): return self._do_update( - class_name, shares=shares, gigabytes=gigabytes, - snapshots=snapshots, snapshot_gigabytes=snapshot_gigabytes, - share_networks=share_networks, resource_path=RESOURCE_PATH) + class_name, + shares=shares, + gigabytes=gigabytes, + snapshots=snapshots, + snapshot_gigabytes=snapshot_gigabytes, + share_networks=share_networks, + resource_path=RESOURCE_PATH, + ) @api_versions.wraps("2.40", "2.52") # noqa - def update(self, class_name, shares=None, gigabytes=None, # noqa - snapshots=None, snapshot_gigabytes=None, share_networks=None, - share_groups=None, share_group_snapshots=None): + def update( # noqa + self, + class_name, + shares=None, + gigabytes=None, + snapshots=None, + snapshot_gigabytes=None, + share_networks=None, + share_groups=None, + share_group_snapshots=None, + ): return self._do_update( - class_name, shares=shares, gigabytes=gigabytes, - snapshots=snapshots, snapshot_gigabytes=snapshot_gigabytes, - share_networks=share_networks, share_groups=share_groups, + class_name, + shares=shares, + gigabytes=gigabytes, + snapshots=snapshots, + snapshot_gigabytes=snapshot_gigabytes, + share_networks=share_networks, + share_groups=share_groups, share_group_snapshots=share_group_snapshots, - resource_path=RESOURCE_PATH) + resource_path=RESOURCE_PATH, + ) @api_versions.wraps(REPLICA_QUOTAS_MICROVERSION, "2.61") # noqa - def update(self, class_name, shares=None, gigabytes=None, # noqa - snapshots=None, snapshot_gigabytes=None, share_networks=None, - share_groups=None, share_group_snapshots=None, - share_replicas=None, replica_gigabytes=None): + def update( # noqa + self, + class_name, + shares=None, + gigabytes=None, + snapshots=None, + snapshot_gigabytes=None, + share_networks=None, + share_groups=None, + share_group_snapshots=None, + share_replicas=None, + replica_gigabytes=None, + ): return self._do_update( - class_name, shares=shares, gigabytes=gigabytes, - snapshots=snapshots, snapshot_gigabytes=snapshot_gigabytes, - share_networks=share_networks, share_groups=share_groups, + class_name, + shares=shares, + gigabytes=gigabytes, + snapshots=snapshots, + snapshot_gigabytes=snapshot_gigabytes, + share_networks=share_networks, + share_groups=share_groups, share_group_snapshots=share_group_snapshots, - share_replicas=share_replicas, replica_gigabytes=replica_gigabytes, - resource_path=RESOURCE_PATH) + share_replicas=share_replicas, + replica_gigabytes=replica_gigabytes, + resource_path=RESOURCE_PATH, + ) @api_versions.wraps("2.62") # noqa - def update(self, class_name, shares=None, gigabytes=None, # noqa - snapshots=None, snapshot_gigabytes=None, share_networks=None, - share_groups=None, share_group_snapshots=None, - share_replicas=None, replica_gigabytes=None, - per_share_gigabytes=None): + def update( # noqa + self, + class_name, + shares=None, + gigabytes=None, + snapshots=None, + snapshot_gigabytes=None, + share_networks=None, + share_groups=None, + share_group_snapshots=None, + share_replicas=None, + replica_gigabytes=None, + per_share_gigabytes=None, + ): return self._do_update( - class_name, shares=shares, gigabytes=gigabytes, - snapshots=snapshots, snapshot_gigabytes=snapshot_gigabytes, - share_networks=share_networks, share_groups=share_groups, + class_name, + shares=shares, + gigabytes=gigabytes, + snapshots=snapshots, + snapshot_gigabytes=snapshot_gigabytes, + share_networks=share_networks, + share_groups=share_groups, share_group_snapshots=share_group_snapshots, share_replicas=share_replicas, replica_gigabytes=replica_gigabytes, per_share_gigabytes=per_share_gigabytes, - resource_path=RESOURCE_PATH) + resource_path=RESOURCE_PATH, + ) diff --git a/manilaclient/v2/quotas.py b/manilaclient/v2/quotas.py index 39a9745c..46bda801 100644 --- a/manilaclient/v2/quotas.py +++ b/manilaclient/v2/quotas.py @@ -22,7 +22,6 @@ class QuotaSet(base.Resource): - @property def id(self): """Needed by Resource to self-refresh and be indexed.""" @@ -39,10 +38,17 @@ def _check_user_id_and_share_type_args(self, user_id, share_type): if user_id and share_type: raise ValueError( "'user_id' and 'share_type' values are mutually exclusive. " - "one or both should be unset.") - - def _do_get(self, tenant_id, user_id=None, share_type=None, detail=False, - resource_path=RESOURCE_PATH): + "one or both should be unset." + ) + + def _do_get( + self, + tenant_id, + user_id=None, + share_type=None, + detail=False, + resource_path=RESOURCE_PATH, + ): self._check_user_id_and_share_type_args(user_id, share_type) if hasattr(tenant_id, 'tenant_id'): tenant_id = tenant_id.tenant_id @@ -53,12 +59,11 @@ def _do_get(self, tenant_id, user_id=None, share_type=None, detail=False, query = '' if user_id and share_type: - query = '%s?user_id=%s&share_type=%s' % ( - query, user_id, share_type) + query = f'{query}?user_id={user_id}&share_type={share_type}' elif user_id: - query = '%s?user_id=%s' % (query, user_id) + query = f'{query}?user_id={user_id}' elif share_type: - query = '%s?share_type=%s' % (query, share_type) + query = f'{query}?share_type={share_type}' data = { "resource_path": resource_path, "tenant_id": tenant_id, @@ -69,33 +74,49 @@ def _do_get(self, tenant_id, user_id=None, share_type=None, detail=False, @api_versions.wraps("1.0", "2.6") def get(self, tenant_id, user_id=None, detail=False): - return self._do_get(tenant_id, user_id, - resource_path=RESOURCE_PATH_LEGACY) + return self._do_get( + tenant_id, user_id, resource_path=RESOURCE_PATH_LEGACY + ) @api_versions.wraps("2.7", "2.24") # noqa def get(self, tenant_id, user_id=None, detail=False): # noqa - return self._do_get(tenant_id, user_id, - resource_path=RESOURCE_PATH) + return self._do_get(tenant_id, user_id, resource_path=RESOURCE_PATH) @api_versions.wraps("2.25", "2.38") # noqa def get(self, tenant_id, user_id=None, detail=False): # noqa - return self._do_get(tenant_id, user_id, detail=detail, - resource_path=RESOURCE_PATH) + return self._do_get( + tenant_id, user_id, detail=detail, resource_path=RESOURCE_PATH + ) @api_versions.wraps("2.39") # noqa - def get(self, tenant_id, user_id=None, share_type=None, detail=False): # noqa + def get(self, tenant_id, user_id=None, share_type=None, detail=False): # noqa return self._do_get( - tenant_id, user_id, share_type=share_type, detail=detail, - resource_path=RESOURCE_PATH) - - def _do_update(self, tenant_id, shares=None, snapshots=None, - gigabytes=None, snapshot_gigabytes=None, - share_networks=None, - force=None, user_id=None, share_type=None, - share_groups=None, share_group_snapshots=None, - share_replicas=None, replica_gigabytes=None, - per_share_gigabytes=None, encryption_keys=None, - resource_path=RESOURCE_PATH): + tenant_id, + user_id, + share_type=share_type, + detail=detail, + resource_path=RESOURCE_PATH, + ) + + def _do_update( + self, + tenant_id, + shares=None, + snapshots=None, + gigabytes=None, + snapshot_gigabytes=None, + share_networks=None, + force=None, + user_id=None, + share_type=None, + share_groups=None, + share_group_snapshots=None, + share_replicas=None, + replica_gigabytes=None, + per_share_gigabytes=None, + encryption_keys=None, + resource_path=RESOURCE_PATH, + ): self._check_user_id_and_share_type_args(user_id, share_type) body = { 'quota_set': { @@ -125,60 +146,123 @@ def _do_update(self, tenant_id, shares=None, snapshots=None, "st": share_type, } if user_id: - url = '%(resource_path)s/%(tenant_id)s?user_id=%(user_id)s' % data + url = '{resource_path}/{tenant_id}?user_id={user_id}'.format( + **data + ) elif share_type: - url = '%(resource_path)s/%(tenant_id)s?share_type=%(st)s' % data + url = '{resource_path}/{tenant_id}?share_type={st}'.format(**data) else: - url = "%(resource_path)s/%(tenant_id)s" % data + url = "{resource_path}/{tenant_id}".format(**data) return self._update(url, body, 'quota_set') @api_versions.wraps("1.0", "2.6") - def update(self, tenant_id, shares=None, snapshots=None, gigabytes=None, - snapshot_gigabytes=None, share_networks=None, force=None, - user_id=None): + def update( + self, + tenant_id, + shares=None, + snapshots=None, + gigabytes=None, + snapshot_gigabytes=None, + share_networks=None, + force=None, + user_id=None, + ): return self._do_update( - tenant_id, shares, snapshots, gigabytes, snapshot_gigabytes, - share_networks, force, user_id, resource_path=RESOURCE_PATH_LEGACY, + tenant_id, + shares, + snapshots, + gigabytes, + snapshot_gigabytes, + share_networks, + force, + user_id, + resource_path=RESOURCE_PATH_LEGACY, ) @api_versions.wraps("2.7", "2.38") # noqa - def update(self, tenant_id, shares=None, snapshots=None, gigabytes=None, # noqa - snapshot_gigabytes=None, share_networks=None, force=None, - user_id=None): + def update( # noqa + self, + tenant_id, + shares=None, + snapshots=None, + gigabytes=None, + snapshot_gigabytes=None, + share_networks=None, + force=None, + user_id=None, + ): return self._do_update( - tenant_id, shares, snapshots, gigabytes, snapshot_gigabytes, - share_networks, force, user_id, resource_path=RESOURCE_PATH, + tenant_id, + shares, + snapshots, + gigabytes, + snapshot_gigabytes, + share_networks, + force, + user_id, + resource_path=RESOURCE_PATH, ) def _validate_st_and_sn_in_same_request(self, share_type, share_networks): if share_type and share_networks: raise ValueError( "'share_networks' quota can be set only for project or user, " - "not share type.") + "not share type." + ) @api_versions.wraps("2.39", "2.39") # noqa - def update(self, tenant_id, user_id=None, share_type=None, # noqa - shares=None, snapshots=None, gigabytes=None, - snapshot_gigabytes=None, share_networks=None, force=None): + def update( # noqa + self, + tenant_id, + user_id=None, + share_type=None, + shares=None, + snapshots=None, + gigabytes=None, + snapshot_gigabytes=None, + share_networks=None, + force=None, + ): self._validate_st_and_sn_in_same_request(share_type, share_networks) return self._do_update( - tenant_id, shares, snapshots, gigabytes, snapshot_gigabytes, - share_networks, force, user_id, + tenant_id, + shares, + snapshots, + gigabytes, + snapshot_gigabytes, + share_networks, + force, + user_id, share_type=share_type, resource_path=RESOURCE_PATH, ) @api_versions.wraps("2.40", "2.52") # noqa - def update(self, tenant_id, user_id=None, share_type=None, # noqa - shares=None, snapshots=None, gigabytes=None, - snapshot_gigabytes=None, share_networks=None, - share_groups=None, share_group_snapshots=None, - force=None): + def update( # noqa + self, + tenant_id, + user_id=None, + share_type=None, + shares=None, + snapshots=None, + gigabytes=None, + snapshot_gigabytes=None, + share_networks=None, + share_groups=None, + share_group_snapshots=None, + force=None, + ): self._validate_st_and_sn_in_same_request(share_type, share_networks) return self._do_update( - tenant_id, shares, snapshots, gigabytes, snapshot_gigabytes, - share_networks, force, user_id, + tenant_id, + shares, + snapshots, + gigabytes, + snapshot_gigabytes, + share_networks, + force, + user_id, share_type=share_type, share_groups=share_groups, share_group_snapshots=share_group_snapshots, @@ -186,54 +270,106 @@ def update(self, tenant_id, user_id=None, share_type=None, # noqa ) @api_versions.wraps(REPLICA_QUOTAS_MICROVERSION, "2.61") # noqa - def update(self, tenant_id, user_id=None, share_type=None, # noqa - shares=None, snapshots=None, gigabytes=None, - snapshot_gigabytes=None, share_networks=None, - share_groups=None, share_group_snapshots=None, - share_replicas=None, replica_gigabytes=None, force=None): + def update( # noqa + self, + tenant_id, + user_id=None, + share_type=None, + shares=None, + snapshots=None, + gigabytes=None, + snapshot_gigabytes=None, + share_networks=None, + share_groups=None, + share_group_snapshots=None, + share_replicas=None, + replica_gigabytes=None, + force=None, + ): self._validate_st_and_sn_in_same_request(share_type, share_networks) return self._do_update( - tenant_id, shares, snapshots, gigabytes, snapshot_gigabytes, - share_networks, force, user_id, + tenant_id, + shares, + snapshots, + gigabytes, + snapshot_gigabytes, + share_networks, + force, + user_id, share_type=share_type, share_groups=share_groups, share_group_snapshots=share_group_snapshots, share_replicas=share_replicas, replica_gigabytes=replica_gigabytes, - resource_path=RESOURCE_PATH + resource_path=RESOURCE_PATH, ) @api_versions.wraps("2.62", "2.89") # noqa - def update(self, tenant_id, user_id=None, share_type=None, # noqa - shares=None, snapshots=None, gigabytes=None, - snapshot_gigabytes=None, share_networks=None, - share_groups=None, share_group_snapshots=None, - share_replicas=None, replica_gigabytes=None, force=None, - per_share_gigabytes=None): + def update( # noqa + self, + tenant_id, + user_id=None, + share_type=None, + shares=None, + snapshots=None, + gigabytes=None, + snapshot_gigabytes=None, + share_networks=None, + share_groups=None, + share_group_snapshots=None, + share_replicas=None, + replica_gigabytes=None, + force=None, + per_share_gigabytes=None, + ): self._validate_st_and_sn_in_same_request(share_type, share_networks) return self._do_update( - tenant_id, shares, snapshots, gigabytes, snapshot_gigabytes, - share_networks, force, user_id, + tenant_id, + shares, + snapshots, + gigabytes, + snapshot_gigabytes, + share_networks, + force, + user_id, share_type=share_type, share_groups=share_groups, share_group_snapshots=share_group_snapshots, share_replicas=share_replicas, replica_gigabytes=replica_gigabytes, per_share_gigabytes=per_share_gigabytes, - resource_path=RESOURCE_PATH + resource_path=RESOURCE_PATH, ) @api_versions.wraps("2.90") # noqa - def update(self, tenant_id, user_id=None, share_type=None, # noqa - shares=None, snapshots=None, gigabytes=None, - snapshot_gigabytes=None, share_networks=None, - share_groups=None, share_group_snapshots=None, - share_replicas=None, replica_gigabytes=None, force=None, - per_share_gigabytes=None, encryption_keys=None): + def update( # noqa + self, + tenant_id, + user_id=None, + share_type=None, + shares=None, + snapshots=None, + gigabytes=None, + snapshot_gigabytes=None, + share_networks=None, + share_groups=None, + share_group_snapshots=None, + share_replicas=None, + replica_gigabytes=None, + force=None, + per_share_gigabytes=None, + encryption_keys=None, + ): self._validate_st_and_sn_in_same_request(share_type, share_networks) return self._do_update( - tenant_id, shares, snapshots, gigabytes, snapshot_gigabytes, - share_networks, force, user_id, + tenant_id, + shares, + snapshots, + gigabytes, + snapshot_gigabytes, + share_networks, + force, + user_id, share_type=share_type, share_groups=share_groups, share_group_snapshots=share_group_snapshots, @@ -241,25 +377,26 @@ def update(self, tenant_id, user_id=None, share_type=None, # noqa replica_gigabytes=replica_gigabytes, per_share_gigabytes=per_share_gigabytes, encryption_keys=encryption_keys, - resource_path=RESOURCE_PATH + resource_path=RESOURCE_PATH, ) @api_versions.wraps("1.0", "2.6") def defaults(self, tenant_id): return self._get( - "%(resource_path)s/%(tenant_id)s/defaults" % { - "resource_path": RESOURCE_PATH_LEGACY, "tenant_id": tenant_id}, - "quota_set") + f"{RESOURCE_PATH_LEGACY}/{tenant_id}/defaults", "quota_set" + ) @api_versions.wraps("2.7") # noqa def defaults(self, tenant_id): # noqa - return self._get( - "%(resource_path)s/%(tenant_id)s/defaults" % { - "resource_path": RESOURCE_PATH, "tenant_id": tenant_id}, - "quota_set") - - def _do_delete(self, tenant_id, user_id=None, share_type=None, - resource_path=RESOURCE_PATH): + return self._get(f"{RESOURCE_PATH}/{tenant_id}/defaults", "quota_set") + + def _do_delete( + self, + tenant_id, + user_id=None, + share_type=None, + resource_path=RESOURCE_PATH, + ): self._check_user_id_and_share_type_args(user_id, share_type) data = { "resource_path": resource_path, @@ -268,23 +405,27 @@ def _do_delete(self, tenant_id, user_id=None, share_type=None, "st": share_type, } if user_id: - url = '%(resource_path)s/%(tenant_id)s?user_id=%(user_id)s' % data + url = '{resource_path}/{tenant_id}?user_id={user_id}'.format( + **data + ) elif share_type: - url = '%(resource_path)s/%(tenant_id)s?share_type=%(st)s' % data + url = '{resource_path}/{tenant_id}?share_type={st}'.format(**data) else: - url = '%(resource_path)s/%(tenant_id)s' % data + url = '{resource_path}/{tenant_id}'.format(**data) self._delete(url) @api_versions.wraps("1.0", "2.6") def delete(self, tenant_id, user_id=None): return self._do_delete( - tenant_id, user_id, resource_path=RESOURCE_PATH_LEGACY) + tenant_id, user_id, resource_path=RESOURCE_PATH_LEGACY + ) @api_versions.wraps("2.7", "2.38") # noqa def delete(self, tenant_id, user_id=None): # noqa return self._do_delete(tenant_id, user_id, resource_path=RESOURCE_PATH) @api_versions.wraps("2.39") # noqa - def delete(self, tenant_id, user_id=None, share_type=None): # noqa + def delete(self, tenant_id, user_id=None, share_type=None): # noqa return self._do_delete( - tenant_id, user_id, share_type, resource_path=RESOURCE_PATH) + tenant_id, user_id, share_type, resource_path=RESOURCE_PATH + ) diff --git a/manilaclient/v2/resource_locks.py b/manilaclient/v2/resource_locks.py index b396420f..80e8ec15 100644 --- a/manilaclient/v2/resource_locks.py +++ b/manilaclient/v2/resource_locks.py @@ -19,7 +19,7 @@ class ResourceLock(base.Resource): """Lock a share resource action from being executed""" def __repr__(self): - return "" % self.id + return f"" def delete(self): """Delete this lock.""" @@ -32,11 +32,17 @@ def update(self, **kwargs): class ResourceLockManager(base.ManagerWithFind): """Manage :class:`ResourceLock` resources.""" + resource_class = ResourceLock @api_versions.wraps(constants.RESOURCE_LOCK_VERSION) - def create(self, resource_id, resource_type, - resource_action='delete', lock_reason=None): + def create( + self, + resource_id, + resource_type, + resource_action='delete', + lock_reason=None, + ): """Creates a resource lock. :param resource_id: The ID of the resource to lock @@ -65,7 +71,7 @@ def get(self, lock_id): :param lock_id: The ID of the resource lock to display. :rtype: :class:`ResourceLock` """ - return self._get("/resource-locks/%s" % lock_id, "resource_lock") + return self._get(f"/resource-locks/{lock_id}", "resource_lock") @api_versions.wraps(constants.RESOURCE_LOCK_VERSION) def list(self, search_opts=None, sort_key=None, sort_dir=None): @@ -83,18 +89,23 @@ def list(self, search_opts=None, sort_key=None, sort_dir=None): search_opts['sort_key'] = sort_key else: raise ValueError( - 'sort_key must be one of the following: %s.' - % ', '.join(constants.RESOURCE_LOCK_SORT_KEY_VALUES)) + 'sort_key must be one of the following: {}.'.format( + ', '.join(constants.RESOURCE_LOCK_SORT_KEY_VALUES) + ) + ) sort_dir = sort_dir or 'desc' if sort_dir in constants.SORT_DIR_VALUES: search_opts['sort_dir'] = sort_dir else: - raise ValueError('sort_dir must be one of the following: %s.' - % ', '.join(constants.SORT_DIR_VALUES)) + raise ValueError( + 'sort_dir must be one of the following: {}.'.format( + ', '.join(constants.SORT_DIR_VALUES) + ) + ) query_string = self._build_query_string(search_opts) - path = "/resource-locks%s" % (query_string,) + path = f"/resource-locks{query_string}" return self._list(path, 'resource_locks') @@ -114,12 +125,12 @@ def update(self, lock, **kwargs): if 'lock_reason' in kwargs: body['resource_lock']['lock_reason'] = kwargs['lock_reason'] if 'resource_action' in kwargs: - body['resource_lock']['resource_action'] = ( - kwargs['resource_action'] - ) + body['resource_lock']['resource_action'] = kwargs[ + 'resource_action' + ] lock_id = base.getid(lock) - return self._update("/resource-locks/%s" % lock_id, body) + return self._update(f"/resource-locks/{lock_id}", body) @api_versions.wraps(constants.RESOURCE_LOCK_VERSION) def delete(self, lock): @@ -127,4 +138,4 @@ def delete(self, lock): :param lock: The :class:`ResourceLock` object, or a lock id to delete. """ - return self._delete("/resource-locks/%s" % base.getid(lock)) + return self._delete(f"/resource-locks/{base.getid(lock)}") diff --git a/manilaclient/v2/scheduler_stats.py b/manilaclient/v2/scheduler_stats.py index a6f6295e..642db840 100644 --- a/manilaclient/v2/scheduler_stats.py +++ b/manilaclient/v2/scheduler_stats.py @@ -19,13 +19,13 @@ class Pool(base.Resource): - def __repr__(self): - return "" % self.name + return f"" class PoolManager(base.Manager): """Manage :class:`Pool` resources.""" + resource_class = Pool def list(self, detailed=True, search_opts=None): @@ -35,14 +35,8 @@ def list(self, detailed=True, search_opts=None): """ query_string = self._build_query_string(search_opts) if detailed: - path = '%(resources_path)s/detail%(query)s' % { - 'resources_path': RESOURCES_PATH, - 'query': query_string - } + path = f'{RESOURCES_PATH}/detail{query_string}' else: - path = '%(resources_path)s%(query)s' % { - 'resources_path': RESOURCES_PATH, - 'query': query_string - } + path = f'{RESOURCES_PATH}{query_string}' return self._list(path, RESOURCES_NAME) diff --git a/manilaclient/v2/security_services.py b/manilaclient/v2/security_services.py index 7732a318..2f40648f 100644 --- a/manilaclient/v2/security_services.py +++ b/manilaclient/v2/security_services.py @@ -25,15 +25,16 @@ class SecurityService(base.Resource): """Security service for Manila shares.""" + def __repr__(self): - return "" % self.id + return f"" def update(self, **kwargs): """Update this security service.""" return self.manager.update(self, **kwargs) def delete(self): - """"Delete this security service.""" + """Delete this security service.""" self.manager.delete(self) @@ -43,9 +44,18 @@ class SecurityServiceManager(base.ManagerWithFind): resource_class = SecurityService @api_versions.wraps("1.0", "2.75") - def create(self, type, dns_ip=None, ou=None, server=None, domain=None, - user=None, password=None, name=None, - description=None): + def create( + self, + type, + dns_ip=None, + ou=None, + server=None, + domain=None, + user=None, + password=None, + name=None, + description=None, + ): """Create security service for NAS. :param type: security service type - 'ldap', 'kerberos' or @@ -60,16 +70,32 @@ def create(self, type, dns_ip=None, ou=None, server=None, domain=None, :param description: security service description :rtype: :class:`SecurityService` """ - return self._create_security_service(type, dns_ip=dns_ip, ou=ou, - server=server, domain=domain, - user=user, password=password, - name=name, - description=description) + return self._create_security_service( + type, + dns_ip=dns_ip, + ou=ou, + server=server, + domain=domain, + user=user, + password=password, + name=name, + description=description, + ) @api_versions.wraps("2.76") # noqa - def create(self, type, dns_ip=None, ou=None, server=None, # noqa - domain=None, user=None, password=None, name=None, - description=None, default_ad_site=None): + def create( # noqa + self, + type, + dns_ip=None, + ou=None, + server=None, + domain=None, + user=None, + password=None, + name=None, + description=None, + default_ad_site=None, + ): """Create security service for NAS. :param type: security service type - 'ldap', 'kerberos' or @@ -85,17 +111,32 @@ def create(self, type, dns_ip=None, ou=None, server=None, # noqa :param default_ad_site: default AD-Site :rtype: :class:`SecurityService` """ - return self._create_security_service(type, dns_ip=dns_ip, ou=ou, - server=server, domain=domain, - user=user, password=password, - name=name, - description=description, - default_ad_site=default_ad_site) - - def _create_security_service(self, type, dns_ip=None, ou=None, - server=None, domain=None, user=None, - password=None, name=None, - description=None, default_ad_site=None): + return self._create_security_service( + type, + dns_ip=dns_ip, + ou=ou, + server=server, + domain=domain, + user=user, + password=password, + name=name, + description=description, + default_ad_site=default_ad_site, + ) + + def _create_security_service( + self, + type, + dns_ip=None, + ou=None, + server=None, + domain=None, + user=None, + password=None, + name=None, + description=None, + default_ad_site=None, + ): values = {'type': type} if dns_ip: values['dns_ip'] = dns_ip @@ -132,9 +173,18 @@ def get(self, security_service): ) @api_versions.wraps("1.0", "2.75") - def update(self, security_service, dns_ip=None, ou=None, server=None, - domain=None, password=None, user=None, name=None, - description=None): + def update( + self, + security_service, + dns_ip=None, + ou=None, + server=None, + domain=None, + password=None, + user=None, + name=None, + description=None, + ): """Updates a security service. :param security_service: security service to update. @@ -148,16 +198,32 @@ def update(self, security_service, dns_ip=None, ou=None, server=None, :param description: security service description :rtype: :class:`SecurityService` """ - return self._update_security_service(security_service, dns_ip=dns_ip, - ou=ou, server=server, - domain=domain, password=password, - user=user, name=name, - description=description) + return self._update_security_service( + security_service, + dns_ip=dns_ip, + ou=ou, + server=server, + domain=domain, + password=password, + user=user, + name=name, + description=description, + ) @api_versions.wraps("2.76") # noqa - def update(self, security_service, dns_ip=None, ou=None, # noqa - server=None, domain=None, password=None, user=None, - name=None, description=None, default_ad_site=None): + def update( # noqa + self, + security_service, + dns_ip=None, + ou=None, + server=None, + domain=None, + password=None, + user=None, + name=None, + description=None, + default_ad_site=None, + ): """Updates a security service. :param security_service: security service to update. @@ -172,17 +238,32 @@ def update(self, security_service, dns_ip=None, ou=None, # noqa :param default_ad_site: default AD-Site :rtype: :class:`SecurityService` """ - return self._update_security_service(security_service, dns_ip=dns_ip, - ou=ou, server=server, - domain=domain, password=password, - user=user, name=name, - description=description, - default_ad_site=default_ad_site) - - def _update_security_service(self, security_service, dns_ip=None, ou=None, - server=None, domain=None, password=None, - user=None, name=None, description=None, - default_ad_site=None): + return self._update_security_service( + security_service, + dns_ip=dns_ip, + ou=ou, + server=server, + domain=domain, + password=password, + user=user, + name=name, + description=description, + default_ad_site=default_ad_site, + ) + + def _update_security_service( + self, + security_service, + dns_ip=None, + ou=None, + server=None, + domain=None, + password=None, + user=None, + name=None, + description=None, + default_ad_site=None, + ): values = {} if dns_ip is not None: values['dns_ip'] = dns_ip diff --git a/manilaclient/v2/services.py b/manilaclient/v2/services.py index 0fd288c3..4d7922ba 100644 --- a/manilaclient/v2/services.py +++ b/manilaclient/v2/services.py @@ -22,9 +22,8 @@ class Service(base.Resource): - def __repr__(self): - return "" % self.id + return f"" def server_api_version(self, **kwargs): """Get api version.""" @@ -33,6 +32,7 @@ def server_api_version(self, **kwargs): class ServiceManager(base.Manager): """Manage :class:`Service` resources.""" + resource_class = Service def _do_list(self, search_opts=None, resource_path=RESOURCE_PATH): @@ -46,17 +46,19 @@ def _do_list(self, search_opts=None, resource_path=RESOURCE_PATH): @api_versions.wraps("1.0", "2.6") def list(self, search_opts=None): return self._do_list( - search_opts=search_opts, resource_path=RESOURCE_PATH_LEGACY) + search_opts=search_opts, resource_path=RESOURCE_PATH_LEGACY + ) @api_versions.wraps("2.7") # noqa def list(self, search_opts=None): # noqa return self._do_list( - search_opts=search_opts, resource_path=RESOURCE_PATH) + search_opts=search_opts, resource_path=RESOURCE_PATH + ) def _do_enable(self, host, binary, resource_path=RESOURCE_PATH): """Enable the service specified by hostname and binary.""" body = {"host": host, "binary": binary} - return self._update("%s/enable" % resource_path, body) + return self._update(f"{resource_path}/enable", body) @api_versions.wraps("1.0", "2.6") def enable(self, host, binary): @@ -66,13 +68,14 @@ def enable(self, host, binary): def enable(self, host, binary): # noqa return self._do_enable(host, binary, RESOURCE_PATH) - def _do_disable(self, host, binary, resource_path=RESOURCE_PATH, - disable_reason=None): + def _do_disable( + self, host, binary, resource_path=RESOURCE_PATH, disable_reason=None + ): """Disable the service specified by hostname and binary.""" body = {"host": host, "binary": binary} if disable_reason: body["disabled_reason"] = disable_reason - return self._update("%s/disable" % resource_path, body) + return self._update(f"{resource_path}/disable", body) @api_versions.wraps("1.0", "2.6") def disable(self, host, binary): @@ -84,8 +87,9 @@ def disable(self, host, binary): # noqa @api_versions.wraps("2.83") # noqa def disable(self, host, binary, disable_reason=None): # noqa - return self._do_disable(host, binary, RESOURCE_PATH, - disable_reason=disable_reason) + return self._do_disable( + host, binary, RESOURCE_PATH, disable_reason=disable_reason + ) @api_versions.wraps("2.86") def ensure_shares(self, host): # noqa diff --git a/manilaclient/v2/share_access_rules.py b/manilaclient/v2/share_access_rules.py index 2f68f5ac..47053084 100644 --- a/manilaclient/v2/share_access_rules.py +++ b/manilaclient/v2/share_access_rules.py @@ -32,10 +32,10 @@ class ShareAccessRule(base.Resource): """A Share Access Rule.""" def __repr__(self): - return "" % self.id + return f"" def delete(self): - """"Delete this share access rule.""" + """Delete this share access rule.""" self.manager.delete(self) @@ -87,11 +87,7 @@ def set_access_level(self, access, access_level): :param access: either share access rule object or text with its ID. :param access_level: value of access_level (e.g. ro/rw) """ - body = { - 'update_access': { - 'access_level': access_level - } - } + body = {'update_access': {'access_level': access_level}} access_id = base.getid(access) url = RESOURCE_PATH % access_id return self._update(url, body) diff --git a/manilaclient/v2/share_backups.py b/manilaclient/v2/share_backups.py index 9714dbda..64ff36d4 100644 --- a/manilaclient/v2/share_backups.py +++ b/manilaclient/v2/share_backups.py @@ -23,11 +23,12 @@ class ShareBackup(base.Resource): def __repr__(self): - return "" % self.id + return f"" class ShareBackupManager(base.ManagerWithFind): """Manage :class:`ShareBackup` resources.""" + resource_class = ShareBackup @api_versions.wraps("2.80") @@ -43,8 +44,9 @@ def get(self, backup): @api_versions.wraps("2.80") @api_versions.experimental_api - def list(self, detailed=True, search_opts=None, sort_key=None, - sort_dir=None): + def list( + self, detailed=True, search_opts=None, sort_key=None, sort_dir=None + ): """List all share backups or list backups belonging to a share. :param detailed: list backups with detailed fields. @@ -61,22 +63,26 @@ def list(self, detailed=True, search_opts=None, sort_key=None, search_opts['sort_key'] = sort_key else: raise ValueError( - 'sort_key must be one of the following: %s.' - % ', '.join(constants.BACKUP_SORT_KEY_VALUES)) + 'sort_key must be one of the following: {}.'.format( + ', '.join(constants.BACKUP_SORT_KEY_VALUES) + ) + ) if sort_dir is not None: if sort_dir in constants.SORT_DIR_VALUES: search_opts['sort_dir'] = sort_dir else: raise ValueError( - 'sort_dir must be one of the following: %s.' - % ', '.join(constants.SORT_DIR_VALUES)) + 'sort_dir must be one of the following: {}.'.format( + ', '.join(constants.SORT_DIR_VALUES) + ) + ) query_string = self._build_query_string(search_opts) if detailed: - path = "/share-backups/detail%s" % (query_string,) + path = f"/share-backups/detail{query_string}" else: - path = "/share-backups%s" % (query_string,) + path = f"/share-backups{query_string}" return self._list(path, 'share_backups') @@ -99,9 +105,9 @@ def create(self, share, backup_options=None, description=None, name=None): 'name': name, } - return self._create(RESOURCES_PATH, - {RESOURCE_NAME: body}, - RESOURCE_NAME) + return self._create( + RESOURCES_PATH, {RESOURCE_NAME: body}, RESOURCE_NAME + ) @api_versions.wraps("2.80") @api_versions.experimental_api @@ -117,7 +123,7 @@ def restore(self, backup_id): @api_versions.wraps("2.91") @api_versions.experimental_api - def restore(self, backup_id, target_share_id=None): # noqa F811 + def restore(self, backup_id, target_share_id=None): # noqa F811 return self._action('restore', backup_id, info=target_share_id) @api_versions.wraps("2.80") diff --git a/manilaclient/v2/share_export_locations.py b/manilaclient/v2/share_export_locations.py index ed716aa9..fa9b6263 100644 --- a/manilaclient/v2/share_export_locations.py +++ b/manilaclient/v2/share_export_locations.py @@ -21,7 +21,7 @@ class ShareExportLocation(base.Resource): """Resource class for a share export location.""" def __repr__(self): - return "" % self.id + return f"" def __getitem__(self, key): return self._info[key] @@ -29,6 +29,7 @@ def __getitem__(self, key): class ShareExportLocationManager(base.MetadataCapableManager): """Manage :class:`ShareExportLocation` resources.""" + resource_class = ShareExportLocation resource_path = '/shares' subresource_path = '/export_locations' @@ -37,8 +38,9 @@ class ShareExportLocationManager(base.MetadataCapableManager): def list(self, share, search_opts=None): """List all share export locations.""" share_id = base.getid(share) - return self._list("/shares/%s/export_locations" % share_id, - "export_locations") + return self._list( + f"/shares/{share_id}/export_locations", "export_locations" + ) @api_versions.wraps("2.9") def get(self, share, export_location): @@ -46,26 +48,26 @@ def get(self, share, export_location): share_id = base.getid(share) export_location_id = base.getid(export_location) return self._get( - "/shares/%(share_id)s/export_locations/%(export_location_id)s" % { - "share_id": share_id, - "export_location_id": export_location_id}, "export_location") + f"/shares/{share_id}/export_locations/{export_location_id}", + "export_location", + ) @api_versions.wraps('2.87') def get_metadata(self, share, share_export_location): - return super(ShareExportLocationManager, self).get_metadata( - share, subresource=share_export_location) + return super().get_metadata(share, subresource=share_export_location) @api_versions.wraps('2.87') def set_metadata(self, resource, metadata, subresource=None): - return super(ShareExportLocationManager, self).set_metadata( - resource, metadata, subresource=subresource) + return super().set_metadata( + resource, metadata, subresource=subresource + ) @api_versions.wraps('2.87') def delete_metadata(self, resource, keys, subresource=None): - return super(ShareExportLocationManager, self).delete_metadata( - resource, keys, subresource=subresource) + return super().delete_metadata(resource, keys, subresource=subresource) @api_versions.wraps('2.87') def update_all_metadata(self, resource, metadata, subresource=None): - return super(ShareExportLocationManager, self).update_all_metadata( - resource, metadata, subresource=subresource) + return super().update_all_metadata( + resource, metadata, subresource=subresource + ) diff --git a/manilaclient/v2/share_group_snapshots.py b/manilaclient/v2/share_group_snapshots.py index 52c1da97..5daee374 100644 --- a/manilaclient/v2/share_group_snapshots.py +++ b/manilaclient/v2/share_group_snapshots.py @@ -30,7 +30,7 @@ class ShareGroupSnapshot(base.Resource): """A snapshot of a share group.""" def __repr__(self): - return "" % self.id + return f"" def update(self, **kwargs): """Update this share group snapshot.""" @@ -47,10 +47,12 @@ def reset_state(self, state): class ShareGroupSnapshotManager(base.ManagerWithFind): """Manage :class:`ShareGroupSnapshot` resources.""" + resource_class = ShareGroupSnapshot - def _create_share_group_snapshot(self, share_group, name=None, - description=None): + def _create_share_group_snapshot( + self, share_group, name=None, description=None + ): """Create a share group snapshot. :param share_group: either ShareGroup object or text with its UUID @@ -66,18 +68,21 @@ def _create_share_group_snapshot(self, share_group, name=None, body['description'] = description return self._create( - RESOURCES_PATH, {RESOURCE_NAME: body}, RESOURCE_NAME) + RESOURCES_PATH, {RESOURCE_NAME: body}, RESOURCE_NAME + ) @api_versions.wraps("2.31", "2.54") @api_versions.experimental_api def create(self, share_group, name=None, description=None): - return self._create_share_group_snapshot(share_group, name, - description) + return self._create_share_group_snapshot( + share_group, name, description + ) @api_versions.wraps(SG_GRADUATION_VERSION) # noqa def create(self, share_group, name=None, description=None): # noqa - return self._create_share_group_snapshot(share_group, name, - description) + return self._create_share_group_snapshot( + share_group, name, description + ) def _get_share_group_snapshot(self, share_group_snapshot): """Get a share group snapshot. @@ -99,8 +104,9 @@ def get(self, share_group_snapshot): def get(self, share_group_snapshot): # noqa return self._get_share_group_snapshot(share_group_snapshot) - def _list_share_group_snapshots(self, detailed=True, search_opts=None, - sort_key=None, sort_dir=None): + def _list_share_group_snapshots( + self, detailed=True, search_opts=None, sort_key=None, sort_dir=None + ): """Get a list of all share group snapshots. :param detailed: Whether to return detailed snapshot info or not. @@ -125,15 +131,19 @@ def _list_share_group_snapshots(self, detailed=True, search_opts=None, else: msg = 'sort_key must be one of the following: %s.' msg_args = ', '.join( - constants.SHARE_GROUP_SNAPSHOT_SORT_KEY_VALUES) + constants.SHARE_GROUP_SNAPSHOT_SORT_KEY_VALUES + ) raise ValueError(msg % msg_args) if sort_dir is not None: if sort_dir in constants.SORT_DIR_VALUES: search_opts['sort_dir'] = sort_dir else: - raise ValueError('sort_dir must be one of the following: %s.' - % ', '.join(constants.SORT_DIR_VALUES)) + raise ValueError( + 'sort_dir must be one of the following: {}.'.format( + ', '.join(constants.SORT_DIR_VALUES) + ) + ) query_string = self._build_query_string(search_opts) @@ -146,18 +156,30 @@ def _list_share_group_snapshots(self, detailed=True, search_opts=None, @api_versions.wraps("2.31", "2.54") @api_versions.experimental_api - def list(self, detailed=True, search_opts=None, - sort_key=None, sort_dir=None): + def list( + self, detailed=True, search_opts=None, sort_key=None, sort_dir=None + ): return self._list_share_group_snapshots( - detailed=detailed, search_opts=search_opts, - sort_key=sort_key, sort_dir=sort_dir) + detailed=detailed, + search_opts=search_opts, + sort_key=sort_key, + sort_dir=sort_dir, + ) @api_versions.wraps(SG_GRADUATION_VERSION) # noqa - def list(self, detailed=True, search_opts=None, # noqa - sort_key=None, sort_dir=None): + def list( # noqa + self, + detailed=True, + search_opts=None, + sort_key=None, + sort_dir=None, + ): return self._list_share_group_snapshots( - detailed=detailed, search_opts=search_opts, - sort_key=sort_key, sort_dir=sort_dir) + detailed=detailed, + search_opts=search_opts, + sort_key=sort_key, + sort_dir=sort_dir, + ) def _update_share_group_snapshot(self, share_group_snapshot, **kwargs): """Updates a share group snapshot. @@ -177,13 +199,15 @@ def _update_share_group_snapshot(self, share_group_snapshot, **kwargs): @api_versions.wraps("2.31", "2.54") @api_versions.experimental_api def update(self, share_group_snapshot, **kwargs): - return self._update_share_group_snapshot(share_group_snapshot, - **kwargs) + return self._update_share_group_snapshot( + share_group_snapshot, **kwargs + ) @api_versions.wraps(SG_GRADUATION_VERSION) # noqa def update(self, share_group_snapshot, **kwargs): # noqa - return self._update_share_group_snapshot(share_group_snapshot, - **kwargs) + return self._update_share_group_snapshot( + share_group_snapshot, **kwargs + ) def _delete_share_group_snapshot(self, share_group_snapshot, force=False): """Delete a share group snapshot. @@ -228,5 +252,5 @@ def reset_state(self, share_group_snapshot, state): self._share_group_snapshot_reset_state(share_group_snapshot, state) @api_versions.wraps(SG_GRADUATION_VERSION) # noqa - def reset_state(self, share_group_snapshot, state): # noqa + def reset_state(self, share_group_snapshot, state): # noqa self._share_group_snapshot_reset_state(share_group_snapshot, state) diff --git a/manilaclient/v2/share_group_type_access.py b/manilaclient/v2/share_group_type_access.py index de409145..85cce7c0 100644 --- a/manilaclient/v2/share_group_type_access.py +++ b/manilaclient/v2/share_group_type_access.py @@ -25,15 +25,17 @@ class ShareGroupTypeAccess(base.Resource): def __repr__(self): - return "" % self.share_group_type_id + return f"" class ShareGroupTypeAccessManager(base.ManagerWithFind): """Manage :class:`ShareGroupTypeAccess` resources.""" + resource_class = ShareGroupTypeAccess - def _list_share_group_type_access(self, share_group_type, - search_opts=None): + def _list_share_group_type_access( + self, share_group_type, search_opts=None + ): if share_group_type.is_public: return None share_group_type_id = base.getid(share_group_type) @@ -43,13 +45,15 @@ def _list_share_group_type_access(self, share_group_type, @api_versions.wraps("2.31", "2.54") @api_versions.experimental_api def list(self, share_group_type, search_opts=None): - return self._list_share_group_type_access(share_group_type, - search_opts) + return self._list_share_group_type_access( + share_group_type, search_opts + ) @api_versions.wraps(SG_GRADUATION_VERSION) # noqa def list(self, share_group_type, search_opts=None): # noqa - return self._list_share_group_type_access(share_group_type, - search_opts) + return self._list_share_group_type_access( + share_group_type, search_opts + ) @api_versions.wraps("2.31", "2.54") @api_versions.experimental_api diff --git a/manilaclient/v2/share_group_types.py b/manilaclient/v2/share_group_types.py index f1bdd15c..2fe5f24d 100644 --- a/manilaclient/v2/share_group_types.py +++ b/manilaclient/v2/share_group_types.py @@ -33,11 +33,11 @@ class ShareGroupType(base.Resource): """A Share Group Type is the type of share group to be created.""" def __init__(self, manager, info, loaded=False): - super(ShareGroupType, self).__init__(manager, info, loaded) + super().__init__(manager, info, loaded) self._group_specs = info.get(GROUP_SPECS_RESOURCES_NAME, {}) def __repr__(self): - return "" % self.name + return f"" @property def is_public(self): @@ -71,7 +71,8 @@ def set_keys(self, group_specs): url = GROUP_SPECS_RESOURCES_PATH % share_group_type_id body = {GROUP_SPECS_RESOURCES_NAME: group_specs} return self.manager._create( - url, body, GROUP_SPECS_RESOURCES_NAME, return_raw=True) + url, body, GROUP_SPECS_RESOURCES_NAME, return_raw=True + ) def unset_keys(self, keys): """Unset group specs on a share group type. @@ -89,10 +90,12 @@ def unset_keys(self, keys): class ShareGroupTypeManager(base.ManagerWithFind): """Manage :class:`ShareGroupType` resources.""" + resource_class = ShareGroupType - def _create_share_group_type(self, name, share_types, is_public=False, - group_specs=None): + def _create_share_group_type( + self, name, share_types, is_public=False, group_specs=None + ): """Create a share group type. :param name: Descriptive name of the share group type @@ -103,28 +106,34 @@ def _create_share_group_type(self, name, share_types, is_public=False, :rtype: :class:`ShareGroupType` """ if not share_types: - raise ValueError('At least one share type must be specified when ' - 'creating a share group type.') + raise ValueError( + 'At least one share type must be specified when ' + 'creating a share group type.' + ) body = { 'name': name, 'is_public': is_public, 'group_specs': group_specs or {}, - 'share_types': [base.getid(share_type) - for share_type in share_types], + 'share_types': [ + base.getid(share_type) for share_type in share_types + ], } return self._create( - RESOURCES_PATH, {RESOURCE_NAME: body}, RESOURCE_NAME) + RESOURCES_PATH, {RESOURCE_NAME: body}, RESOURCE_NAME + ) @api_versions.wraps("2.31", "2.54") @api_versions.experimental_api def create(self, name, share_types, is_public=False, group_specs=None): - return self._create_share_group_type(name, share_types, is_public, - group_specs) + return self._create_share_group_type( + name, share_types, is_public, group_specs + ) @api_versions.wraps(SG_GRADUATION_VERSION) # noqa def create(self, name, share_types, is_public=False, group_specs=None): # noqa - return self._create_share_group_type(name, share_types, is_public, - group_specs) + return self._create_share_group_type( + name, share_types, is_public, group_specs + ) def _get_share_group_type(self, share_group_type="default"): """Get a specific share group type. diff --git a/manilaclient/v2/share_groups.py b/manilaclient/v2/share_groups.py index 3cb85352..e5903bd1 100644 --- a/manilaclient/v2/share_groups.py +++ b/manilaclient/v2/share_groups.py @@ -31,7 +31,7 @@ class ShareGroup(base.Resource): """A share group is a logical grouping of shares on a single backend.""" def __repr__(self): - return "" % self.id + return f"" def update(self, **kwargs): """Update this share group.""" @@ -48,12 +48,19 @@ def reset_state(self, state): class ShareGroupManager(base.ManagerWithFind): """Manage :class:`ShareGroup` resources.""" + resource_class = ShareGroup def _create_share_group( - self, share_group_type=None, share_types=None, share_network=None, - name=None, description=None, source_share_group_snapshot=None, - availability_zone=None): + self, + share_group_type=None, + share_types=None, + share_network=None, + name=None, + description=None, + source_share_group_snapshot=None, + availability_zone=None, + ): """Create a Share Group. :param share_group_type: either instance of ShareGroupType or text @@ -75,8 +82,10 @@ def _create_share_group( """ if share_types and source_share_group_snapshot: - raise ValueError('Cannot specify a share group with both' - 'share_types and source_share_group_snapshot.') + raise ValueError( + 'Cannot specify a share group with both' + 'share_types and source_share_group_snapshot.' + ) body = {} @@ -93,34 +102,59 @@ def _create_share_group( if source_share_group_snapshot: body['source_share_group_snapshot_id'] = base.getid( - source_share_group_snapshot) + source_share_group_snapshot + ) elif share_types: - body['share_types'] = [base.getid(share_type) - for share_type in share_types] + body['share_types'] = [ + base.getid(share_type) for share_type in share_types + ] return self._create( - RESOURCES_PATH, {RESOURCE_NAME: body}, RESOURCE_NAME) + RESOURCES_PATH, {RESOURCE_NAME: body}, RESOURCE_NAME + ) @api_versions.wraps("2.31", "2.54") @api_versions.experimental_api - def create(self, share_group_type=None, share_types=None, - share_network=None, name=None, description=None, - source_share_group_snapshot=None, availability_zone=None): + def create( + self, + share_group_type=None, + share_types=None, + share_network=None, + name=None, + description=None, + source_share_group_snapshot=None, + availability_zone=None, + ): return self._create_share_group( - share_group_type=share_group_type, share_types=share_types, - share_network=share_network, name=name, description=description, + share_group_type=share_group_type, + share_types=share_types, + share_network=share_network, + name=name, + description=description, source_share_group_snapshot=source_share_group_snapshot, - availability_zone=availability_zone) + availability_zone=availability_zone, + ) @api_versions.wraps(SG_GRADUATION_VERSION) # noqa - def create(self, share_group_type=None, share_types=None, # noqa - share_network=None, name=None, description=None, - source_share_group_snapshot=None, availability_zone=None): + def create( # noqa + self, + share_group_type=None, + share_types=None, + share_network=None, + name=None, + description=None, + source_share_group_snapshot=None, + availability_zone=None, + ): return self._create_share_group( - share_group_type=share_group_type, share_types=share_types, - share_network=share_network, name=name, description=description, + share_group_type=share_group_type, + share_types=share_types, + share_network=share_network, + name=name, + description=description, source_share_group_snapshot=source_share_group_snapshot, - availability_zone=availability_zone) + availability_zone=availability_zone, + ) def _get_share_group(self, share_group): """Get a share group. @@ -141,8 +175,9 @@ def get(self, share_group): def get(self, share_group): # noqa return self._get_share_group(share_group) - def _list_share_groups(self, detailed=True, search_opts=None, - sort_key=None, sort_dir=None): + def _list_share_groups( + self, detailed=True, search_opts=None, sort_key=None, sort_dir=None + ): """Get a list of all share groups. :param detailed: Whether to return detailed share group info or not. @@ -183,8 +218,11 @@ def _list_share_groups(self, detailed=True, search_opts=None, if sort_dir in constants.SORT_DIR_VALUES: search_opts['sort_dir'] = sort_dir else: - raise ValueError('sort_dir must be one of the following: %s.' - % ', '.join(constants.SORT_DIR_VALUES)) + raise ValueError( + 'sort_dir must be one of the following: {}.'.format( + ', '.join(constants.SORT_DIR_VALUES) + ) + ) query_string = self._build_query_string(search_opts) @@ -197,18 +235,30 @@ def _list_share_groups(self, detailed=True, search_opts=None, @api_versions.wraps("2.31", "2.54") @api_versions.experimental_api - def list(self, detailed=True, search_opts=None, - sort_key=None, sort_dir=None): + def list( + self, detailed=True, search_opts=None, sort_key=None, sort_dir=None + ): return self._list_share_groups( - detailed=detailed, search_opts=search_opts, - sort_key=sort_key, sort_dir=sort_dir) + detailed=detailed, + search_opts=search_opts, + sort_key=sort_key, + sort_dir=sort_dir, + ) @api_versions.wraps(SG_GRADUATION_VERSION) # noqa - def list(self, detailed=True, search_opts=None, # noqa - sort_key=None, sort_dir=None): + def list( # noqa + self, + detailed=True, + search_opts=None, + sort_key=None, + sort_dir=None, + ): return self._list_share_groups( - detailed=detailed, search_opts=search_opts, sort_key=sort_key, - sort_dir=sort_dir) + detailed=detailed, + search_opts=search_opts, + sort_key=sort_key, + sort_dir=sort_dir, + ) def _update_share_group(self, share_group, **kwargs): """Updates a share group. diff --git a/manilaclient/v2/share_instance_export_locations.py b/manilaclient/v2/share_instance_export_locations.py index 783d1a92..00214e4e 100644 --- a/manilaclient/v2/share_instance_export_locations.py +++ b/manilaclient/v2/share_instance_export_locations.py @@ -21,7 +21,7 @@ class ShareInstanceExportLocation(base.Resource): """Resource class for a share export location.""" def __repr__(self): - return "" % self.id + return f"" def __getitem__(self, key): return self._info[key] @@ -29,6 +29,7 @@ def __getitem__(self, key): class ShareInstanceExportLocationManager(base.ManagerWithFind): """Manage :class:`ShareInstanceExportLocation` resources.""" + resource_class = ShareInstanceExportLocation @api_versions.wraps("2.9") @@ -36,8 +37,9 @@ def list(self, share_instance, search_opts=None): """List all share export locations.""" share_instance_id = base.getid(share_instance) return self._list( - "/share_instances/%s/export_locations" % share_instance_id, - "export_locations") + f"/share_instances/{share_instance_id}/export_locations", + "export_locations", + ) @api_versions.wraps("2.9") def get(self, share_instance, export_location): @@ -45,9 +47,9 @@ def get(self, share_instance, export_location): share_instance_id = base.getid(share_instance) export_location_id = base.getid(export_location) return self._get( - ("/share_instances/%(share_instance_id)s/export_locations/" - "%(export_location_id)s") % { - "share_instance_id": share_instance_id, - "export_location_id": export_location_id, - }, - "export_location") + ( + f"/share_instances/{share_instance_id}/export_locations/" + f"{export_location_id}" + ), + "export_location", + ) diff --git a/manilaclient/v2/share_instances.py b/manilaclient/v2/share_instances.py index f248e3a3..92f6dc0e 100644 --- a/manilaclient/v2/share_instances.py +++ b/manilaclient/v2/share_instances.py @@ -21,8 +21,9 @@ class ShareInstance(base.Resource): """A share is an extra block level storage to the OpenStack instances.""" + def __repr__(self): - return "" % self.id + return f"" def force_delete(self): """Delete the specified share ignoring its current state.""" @@ -35,6 +36,7 @@ def reset_state(self, state): class ShareInstanceManager(base.ManagerWithFind): """Manage :class:`ShareInstances` resources.""" + resource_class = ShareInstance @api_versions.wraps("2.3") @@ -45,14 +47,14 @@ def get(self, instance): :rtype: :class:`ShareInstance` """ share_id = base.getid(instance) - return self._get("/share_instances/%s" % share_id, "share_instance") + return self._get(f"/share_instances/{share_id}", "share_instance") @api_versions.wraps("2.3", "2.34") def list(self, search_opts=None): """List all share instances.""" return self.do_list() - @api_versions.wraps("2.35") # noqa + @api_versions.wraps("2.35") # noqa def list(self, export_location=None, search_opts=None): # noqa """List all share instances.""" return self.do_list(export_location) @@ -78,7 +80,7 @@ def _action(self, action, instance, info=None, **kwargs): """ body = {action: info} self.run_hooks('modify_body_for_action', body, **kwargs) - url = '/share_instances/%s/action' % base.getid(instance) + url = f'/share_instances/{base.getid(instance)}/action' return self.api.client.post(url, body=body) def _do_force_delete(self, instance, action_name="force_delete"): diff --git a/manilaclient/v2/share_network_subnets.py b/manilaclient/v2/share_network_subnets.py index d1679e94..1acb1b9c 100644 --- a/manilaclient/v2/share_network_subnets.py +++ b/manilaclient/v2/share_network_subnets.py @@ -23,8 +23,9 @@ class ShareNetworkSubnet(base.MetadataCapableResource): """Network subnet info for Manila share networks.""" + def __repr__(self): - return "" % self.id + return f"" def __getitem__(self, key): return self._info[key] @@ -41,9 +42,14 @@ class ShareNetworkSubnetManager(base.MetadataCapableManager): resource_path = '/share-networks' subresource_path = '/subnets' - def _do_create(self, neutron_net_id=None, neutron_subnet_id=None, - availability_zone=None, share_network_id=None, - metadata=None): + def _do_create( + self, + neutron_net_id=None, + neutron_subnet_id=None, + availability_zone=None, + share_network_id=None, + metadata=None, + ): """Create share network subnet. :param neutron_net_id: ID of Neutron network @@ -63,23 +69,41 @@ def _do_create(self, neutron_net_id=None, neutron_subnet_id=None, values['metadata'] = metadata body = {'share-network-subnet': values} - url = '/share-networks/%(share_network_id)s/subnets' % { - 'share_network_id': share_network_id - } + url = f'/share-networks/{share_network_id}/subnets' return self._create(url, body, RESOURCE_NAME) @api_versions.wraps("2.0", "2.77") - def create(self, neutron_net_id=None, neutron_subnet_id=None, - availability_zone=None, share_network_id=None): - return self._do_create(neutron_net_id, neutron_subnet_id, - availability_zone, share_network_id) + def create( + self, + neutron_net_id=None, + neutron_subnet_id=None, + availability_zone=None, + share_network_id=None, + ): + return self._do_create( + neutron_net_id, + neutron_subnet_id, + availability_zone, + share_network_id, + ) @api_versions.wraps("2.78") - def create(self, neutron_net_id=None, neutron_subnet_id=None, # noqa F811 - availability_zone=None, share_network_id=None, metadata=None): - return self._do_create(neutron_net_id, neutron_subnet_id, - availability_zone, share_network_id, metadata) + def create( # noqa + self, + neutron_net_id=None, + neutron_subnet_id=None, + availability_zone=None, + share_network_id=None, + metadata=None, + ): + return self._do_create( + neutron_net_id, + neutron_subnet_id, + availability_zone, + share_network_id, + metadata, + ) def get(self, share_network, share_network_subnet): """Get a share network subnet. @@ -89,11 +113,10 @@ def get(self, share_network, share_network_subnet): """ share_network_id = base.getid(share_network) share_network_subnet_id = base.getid(share_network_subnet) - url = ('/share-networks/%(share_network_id)s/subnets' - '/%(share_network_subnet)s') % { - 'share_network_id': share_network_id, - 'share_network_subnet': share_network_subnet_id - } + url = ( + f'/share-networks/{share_network_id}/subnets' + f'/{share_network_subnet_id}' + ) return self._get(url, "share_network_subnet") def delete(self, share_network, share_network_subnet): @@ -102,29 +125,30 @@ def delete(self, share_network, share_network_subnet): :param share_network: share network that owns the subnet. :param share_network_subnet: share network subnet to be deleted. """ - url = ('/share-networks/%(share_network_id)s/subnets' - '/%(share_network_subnet)s') % { - 'share_network_id': base.getid(share_network), - 'share_network_subnet': share_network_subnet - } + url = ( + f'/share-networks/{base.getid(share_network)}/subnets' + f'/{share_network_subnet}' + ) self._delete(url) @api_versions.wraps('2.78') def get_metadata(self, share_network, share_network_subnet): - return super(ShareNetworkSubnetManager, self).get_metadata( - share_network, subresource=share_network_subnet) + return super().get_metadata( + share_network, subresource=share_network_subnet + ) @api_versions.wraps('2.78') def set_metadata(self, resource, metadata, subresource=None): - return super(ShareNetworkSubnetManager, self).set_metadata( - resource, metadata, subresource=subresource) + return super().set_metadata( + resource, metadata, subresource=subresource + ) @api_versions.wraps('2.78') def delete_metadata(self, resource, keys, subresource=None): - return super(ShareNetworkSubnetManager, self).delete_metadata( - resource, keys, subresource=subresource) + return super().delete_metadata(resource, keys, subresource=subresource) @api_versions.wraps('2.78') def update_all_metadata(self, resource, metadata, subresource=None): - return super(ShareNetworkSubnetManager, self).update_all_metadata( - resource, metadata, subresource=subresource) + return super().update_all_metadata( + resource, metadata, subresource=subresource + ) diff --git a/manilaclient/v2/share_networks.py b/manilaclient/v2/share_networks.py index ec204500..cc858679 100644 --- a/manilaclient/v2/share_networks.py +++ b/manilaclient/v2/share_networks.py @@ -26,8 +26,9 @@ class ShareNetwork(base.Resource): """Network info for Manila shares.""" + def __repr__(self): - return "" % self.id + return f"" def update(self, **kwargs): """Update this share network.""" @@ -40,11 +41,18 @@ def delete(self): class ShareNetworkManager(base.ManagerWithFind): """Manage :class:`ShareNetwork` resources.""" + resource_class = ShareNetwork @api_versions.wraps("1.0", "2.25") - def create(self, neutron_net_id=None, neutron_subnet_id=None, - nova_net_id=None, name=None, description=None): + def create( + self, + neutron_net_id=None, + neutron_subnet_id=None, + nova_net_id=None, + name=None, + description=None, + ): """Create share network. :param neutron_net_id: ID of Neutron network @@ -71,8 +79,13 @@ def create(self, neutron_net_id=None, neutron_subnet_id=None, return self._create(RESOURCES_PATH, body, RESOURCE_NAME) @api_versions.wraps("2.26", "2.50") # noqa - def create(self, neutron_net_id=None, neutron_subnet_id=None, # noqa - name=None, description=None): + def create( # noqa + self, + neutron_net_id=None, + neutron_subnet_id=None, + name=None, + description=None, + ): """Create share network. :param neutron_net_id: ID of Neutron network @@ -96,8 +109,14 @@ def create(self, neutron_net_id=None, neutron_subnet_id=None, # noqa return self._create(RESOURCES_PATH, body, RESOURCE_NAME) @api_versions.wraps("2.51") # noqa - def create(self, neutron_net_id=None, neutron_subnet_id=None, # noqa - name=None, description=None, availability_zone=None): + def create( # noqa + self, + neutron_net_id=None, + neutron_subnet_id=None, + name=None, + description=None, + availability_zone=None, + ): values = {} if neutron_net_id: @@ -139,13 +158,20 @@ def get(self, share_network): :param policy: share network to get. :rtype: :class:`NetworkInfo` """ - return self._get(RESOURCE_PATH % base.getid(share_network), - RESOURCE_NAME) + return self._get( + RESOURCE_PATH % base.getid(share_network), RESOURCE_NAME + ) @api_versions.wraps("1.0", "2.25") - def update(self, share_network, neutron_net_id=None, - neutron_subnet_id=None, nova_net_id=None, - name=None, description=None): + def update( + self, + share_network, + neutron_net_id=None, + neutron_subnet_id=None, + nova_net_id=None, + name=None, + description=None, + ): """Updates a share network. :param share_network: share network to update. @@ -172,14 +198,19 @@ def update(self, share_network, neutron_net_id=None, raise exceptions.CommandError(msg) body = {RESOURCE_NAME: values} - return self._update(RESOURCE_PATH % base.getid(share_network), - body, - RESOURCE_NAME) + return self._update( + RESOURCE_PATH % base.getid(share_network), body, RESOURCE_NAME + ) @api_versions.wraps("2.26") # noqa - def update(self, share_network, neutron_net_id=None, # noqa - neutron_subnet_id=None, name=None, - description=None): + def update( # noqa + self, + share_network, + neutron_net_id=None, + neutron_subnet_id=None, + name=None, + description=None, + ): """Updates a share network. :param share_network: share network to update. @@ -204,9 +235,9 @@ def update(self, share_network, neutron_net_id=None, # noqa raise exceptions.CommandError(msg) body = {RESOURCE_NAME: values} - return self._update(RESOURCE_PATH % base.getid(share_network), - body, - RESOURCE_NAME) + return self._update( + RESOURCE_PATH % base.getid(share_network), body, RESOURCE_NAME + ) def delete(self, share_network): """Delete a share network. @@ -254,8 +285,9 @@ def add_security_service(self, share_network, security_service): return self._action('add_security_service', share_network, info) @api_versions.wraps("2.63") - def add_security_service_check(self, share_network, security_service, - reset_operation=False): + def add_security_service_check( + self, share_network, security_service, reset_operation=False + ): """Associate given security service with a share network. :param share_network: share network name, id or ShareNetwork instance @@ -270,9 +302,9 @@ def add_security_service_check(self, share_network, security_service, return self._action('add_security_service_check', share_network, info) @api_versions.wraps("2.63") - def update_share_network_security_service(self, share_network, - current_security_service, - new_security_service): + def update_share_network_security_service( + self, share_network, current_security_service, new_security_service + ): """Update current security service to new one of a given share network. :param share_network: share network name, id or ShareNetwork instance @@ -284,14 +316,19 @@ def update_share_network_security_service(self, share_network, """ info = { 'current_service_id': base.getid(current_security_service), - 'new_service_id': base.getid(new_security_service)} + 'new_service_id': base.getid(new_security_service), + } return self._action('update_security_service', share_network, info) @api_versions.wraps("2.63") def update_share_network_security_service_check( - self, share_network, current_security_service, - new_security_service, reset_operation=False): + self, + share_network, + current_security_service, + new_security_service, + reset_operation=False, + ): """Validates if the security service update is supported by all hosts. :param share_network: share network name, id or ShareNetwork instance @@ -305,11 +342,12 @@ def update_share_network_security_service_check( info = { 'current_service_id': base.getid(current_security_service), 'new_service_id': base.getid(new_security_service), - 'reset_operation': reset_operation + 'reset_operation': reset_operation, } - return self._action('update_security_service_check', - share_network, info) + return self._action( + 'update_security_service_check', share_network, info + ) @api_versions.wraps("2.63") def reset_state(self, share_network, state): @@ -319,15 +357,17 @@ def reset_state(self, share_network, state): or name. :param state: text with new state to set for share network. """ - return self._action('reset_status', share_network, - {"status": state}) + return self._action('reset_status', share_network, {"status": state}) @api_versions.wraps("2.70") - def share_network_subnet_create_check(self, share_network_id, - neutron_net_id=None, - neutron_subnet_id=None, - availability_zone=None, - reset_operation=False): + def share_network_subnet_create_check( + self, + share_network_id, + neutron_net_id=None, + neutron_subnet_id=None, + availability_zone=None, + reset_operation=False, + ): """Check if share network subnet can be created in given share network. :param share_network_id: ID of the Share network @@ -346,5 +386,6 @@ def share_network_subnet_create_check(self, share_network_id, values['availability_zone'] = availability_zone values['reset_operation'] = reset_operation - return self._action('share_network_subnet_create_check', - share_network_id, values) + return self._action( + 'share_network_subnet_create_check', share_network_id, values + ) diff --git a/manilaclient/v2/share_replica_export_locations.py b/manilaclient/v2/share_replica_export_locations.py index 3d69bfa9..d5ab4178 100644 --- a/manilaclient/v2/share_replica_export_locations.py +++ b/manilaclient/v2/share_replica_export_locations.py @@ -21,7 +21,7 @@ class ShareReplicaExportLocation(base.Resource): """Resource class for a share replica export location.""" def __repr__(self): - return "" % self.id + return f"" def __getitem__(self, key): return self._info[key] @@ -29,6 +29,7 @@ def __getitem__(self, key): class ShareReplicaExportLocationManager(base.ManagerWithFind): """Manage :class:`ShareInstanceExportLocation` resources.""" + resource_class = ShareReplicaExportLocation @api_versions.wraps("2.47", constants.REPLICA_PRE_GRADUATION_VERSION) @@ -37,36 +38,40 @@ def list(self, share_replica, search_opts=None): """List all share replica export locations.""" share_replica_id = base.getid(share_replica) return self._list( - "/share-replicas/%s/export-locations" % share_replica_id, - "export_locations") + f"/share-replicas/{share_replica_id}/export-locations", + "export_locations", + ) @api_versions.wraps(constants.REPLICA_GRADUATION_VERSION) # noqa def list(self, share_replica, search_opts=None): # noqa F811 """List all share replica export locations.""" share_replica_id = base.getid(share_replica) return self._list( - "/share-replicas/%s/export-locations" % share_replica_id, - "export_locations") + f"/share-replicas/{share_replica_id}/export-locations", + "export_locations", + ) @api_versions.wraps("2.47", constants.REPLICA_PRE_GRADUATION_VERSION) @api_versions.experimental_api def get(self, share_replica, export_location): return self._get_replica_export_location( - share_replica, export_location) + share_replica, export_location + ) @api_versions.wraps(constants.REPLICA_GRADUATION_VERSION) # noqa def get(self, share_replica, export_location): # noqa F811 return self._get_replica_export_location( - share_replica, export_location) + share_replica, export_location + ) def _get_replica_export_location(self, share_replica, export_location): """Get a share replica export location.""" share_replica_id = base.getid(share_replica) export_location_id = base.getid(export_location) return self._get( - ("/share-replicas/%(share_replica_id)s/export-locations/" - "%(export_location_id)s") % { - "share_replica_id": share_replica_id, - "export_location_id": export_location_id, - }, - "export_location") + ( + f"/share-replicas/{share_replica_id}/export-locations/" + f"{export_location_id}" + ), + "export_location", + ) diff --git a/manilaclient/v2/share_replicas.py b/manilaclient/v2/share_replicas.py index 8965e5d9..158c5fe2 100644 --- a/manilaclient/v2/share_replicas.py +++ b/manilaclient/v2/share_replicas.py @@ -26,8 +26,9 @@ class ShareReplica(base.Resource): """A replica is 'mirror' instance of a share at some point in time.""" + def __repr__(self): - return "" % self.id + return f"" def resync(self): """Re-sync this replica.""" @@ -48,6 +49,7 @@ def reset_replica_state(self, replica_state): class ShareReplicaManager(base.ManagerWithFind): """Manage :class:`ShareReplica` resources.""" + resource_class = ShareReplica @api_versions.wraps("2.11", constants.REPLICA_PRE_GRADUATION_VERSION) @@ -125,30 +127,45 @@ def promote(self, replica, quiesce_wait_time=None): # noqa F811 @api_versions.experimental_api def create(self, share, availability_zone=None): return self._create_share_replica( - share, availability_zone=availability_zone) + share, availability_zone=availability_zone + ) @api_versions.wraps(constants.REPLICA_GRADUATION_VERSION, '2.66') # noqa def create(self, share, availability_zone=None): # noqa F811 return self._create_share_replica( - share, availability_zone=availability_zone) + share, availability_zone=availability_zone + ) @api_versions.wraps("2.67", "2.71") # noqa - def create(self, share, availability_zone=None, scheduler_hints=None): # noqa F811 + def create(self, share, availability_zone=None, scheduler_hints=None): # noqa F811 return self._create_share_replica( - share, availability_zone=availability_zone, - scheduler_hints=scheduler_hints) + share, + availability_zone=availability_zone, + scheduler_hints=scheduler_hints, + ) @api_versions.wraps("2.72") # noqa - def create(self, share, # pylint: disable=function-redefined # noqa F811 - availability_zone=None, scheduler_hints=None, - share_network=None): + def create( # noqa + self, + share, # pylint: disable=function-redefined # noqa F811 + availability_zone=None, + scheduler_hints=None, + share_network=None, + ): return self._create_share_replica( - share, availability_zone=availability_zone, + share, + availability_zone=availability_zone, scheduler_hints=scheduler_hints, - share_network=share_network) - - def _create_share_replica(self, share, availability_zone=None, - scheduler_hints=None, share_network=None): + share_network=share_network, + ) + + def _create_share_replica( + self, + share, + availability_zone=None, + scheduler_hints=None, + share_network=None, + ): """Create a replica for a share. :param share: The share to create the replica of. Can be the share @@ -171,9 +188,9 @@ def _create_share_replica(self, share, availability_zone=None, if share_network: body['share_network_id'] = base.getid(share_network) - return self._create(RESOURCES_PATH, - {RESOURCE_NAME: body}, - RESOURCE_NAME) + return self._create( + RESOURCES_PATH, {RESOURCE_NAME: body}, RESOURCE_NAME + ) @api_versions.wraps("2.11", constants.REPLICA_PRE_GRADUATION_VERSION) @api_versions.experimental_api diff --git a/manilaclient/v2/share_servers.py b/manilaclient/v2/share_servers.py index 7f53142b..a61f93f4 100644 --- a/manilaclient/v2/share_servers.py +++ b/manilaclient/v2/share_servers.py @@ -24,14 +24,13 @@ class ShareServer(base.Resource): - def __repr__(self): - return "" % self.id + return f"" def __getattr__(self, attr): if attr == 'share_network': attr = 'share_network_name' - return super(ShareServer, self).__getattr__(attr) + return super().__getattr__(attr) def delete(self): """Delete this share server.""" @@ -45,19 +44,41 @@ def reset_state(self, state): """Update the share server with the provided state.""" self.manager.reset_state(self, state) - def migration_check(self, host, writable, nondisruptive, - preserve_snapshots, new_share_network_id=None): + def migration_check( + self, + host, + writable, + nondisruptive, + preserve_snapshots, + new_share_network_id=None, + ): """Check if the new host is suitable for migration.""" return self.manager.migration_check( - self, host, writable, nondisruptive, - preserve_snapshots, new_share_network_id=new_share_network_id) - - def migration_start(self, host, writable, nondisruptive, - preserve_snapshots, new_share_network_id=None): + self, + host, + writable, + nondisruptive, + preserve_snapshots, + new_share_network_id=new_share_network_id, + ) + + def migration_start( + self, + host, + writable, + nondisruptive, + preserve_snapshots, + new_share_network_id=None, + ): """Migrate the share server to a new host.""" self.manager.migration_start( - self, host, writable, nondisruptive, - preserve_snapshots, new_share_network_id=new_share_network_id) + self, + host, + writable, + nondisruptive, + preserve_snapshots, + new_share_network_id=new_share_network_id, + ) def migration_complete(self): """Complete migration of a share server.""" @@ -78,6 +99,7 @@ def reset_task_state(self, task_state): class ShareServerManager(base.ManagerWithFind): """Manage :class:`ShareServer` resources.""" + resource_class = ShareServer def get(self, server): @@ -87,8 +109,7 @@ def get(self, server): :rtype: :class:`ShareServer` """ server_id = base.getid(server) - server = self._get("%s/%s" % (RESOURCES_PATH, server_id), - RESOURCE_NAME) + server = self._get(f"{RESOURCES_PATH}/{server_id}", RESOURCE_NAME) # Split big dict 'backend_details' to separated strings # as next: # +---------------------+------------------------------------+ @@ -97,7 +118,7 @@ def get(self, server): # | details:instance_id |35203a78-c733-4b1f-b82c-faded312e537| # +---------------------+------------------------------------+ for k, v in server._info["backend_details"].items(): - server._info["details:%s" % k] = v + server._info[f"details:{k}"] = v return server def details(self, server): @@ -107,8 +128,7 @@ def details(self, server): :rtype: list of :class:`ShareServerBackendDetails """ server_id = base.getid(server) - return self._get("%s/%s/details" % (RESOURCES_PATH, server_id), - "details") + return self._get(f"{RESOURCES_PATH}/{server_id}/details", "details") def delete(self, server): """Delete share server. @@ -128,7 +148,6 @@ def list(self, search_opts=None): @api_versions.wraps("2.49", "2.50") def manage(self, host, share_network_id, identifier, driver_options=None): - driver_options = driver_options or {} body = { 'host': host, @@ -138,13 +157,19 @@ def manage(self, host, share_network_id, identifier, driver_options=None): } resource_path = RESOURCE_PATH % 'manage' - return self._create(resource_path, {'share_server': body}, - 'share_server') + return self._create( + resource_path, {'share_server': body}, 'share_server' + ) @api_versions.wraps("2.51") # noqa - def manage(self, host, share_network_id, identifier, # noqa - share_network_subnet_id=None, driver_options=None): - + def manage( # noqa + self, + host, + share_network_id, + identifier, + share_network_subnet_id=None, + driver_options=None, + ): driver_options = driver_options or {} body = { 'host': host, @@ -155,8 +180,9 @@ def manage(self, host, share_network_id, identifier, # noqa } resource_path = RESOURCE_PATH % 'manage' - return self._create(resource_path, {'share_server': body}, - 'share_server') + return self._create( + resource_path, {'share_server': body}, 'share_server' + ) @api_versions.wraps("2.49") def unmanage(self, share_server, force=False): @@ -185,8 +211,15 @@ def _action(self, action, share_server, info=None): @api_versions.wraps("2.57") @api_versions.experimental_api - def migration_check(self, share_server, host, writable, nondisruptive, - preserve_snapshots, new_share_network_id=None): + def migration_check( + self, + share_server, + host, + writable, + nondisruptive, + preserve_snapshots, + new_share_network_id=None, + ): """Check the share server migration to a new host :param share_server: either share_server object or text with its ID. @@ -197,20 +230,29 @@ def migration_check(self, share_server, host, writable, nondisruptive, :param new_share_network_id: Specify the new share network id. """ result = self._action( - "migration_check", share_server, { + "migration_check", + share_server, + { "host": host, "preserve_snapshots": preserve_snapshots, "writable": writable, "nondisruptive": nondisruptive, "new_share_network_id": new_share_network_id, - }) + }, + ) return result[1] @api_versions.wraps("2.57") @api_versions.experimental_api - def migration_start(self, share_server, host, writable, - nondisruptive, preserve_snapshots, - new_share_network_id=None): + def migration_start( + self, + share_server, + host, + writable, + nondisruptive, + preserve_snapshots, + new_share_network_id=None, + ): """Migrates share server to a new host :param share_server: either share_server object or text with its ID. @@ -221,13 +263,16 @@ def migration_start(self, share_server, host, writable, :param new_share_network_id: Specify the new share network id. """ return self._action( - "migration_start", share_server, { + "migration_start", + share_server, + { "host": host, "writable": writable, "nondisruptive": nondisruptive, "preserve_snapshots": preserve_snapshots, "new_share_network_id": new_share_network_id, - }) + }, + ) @api_versions.wraps("2.57") @api_versions.experimental_api @@ -237,8 +282,9 @@ def reset_task_state(self, share_server, task_state): :param share_server: either share_server object or text with its ID. :param task_state: text with new task state to set for share. """ - return self._action('reset_task_state', share_server, - {"task_state": task_state}) + return self._action( + 'reset_task_state', share_server, {"task_state": task_state} + ) @api_versions.wraps("2.57") @api_versions.experimental_api @@ -258,8 +304,7 @@ def migration_cancel(self, share_server): :param share_server: either share_server object or text with its ID. """ - return self._action('migration_cancel', - share_server) + return self._action('migration_cancel', share_server) @api_versions.wraps("2.57") @api_versions.experimental_api diff --git a/manilaclient/v2/share_snapshot_export_locations.py b/manilaclient/v2/share_snapshot_export_locations.py index 0775fa93..9bff10b4 100644 --- a/manilaclient/v2/share_snapshot_export_locations.py +++ b/manilaclient/v2/share_snapshot_export_locations.py @@ -21,7 +21,7 @@ class ShareSnapshotExportLocation(base.Resource): """Represent an export location snapshot of a snapshot.""" def __repr__(self): - return "" % self.id + return f"" def __getitem__(self, key): return self._info[key] @@ -29,13 +29,15 @@ def __getitem__(self, key): class ShareSnapshotExportLocationManager(base.ManagerWithFind): """Manage :class:`ShareSnapshotExportLocation` resources.""" + resource_class = ShareSnapshotExportLocation @api_versions.wraps("2.32") def list(self, snapshot=None, search_opts=None): - return self._list("/snapshots/%s/export-locations" % - base.getid(snapshot), - 'share_snapshot_export_locations') + return self._list( + f"/snapshots/{base.getid(snapshot)}/export-locations", + 'share_snapshot_export_locations', + ) @api_versions.wraps("2.32") def get(self, export_location, snapshot=None): @@ -44,6 +46,8 @@ def get(self, export_location, snapshot=None): "export_location_id": base.getid(export_location), } - return self._get("/snapshots/%(snapshot_id)s/export-locations/" - "%(export_location_id)s" % params, - "share_snapshot_export_location") + return self._get( + "/snapshots/{snapshot_id}/export-locations/" + "{export_location_id}".format(**params), + "share_snapshot_export_location", + ) diff --git a/manilaclient/v2/share_snapshot_instance_export_locations.py b/manilaclient/v2/share_snapshot_instance_export_locations.py index 73c23f76..4ba44a39 100644 --- a/manilaclient/v2/share_snapshot_instance_export_locations.py +++ b/manilaclient/v2/share_snapshot_instance_export_locations.py @@ -21,7 +21,7 @@ class ShareSnapshotInstanceExportLocation(base.Resource): """Represent an export location from a snapshot instance.""" def __repr__(self): - return "" % self.id + return f"" def __getitem__(self, key): return self._info[key] @@ -29,13 +29,15 @@ def __getitem__(self, key): class ShareSnapshotInstanceExportLocationManager(base.ManagerWithFind): """Manage :class:`ShareSnapshotInstanceExportLocation` resources.""" + resource_class = ShareSnapshotInstanceExportLocation @api_versions.wraps("2.32") def list(self, snapshot_instance=None, search_opts=None): - return self._list("/snapshot-instances/%s/export-locations" % - base.getid(snapshot_instance), - 'share_snapshot_export_locations') + return self._list( + f"/snapshot-instances/{base.getid(snapshot_instance)}/export-locations", + 'share_snapshot_export_locations', + ) @api_versions.wraps("2.32") def get(self, export_location, snapshot_instance=None): @@ -44,6 +46,8 @@ def get(self, export_location, snapshot_instance=None): "export_location_id": base.getid(export_location), } - return self._get("/snapshot-instances/%(snapshot_instance_id)s/" - "export-locations/%(export_location_id)s" % params, - "share_snapshot_export_location") + return self._get( + "/snapshot-instances/{snapshot_instance_id}/" + "export-locations/{export_location_id}".format(**params), + "share_snapshot_export_location", + ) diff --git a/manilaclient/v2/share_snapshot_instances.py b/manilaclient/v2/share_snapshot_instances.py index a4c4282d..1c9a2d3b 100644 --- a/manilaclient/v2/share_snapshot_instances.py +++ b/manilaclient/v2/share_snapshot_instances.py @@ -21,7 +21,7 @@ class ShareSnapshotInstance(base.Resource): """A snapshot instance is an instance of a snapshot.""" def __repr__(self): - return "" % self.id + return f"" def reset_state(self, state): """Update snapshot instance's 'status' attr.""" @@ -30,6 +30,7 @@ def reset_state(self, state): class ShareSnapshotInstanceManager(base.ManagerWithFind): """Manage :class:`SnapshotInstances` resources.""" + resource_class = ShareSnapshotInstance @api_versions.wraps("2.19") @@ -40,8 +41,9 @@ def get(self, instance): :rtype: :class:`ShareSnapshotInstance` """ snapshot_instance_id = base.getid(instance) - return self._get("/snapshot-instances/%s" % snapshot_instance_id, - "snapshot_instance") + return self._get( + f"/snapshot-instances/{snapshot_instance_id}", "snapshot_instance" + ) @api_versions.wraps("2.19") def list(self, detailed=False, snapshot=None, search_opts=None): @@ -52,7 +54,7 @@ def list(self, detailed=False, snapshot=None, search_opts=None): url = '/snapshot-instances' if snapshot: - url += '?snapshot_id=%s' % base.getid(snapshot) + url += f'?snapshot_id={base.getid(snapshot)}' return self._list(url, 'snapshot_instances') @api_versions.wraps("2.19") @@ -68,6 +70,5 @@ def _action(self, action, instance, info=None, **kwargs): """Perform a snapshot instance 'action'.""" body = {action: info} self.run_hooks('modify_body_for_action', body, **kwargs) - url = ('/snapshot-instances/%s/action' % - base.getid(instance)) + url = f'/snapshot-instances/{base.getid(instance)}/action' return self.api.client.post(url, body=body) diff --git a/manilaclient/v2/share_snapshots.py b/manilaclient/v2/share_snapshots.py index 72458a00..d2fb57b5 100644 --- a/manilaclient/v2/share_snapshots.py +++ b/manilaclient/v2/share_snapshots.py @@ -20,11 +20,10 @@ class ShareSnapshot(base.MetadataCapableResource): - """Represent a snapshot of a share.""" def __repr__(self): - return "" % self.id + return f"" def update(self, **kwargs): """Update this snapshot.""" @@ -60,11 +59,13 @@ def access_list(self): class ShareSnapshotManager(base.MetadataCapableManager): """Manage :class:`ShareSnapshot` resources.""" + resource_class = ShareSnapshot resource_path = '/snapshots' - def _do_create(self, share, force=False, name=None, description=None, - metadata=None): + def _do_create( + self, share, force=False, name=None, description=None, metadata=None + ): """Create a snapshot of the given share. :param share_id: The ID of the share to snapshot. @@ -77,11 +78,15 @@ def _do_create(self, share, force=False, name=None, description=None, """ metadata = metadata if metadata is not None else dict() - body = {'snapshot': {'share_id': base.getid(share), - 'force': force, - 'name': name, - 'description': description, - 'metadata': metadata}} + body = { + 'snapshot': { + 'share_id': base.getid(share), + 'force': force, + 'name': name, + 'description': description, + 'metadata': metadata, + } + } return self._create('/snapshots', body, 'snapshot') @api_versions.wraps("2.0", "2.72") @@ -89,14 +94,25 @@ def create(self, share, force=False, name=None, description=None): return self._do_create(share, force, name, description) @api_versions.wraps("2.73") - def create(self, share, force=False, name=None, description=None,# noqa F811 - metadata=None): + def create( # noqa + self, + share, + force=False, + name=None, + description=None, + metadata=None, + ): return self._do_create(share, force, name, description, metadata) @api_versions.wraps("2.12") - def manage(self, share, provider_location, - driver_options=None, - name=None, description=None): + def manage( + self, + share, + provider_location, + driver_options=None, + name=None, + description=None, + ): """Manage an existing share snapshot. :param share: The share object. @@ -114,8 +130,9 @@ def manage(self, share, provider_location, 'name': name, 'description': description, } - return self._create('/snapshots/manage', {'snapshot': body}, - 'snapshot') + return self._create( + '/snapshots/manage', {'snapshot': body}, 'snapshot' + ) @api_versions.wraps("2.12") def unmanage(self, snapshot): @@ -133,10 +150,11 @@ def get(self, snapshot): :rtype: :class:`ShareSnapshot` """ snapshot_id = base.getid(snapshot) - return self._get('/snapshots/%s' % snapshot_id, 'snapshot') + return self._get(f'/snapshots/{snapshot_id}', 'snapshot') - def list(self, detailed=True, search_opts=None, sort_key=None, - sort_dir=None): + def list( + self, detailed=True, search_opts=None, sort_key=None, sort_dir=None + ): """Get a list of snapshots of shares. :param search_opts: Search options to filter out shares. @@ -151,23 +169,27 @@ def list(self, detailed=True, search_opts=None, sort_key=None, search_opts['sort_key'] = sort_key else: raise ValueError( - 'sort_key must be one of the following: %s.' - % ', '.join(constants.SNAPSHOT_SORT_KEY_VALUES)) + 'sort_key must be one of the following: {}.'.format( + ', '.join(constants.SNAPSHOT_SORT_KEY_VALUES) + ) + ) if sort_dir is not None: if sort_dir in constants.SORT_DIR_VALUES: search_opts['sort_dir'] = sort_dir else: raise ValueError( - 'sort_dir must be one of the following: %s.' - % ', '.join(constants.SORT_DIR_VALUES)) + 'sort_dir must be one of the following: {}.'.format( + ', '.join(constants.SORT_DIR_VALUES) + ) + ) query_string = self._build_query_string(search_opts) if detailed: - path = "/snapshots/detail%s" % (query_string,) + path = f"/snapshots/detail{query_string}" else: - path = "/snapshots%s" % (query_string,) + path = f"/snapshots{query_string}" return self._list(path, 'snapshots') @@ -176,7 +198,7 @@ def delete(self, snapshot): :param snapshot: The :class:`ShareSnapshot` to delete. """ - self._delete("/snapshots/%s" % base.getid(snapshot)) + self._delete(f"/snapshots/{base.getid(snapshot)}") def _do_force_delete(self, snapshot, action_name="force_delete"): """Delete the specified snapshot ignoring its current state.""" @@ -200,9 +222,11 @@ def update(self, snapshot, **kwargs): if not kwargs: return - body = {'snapshot': kwargs, } + body = { + 'snapshot': kwargs, + } snapshot_id = base.getid(snapshot) - return self._update("/snapshots/%s" % snapshot_id, body) + return self._update(f"/snapshots/{snapshot_id}", body) def _do_reset_state(self, snapshot, state, action_name="reset_status"): """Update the specified share snapshot with the provided state.""" @@ -222,8 +246,9 @@ def _do_allow(self, snapshot, access_type, access_to): 'access_to': access_to, } - return self._action('allow_access', snapshot, - access_params)[1]['snapshot_access'] + return self._action('allow_access', snapshot, access_params)[1][ + 'snapshot_access' + ] @api_versions.wraps("2.32") def allow(self, snapshot, access_type, access_to): @@ -238,8 +263,9 @@ def deny(self, snapshot, id): def _do_access_list(self, snapshot): snapshot_id = base.getid(snapshot) - access_list = self._list("/snapshots/%s/access-list" % snapshot_id, - 'snapshot_access_list') + access_list = self._list( + f"/snapshots/{snapshot_id}/access-list", 'snapshot_access_list' + ) return access_list @api_versions.wraps("2.32") @@ -250,5 +276,5 @@ def _action(self, action, snapshot, info=None, **kwargs): """Perform a snapshot 'action'.""" body = {action: info} self.run_hooks('modify_body_for_action', body, **kwargs) - url = '/snapshots/%s/action' % base.getid(snapshot) + url = f'/snapshots/{base.getid(snapshot)}/action' return self.api.client.post(url, body=body) diff --git a/manilaclient/v2/share_transfers.py b/manilaclient/v2/share_transfers.py index 3304d89a..9720b798 100644 --- a/manilaclient/v2/share_transfers.py +++ b/manilaclient/v2/share_transfers.py @@ -22,7 +22,7 @@ class ShareTransfer(base.Resource): """Transfer a share from one tenant to another""" def __repr__(self): - return "" % self.id + return f"" def delete(self): """Delete this share transfer.""" @@ -31,6 +31,7 @@ def delete(self): class ShareTransferManager(base.ManagerWithFind): """Manage :class:`ShareTransfer` resources.""" + resource_class = ShareTransfer @api_versions.wraps(constants.SHARE_TRANSFER_VERSION) @@ -41,8 +42,7 @@ def create(self, share_id, name=None): :param name: The name of the transfer. :rtype: :class:`ShareTransfer` """ - body = {'transfer': {'share_id': share_id, - 'name': name}} + body = {'transfer': {'share_id': share_id, 'name': name}} return self._create('/share-transfers', body, 'transfer') @@ -56,10 +56,14 @@ def accept(self, transfer, auth_key, clear_access_rules=False): :rtype: :class:`ShareTransfer` """ transfer_id = base.getid(transfer) - body = {'accept': {'auth_key': auth_key, - 'clear_access_rules': clear_access_rules}} + body = { + 'accept': { + 'auth_key': auth_key, + 'clear_access_rules': clear_access_rules, + } + } - self._accept('/share-transfers/%s/accept' % transfer_id, body) + self._accept(f'/share-transfers/{transfer_id}/accept', body) @api_versions.wraps(constants.SHARE_TRANSFER_VERSION) def get(self, transfer_id): @@ -68,11 +72,12 @@ def get(self, transfer_id): :param transfer_id: The ID of the share transfer to display. :rtype: :class:`ShareTransfer` """ - return self._get("/share-transfers/%s" % transfer_id, "transfer") + return self._get(f"/share-transfers/{transfer_id}", "transfer") @api_versions.wraps(constants.SHARE_TRANSFER_VERSION) - def list(self, detailed=True, search_opts=None, - sort_key=None, sort_dir=None): + def list( + self, detailed=True, search_opts=None, sort_key=None, sort_dir=None + ): """Get a list of all share transfer. :param detailed: Get detailed object information. @@ -92,22 +97,27 @@ def list(self, detailed=True, search_opts=None, search_opts['sort_key'] = 'display_name' else: raise ValueError( - 'sort_key must be one of the following: %s.' - % ', '.join(constants.SHARE_TRANSFER_SORT_KEY_VALUES)) + 'sort_key must be one of the following: {}.'.format( + ', '.join(constants.SHARE_TRANSFER_SORT_KEY_VALUES) + ) + ) if sort_dir is not None: if sort_dir in constants.SORT_DIR_VALUES: search_opts['sort_dir'] = sort_dir else: - raise ValueError('sort_dir must be one of the following: %s.' - % ', '.join(constants.SORT_DIR_VALUES)) + raise ValueError( + 'sort_dir must be one of the following: {}.'.format( + ', '.join(constants.SORT_DIR_VALUES) + ) + ) query_string = self._build_query_string(search_opts) if detailed: - path = "/share-transfers/detail%s" % (query_string,) + path = f"/share-transfers/detail{query_string}" else: - path = "/share-transfers%s" % (query_string,) + path = f"/share-transfers{query_string}" return self._list(path, 'transfers') @@ -118,4 +128,4 @@ def delete(self, transfer_id): :param transfer_id: The :class:`ShareTransfer` to delete. """ - return self._delete("/share-transfers/%s" % base.getid(transfer_id)) + return self._delete(f"/share-transfers/{base.getid(transfer_id)}") diff --git a/manilaclient/v2/share_type_access.py b/manilaclient/v2/share_type_access.py index 56d7d266..02ff0eb0 100644 --- a/manilaclient/v2/share_type_access.py +++ b/manilaclient/v2/share_type_access.py @@ -20,7 +20,7 @@ class ShareTypeAccess(base.Resource): def __repr__(self): - return "" % self.id + return f"" class ShareTypeAccessManager(base.ManagerWithFind): @@ -33,10 +33,9 @@ def _do_list(self, share_type, action_name="share_type_access"): return None return self._list( - "/types/%(st_id)s/%(action_name)s" % { - "st_id": base.getid(share_type), - "action_name": action_name}, - "share_type_access") + f"/types/{base.getid(share_type)}/{action_name}", + "share_type_access", + ) @api_versions.wraps("1.0", "2.6") def list(self, share_type, search_opts=None): @@ -60,5 +59,5 @@ def _action(self, action, share_type, info, **kwargs): """Perform a share type action.""" body = {action: info} self.run_hooks('modify_body_for_action', body, **kwargs) - url = '/types/%s/action' % base.getid(share_type) + url = f'/types/{base.getid(share_type)}/action' return self.api.client.post(url, body=body) diff --git a/manilaclient/v2/share_types.py b/manilaclient/v2/share_types.py index e2383e76..ac2db13c 100644 --- a/manilaclient/v2/share_types.py +++ b/manilaclient/v2/share_types.py @@ -27,21 +27,22 @@ class ShareType(base.Resource): """A Share Type is the type of share to be created.""" def __init__(self, manager, info, loaded=False): - super(ShareType, self).__init__(manager, info, loaded) + super().__init__(manager, info, loaded) self._required_extra_specs = info.get('required_extra_specs', {}) self._optional_extra_specs = info.get('extra_specs', {}).copy() for key in self._required_extra_specs.keys(): self._optional_extra_specs.pop(key, None) def __repr__(self): - return "" % self.name + return f"" @property def is_public(self): """Provide a user-friendly accessor to [os-]share-type-access.""" return self._info.get( "share_type_access:is_public", - self._info.get("os-share-type-access:is_public", "N/A")) + self._info.get("os-share-type-access:is_public", "N/A"), + ) def get_keys(self, prefer_resource_data=True): """Get extra specs from a share type. @@ -56,7 +57,8 @@ def get_keys(self, prefer_resource_data=True): return extra_specs _resp, body = self.manager.api.client.get( - "/types/%s/extra_specs" % base.getid(self)) + f"/types/{base.getid(self)}/extra_specs" + ) self.extra_specs = body["extra_specs"] @@ -76,7 +78,7 @@ def set_keys(self, metadata): """ body = {'extra_specs': metadata} return self.manager._create( - "/types/%s/extra_specs" % base.getid(self), + f"/types/{base.getid(self)}/extra_specs", body, "extra_specs", return_raw=True, @@ -96,7 +98,8 @@ def unset_keys(self, keys): resp = None for k in keys: resp = self.manager._delete( - "/types/%s/extra_specs/%s" % (base.getid(self), k)) + f"/types/{base.getid(self)}/extra_specs/{k}" + ) if resp is not None: return resp @@ -119,7 +122,7 @@ def list(self, search_opts=None, show_all=True): if show_all: search_opts['is_public'] = 'all' query_string = self._build_query_string(search_opts) - return self._list("/types%s" % query_string, "share_types") + return self._list(f"/types{query_string}", "share_types") def show(self, share_type): """Get a share type. @@ -128,7 +131,7 @@ def show(self, share_type): :rtype: :class:`ShareType` """ type_id = base.getid(share_type) - return self._get("/types/%s" % type_id, "share_type") + return self._get(f"/types/{type_id}", "share_type") def get(self, share_type="default"): """Get a specific share type. @@ -136,19 +139,23 @@ def get(self, share_type="default"): :param share_type: The ID of the :class:`ShareType` to get. :rtype: :class:`ShareType` """ - return self._get("/types/%s" % base.getid(share_type), - "share_type") + return self._get(f"/types/{base.getid(share_type)}", "share_type") def delete(self, share_type): """Delete a specific share_type. :param share_type: The name or ID of the :class:`ShareType` to get. """ - self._delete("/types/%s" % base.getid(share_type)) - - def _do_create(self, name, extra_specs, is_public, - is_public_keyname="share_type_access:is_public", - description=None): + self._delete(f"/types/{base.getid(share_type)}") + + def _do_create( + self, + name, + extra_specs, + is_public, + is_public_keyname="share_type_access:is_public", + description=None, + ): """Create a share type. :param name: Descriptive name of the share type @@ -167,9 +174,14 @@ def _do_create(self, name, extra_specs, is_public, body["share_type"]["description"] = description return self._create("/types", body, "share_type") - def _do_update(self, share_type, name=None, is_public=None, - is_public_keyname="share_type_access:is_public", - description=None): + def _do_update( + self, + share_type, + name=None, + is_public=None, + is_public_keyname="share_type_access:is_public", + description=None, + ): """Update the name and/or description for a share type. :param share_type: the ID of the :class: `ShareType` to update. @@ -178,9 +190,7 @@ def _do_update(self, share_type, name=None, is_public=None, :rtype: :class:`ShareType` """ - body = { - "share_type": {} - } + body = {"share_type": {}} if name: body["share_type"]["name"] = name @@ -188,90 +198,130 @@ def _do_update(self, share_type, name=None, is_public=None, body["share_type"][is_public_keyname] = is_public if description or description == "": body["share_type"]["description"] = description - return self._update("/types/%s" % base.getid(share_type), - body, "share_type") + return self._update( + f"/types/{base.getid(share_type)}", body, "share_type" + ) @api_versions.wraps("1.0", "2.6") - def create(self, name, spec_driver_handles_share_servers, - spec_snapshot_support=None, is_public=True, extra_specs=None): - + def create( + self, + name, + spec_driver_handles_share_servers, + spec_snapshot_support=None, + is_public=True, + extra_specs=None, + ): if extra_specs is None: extra_specs = {} self._handle_spec_driver_handles_share_servers( - extra_specs, spec_driver_handles_share_servers) + extra_specs, spec_driver_handles_share_servers + ) self._handle_spec_snapshot_support( - extra_specs, spec_snapshot_support, set_default=True) + extra_specs, spec_snapshot_support, set_default=True + ) return self._do_create( - name, extra_specs, is_public, - is_public_keyname="os-share-type-access:is_public") + name, + extra_specs, + is_public, + is_public_keyname="os-share-type-access:is_public", + ) @api_versions.wraps("2.7", "2.23") # noqa - def create(self, name, spec_driver_handles_share_servers, # noqa - spec_snapshot_support=None, is_public=True, extra_specs=None): - + def create( # noqa + self, + name, + spec_driver_handles_share_servers, + spec_snapshot_support=None, + is_public=True, + extra_specs=None, + ): if extra_specs is None: extra_specs = {} self._handle_spec_driver_handles_share_servers( - extra_specs, spec_driver_handles_share_servers) + extra_specs, spec_driver_handles_share_servers + ) self._handle_spec_snapshot_support( - extra_specs, spec_snapshot_support, set_default=True) + extra_specs, spec_snapshot_support, set_default=True + ) return self._do_create(name, extra_specs, is_public) @api_versions.wraps("2.24", "2.40") # noqa - def create(self, name, spec_driver_handles_share_servers, # noqa - spec_snapshot_support=None, is_public=True, extra_specs=None): - + def create( # noqa + self, + name, + spec_driver_handles_share_servers, + spec_snapshot_support=None, + is_public=True, + extra_specs=None, + ): if extra_specs is None: extra_specs = {} self._handle_spec_driver_handles_share_servers( - extra_specs, spec_driver_handles_share_servers) + extra_specs, spec_driver_handles_share_servers + ) self._handle_spec_snapshot_support(extra_specs, spec_snapshot_support) return self._do_create(name, extra_specs, is_public) @api_versions.wraps("2.41") # noqa - def create(self, name, spec_driver_handles_share_servers, # noqa - spec_snapshot_support=None, is_public=True, extra_specs=None, - description=None): + def create( # noqa + self, + name, + spec_driver_handles_share_servers, + spec_snapshot_support=None, + is_public=True, + extra_specs=None, + description=None, + ): if extra_specs is None: extra_specs = {} self._handle_spec_driver_handles_share_servers( - extra_specs, spec_driver_handles_share_servers) + extra_specs, spec_driver_handles_share_servers + ) self._handle_spec_snapshot_support(extra_specs, spec_snapshot_support) - return self._do_create(name, extra_specs, is_public, - description=description) + return self._do_create( + name, extra_specs, is_public, description=description + ) @api_versions.wraps("2.50") def update(self, share_type, name=None, is_public=None, description=None): - return self._do_update(share_type, name, is_public, - description=description) + return self._do_update( + share_type, name, is_public, description=description + ) def _handle_spec_driver_handles_share_servers( - self, extra_specs, spec_driver_handles_share_servers): + self, extra_specs, spec_driver_handles_share_servers + ): """Validation and default for DHSS extra spec.""" if spec_driver_handles_share_servers is not None: if 'driver_handles_share_servers' in extra_specs: - msg = ("'driver_handles_share_servers' is already set via " - "positional argument.") + msg = ( + "'driver_handles_share_servers' is already set via " + "positional argument." + ) raise exceptions.CommandError(msg) else: extra_specs['driver_handles_share_servers'] = ( - spec_driver_handles_share_servers) + spec_driver_handles_share_servers + ) else: - msg = ("'driver_handles_share_servers' is not set via " - "positional argument.") + msg = ( + "'driver_handles_share_servers' is not set via " + "positional argument." + ) raise exceptions.CommandError(msg) - def _handle_spec_snapshot_support(self, extra_specs, spec_snapshot_support, - set_default=False): + def _handle_spec_snapshot_support( + self, extra_specs, spec_snapshot_support, set_default=False + ): """Validation and default for snapshot extra spec.""" if spec_snapshot_support is not None: diff --git a/manilaclient/v2/shares.py b/manilaclient/v2/shares.py index 5782e8e6..73c2f8a0 100644 --- a/manilaclient/v2/shares.py +++ b/manilaclient/v2/shares.py @@ -28,10 +28,10 @@ class Share(base.MetadataCapableResource): - """A share is an extra block level storage to the OpenStack instances.""" + def __repr__(self): - return "" % self.id + return f"" def update(self, **kwargs): """Update this share.""" @@ -41,15 +41,29 @@ def unmanage(self, **kwargs): """Unmanage this share.""" self.manager.unmanage(self, **kwargs) - def migration_start(self, host, force_host_assisted_migration, - preserve_metadata, writable, nondisruptive, - preserve_snapshots, new_share_network_id=None, - new_share_type_id=None): + def migration_start( + self, + host, + force_host_assisted_migration, + preserve_metadata, + writable, + nondisruptive, + preserve_snapshots, + new_share_network_id=None, + new_share_type_id=None, + ): """Migrate the share to a new host.""" - self.manager.migration_start(self, host, force_host_assisted_migration, - preserve_metadata, writable, - nondisruptive, preserve_snapshots, - new_share_network_id, new_share_type_id) + self.manager.migration_start( + self, + host, + force_host_assisted_migration, + preserve_metadata, + writable, + nondisruptive, + preserve_snapshots, + new_share_network_id, + new_share_type_id, + ) def migration_complete(self): """Complete migration of a share.""" @@ -118,14 +132,28 @@ def restore(self): class ShareManager(base.MetadataCapableManager): """Manage :class:`Share` resources.""" + resource_class = Share resource_path = '/shares' - def create(self, share_proto, size, snapshot_id=None, name=None, - description=None, metadata=None, share_network=None, - share_type=None, is_public=False, availability_zone=None, - share_group_id=None, scheduler_hints=None, return_raw=False, - mount_point_name=None, encryption_key_ref=None): + def create( + self, + share_proto, + size, + snapshot_id=None, + name=None, + description=None, + metadata=None, + share_network=None, + share_type=None, + is_public=False, + availability_zone=None, + share_group_id=None, + scheduler_hints=None, + return_raw=False, + mount_point_name=None, + encryption_key_ref=None, + ): """Create a share. :param share_proto: text - share protocol for new share available @@ -151,8 +179,9 @@ def create(self, share_proto, size, snapshot_id=None, name=None, :rtype: :class:`Share` """ share_metadata = metadata if metadata is not None else dict() - scheduler_hints = (scheduler_hints if scheduler_hints is not None - else dict()) + scheduler_hints = ( + scheduler_hints if scheduler_hints is not None else dict() + ) body = { 'size': size, 'snapshot_id': snapshot_id, @@ -175,17 +204,28 @@ def create(self, share_proto, size, snapshot_id=None, name=None, if encryption_key_ref: body['encryption_key_ref'] = encryption_key_ref - return self._create('/shares', {'share': body}, 'share', - return_raw=return_raw) + return self._create( + '/shares', {'share': body}, 'share', return_raw=return_raw + ) @api_versions.wraps("2.29") @api_versions.experimental_api - def migration_start(self, share, host, force_host_assisted_migration, - preserve_metadata, writable, nondisruptive, - preserve_snapshots, new_share_network_id=None, - new_share_type_id=None): + def migration_start( + self, + share, + host, + force_host_assisted_migration, + preserve_metadata, + writable, + nondisruptive, + preserve_snapshots, + new_share_network_id=None, + new_share_type_id=None, + ): return self._action( - "migration_start", share, { + "migration_start", + share, + { "host": host, "force_host_assisted_migration": force_host_assisted_migration, "preserve_metadata": preserve_metadata, @@ -194,7 +234,8 @@ def migration_start(self, share, host, force_host_assisted_migration, "nondisruptive": nondisruptive, "new_share_network_id": new_share_network_id, "new_share_type_id": new_share_type_id, - }) + }, + ) @api_versions.wraps("2.22") @api_versions.experimental_api @@ -204,8 +245,9 @@ def reset_task_state(self, share, task_state): :param share: either share object or text with its ID. :param task_state: text with new task state to set for share. """ - return self._action('reset_task_state', share, - {"task_state": task_state}) + return self._action( + 'reset_task_state', share, {"task_state": task_state} + ) @api_versions.wraps("2.22") @api_versions.experimental_api @@ -234,10 +276,19 @@ def migration_get_progress(self, share): """ return self._action('migration_get_progress', share) - def _do_manage(self, service_host, protocol, export_path, - driver_options=None, share_type=None, - name=None, description=None, is_public=None, - share_server_id=None, resource_path="/shares/manage"): + def _do_manage( + self, + service_host, + protocol, + export_path, + driver_options=None, + share_type=None, + name=None, + description=None, + is_public=None, + share_server_id=None, + resource_path="/shares/manage", + ): """Manage some existing share. :param service_host: text - host where manila share service is running @@ -268,38 +319,98 @@ def _do_manage(self, service_host, protocol, export_path, return self._create(resource_path, {'share': body}, 'share') @api_versions.wraps("1.0", "2.6") - def manage(self, service_host, protocol, export_path, driver_options=None, - share_type=None, name=None, description=None): + def manage( + self, + service_host, + protocol, + export_path, + driver_options=None, + share_type=None, + name=None, + description=None, + ): return self._do_manage( - service_host, protocol, export_path, driver_options=driver_options, - share_type=share_type, name=name, description=description, - resource_path="/os-share-manage") + service_host, + protocol, + export_path, + driver_options=driver_options, + share_type=share_type, + name=name, + description=description, + resource_path="/os-share-manage", + ) @api_versions.wraps("2.7", "2.7") # noqa - def manage(self, service_host, protocol, export_path, driver_options=None, # noqa - share_type=None, name=None, description=None): + def manage( # noqa + self, + service_host, + protocol, + export_path, + driver_options=None, + share_type=None, + name=None, + description=None, + ): return self._do_manage( - service_host, protocol, export_path, driver_options=driver_options, - share_type=share_type, name=name, description=description, - resource_path="/shares/manage") + service_host, + protocol, + export_path, + driver_options=driver_options, + share_type=share_type, + name=name, + description=description, + resource_path="/shares/manage", + ) @api_versions.wraps("2.8", "2.48") # noqa - def manage(self, service_host, protocol, export_path, driver_options=None, # noqa - share_type=None, name=None, description=None, is_public=False): + def manage( # noqa + self, + service_host, + protocol, + export_path, + driver_options=None, + share_type=None, + name=None, + description=None, + is_public=False, + ): return self._do_manage( - service_host, protocol, export_path, driver_options=driver_options, - share_type=share_type, name=name, description=description, - is_public=is_public, resource_path="/shares/manage") + service_host, + protocol, + export_path, + driver_options=driver_options, + share_type=share_type, + name=name, + description=description, + is_public=is_public, + resource_path="/shares/manage", + ) @api_versions.wraps("2.49") # noqa - def manage(self, service_host, protocol, export_path, driver_options=None, # noqa - share_type=None, name=None, description=None, is_public=False, - share_server_id=None): + def manage( # noqa + self, + service_host, + protocol, + export_path, + driver_options=None, + share_type=None, + name=None, + description=None, + is_public=False, + share_server_id=None, + ): return self._do_manage( - service_host, protocol, export_path, driver_options=driver_options, - share_type=share_type, name=name, description=description, - is_public=is_public, share_server_id=share_server_id, - resource_path="/shares/manage") + service_host, + protocol, + export_path, + driver_options=driver_options, + share_type=share_type, + name=name, + description=description, + is_public=is_public, + share_server_id=share_server_id, + resource_path="/shares/manage", + ) @api_versions.wraps("1.0", "2.6") def unmanage(self, share): @@ -308,10 +419,11 @@ def unmanage(self, share): :param share: either share object or text with its ID. """ return self.api.client.post( - "/os-share-unmanage/%s/unmanage" % base.getid(share)) + f"/os-share-unmanage/{base.getid(share)}/unmanage" + ) @api_versions.wraps("2.7") # noqa - def unmanage(self, share): # noqa + def unmanage(self, share): # noqa """Unmanage a share. :param share: either share object or text with its ID. @@ -338,8 +450,7 @@ def get(self, share, return_raw=False): :rtype: :class:`Share` """ share_id = base.getid(share) - return self._get("/shares/%s" % share_id, "share", - return_raw=return_raw) + return self._get(f"/shares/{share_id}", "share", return_raw=return_raw) def update(self, share, **kwargs): """Updates a share. @@ -350,54 +461,102 @@ def update(self, share, **kwargs): if not kwargs: return - body = {'share': kwargs, } + body = { + 'share': kwargs, + } share_id = base.getid(share) - return self._update("/shares/%s" % share_id, body) + return self._update(f"/shares/{share_id}", body) @api_versions.wraps("1.0", "2.34") - def list(self, detailed=True, search_opts=None, - sort_key=None, sort_dir=None, return_raw=False): + def list( + self, + detailed=True, + search_opts=None, + sort_key=None, + sort_dir=None, + return_raw=False, + ): """Get a list of all shares.""" search_opts = search_opts or {} search_opts.pop("export_location", None) search_opts.pop("is_soft_deleted", None) search_opts.pop("encryption_key_ref", None) - return self.do_list(detailed=detailed, search_opts=search_opts, - sort_key=sort_key, sort_dir=sort_dir, - return_raw=return_raw) + return self.do_list( + detailed=detailed, + search_opts=search_opts, + sort_key=sort_key, + sort_dir=sort_dir, + return_raw=return_raw, + ) - @api_versions.wraps("2.35", "2.68") # noqa - def list(self, detailed=True, search_opts=None, # noqa - sort_key=None, sort_dir=None, return_raw=False): + @api_versions.wraps("2.35", "2.68") # noqa + def list( # noqa + self, + detailed=True, + search_opts=None, + sort_key=None, + sort_dir=None, + return_raw=False, + ): """Get a list of all shares.""" if search_opts is None: search_opts = {} search_opts.pop("is_soft_deleted", None) search_opts.pop("encryption_key_ref", None) - return self.do_list(detailed=detailed, search_opts=search_opts, - sort_key=sort_key, sort_dir=sort_dir, - return_raw=return_raw) + return self.do_list( + detailed=detailed, + search_opts=search_opts, + sort_key=sort_key, + sort_dir=sort_dir, + return_raw=return_raw, + ) @api_versions.wraps("2.69", "2.89") # noqa - def list(self, detailed=True, search_opts=None, # noqa - sort_key=None, sort_dir=None, return_raw=False): + def list( # noqa + self, + detailed=True, + search_opts=None, + sort_key=None, + sort_dir=None, + return_raw=False, + ): """Get a list of all shares.""" search_opts = search_opts or {} search_opts.pop("encryption_key_ref", None) - return self.do_list(detailed=detailed, search_opts=search_opts, - sort_key=sort_key, sort_dir=sort_dir, - return_raw=return_raw) + return self.do_list( + detailed=detailed, + search_opts=search_opts, + sort_key=sort_key, + sort_dir=sort_dir, + return_raw=return_raw, + ) @api_versions.wraps("2.90") # noqa - def list(self, detailed=True, search_opts=None, # noqa - sort_key=None, sort_dir=None, return_raw=False): + def list( # noqa + self, + detailed=True, + search_opts=None, + sort_key=None, + sort_dir=None, + return_raw=False, + ): """Get a list of all shares.""" - return self.do_list(detailed=detailed, search_opts=search_opts, - sort_key=sort_key, sort_dir=sort_dir, - return_raw=return_raw) + return self.do_list( + detailed=detailed, + search_opts=search_opts, + sort_key=sort_key, + sort_dir=sort_dir, + return_raw=return_raw, + ) - def do_list(self, detailed=True, search_opts=None, - sort_key=None, sort_dir=None, return_raw=False): + def do_list( + self, + detailed=True, + search_opts=None, + sort_key=None, + sort_dir=None, + return_raw=False, + ): """Get a list of all shares. :param detailed: Whether to return detailed share info or not. @@ -442,15 +601,21 @@ def do_list(self, detailed=True, search_opts=None, elif sort_key == 'availability_zone': search_opts['sort_key'] = 'availability_zone_id' else: - raise ValueError('sort_key must be one of the following: %s.' - % ', '.join(constants.SHARE_SORT_KEY_VALUES)) + raise ValueError( + 'sort_key must be one of the following: {}.'.format( + ', '.join(constants.SHARE_SORT_KEY_VALUES) + ) + ) if sort_dir is not None: if sort_dir in constants.SORT_DIR_VALUES: search_opts['sort_dir'] = sort_dir else: - raise ValueError('sort_dir must be one of the following: %s.' - % ', '.join(constants.SORT_DIR_VALUES)) + raise ValueError( + 'sort_dir must be one of the following: {}.'.format( + ', '.join(constants.SORT_DIR_VALUES) + ) + ) if 'is_public' not in search_opts: search_opts['is_public'] = True @@ -465,9 +630,9 @@ def do_list(self, detailed=True, search_opts=None, query_string = self._build_query_string(search_opts) if detailed: - path = "/shares/detail%s" % (query_string,) + path = f"/shares/detail{query_string}" else: - path = "/shares%s" % (query_string,) + path = f"/shares{query_string}" return self._list(path, 'shares', return_raw=return_raw) @@ -478,9 +643,9 @@ def delete(self, share, share_group_id=None): :param share_group_id: text - ID of the share group to which the share belongs """ - url = "/shares/%s" % base.getid(share) + url = f"/shares/{base.getid(share)}" if share_group_id: - url += "?share_group_id=%s" % share_group_id + url += f"?share_group_id={share_group_id}" self._delete(url) def _do_force_delete(self, share, action_name): @@ -495,7 +660,7 @@ def force_delete(self, share): return self._do_force_delete(share, "os-force_delete") @api_versions.wraps("2.7") # noqa - def force_delete(self, share): # noqa + def force_delete(self, share): # noqa return self._do_force_delete(share, "force_delete") @api_versions.wraps("2.69") @@ -517,7 +682,7 @@ def restore(self, share): @staticmethod def _validate_common_name(access): if len(access) == 0 or len(access) > 64: - exc_str = ('Invalid CN (common name). Must be 1-64 chars long.') + exc_str = 'Invalid CN (common name). Must be 1-64 chars long.' raise exceptions.CommandError(exc_str) ''' @@ -528,6 +693,7 @@ def _validate_common_name(access): 2:https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/ windows-server-2000/bb726984(v=technet.10) ''' + @staticmethod def _validate_username(access): sole_periods_spaces_re = r'[\s|\.]+$' @@ -535,38 +701,42 @@ def _validate_username(access): username = access if re.match(sole_periods_spaces_re, username): - exc_str = ('Invalid user or group name,cannot consist solely ' - 'of periods or spaces.') + exc_str = ( + 'Invalid user or group name,cannot consist solely ' + 'of periods or spaces.' + ) raise exceptions.CommandError(exc_str) if not re.match(valid_username_re, username): - exc_str = ('Invalid user or group name. Must be 4-255 characters ' - 'and consist of alphanumeric characters and ' - 'exclude special characters "/\\[]:;|=,+*?<>') + exc_str = ( + 'Invalid user or group name. Must be 4-255 characters ' + 'and consist of alphanumeric characters and ' + 'exclude special characters "/\\[]:;|=,+*?<>' + ) raise exceptions.CommandError(exc_str) @staticmethod def _validate_cephx_id(cephx_id): if not cephx_id: - raise exceptions.CommandError( - 'Ceph IDs may not be empty.') + raise exceptions.CommandError('Ceph IDs may not be empty.') # This restriction may be lifted in Ceph in the future: # http://tracker.ceph.com/issues/14626 if not set(cephx_id) <= set(string.printable): raise exceptions.CommandError( - 'Ceph IDs must consist of ASCII printable characters.') + 'Ceph IDs must consist of ASCII printable characters.' + ) # Periods are technically permitted, but we restrict them here # to avoid confusion where users are unsure whether they should # include the "client." prefix: otherwise they could accidentally # create "client.client.foobar". if '.' in cephx_id: - raise exceptions.CommandError( - 'Ceph IDs may not contain periods.') + raise exceptions.CommandError('Ceph IDs may not contain periods.') - def _validate_access(self, access_type, access, valid_access_types=None, - enable_ipv6=False): + def _validate_access( + self, access_type, access, valid_access_types=None, enable_ipv6=False + ): if not valid_access_types: valid_access_types = ('ip', 'user', 'cert') @@ -591,13 +761,23 @@ def _validate_access(self, access_type, access, valid_access_types=None, elif access_type == 'cephx': self._validate_cephx_id(access.strip()) else: - msg = ('Only following access types are supported: %s' % - ', '.join(valid_access_types)) + msg = 'Only following access types are supported: {}'.format( + ', '.join(valid_access_types) + ) raise exceptions.CommandError(msg) - def _do_allow(self, share, access_type, access, access_level, action_name, - metadata=None, lock_visibility=False, - lock_deletion=False, lock_reason=None): + def _do_allow( + self, + share, + access_type, + access, + access_level, + action_name, + metadata=None, + lock_visibility=False, + lock_deletion=False, + lock_reason=None, + ): """Allow access to a share. :param share: either share object or text with its ID. @@ -620,57 +800,83 @@ def _do_allow(self, share, access_type, access, access_level, action_name, access_params['lock_deletion'] = lock_deletion if lock_reason: access_params['lock_reason'] = lock_reason - access = self._action(action_name, share, - access_params)[1]["access"] + access = self._action(action_name, share, access_params)[1]["access"] return access @api_versions.wraps("1.0", "2.6") def allow(self, share, access_type, access, access_level, metadata=None): self._validate_access(access_type, access) return self._do_allow( - share, access_type, access, access_level, "os-allow_access") + share, access_type, access, access_level, "os-allow_access" + ) @api_versions.wraps("2.7", "2.12") # noqa - def allow(self, share, access_type, access, access_level, metadata=None): # noqa + def allow(self, share, access_type, access, access_level, metadata=None): # noqa self._validate_access(access_type, access) return self._do_allow( - share, access_type, access, access_level, "allow_access") + share, access_type, access, access_level, "allow_access" + ) @api_versions.wraps("2.13", "2.37") # noqa - def allow(self, share, access_type, access, access_level, metadata=None): # noqa + def allow(self, share, access_type, access, access_level, metadata=None): # noqa valid_access_types = ('ip', 'user', 'cert', 'cephx') self._validate_access(access_type, access, valid_access_types) return self._do_allow( - share, access_type, access, access_level, "allow_access") + share, access_type, access, access_level, "allow_access" + ) @api_versions.wraps("2.38", "2.44") # noqa - def allow(self, share, access_type, access, access_level, metadata=None): # noqa + def allow(self, share, access_type, access, access_level, metadata=None): # noqa valid_access_types = ('ip', 'user', 'cert', 'cephx') - self._validate_access(access_type, access, valid_access_types, - enable_ipv6=True) + self._validate_access( + access_type, access, valid_access_types, enable_ipv6=True + ) return self._do_allow( - share, access_type, access, access_level, "allow_access") + share, access_type, access, access_level, "allow_access" + ) @api_versions.wraps("2.45", "2.81") # noqa - def allow(self, share, access_type, access, access_level, metadata=None): # noqa + def allow(self, share, access_type, access, access_level, metadata=None): # noqa valid_access_types = ('ip', 'user', 'cert', 'cephx') - self._validate_access(access_type, access, valid_access_types, - enable_ipv6=True) + self._validate_access( + access_type, access, valid_access_types, enable_ipv6=True + ) return self._do_allow( - share, access_type, access, access_level, "allow_access", - metadata=metadata) + share, + access_type, + access, + access_level, + "allow_access", + metadata=metadata, + ) @api_versions.wraps("2.82") # noqa - def allow(self, share, access_type, access, access_level, # pylint: disable=function-redefined # noqa F811 - metadata=None, lock_visibility=False, lock_deletion=False, - lock_reason=None): + def allow( # noqa + self, + share, + access_type, + access, + access_level, # pylint: disable=function-redefined # noqa F811 + metadata=None, + lock_visibility=False, + lock_deletion=False, + lock_reason=None, + ): valid_access_types = ('ip', 'user', 'cert', 'cephx') - self._validate_access(access_type, access, valid_access_types, - enable_ipv6=True) + self._validate_access( + access_type, access, valid_access_types, enable_ipv6=True + ) return self._do_allow( - share, access_type, access, access_level, "allow_access", - metadata=metadata, lock_visibility=lock_visibility, - lock_deletion=lock_deletion, lock_reason=lock_reason) + share, + access_type, + access, + access_level, + "allow_access", + metadata=metadata, + lock_visibility=lock_visibility, + lock_deletion=lock_deletion, + lock_reason=lock_reason, + ) def _do_deny(self, share, access_id, action_name, unrestrict=False): """Deny access to a share. @@ -690,13 +896,14 @@ def deny(self, share, access_id): return self._do_deny(share, access_id, "os-deny_access") @api_versions.wraps("2.7", "2.81") # noqa - def deny(self, share, access_id): # noqa + def deny(self, share, access_id): # noqa return self._do_deny(share, access_id, "deny_access") @api_versions.wraps("2.82") # noqa def deny(self, share, access_id, unrestrict=False): # noqa - return self._do_deny(share, access_id, "deny_access", - unrestrict=unrestrict) + return self._do_deny( + share, access_id, "deny_access", unrestrict=unrestrict + ) def _do_access_list(self, share, action_name): """Get access list to a share. @@ -715,7 +922,7 @@ def access_list(self, share): return self._do_access_list(share, "os-access_list") @api_versions.wraps("2.7", "2.44") # noqa - def access_list(self, share): # noqa + def access_list(self, share): # noqa return self._do_access_list(share, "access_list") def _action(self, action, share, info=None, **kwargs): @@ -728,7 +935,7 @@ def _action(self, action, share, info=None, **kwargs): """ body = {action: info} self.run_hooks('modify_body_for_action', body, **kwargs) - url = '/shares/%s/action' % base.getid(share) + url = f'/shares/{base.getid(share)}/action' return self.api.client.post(url, body=body) def _do_reset_state(self, share, state, action_name): @@ -786,7 +993,7 @@ def shrink(self, share, new_size): return self._do_shrink(share, new_size, "os-shrink") @api_versions.wraps("2.7") # noqa - def shrink(self, share, new_size): # noqa + def shrink(self, share, new_size): # noqa return self._do_shrink(share, new_size, "shrink") def list_instances(self, share): @@ -795,7 +1002,7 @@ def list_instances(self, share): :param share: either share object or text with its ID. """ return self._list( - '/shares/%s/instances' % base.getid(share), + f'/shares/{base.getid(share)}/instances', 'share_instances', - manager=share_instances.ShareInstanceManager(self) + manager=share_instances.ShareInstanceManager(self), ) diff --git a/manilaclient/v2/shell.py b/manilaclient/v2/shell.py index 999552c9..d4e05a20 100644 --- a/manilaclient/v2/shell.py +++ b/manilaclient/v2/shell.py @@ -30,13 +30,15 @@ import manilaclient.v2.shares -def _wait_for_resource_status(cs, - resource, - expected_status, - resource_type='share', - status_attr='status', - poll_timeout=900, - poll_interval=2): +def _wait_for_resource_status( + cs, + resource, + expected_status, + resource_type='share', + status_attr='status', + poll_timeout=900, + poll_interval=2, +): """Waiter for resource status changes :param cs: command shell control @@ -70,19 +72,24 @@ def _wait_for_resource_status(cs, 'share_access_rule': _print_share_access_rule, } - expected_status = expected_status or ('available', ) + expected_status = expected_status or ('available',) if not isinstance(expected_status, (list, tuple, set)): - expected_status = (expected_status, ) + expected_status = (expected_status,) time_elapsed = 0 - timeout_message = ("%(resource_type)s %(resource)s did not reach " - "%(expected_states)s within %(seconds)d seconds.") - error_message = ("%(resource_type)s %(resource)s has reached a failed " - "state.") - deleted_message = ("%(resource_type)s %(resource)s has been successfully " - "deleted.") - unmanaged_message = ("%(resource_type)s %(resource)s has been " - "successfully unmanaged.") + timeout_message = ( + "%(resource_type)s %(resource)s did not reach " + "%(expected_states)s within %(seconds)d seconds." + ) + error_message = ( + "%(resource_type)s %(resource)s has reached a failed state." + ) + deleted_message = ( + "%(resource_type)s %(resource)s has been successfully deleted." + ) + unmanaged_message = ( + "%(resource_type)s %(resource)s has been successfully unmanaged." + ) message_payload = { 'resource_type': resource_type.capitalize(), 'resource': resource.id, @@ -91,14 +98,16 @@ def _wait_for_resource_status(cs, while True: if time_elapsed > poll_timeout: print_resource[resource_type](cs, resource) - message_payload.update({'expected_states': expected_status, - 'seconds': poll_timeout}) + message_payload.update( + {'expected_states': expected_status, 'seconds': poll_timeout} + ) raise exceptions.TimeoutException( - message=timeout_message % message_payload) + message=timeout_message % message_payload + ) try: resource = find_resource[resource_type](cs, resource.id) except exceptions.CommandError as e: - if (re.search(not_found_regex, str(e), flags=re.IGNORECASE)): + if re.search(not_found_regex, str(e), flags=re.IGNORECASE): if 'deleted' in expected_status: print(deleted_message % message_payload) break @@ -113,7 +122,8 @@ def _wait_for_resource_status(cs, elif 'error' in getattr(resource, status_attr): print_resource[resource_type](cs, resource) raise exceptions.ResourceInErrorState( - message=error_message % message_payload) + message=error_message % message_payload + ) time.sleep(poll_interval) time_elapsed += poll_interval @@ -186,12 +196,13 @@ def _print_share(cs, share): # noqa # | share_proto | NFS | # +-------------------+--------------------------------------------+ if info.get('export_locations'): - info['export_locations'] = ( - cliutils.convert_dict_list_to_string( - info['export_locations'], - ignored_keys=['replica_state', - 'availability_zone', - 'share_replica_id']) + info['export_locations'] = cliutils.convert_dict_list_to_string( + info['export_locations'], + ignored_keys=[ + 'replica_state', + 'availability_zone', + 'share_replica_id', + ], ) # No need to print both volume_type and share_type to CLI @@ -203,7 +214,8 @@ def _print_share(cs, share): # noqa def _wait_for_share_status(cs, share, expected_status='available'): return _wait_for_resource_status( - cs, share, expected_status, resource_type='share') + cs, share, expected_status, resource_type='share' + ) def _find_share_instance(cs, instance): @@ -212,7 +224,6 @@ def _find_share_instance(cs, instance): def _print_type_show(stype, default_share_type=None): - if hasattr(stype, 'is_default'): is_default = 'YES' if stype.is_default else 'NO' elif default_share_type: @@ -244,12 +255,13 @@ def _print_share_instance(cs, instance): # noqa info = instance._info.copy() info.pop('links', None) if info.get('export_locations'): - info['export_locations'] = ( - cliutils.convert_dict_list_to_string( - info['export_locations'], - ignored_keys=['replica_state', - 'availability_zone', - 'share_replica_id']) + info['export_locations'] = cliutils.convert_dict_list_to_string( + info['export_locations'], + ignored_keys=[ + 'replica_state', + 'availability_zone', + 'share_replica_id', + ], ) cliutils.print_dict(info) @@ -283,11 +295,14 @@ def _print_share_replica(cs, replica): # noqa info = replica._info.copy() info.pop('links', None) if info.get('export_locations'): - info['export_locations'] = ( - cliutils.convert_dict_list_to_string( - info['export_locations'], - ignored_keys=['replica_state', 'availability_zone', - 'share_replica_id'])) + info['export_locations'] = cliutils.convert_dict_list_to_string( + info['export_locations'], + ignored_keys=[ + 'replica_state', + 'availability_zone', + 'share_replica_id', + ], + ) cliutils.print_dict(info) @@ -311,7 +326,8 @@ def _print_share_group(cs, share_group): def _find_share_group_snapshot(cs, share_group_snapshot): """Get a share group snapshot by name or ID.""" return apiclient_utils.find_resource( - cs.share_group_snapshots, share_group_snapshot) + cs.share_group_snapshots, share_group_snapshot + ) def _print_share_group_snapshot(cs, share_group_snapshot): @@ -328,7 +344,8 @@ def _print_share_group_snapshot_members(cs, share_group_snapshot): def _wait_for_snapshot_status(cs, snapshot, expected_status='available'): return _wait_for_resource_status( - cs, snapshot, expected_status, resource_type='snapshot') + cs, snapshot, expected_status, resource_type='snapshot' + ) def _find_share_snapshot(cs, snapshot): @@ -341,9 +358,9 @@ def _print_share_snapshot(cs, snapshot): info.pop('links', None) if info.get('export_locations'): - info['export_locations'] = ( - cliutils.convert_dict_list_to_string( - info['export_locations'])) + info['export_locations'] = cliutils.convert_dict_list_to_string( + info['export_locations'] + ) cliutils.print_dict(info) @@ -355,7 +372,8 @@ def _quota_set_pretty_show(quotas): for quota_k, quota_v in sorted(quotas.to_dict().items()): if isinstance(quota_v, dict): quota_v = '\n'.join( - ['%s = %s' % (k, v) for k, v in sorted(quota_v.items())]) + ['%s = %s' % (k, v) for k, v in sorted(quota_v.items())] + ) new_quotas[quota_k] = quota_v cliutils.print_dict(new_quotas) @@ -364,7 +382,8 @@ def _quota_set_pretty_show(quotas): def _find_share_snapshot_instance(cs, snapshot_instance): """Get a share snapshot instance by ID.""" return apiclient_utils.find_resource( - cs.share_snapshot_instances, snapshot_instance) + cs.share_snapshot_instances, snapshot_instance + ) def _find_share_network(cs, share_network): @@ -374,8 +393,9 @@ def _find_share_network(cs, share_network): def _find_security_service(cs, security_service): """Get a security service by ID or name.""" - return apiclient_utils.find_resource(cs.security_services, - security_service) + return apiclient_utils.find_resource( + cs.security_services, security_service + ) def _find_share_server(cs, share_server): @@ -439,11 +459,13 @@ def _extract_key_value_options(args, option_name, allow_empty_key=True): def _split_columns(columns, title=True): if title: - list_of_keys = list(map(lambda x: x.strip().title(), - columns.split(","))) + list_of_keys = list( + map(lambda x: x.strip().title(), columns.split(",")) + ) else: - list_of_keys = list(map(lambda x: x.strip().lower(), - columns.split(","))) + list_of_keys = list( + map(lambda x: x.strip().lower(), columns.split(",")) + ) return list_of_keys @@ -490,7 +512,7 @@ def do_credentials(cs, args): 'replica_gigabytes', 'per_share_gigabytes', 'share_groups', - 'share_group_snapshots' + 'share_group_snapshots', ] @@ -506,19 +528,23 @@ def _quota_class_update(manager, identifier, args): @cliutils.arg( - '--tenant-id', '--tenant', - '--project', '--project-id', + '--tenant-id', + '--tenant', + '--project', + '--project-id', action='single_alias', dest='project_id', metavar='', default=None, - help='ID of project to list the quotas for.') + help='ID of project to list the quotas for.', +) @cliutils.arg( '--user-id', metavar='', default=None, help="ID of user to list the quotas for. Optional. " - "Mutually exclusive with '--share-type'.") + "Mutually exclusive with '--share-type'.", +) @cliutils.arg( '--share-type', '--share_type', @@ -527,13 +553,15 @@ def _quota_class_update(manager, identifier, args): default=None, action='single_alias', help="UUID or name of a share type to set the quotas for. Optional. " - "Mutually exclusive with '--user-id'. " - "Available only for microversion >= 2.39") + "Mutually exclusive with '--user-id'. " + "Available only for microversion >= 2.39", +) @cliutils.arg( '--detail', action='store_true', help='Optional flag to indicate whether to show quota in detail. ' - 'Default false, available only for microversion >= 2.25.') + 'Default false, available only for microversion >= 2.25.', +) @api_versions.wraps("1.0") def do_quota_show(cs, args): """List the quotas for a project, user or share type.""" @@ -547,19 +575,23 @@ def do_quota_show(cs, args): if cs.api_version < api_versions.APIVersion("2.39"): raise exceptions.CommandError( "'share type' quotas are available only starting with " - "'2.39' API microversion.") + "'2.39' API microversion." + ) kwargs["share_type"] = args.share_type _quota_set_pretty_show(cs.quotas.get(**kwargs)) @cliutils.arg( - '--tenant-id', '--tenant', - '--project', '--project-id', + '--tenant-id', + '--tenant', + '--project', + '--project-id', action='single_alias', dest='project_id', metavar='', default=None, - help='ID of the project to list the default quotas for.') + help='ID of the project to list the default quotas for.', +) def do_quota_defaults(cs, args): """List the default quotas for a project.""" project = args.project_id or cs.keystone_client.project_id @@ -569,31 +601,36 @@ def do_quota_defaults(cs, args): @cliutils.arg( 'project_id', metavar='', - help='UUID of project to set the quotas for.') + help='UUID of project to set the quotas for.', +) @cliutils.arg( '--user-id', metavar='', default=None, help="ID of a user to set the quotas for. Optional. " - "Mutually exclusive with '--share-type'.") + "Mutually exclusive with '--share-type'.", +) @cliutils.arg( '--shares', metavar='', type=int, default=None, - help='New value for the "shares" quota.') + help='New value for the "shares" quota.', +) @cliutils.arg( '--snapshots', metavar='', type=int, default=None, - help='New value for the "snapshots" quota.') + help='New value for the "snapshots" quota.', +) @cliutils.arg( '--gigabytes', metavar='', type=int, default=None, - help='New value for the "gigabytes" quota.') + help='New value for the "gigabytes" quota.', +) @cliutils.arg( '--snapshot-gigabytes', '--snapshot_gigabytes', # alias @@ -601,7 +638,8 @@ def do_quota_defaults(cs, args): type=int, default=None, action='single_alias', - help='New value for the "snapshot_gigabytes" quota.') + help='New value for the "snapshot_gigabytes" quota.', +) @cliutils.arg( '--share-networks', '--share_networks', @@ -609,22 +647,29 @@ def do_quota_defaults(cs, args): type=int, default=None, action='single_alias', - help='New value for the "share_networks" quota.') + help='New value for the "share_networks" quota.', +) @cliutils.arg( - '--share-groups', '--share_groups', '--groups', + '--share-groups', + '--share_groups', + '--groups', metavar='', type=int, default=None, action='single_alias', - help='New value for the "share_groups" quota.') + help='New value for the "share_groups" quota.', +) @cliutils.arg( - '--share-group-snapshots', '--share_group_snapshots', - '--group-snapshots', '--group_snapshots', + '--share-group-snapshots', + '--share_group_snapshots', + '--group-snapshots', + '--group_snapshots', metavar='', type=int, default=None, action='single_alias', - help='New value for the "share_group_snapshots" quota.') + help='New value for the "share_group_snapshots" quota.', +) @cliutils.arg( '--share-type', '--share_type', @@ -633,8 +678,9 @@ def do_quota_defaults(cs, args): default=None, action='single_alias', help="UUID or name of a share type to set the quotas for. Optional. " - "Mutually exclusive with '--user-id'. " - "Available only for microversion >= 2.39") + "Mutually exclusive with '--user-id'. " + "Available only for microversion >= 2.39", +) @cliutils.arg( '--share-replicas', '--share_replicas', @@ -643,7 +689,8 @@ def do_quota_defaults(cs, args): type=int, default=None, help='New value for the "share_replicas" quota. Available only for ' - 'microversion >= 2.53') + 'microversion >= 2.53', +) @cliutils.arg( '--replica-gigabytes', '--replica_gigabytes', @@ -651,7 +698,8 @@ def do_quota_defaults(cs, args): type=int, default=None, help='New value for the "replica_gigabytes" quota. Available only for ' - 'microversion >= 2.53') + 'microversion >= 2.53', +) @cliutils.arg( '--per-share-gigabytes', '--per_share_gigabytes', @@ -659,14 +707,16 @@ def do_quota_defaults(cs, args): type=int, default=None, help='New value for the "per_share_gigabytes" quota. Available only for ' - 'microversion >= 2.62') + 'microversion >= 2.62', +) @cliutils.arg( '--force', dest='force', action="store_true", default=None, help='Whether force update the quota even if the already used ' - 'and reserved exceeds the new quota.') + 'and reserved exceeds the new quota.', +) @api_versions.wraps("1.0") def do_quota_update(cs, args): """Update the quotas for a project/user and/or share type (Admin only).""" @@ -684,47 +734,56 @@ def do_quota_update(cs, args): if cs.api_version < api_versions.APIVersion("2.39"): raise exceptions.CommandError( "'share type' quotas are available only starting with " - "'2.39' API microversion.") + "'2.39' API microversion." + ) kwargs["share_type"] = args.share_type if args.share_groups is not None or args.share_group_snapshots is not None: if cs.api_version < api_versions.APIVersion("2.40"): raise exceptions.CommandError( "'share group' quotas are available only starting with " - "'2.40' API microversion.") + "'2.40' API microversion." + ) elif args.share_type is not None: raise exceptions.CommandError( - "Share type quotas cannot be used to constrain share groups.") + "Share type quotas cannot be used to constrain share groups." + ) kwargs["share_groups"] = args.share_groups kwargs["share_group_snapshots"] = args.share_group_snapshots if args.share_replicas is not None or args.replica_gigabytes is not None: if cs.api_version < api_versions.APIVersion("2.53"): raise exceptions.CommandError( "'share replica' quotas are available only starting with " - "'2.53' API microversion.") + "'2.53' API microversion." + ) kwargs["share_replicas"] = args.share_replicas kwargs["replica_gigabytes"] = args.replica_gigabytes if args.per_share_gigabytes is not None: if cs.api_version < api_versions.APIVersion("2.62"): raise exceptions.CommandError( "'per share gigabytes' quotas are available only starting " - "with '2.62' API microversion.") + "with '2.62' API microversion." + ) kwargs["per_share_gigabytes"] = args.per_share_gigabytes cs.quotas.update(**kwargs) @cliutils.arg( - '--tenant-id', '--tenant', - '--project', '--project-id', + '--tenant-id', + '--tenant', + '--project', + '--project-id', action='single_alias', dest='project_id', metavar='', - help='ID of the project to delete quota for.') + help='ID of the project to delete quota for.', +) @cliutils.arg( '--user-id', metavar='', help="ID of user to delete quota for. Optional." - "Mutually exclusive with '--share-type'.") + "Mutually exclusive with '--share-type'.", +) @cliutils.arg( '--share-type', '--share_type', @@ -733,8 +792,9 @@ def do_quota_update(cs, args): default=None, action='single_alias', help="UUID or name of a share type to set the quotas for. Optional. " - "Mutually exclusive with '--user-id'. " - "Available only for microversion >= 2.39") + "Mutually exclusive with '--user-id'. " + "Available only for microversion >= 2.39", +) @api_versions.wraps("1.0") def do_quota_delete(cs, args): """Delete quota for a project, or project/user or project/share-type. @@ -750,7 +810,8 @@ def do_quota_delete(cs, args): if cs.api_version < api_versions.APIVersion("2.39"): raise exceptions.CommandError( "'share type' quotas are available only starting with " - "'2.39' API microversion.") + "'2.39' API microversion." + ) kwargs["share_type"] = args.share_type cs.quotas.delete(**kwargs) @@ -759,7 +820,8 @@ def do_quota_delete(cs, args): @cliutils.arg( 'class_name', metavar='', - help='Name of quota class to list the quotas for.') + help='Name of quota class to list the quotas for.', +) def do_quota_class_show(cs, args): """List the quotas for a quota class.""" @@ -769,25 +831,29 @@ def do_quota_class_show(cs, args): @cliutils.arg( 'class_name', metavar='', - help='Name of quota class to set the quotas for.') + help='Name of quota class to set the quotas for.', +) @cliutils.arg( '--shares', metavar='', type=int, default=None, - help='New value for the "shares" quota.') + help='New value for the "shares" quota.', +) @cliutils.arg( '--snapshots', metavar='', type=int, default=None, - help='New value for the "snapshots" quota.') + help='New value for the "snapshots" quota.', +) @cliutils.arg( '--gigabytes', metavar='', type=int, default=None, - help='New value for the "gigabytes" quota.') + help='New value for the "gigabytes" quota.', +) @cliutils.arg( '--snapshot-gigabytes', '--snapshot_gigabytes', # alias @@ -795,7 +861,8 @@ def do_quota_class_show(cs, args): type=int, default=None, action='single_alias', - help='New value for the "snapshot_gigabytes" quota.') + help='New value for the "snapshot_gigabytes" quota.', +) @cliutils.arg( '--share-networks', '--share_networks', # alias @@ -803,7 +870,8 @@ def do_quota_class_show(cs, args): type=int, default=None, action='single_alias', - help='New value for the "share_networks" quota.') + help='New value for the "share_networks" quota.', +) @cliutils.arg( '--share-groups', '--share_groups', # alias @@ -812,7 +880,8 @@ def do_quota_class_show(cs, args): default=None, action='single_alias', help='New value for the "share_groups" quota. Available only for ' - 'microversion >= 2.40') + 'microversion >= 2.40', +) @cliutils.arg( '--share-group-snapshots', '--share_group_snapshots', @@ -821,7 +890,8 @@ def do_quota_class_show(cs, args): default=None, action='single_alias', help='New value for the "share_group_snapshots" quota. Available only for ' - 'microversion >= 2.40') + 'microversion >= 2.40', +) @cliutils.arg( '--share-replicas', '--share_replicas', # alias @@ -831,7 +901,8 @@ def do_quota_class_show(cs, args): default=None, action='single_alias', help='New value for the "share_replicas" quota. Available only for ' - 'microversion >= 2.53') + 'microversion >= 2.53', +) @cliutils.arg( '--replica-gigabytes', '--replica_gigabytes', # alias @@ -840,7 +911,8 @@ def do_quota_class_show(cs, args): default=None, action='single_alias', help='New value for the "replica_gigabytes" quota. Available only for ' - 'microversion >= 2.53') + 'microversion >= 2.53', +) @cliutils.arg( '--per-share-gigabytes', '--per_share_gigabytes', # alias @@ -849,24 +921,28 @@ def do_quota_class_show(cs, args): default=None, action='single_alias', help='New value for the "per_share_gigabytes" quota. Available only for ' - 'microversion >= 2.62') + 'microversion >= 2.62', +) def do_quota_class_update(cs, args): """Update the quotas for a quota class (Admin only).""" if args.share_groups is not None or args.share_group_snapshots is not None: if cs.api_version < api_versions.APIVersion("2.40"): raise exceptions.CommandError( "'share groups' quotas are available only starting with " - "'2.40' API microversion.") + "'2.40' API microversion." + ) if args.share_replicas is not None or args.replica_gigabytes is not None: if cs.api_version < api_versions.APIVersion("2.53"): raise exceptions.CommandError( "'share replica' quotas are available only starting with " - "'2.53' API microversion.") + "'2.53' API microversion." + ) if args.per_share_gigabytes is not None: if cs.api_version < api_versions.APIVersion("2.62"): raise exceptions.CommandError( "'per_share_gigabytes' quota is available only starting " - "with '2.62' API microversion.") + "with '2.62' API microversion." + ) _quota_class_update(cs.quota_classes, args.class_name, args) @@ -884,7 +960,8 @@ def do_absolute_limits(cs, args): type=str, default=None, help='Comma separated list of columns to be displayed ' - 'example --columns "verb,uri,value".') + 'example --columns "verb,uri,value".', +) def do_rate_limits(cs, args): """Print a list of rate limits for a user.""" limits = cs.limits.get().rate @@ -900,12 +977,9 @@ def do_rate_limits(cs, args): 'share_protocol', metavar='', type=str, - help='Share protocol (NFS, CIFS, CephFS, GlusterFS, HDFS or MAPRFS).') -@cliutils.arg( - 'size', - metavar='', - type=int, - help='Share size in GiB.') + help='Share protocol (NFS, CIFS, CephFS, GlusterFS, HDFS or MAPRFS).', +) +@cliutils.arg('size', metavar='', type=int, help='Share size in GiB.') @cliutils.arg( '--snapshot-id', '--snapshot_id', @@ -913,71 +987,87 @@ def do_rate_limits(cs, args): metavar='', action='single_alias', help='Optional snapshot ID or name to create the share from.' - ' (Default=None)', - default=None) + ' (Default=None)', + default=None, +) @cliutils.arg( '--name', metavar='', help='Optional share name. (Default=None)', - default=None) + default=None, +) @cliutils.arg( '--metadata', type=str, nargs='*', metavar='', help='Metadata key=value pairs (Optional, Default=None).', - default=None) + default=None, +) @cliutils.arg( '--share-network', '--share_network', metavar='', action='single_alias', help='Optional network info ID or name.', - default=None) + default=None, +) @cliutils.arg( '--description', metavar='', help='Optional share description. (Default=None)', - default=None) + default=None, +) @cliutils.arg( - '--share-type', '--share_type', '--volume-type', '--volume_type', + '--share-type', + '--share_type', + '--volume-type', + '--volume_type', metavar='', default=None, action='single_alias', help='Optional share type. Use of optional volume type is deprecated. ' - '(Default=None)') + '(Default=None)', +) @cliutils.arg( '--public', dest='public', action='store_true', default=False, help="Level of visibility for share. Defines whether other projects are " - "able to see it or not. (Default=False)") + "able to see it or not. (Default=False)", +) @cliutils.arg( - '--availability-zone', '--availability_zone', '--az', + '--availability-zone', + '--availability_zone', + '--az', metavar='', default=None, action='single_alias', - help='Availability zone in which share should be created.') + help='Availability zone in which share should be created.', +) @cliutils.arg( - '--share-group', '--share_group', '--group', + '--share-group', + '--share_group', + '--group', metavar='', action='single_alias', help='Optional share group name or ID in which to create the share ' - '(Default=None).', - default=None) -@cliutils.arg( - '--wait', - action='store_true', - help='Wait for share creation') + '(Default=None).', + default=None, +) +@cliutils.arg('--wait', action='store_true', help='Wait for share creation') @cliutils.arg( - '--scheduler-hints', '--scheduler_hints', '--sh', + '--scheduler-hints', + '--scheduler_hints', + '--sh', metavar='', nargs='*', help='Scheduler hints for the share as key=value pairs, ' - 'possible keys are same_host, different_host, ' - 'value must be share_name or share_id.', - default=None) + 'possible keys are same_host, different_host, ' + 'value must be share_name or share_id.', + default=None, +) @cliutils.service_type('sharev2') def do_create(cs, args): """Creates a new share (NFS, CIFS, CephFS, GlusterFS, HDFS or MAPRFS).""" @@ -1001,14 +1091,17 @@ def do_create(cs, args): if args.name: if args.name.capitalize() == 'None': raise exceptions.CommandError( - "Share name cannot be with the value 'None'") + "Share name cannot be with the value 'None'" + ) if not args.share_type: try: _find_share_type(cs, "default") except exceptions.CommandError: - msg = ("There is no default share type available. You must pick " - "a valid share type to create a share.") + msg = ( + "There is no default share type available. You must pick " + "a valid share type to create a share." + ) raise exceptions.CommandError(msg) scheduler_hints = {} @@ -1028,17 +1121,23 @@ def do_create(cs, args): for sh in different_host_hint_shares.split(',') ] scheduler_hints['different_host'] = ','.join( - different_host_hint_shares) - - share = cs.shares.create(args.share_protocol, args.size, snapshot, - args.name, args.description, - metadata=share_metadata, - share_network=share_network, - share_type=args.share_type, - is_public=args.public, - availability_zone=args.availability_zone, - share_group_id=share_group, - scheduler_hints=scheduler_hints) + different_host_hint_shares + ) + + share = cs.shares.create( + args.share_protocol, + args.size, + snapshot, + args.name, + args.description, + metadata=share_metadata, + share_network=share_network, + share_type=args.share_type, + is_public=args.public, + availability_zone=args.availability_zone, + share_group_id=share_group, + scheduler_hints=scheduler_hints, + ) if args.wait: share = _wait_for_share_status(cs, share) @@ -1048,14 +1147,14 @@ def do_create(cs, args): @api_versions.wraps("2.29") @cliutils.arg( - 'share', - metavar='', - help='Name or ID of share to migrate.') + 'share', metavar='', help='Name or ID of share to migrate.' +) @cliutils.arg( 'host', metavar='', help="Destination host where share will be migrated to. Use the " - "format 'host@backend#pool'.") + "format 'host@backend#pool'.", +) @cliutils.arg( '--force_host_assisted_migration', '--force-host-assisted-migration', @@ -1065,7 +1164,8 @@ def do_create(cs, args): required=False, default=False, help="Enforces the use of the host-assisted migration approach, " - "which bypasses driver optimizations. Default=False.") + "which bypasses driver optimizations. Default=False.", +) @cliutils.arg( '--preserve-metadata', '--preserve_metadata', @@ -1074,8 +1174,9 @@ def do_create(cs, args): choices=['True', 'False'], required=True, help="Enforces migration to preserve all file metadata when moving its " - "contents. If set to True, host-assisted migration will not be " - "attempted.") + "contents. If set to True, host-assisted migration will not be " + "attempted.", +) @cliutils.arg( '--preserve-snapshots', '--preserve_snapshots', @@ -1084,22 +1185,25 @@ def do_create(cs, args): choices=['True', 'False'], required=True, help="Enforces migration of the share snapshots to the destination. If " - "set to True, host-assisted migration will not be attempted.") + "set to True, host-assisted migration will not be attempted.", +) @cliutils.arg( '--writable', metavar='', choices=['True', 'False'], required=True, help="Enforces migration to keep the share writable while contents are " - "being moved. If set to True, host-assisted migration will not be " - "attempted.") + "being moved. If set to True, host-assisted migration will not be " + "attempted.", +) @cliutils.arg( '--nondisruptive', metavar='', choices=['True', 'False'], required=True, help="Enforces migration to be nondisruptive. If set to True, " - "host-assisted migration will not be attempted.") + "host-assisted migration will not be attempted.", +) @cliutils.arg( '--new_share_network', '--new-share-network', @@ -1107,9 +1211,10 @@ def do_create(cs, args): action='single_alias', required=False, help='Specify the new share network for the share. Do not specify this ' - 'parameter if the migrating share has to be retained within its ' - 'current share network.', - default=None) + 'parameter if the migrating share has to be retained within its ' + 'current share network.', + default=None, +) @cliutils.arg( '--new_share_type', '--new-share-type', @@ -1117,9 +1222,10 @@ def do_create(cs, args): required=False, action='single_alias', help='Specify the new share type for the share. Do not specify this ' - 'parameter if the migrating share has to be retained with its ' - 'current share type.', - default=None) + 'parameter if the migrating share has to be retained with its ' + 'current share type.', + default=None, +) def do_migration_start(cs, args): """Migrates share to a new host (Admin only, Experimental).""" share = _find_share(cs, args.share) @@ -1131,16 +1237,23 @@ def do_migration_start(cs, args): if args.new_share_type: share_type = _find_share_type(cs, args.new_share_type) new_share_type_id = share_type.id if share_type else None - share.migration_start(args.host, args.force_host_assisted_migration, - args.preserve_metadata, args.writable, - args.nondisruptive, args.preserve_snapshots, - new_share_net_id, new_share_type_id) + share.migration_start( + args.host, + args.force_host_assisted_migration, + args.preserve_metadata, + args.writable, + args.nondisruptive, + args.preserve_snapshots, + new_share_net_id, + new_share_type_id, + ) @cliutils.arg( 'share', metavar='', - help='Name or ID of share to complete migration.') + help='Name or ID of share to complete migration.', +) @api_versions.wraps("2.22") def do_migration_complete(cs, args): """Completes migration for a given share (Admin only, Experimental).""" @@ -1149,9 +1262,8 @@ def do_migration_complete(cs, args): @cliutils.arg( - 'share', - metavar='', - help='Name or ID of share to cancel migration.') + 'share', metavar='', help='Name or ID of share to cancel migration.' +) @api_versions.wraps("2.22") def do_migration_cancel(cs, args): """Cancels migration of a given share when copying @@ -1163,9 +1275,8 @@ def do_migration_cancel(cs, args): @cliutils.arg( - 'share', - metavar='', - help='Name or ID of the share to modify.') + 'share', metavar='', help='Name or ID of the share to modify.' +) @cliutils.arg( '--task-state', '--task_state', @@ -1174,14 +1285,17 @@ def do_migration_cancel(cs, args): default='None', action='single_alias', required=False, - help=('Indicate which task state to assign the share. Options include ' - 'migration_starting, migration_in_progress, migration_completing, ' - 'migration_success, migration_error, migration_cancelled, ' - 'migration_driver_in_progress, migration_driver_phase1_done, ' - 'data_copying_starting, data_copying_in_progress, ' - 'data_copying_completing, data_copying_completed, ' - 'data_copying_cancelled, data_copying_error. If no value is ' - 'provided, None will be used.')) + help=( + 'Indicate which task state to assign the share. Options include ' + 'migration_starting, migration_in_progress, migration_completing, ' + 'migration_success, migration_error, migration_cancelled, ' + 'migration_driver_in_progress, migration_driver_phase1_done, ' + 'data_copying_starting, data_copying_in_progress, ' + 'data_copying_completing, data_copying_completed, ' + 'data_copying_cancelled, data_copying_error. If no value is ' + 'provided, None will be used.' + ), +) @api_versions.wraps("2.22") def do_reset_task_state(cs, args): """Explicitly update the task state of a share @@ -1199,7 +1313,8 @@ def do_reset_task_state(cs, args): 'share', metavar='', help='Name or ID of the share to get share migration progress ' - 'information.') + 'information.', +) @api_versions.wraps("2.22") def do_migration_get_progress(cs, args): """Gets migration progress of a given share when copying @@ -1215,12 +1330,14 @@ def do_migration_get_progress(cs, args): @cliutils.arg( 'share_server_id', metavar='', - help='ID of the share server to check if the migration is possible.') + help='ID of the share server to check if the migration is possible.', +) @cliutils.arg( 'host', metavar='', help="Destination to migrate the share server to. Use the format " - "'@'.") + "'@'.", +) @cliutils.arg( '--preserve-snapshots', '--preserve_snapshots', @@ -1229,22 +1346,25 @@ def do_migration_get_progress(cs, args): choices=['True', 'False'], required=True, help="Set to True if snapshots must be preserved at the migration " - "destination.") + "destination.", +) @cliutils.arg( '--writable', metavar='', choices=['True', 'False'], required=True, help="Set to True if shares associated with the share server must be " - "writable through the first phase of the migration.") + "writable through the first phase of the migration.", +) @cliutils.arg( '--nondisruptive', metavar='', choices=['True', 'False'], required=True, help="Set to True if migration must be non disruptive to clients that are " - "using the shares associated with the share server through both " - "phases of the migration.") + "using the shares associated with the share server through both " + "phases of the migration.", +) @cliutils.arg( '--new_share_network', '--new-share-network', @@ -1252,7 +1372,8 @@ def do_migration_get_progress(cs, args): action='single_alias', required=False, help="New share network to migrate to. Optional, default=None.", - default=None) + default=None, +) @api_versions.wraps("2.57") @api_versions.experimental_api def do_share_server_migration_check(cs, args): @@ -1267,20 +1388,26 @@ def do_share_server_migration_check(cs, args): share_net = _find_share_network(cs, args.new_share_network) new_share_net_id = share_net.id result = share_server.migration_check( - args.host, args.writable, args.nondisruptive, args.preserve_snapshots, - new_share_net_id) + args.host, + args.writable, + args.nondisruptive, + args.preserve_snapshots, + new_share_net_id, + ) cliutils.print_dict(result) @cliutils.arg( 'share_server_id', metavar='', - help='ID of the share server to migrate.') + help='ID of the share server to migrate.', +) @cliutils.arg( 'host', metavar='', help="Destination to migrate the share server to. Use the format " - "'@'.") + "'@'.", +) @cliutils.arg( '--preserve-snapshots', '--preserve_snapshots', @@ -1289,20 +1416,23 @@ def do_share_server_migration_check(cs, args): choices=['True', 'False'], required=True, help="Set to True if snapshots must be preserved at the migration " - "destination.") + "destination.", +) @cliutils.arg( '--writable', metavar='', choices=['True', 'False'], required=True, help="Enforces migration to keep all its shares writable while contents " - "are being moved.") + "are being moved.", +) @cliutils.arg( '--nondisruptive', metavar='', choices=['True', 'False'], required=True, - help="Enforces migration to be nondisruptive.") + help="Enforces migration to be nondisruptive.", +) @cliutils.arg( '--new_share_network', '--new-share-network', @@ -1310,9 +1440,10 @@ def do_share_server_migration_check(cs, args): action='single_alias', required=False, help='Specify a new share network for the share server. Do not ' - 'specify this parameter if the migrating share server has ' - 'to be retained within its current share network.', - default=None) + 'specify this parameter if the migrating share server has ' + 'to be retained within its current share network.', + default=None, +) @api_versions.wraps("2.57") @api_versions.experimental_api def do_share_server_migration_start(cs, args): @@ -1323,14 +1454,20 @@ def do_share_server_migration_start(cs, args): if args.new_share_network: share_net = _find_share_network(cs, args.new_share_network) new_share_net_id = share_net.id - share_server.migration_start(args.host, args.writable, args.nondisruptive, - args.preserve_snapshots, new_share_net_id) + share_server.migration_start( + args.host, + args.writable, + args.nondisruptive, + args.preserve_snapshots, + new_share_net_id, + ) @cliutils.arg( 'share_server_id', metavar='', - help='ID of share server to complete migration.') + help='ID of share server to complete migration.', +) @api_versions.wraps("2.57") @api_versions.experimental_api def do_share_server_migration_complete(cs, args): @@ -1346,7 +1483,8 @@ def do_share_server_migration_complete(cs, args): @cliutils.arg( 'share_server_id', metavar='', - help='ID of share server to complete migration.') + help='ID of share server to complete migration.', +) @api_versions.wraps("2.57") @api_versions.experimental_api def do_share_server_migration_cancel(cs, args): @@ -1361,7 +1499,8 @@ def do_share_server_migration_cancel(cs, args): @cliutils.arg( 'share_server_id', metavar='', - help='ID of share server to complete migration.') + help='ID of share server to complete migration.', +) @cliutils.arg( '--task-state', '--task_state', @@ -1370,12 +1509,15 @@ def do_share_server_migration_cancel(cs, args): default='None', action='single_alias', required=False, - help=('Indicate which task state to assign the share server. Options: ' - 'migration_starting, migration_in_progress, migration_completing, ' - 'migration_success, migration_error, migration_cancel_in_progress, ' - 'migration_cancelled, migration_driver_in_progress, ' - 'migration_driver_phase1_done. If no value is provided, None will ' - 'be used.')) + help=( + 'Indicate which task state to assign the share server. Options: ' + 'migration_starting, migration_in_progress, migration_completing, ' + 'migration_success, migration_error, migration_cancel_in_progress, ' + 'migration_cancelled, migration_driver_in_progress, ' + 'migration_driver_phase1_done. If no value is provided, None will ' + 'be used.' + ), +) @api_versions.wraps("2.57") @api_versions.experimental_api def do_share_server_reset_task_state(cs, args): @@ -1393,7 +1535,8 @@ def do_share_server_reset_task_state(cs, args): @cliutils.arg( 'share_server_id', metavar='', - help='ID of share server to complete migration.') + help='ID of share server to complete migration.', +) @api_versions.wraps("2.57") @api_versions.experimental_api def do_share_server_migration_get_progress(cs, args): @@ -1409,18 +1552,21 @@ def do_share_server_migration_get_progress(cs, args): @cliutils.arg( 'share', metavar='', - help='Name or ID of the share to update metadata on.') + help='Name or ID of the share to update metadata on.', +) @cliutils.arg( 'action', metavar='', choices=['set', 'unset'], - help="Actions: 'set' or 'unset'.") + help="Actions: 'set' or 'unset'.", +) @cliutils.arg( 'metadata', metavar='', nargs='+', default=[], - help='Metadata to set or unset (only key is necessary to unset).') + help='Metadata to set or unset (only key is necessary to unset).', +) def do_metadata(cs, args): """Set or delete metadata on a share.""" share = _find_share(cs, args.share) @@ -1432,10 +1578,7 @@ def do_metadata(cs, args): share.delete_metadata(sorted(list(metadata), reverse=True)) -@cliutils.arg( - 'share', - metavar='', - help='Name or ID of the share.') +@cliutils.arg('share', metavar='', help='Name or ID of the share.') def do_metadata_show(cs, args): """Show metadata of given share.""" share = _find_share(cs, args.share) @@ -1446,13 +1589,15 @@ def do_metadata_show(cs, args): @cliutils.arg( 'share', metavar='', - help='Name or ID of the share to update metadata on.') + help='Name or ID of the share to update metadata on.', +) @cliutils.arg( 'metadata', metavar='', nargs='+', default=[], - help='Metadata entry or entries to update.') + help='Metadata entry or entries to update.', +) def do_metadata_update_all(cs, args): """Update all metadata of a share.""" share = _find_share(cs, args.share) @@ -1462,17 +1607,15 @@ def do_metadata_update_all(cs, args): @api_versions.wraps("2.9") -@cliutils.arg( - 'share', - metavar='', - help='Name or ID of the share.') +@cliutils.arg('share', metavar='', help='Name or ID of the share.') @cliutils.arg( '--columns', metavar='', type=str, default=None, help='Comma separated list of columns to be displayed ' - 'example --columns "id,host,status".') + 'example --columns "id,host,status".', +) def do_share_export_location_list(cs, args): """List export locations of a given share.""" if args.columns is not None: @@ -1489,19 +1632,18 @@ def do_share_export_location_list(cs, args): @api_versions.wraps("2.9") -@cliutils.arg( - 'share', - metavar='', - help='Name or ID of the share.') +@cliutils.arg('share', metavar='', help='Name or ID of the share.') @cliutils.arg( 'export_location', metavar='', - help='ID of the share export location.') + help='ID of the share export location.', +) def do_share_export_location_show(cs, args): """Show export location of the share.""" share = _find_share(cs, args.share) export_location = cs.share_export_locations.get( - share, args.export_location) + share, args.export_location + ) view_data = export_location._info.copy() cliutils.print_dict(view_data) @@ -1510,88 +1652,110 @@ def do_share_export_location_show(cs, args): 'service_host', metavar='', type=str, - help='manage-share service host: some.host@driver#pool.') + help='manage-share service host: some.host@driver#pool.', +) @cliutils.arg( 'protocol', metavar='', type=str, - help='Protocol of the share to manage, such as NFS or CIFS.') + help='Protocol of the share to manage, such as NFS or CIFS.', +) @cliutils.arg( 'export_path', metavar='', type=str, help='Share export path, NFS share such as: 10.0.0.1:/example_path, ' - 'CIFS share such as: \\\\10.0.0.1\\example_cifs_share.') + 'CIFS share such as: \\\\10.0.0.1\\example_cifs_share.', +) @cliutils.arg( '--name', metavar='', help='Optional share name. (Default=None)', - default=None) + default=None, +) @cliutils.arg( '--description', metavar='', help='Optional share description. (Default=None)', - default=None) + default=None, +) @cliutils.arg( - '--share_type', '--share-type', + '--share_type', + '--share-type', metavar='', default=None, action='single_alias', - help='Optional share type assigned to share. (Default=None)') + help='Optional share type assigned to share. (Default=None)', +) @cliutils.arg( - '--driver_options', '--driver-options', + '--driver_options', + '--driver-options', type=str, nargs='*', metavar='', action='single_alias', help='Driver option key=value pairs (Optional, Default=None).', - default=None) + default=None, +) @cliutils.arg( '--public', dest='public', action='store_true', default=False, help="Level of visibility for share. Defines whether other projects are " - "able to see it or not. Available only for microversion >= 2.8. " - "(Default=False)") + "able to see it or not. Available only for microversion >= 2.8. " + "(Default=False)", +) @cliutils.arg( - '--share_server_id', '--share-server-id', + '--share_server_id', + '--share-server-id', metavar='', default=None, action='single_alias', help="Share server associated with share when using a share type with " - "'driver_handles_share_servers' extra_spec set to True. Available " - "only for microversion >= 2.49. (Default=None)") -@cliutils.arg( - '--wait', - action='store_true', - help='Wait for share management') + "'driver_handles_share_servers' extra_spec set to True. Available " + "only for microversion >= 2.49. (Default=None)", +) +@cliutils.arg('--wait', action='store_true', help='Wait for share management') def do_manage(cs, args): """Manage share not handled by Manila (Admin only).""" driver_options = _extract_key_value_options(args, 'driver_options') - if cs.api_version.matches(api_versions.APIVersion("2.49"), - api_versions.APIVersion()): + if cs.api_version.matches( + api_versions.APIVersion("2.49"), api_versions.APIVersion() + ): share = cs.shares.manage( - args.service_host, args.protocol, args.export_path, - driver_options=driver_options, share_type=args.share_type, - name=args.name, description=args.description, - is_public=args.public, share_server_id=args.share_server_id) + args.service_host, + args.protocol, + args.export_path, + driver_options=driver_options, + share_type=args.share_type, + name=args.name, + description=args.description, + is_public=args.public, + share_server_id=args.share_server_id, + ) else: if args.share_server_id: - raise exceptions.CommandError("Invalid parameter " - "--share_server_id specified. This" - " parameter is only supported on" - " microversion 2.49 or newer.") + raise exceptions.CommandError( + "Invalid parameter " + "--share_server_id specified. This" + " parameter is only supported on" + " microversion 2.49 or newer." + ) share = cs.shares.manage( - args.service_host, args.protocol, args.export_path, - driver_options=driver_options, share_type=args.share_type, - name=args.name, description=args.description, - is_public=args.public) + args.service_host, + args.protocol, + args.export_path, + driver_options=driver_options, + share_type=args.share_type, + name=args.name, + description=args.description, + is_public=args.public, + ) if args.wait: share = _wait_for_resource_status( - cs, share, resource_type='share', - expected_status='available' + cs, share, resource_type='share', expected_status='available' ) _print_share(cs, share) @@ -1601,39 +1765,47 @@ def do_manage(cs, args): 'host', metavar='', type=str, - help='Backend name as "@".') + help='Backend name as "@".', +) @cliutils.arg( 'share_network', metavar='', - help="Share network where share server has network allocations in.") + help="Share network where share server has network allocations in.", +) @cliutils.arg( 'identifier', metavar='', type=str, help='A driver-specific share server identifier required by the driver to ' - 'manage the share server.') + 'manage the share server.', +) @cliutils.arg( - '--driver_options', '--driver-options', + '--driver_options', + '--driver-options', type=str, nargs='*', metavar='', action='single_alias', help='One or more driver-specific key=value pairs that may be necessary to' - ' manage the share server (Optional, Default=None).', - default=None) + ' manage the share server (Optional, Default=None).', + default=None, +) @cliutils.arg( - '--share-network-subnet', '--share_network_subnet', + '--share-network-subnet', + '--share_network_subnet', type=str, metavar='', help="Share network subnet where share server has network allocations in. " - "The default subnet will be used if it's not specified. Available " - "for microversion >= 2.51 (Optional, Default=None).", - default=None) + "The default subnet will be used if it's not specified. Available " + "for microversion >= 2.51 (Optional, Default=None).", + default=None, +) @cliutils.arg( '--wait', action='store_true', default='False', - help='Wait for share server to manage') + help='Wait for share server to manage', +) def do_share_server_manage(cs, args): """Manage share server not handled by Manila (Admin only).""" driver_options = _extract_key_value_options(args, 'driver_options') @@ -1645,19 +1817,23 @@ def do_share_server_manage(cs, args): if getattr(args, 'share_network_subnet'): raise exceptions.CommandError( "Share network subnet option is only available with manila " - "API version >= 2.51") + "API version >= 2.51" + ) else: manage_kwargs['share_network_subnet_id'] = args.share_network_subnet share_server = cs.share_servers.manage( - args.host, args.share_network, args.identifier, - **manage_kwargs) + args.host, args.share_network, args.identifier, **manage_kwargs + ) if args.wait: try: _wait_for_resource_status( - cs, share_server, resource_type='share_server', - expected_status='active') + cs, + share_server, + resource_type='share_server', + expected_status='active', + ) except exceptions.CommandError as e: print(e, file=sys.stderr) @@ -1667,15 +1843,19 @@ def do_share_server_manage(cs, args): @cliutils.arg( 'share_server_id', metavar='', - help='ID of the share server to modify.') + help='ID of the share server to modify.', +) @cliutils.arg( '--state', metavar='', default=constants.STATUS_ACTIVE, - help=('Indicate which state to assign the share server. Options include ' - 'active, error, creating, deleting, managing, unmanaging, ' - 'manage_error and unmanage_error. If no state is provided, active ' - 'will be used.')) + help=( + 'Indicate which state to assign the share server. Options include ' + 'active, error, creating, deleting, managing, unmanaging, ' + 'manage_error and unmanage_error. If no state is provided, active ' + 'will be used.' + ), +) @api_versions.wraps("2.49") def do_share_server_reset_state(cs, args): """Explicitly update the state of a share server (Admin only).""" @@ -1684,66 +1864,69 @@ def do_share_server_reset_state(cs, args): @api_versions.wraps("2.12") @cliutils.arg( - 'share', - metavar='', - type=str, - help='Name or ID of the share.') + 'share', metavar='', type=str, help='Name or ID of the share.' +) @cliutils.arg( 'provider_location', metavar='', type=str, - help='Provider location of the snapshot on the backend.') + help='Provider location of the snapshot on the backend.', +) @cliutils.arg( '--name', metavar='', help='Optional snapshot name (Default=None).', - default=None) + default=None, +) @cliutils.arg( '--description', metavar='', help='Optional snapshot description (Default=None).', - default=None) + default=None, +) @cliutils.arg( - '--driver_options', '--driver-options', + '--driver_options', + '--driver-options', type=str, nargs='*', metavar='', action='single_alias', help='Optional driver options as key=value pairs (Default=None).', - default=None) + default=None, +) @cliutils.arg( '--wait', action='store_true', default=False, - help='Wait for share snapshot to be managed') + help='Wait for share snapshot to be managed', +) def do_snapshot_manage(cs, args): """Manage share snapshot not handled by Manila (Admin only).""" share_ref = _find_share(cs, args.share) driver_options = _extract_key_value_options(args, 'driver_options') share_snapshot = cs.share_snapshots.manage( - share_ref, args.provider_location, + share_ref, + args.provider_location, driver_options=driver_options, - name=args.name, description=args.description + name=args.name, + description=args.description, ) if args.wait: try: - _wait_for_snapshot_status(cs, share_snapshot, - expected_status='available') + _wait_for_snapshot_status( + cs, share_snapshot, expected_status='available' + ) except exceptions.CommandError as e: print(e, file=sys.stderr) _print_share_snapshot(cs, share_snapshot) +@cliutils.arg('share', metavar='', help='Name or ID of the share(s).') @cliutils.arg( - 'share', - metavar='', - help='Name or ID of the share(s).') -@cliutils.arg( - '--wait', - action='store_true', - help='Wait for share unmanagement') + '--wait', action='store_true', help='Wait for share unmanagement' +) def do_unmanage(cs, args): """Unmanage share (Admin only).""" share_ref = _find_share(cs, args.share) @@ -1757,7 +1940,8 @@ def do_unmanage(cs, args): 'share_server', metavar='', nargs='+', - help='ID of the share server(s).') + help='ID of the share server(s).', +) @cliutils.arg( '--force', dest='force', @@ -1765,12 +1949,14 @@ def do_unmanage(cs, args): required=False, default=False, help="Enforces the unmanage share server operation, even if the back-end " - "driver does not support it.") + "driver does not support it.", +) @cliutils.arg( '--wait', action='store_true', default=False, - help='Wait for share server(s) to be unmanaged') + help='Wait for share server(s) to be unmanaged', +) def do_share_server_unmanage(cs, args): """Unmanage share server (Admin only).""" failure_count = 0 @@ -1780,16 +1966,22 @@ def do_share_server_unmanage(cs, args): if args.wait: share_server_ref = _find_share_server(cs, server) _wait_for_resource_status( - cs, share_server_ref, resource_type='share_server', - expected_status='unmanaged') + cs, + share_server_ref, + resource_type='share_server', + expected_status='unmanaged', + ) except Exception as e: failure_count += 1 - print("Unmanage for share server %s failed: %s" % (server, e), - file=sys.stderr) + print( + "Unmanage for share server %s failed: %s" % (server, e), + file=sys.stderr, + ) if failure_count == len(args.share_server): - raise exceptions.CommandError("Unable to unmanage any of the " - "specified share servers.") + raise exceptions.CommandError( + "Unable to unmanage any of the specified share servers." + ) @api_versions.wraps("2.12") @@ -1797,12 +1989,14 @@ def do_share_server_unmanage(cs, args): 'snapshot', metavar='', nargs='+', - help='Name or ID of the snapshot(s).') + help='Name or ID of the snapshot(s).', +) @cliutils.arg( '--wait', action='store_true', default=False, - help='Wait for share snapshot to be unmanaged') + help='Wait for share snapshot to be unmanaged', +) def do_snapshot_unmanage(cs, args): """Unmanage one or more share snapshots (Admin only).""" failure_count = 0 @@ -1811,16 +2005,20 @@ def do_snapshot_unmanage(cs, args): snapshot_ref = _find_share_snapshot(cs, snapshot) snapshot_ref.unmanage_snapshot() if args.wait: - _wait_for_snapshot_status(cs, snapshot_ref, - expected_status='deleted') + _wait_for_snapshot_status( + cs, snapshot_ref, expected_status='deleted' + ) except Exception as e: failure_count += 1 - print("Unmanage for share snapshot %s failed: %s" % (snapshot, e), - file=sys.stderr) + print( + "Unmanage for share snapshot %s failed: %s" % (snapshot, e), + file=sys.stderr, + ) if failure_count == len(args.snapshot): - raise exceptions.CommandError("Unable to unmanage any of the " - "specified snapshots.") + raise exceptions.CommandError( + "Unable to unmanage any of the specified snapshots." + ) @api_versions.wraps("2.27") @@ -1828,12 +2026,14 @@ def do_snapshot_unmanage(cs, args): 'snapshot', metavar='', help='Name or ID of the snapshot to restore. The snapshot must be the ' - 'most recent one known to manila.') + 'most recent one known to manila.', +) @cliutils.arg( '--wait', action='store_true', default=False, - help='Wait for share to be reverted from snapshot.') + help='Wait for share to be reverted from snapshot.', +) def do_revert_to_snapshot(cs, args): """Revert a share to the specified snapshot.""" snapshot = _find_share_snapshot(cs, args.snapshot) @@ -1844,21 +2044,19 @@ def do_revert_to_snapshot(cs, args): @cliutils.arg( - 'share', - metavar='', - nargs='+', - help='Name or ID of the share(s).') + 'share', metavar='', nargs='+', help='Name or ID of the share(s).' +) @cliutils.arg( - '--share-group', '--share_group', '--group', + '--share-group', + '--share_group', + '--group', metavar='', action='single_alias', help='Optional share group name or ID which contains the share ' - '(Default=None).', - default=None) -@cliutils.arg( - '--wait', - action='store_true', - help='Wait for share deletion') + '(Default=None).', + default=None, +) +@cliutils.arg('--wait', action='store_true', help='Wait for share deletion') @cliutils.service_type('sharev2') def do_delete(cs, args): """Remove one or more shares.""" @@ -1875,12 +2073,14 @@ def do_delete(cs, args): cs.shares.delete(share_ref) except Exception as e: failure_count += 1 - print("Delete for share %s failed: %s" % (share, e), - file=sys.stderr) + print( + "Delete for share %s failed: %s" % (share, e), file=sys.stderr + ) if failure_count == len(args.share): - raise exceptions.CommandError("Unable to delete any of the specified " - "shares.") + raise exceptions.CommandError( + "Unable to delete any of the specified shares." + ) if args.wait: for share in shares_to_delete: @@ -1894,11 +2094,9 @@ def do_delete(cs, args): 'share', metavar='', nargs='+', - help='Name or ID of the share(s) to force delete.') -@cliutils.arg( - '--wait', - action='store_true', - help='Wait for share to delete') + help='Name or ID of the share(s) to force delete.', +) +@cliutils.arg('--wait', action='store_true', help='Wait for share to delete') @cliutils.service_type('sharev2') def do_force_delete(cs, args): """Attempt force-delete of share, regardless of state (Admin only).""" @@ -1911,11 +2109,13 @@ def do_force_delete(cs, args): share_ref.force_delete() except Exception as e: failure_count += 1 - print("Delete for share %s failed: %s" % (share, e), - file=sys.stderr) + print( + "Delete for share %s failed: %s" % (share, e), file=sys.stderr + ) if failure_count == len(args.share): - raise exceptions.CommandError("Unable to force delete any of " - "specified shares.") + raise exceptions.CommandError( + "Unable to force delete any of specified shares." + ) if args.wait: for share in shares_to_delete: try: @@ -1925,10 +2125,8 @@ def do_force_delete(cs, args): @cliutils.arg( - 'share', - metavar='', - nargs='+', - help='Name or ID of the share(s).') + 'share', metavar='', nargs='+', help='Name or ID of the share(s).' +) @cliutils.service_type('sharev2') @api_versions.wraps("2.69") def do_soft_delete(cs, args): @@ -1941,19 +2139,20 @@ def do_soft_delete(cs, args): cs.shares.soft_delete(share_ref) except Exception as e: failure_count += 1 - print("Soft deletion of share %s failed: %s" % (share, e), - file=sys.stderr) + print( + "Soft deletion of share %s failed: %s" % (share, e), + file=sys.stderr, + ) if failure_count == len(args.share): - raise exceptions.CommandError("Unable to soft delete any of the " - "specified shares.") + raise exceptions.CommandError( + "Unable to soft delete any of the specified shares." + ) @cliutils.arg( - 'share', - metavar='', - nargs='+', - help='Name or ID of the share(s).') + 'share', metavar='', nargs='+', help='Name or ID of the share(s).' +) @cliutils.service_type('sharev2') @api_versions.wraps("2.69") def do_restore(cs, args): @@ -1966,19 +2165,19 @@ def do_restore(cs, args): cs.shares.restore(share_ref) except Exception as e: failure_count += 1 - print("Restoration of share %s failed: %s" % (share, e), - file=sys.stderr) + print( + "Restoration of share %s failed: %s" % (share, e), + file=sys.stderr, + ) if failure_count == len(args.share): - raise exceptions.CommandError("Unable to restore any of the " - "specified shares.") + raise exceptions.CommandError( + "Unable to restore any of the specified shares." + ) @api_versions.wraps("1.0", "2.8") -@cliutils.arg( - 'share', - metavar='', - help='Name or ID of the NAS share.') +@cliutils.arg('share', metavar='', help='Name or ID of the NAS share.') def do_show(cs, args): """Show details about a NAS share.""" share = _find_share(cs, args.share) @@ -1986,10 +2185,7 @@ def do_show(cs, args): @api_versions.wraps("2.9") # noqa -@cliutils.arg( - 'share', - metavar='', - help='Name or ID of the NAS share.') +@cliutils.arg('share', metavar='', help='Name or ID of the NAS share.') def do_show(cs, args): # noqa """Show details about a NAS share.""" share = _find_share(cs, args.share) @@ -1999,18 +2195,17 @@ def do_show(cs, args): # noqa @cliutils.arg( - 'share', - metavar='', - help='Name or ID of the NAS share to modify.') + 'share', metavar='', help='Name or ID of the NAS share to modify.' +) @cliutils.arg( 'access_type', metavar='', help='Access rule type (only "ip", "user"(user or group), "cert" or ' - '"cephx" are supported).') + '"cephx" are supported).', +) @cliutils.arg( - 'access_to', - metavar='', - help='Value that defines access.') + 'access_to', metavar='', help='Value that defines access.' +) @cliutils.arg( '--access-level', '--access_level', # alias @@ -2020,37 +2215,44 @@ def do_show(cs, args): # noqa choices=['rw', 'ro'], action='single_alias', help='Share access level ("rw" and "ro" access levels are supported). ' - 'Defaults to rw.') + 'Defaults to rw.', +) @cliutils.arg( '--metadata', type=str, nargs='*', metavar='', help='Space Separated list of key=value pairs of metadata items. ' - 'OPTIONAL: Default=None. Available only for microversion >= 2.45.', - default=None) + 'OPTIONAL: Default=None. Available only for microversion >= 2.45.', + default=None, +) @cliutils.arg( '--wait', action='store_true', - help='Wait for share access to become active') + help='Wait for share access to become active', +) def do_access_allow(cs, args): """Allow access to a given share.""" access_metadata = None - if cs.api_version.matches(api_versions.APIVersion("2.45"), - api_versions.APIVersion()): + if cs.api_version.matches( + api_versions.APIVersion("2.45"), api_versions.APIVersion() + ): access_metadata = _extract_metadata(args) elif getattr(args, 'metadata'): raise exceptions.CommandError( "Adding metadata to access rules is supported only beyond " - "API version 2.45") + "API version 2.45" + ) share = _find_share(cs, args.share) - access = share.allow(args.access_type, args.access_to, args.access_level, - access_metadata) + access = share.allow( + args.access_type, args.access_to, args.access_level, access_metadata + ) if args.wait: try: - if not cs.api_version.matches(api_versions.APIVersion("2.45"), - api_versions.APIVersion()): + if not cs.api_version.matches( + api_versions.APIVersion("2.45"), api_versions.APIVersion() + ): raise exceptions.CommandError( "Waiting on the allowing access operation is only " "available for API versions equal to or greater than 2.45." @@ -2058,10 +2260,12 @@ def do_access_allow(cs, args): access_id = access.get('id') share_access_rule = cs.share_access_rules.get(access_id) access = _wait_for_resource_status( - cs, share_access_rule, + cs, + share_access_rule, resource_type='share_access_rule', expected_status='active', - status_attr='state')._info + status_attr='state', + )._info except exceptions.CommandError as e: print(e, file=sys.stderr) cliutils.print_dict(access) @@ -2069,9 +2273,8 @@ def do_access_allow(cs, args): @api_versions.wraps("2.45") @cliutils.arg( - 'access_id', - metavar='', - help='ID of the NAS share access rule.') + 'access_id', metavar='', help='ID of the NAS share access rule.' +) def do_access_show(cs, args): """Show details about a NAS share access rule.""" access = cs.share_access_rules.get(args.access_id) @@ -2081,21 +2284,22 @@ def do_access_show(cs, args): @api_versions.wraps("2.45") @cliutils.arg( - 'access_id', - metavar='', - help='ID of the NAS share access rule.') + 'access_id', metavar='', help='ID of the NAS share access rule.' +) @cliutils.arg( 'action', metavar='', choices=['set', 'unset'], - help="Actions: 'set' or 'unset'.") + help="Actions: 'set' or 'unset'.", +) @cliutils.arg( 'metadata', metavar='', nargs='+', default=[], help='Space separated key=value pairs of metadata items to set. ' - 'To unset only keys are required. ') + 'To unset only keys are required. ', +) def do_access_metadata(cs, args): """Set or delete metadata on a share access rule.""" share_access = cs.share_access_rules.get(args.access_id) @@ -2105,23 +2309,25 @@ def do_access_metadata(cs, args): cs.share_access_rules.set_metadata(share_access, metadata) elif args.action == 'unset': cs.share_access_rules.unset_metadata( - share_access, sorted(list(metadata), reverse=True)) + share_access, sorted(list(metadata), reverse=True) + ) @api_versions.wraps("2.32") @cliutils.arg( 'snapshot', metavar='', - help='Name or ID of the share snapshot to allow access to.') + help='Name or ID of the share snapshot to allow access to.', +) @cliutils.arg( 'access_type', metavar='', help='Access rule type (only "ip", "user"(user or group), "cert" or ' - '"cephx" are supported).') + '"cephx" are supported).', +) @cliutils.arg( - 'access_to', - metavar='', - help='Value that defines access.') + 'access_to', metavar='', help='Value that defines access.' +) def do_snapshot_access_allow(cs, args): """Allow read only access to a snapshot.""" share_snapshot = _find_share_snapshot(cs, args.snapshot) @@ -2130,13 +2336,11 @@ def do_snapshot_access_allow(cs, args): @cliutils.arg( - 'share', - metavar='', - help='Name or ID of the NAS share to modify.') + 'share', metavar='', help='Name or ID of the NAS share to modify.' +) @cliutils.arg( - 'id', - metavar='', - help='ID of the access rule to be deleted.') + 'id', metavar='', help='ID of the access rule to be deleted.' +) def do_access_deny(cs, args): """Deny access to a share.""" share = _find_share(cs, args.share) @@ -2147,12 +2351,14 @@ def do_access_deny(cs, args): @cliutils.arg( 'snapshot', metavar='', - help='Name or ID of the share snapshot to deny access to.') + help='Name or ID of the share snapshot to deny access to.', +) @cliutils.arg( 'id', metavar='', nargs='+', - help='ID(s) of the access rule(s) to be deleted.') + help='ID(s) of the access rule(s) to be deleted.', +) def do_snapshot_access_deny(cs, args): """Deny access to a snapshot.""" failure_count = 0 @@ -2162,31 +2368,36 @@ def do_snapshot_access_deny(cs, args): snapshot.deny(access_id) except Exception as e: failure_count += 1 - print("Failed to remove rule %(access)s: %(reason)s." - % {'access': access_id, 'reason': e}, - file=sys.stderr) + print( + "Failed to remove rule %(access)s: %(reason)s." + % {'access': access_id, 'reason': e}, + file=sys.stderr, + ) if failure_count == len(args.id): - raise exceptions.CommandError("Unable to delete any of the specified " - "snapshot rules.") + raise exceptions.CommandError( + "Unable to delete any of the specified snapshot rules." + ) @api_versions.wraps("1.0", "2.20") -@cliutils.arg( - 'share', - metavar='', - help='Name or ID of the share.') +@cliutils.arg('share', metavar='', help='Name or ID of the share.') @cliutils.arg( '--columns', metavar='', type=str, default=None, help='Comma separated list of columns to be displayed ' - 'example --columns "access_type,access_to".') + 'example --columns "access_type,access_to".', +) def do_access_list(cs, args): """Show access list for share.""" list_of_keys = [ - 'id', 'access_type', 'access_to', 'access_level', 'state', + 'id', + 'access_type', + 'access_to', + 'access_level', + 'state', ] if args.columns is not None: @@ -2198,22 +2409,24 @@ def do_access_list(cs, args): @api_versions.wraps("2.21") # noqa -@cliutils.arg( - 'share', - metavar='', - help='Name or ID of the share.') +@cliutils.arg('share', metavar='', help='Name or ID of the share.') @cliutils.arg( '--columns', metavar='', type=str, default=None, help='Comma separated list of columns to be displayed ' - 'example --columns "access_type,access_to".') + 'example --columns "access_type,access_to".', +) def do_access_list(cs, args): # noqa """Show access list for share.""" list_of_keys = [ - 'id', 'access_type', 'access_to', 'access_level', 'state', - 'access_key' + 'id', + 'access_type', + 'access_to', + 'access_level', + 'state', + 'access_key', ] if args.columns is not None: @@ -2225,30 +2438,35 @@ def do_access_list(cs, args): # noqa @api_versions.wraps("2.33") # noqa -@cliutils.arg( - 'share', - metavar='', - help='Name or ID of the share.') +@cliutils.arg('share', metavar='', help='Name or ID of the share.') @cliutils.arg( '--columns', metavar='', type=str, default=None, help='Comma separated list of columns to be displayed ' - 'example --columns "access_type,access_to".') + 'example --columns "access_type,access_to".', +) @cliutils.arg( '--metadata', type=str, nargs='*', metavar='', help='Filters results by a metadata key and value. OPTIONAL: ' - 'Default=None. Available only for microversion >= 2.45', - default=None) + 'Default=None. Available only for microversion >= 2.45', + default=None, +) def do_access_list(cs, args): # noqa """Show access list for share.""" list_of_keys = [ - 'id', 'access_type', 'access_to', 'access_level', 'state', - 'access_key', 'created_at', 'updated_at', + 'id', + 'access_type', + 'access_to', + 'access_level', + 'state', + 'access_key', + 'created_at', + 'updated_at', ] share = _find_share(cs, args.share) @@ -2256,11 +2474,13 @@ def do_access_list(cs, args): # noqa if getattr(args, 'metadata'): raise exceptions.CommandError( "Filtering access rules by metadata is supported only beyond " - "API version 2.45") + "API version 2.45" + ) access_list = share.access_list() else: access_list = cs.share_access_rules.access_list( - share, {'metadata': _extract_metadata(args)}) + share, {'metadata': _extract_metadata(args)} + ) if args.columns is not None: list_of_keys = _split_columns(columns=args.columns) cliutils.print_list(access_list, list_of_keys) @@ -2270,14 +2490,16 @@ def do_access_list(cs, args): # noqa @cliutils.arg( 'snapshot', metavar='', - help='Name or ID of the share snapshot to list access of.') + help='Name or ID of the share snapshot to list access of.', +) @cliutils.arg( '--columns', metavar='', type=str, default=None, help='Comma separated list of columns to be displayed ' - 'example --columns "access_type,access_to".') + 'example --columns "access_type,access_to".', +) def do_snapshot_access_list(cs, args): """Show access list for a snapshot.""" if args.columns is not None: @@ -2291,7 +2513,8 @@ def do_snapshot_access_list(cs, args): @cliutils.arg( - '--all-tenants', '--all-projects', + '--all-tenants', + '--all-projects', action='single_alias', dest='all_projects', metavar='<0|1>', @@ -2299,56 +2522,66 @@ def do_snapshot_access_list(cs, args): type=int, const=1, default=0, - help='Display information from all projects (Admin only).') + help='Display information from all projects (Admin only).', +) @cliutils.arg( '--name', metavar='', type=str, default=None, - help='Filter results by name.') + help='Filter results by name.', +) @cliutils.arg( '--description', metavar='', type=str, default=None, help='Filter results by description. ' - 'Available only for microversion >= 2.36.') + 'Available only for microversion >= 2.36.', +) @cliutils.arg( '--name~', metavar='', type=str, default=None, help='Filter results matching a share name pattern. ' - 'Available only for microversion >= 2.36.') + 'Available only for microversion >= 2.36.', +) @cliutils.arg( '--description~', metavar='', type=str, default=None, help='Filter results matching a share description pattern. ' - 'Available only for microversion >= 2.36.') + 'Available only for microversion >= 2.36.', +) @cliutils.arg( '--status', metavar='', type=str, default=None, - help='Filter results by status.') + help='Filter results by status.', +) @cliutils.arg( '--share-server-id', - '--share-server_id', '--share_server-id', '--share_server_id', # aliases + '--share-server_id', + '--share_server-id', + '--share_server_id', # aliases metavar='', type=str, default=None, action='single_alias', - help='Filter results by share server ID (Admin only).') + help='Filter results by share server ID (Admin only).', +) @cliutils.arg( '--metadata', type=str, nargs='*', metavar='', help='Filters results by a metadata key and value. OPTIONAL: ' - 'Default=None.', - default=None) + 'Default=None.', + default=None, +) @cliutils.arg( '--extra-specs', '--extra_specs', # alias @@ -2357,32 +2590,42 @@ def do_snapshot_access_list(cs, args): metavar='', action='single_alias', help='Filters results by a extra specs key and value of share type that ' - 'was used for share creation. OPTIONAL: Default=None.', - default=None) + 'was used for share creation. OPTIONAL: Default=None.', + default=None, +) @cliutils.arg( - '--share-type', '--volume-type', - '--share_type', '--share-type-id', '--volume-type-id', # aliases - '--share-type_id', '--share_type-id', '--share_type_id', # aliases - '--volume_type', '--volume_type_id', + '--share-type', + '--volume-type', + '--share_type', + '--share-type-id', + '--volume-type-id', # aliases + '--share-type_id', + '--share_type-id', + '--share_type_id', # aliases + '--volume_type', + '--volume_type_id', metavar='', type=str, default=None, action='single_alias', help='Filter results by a share type id or name that was used for share ' - 'creation.') + 'creation.', +) @cliutils.arg( '--limit', metavar='', type=int, default=None, - help='Maximum number of shares to return. OPTIONAL: Default=None.') + help='Maximum number of shares to return. OPTIONAL: Default=None.', +) @cliutils.arg( '--offset', metavar='', type=int, default=None, help='Set offset to define start point of share listing. ' - 'OPTIONAL: Default=None.') + 'OPTIONAL: Default=None.', +) @cliutils.arg( '--sort-key', '--sort_key', # alias @@ -2391,7 +2634,8 @@ def do_snapshot_access_list(cs, args): default=None, action='single_alias', help='Key to be sorted, available keys are %(keys)s. ' - 'OPTIONAL: Default=None.' % {'keys': constants.SHARE_SORT_KEY_VALUES}) + 'OPTIONAL: Default=None.' % {'keys': constants.SHARE_SORT_KEY_VALUES}, +) @cliutils.arg( '--sort-dir', '--sort_dir', # alias @@ -2400,18 +2644,18 @@ def do_snapshot_access_list(cs, args): default=None, action='single_alias', help='Sort direction, available values are %(values)s. ' - 'OPTIONAL: Default=None.' % {'values': constants.SORT_DIR_VALUES}) + 'OPTIONAL: Default=None.' % {'values': constants.SORT_DIR_VALUES}, +) @cliutils.arg( '--snapshot', metavar='', type=str, default=None, - help='Filer results by snapshot name or id, that was used for share.') + help='Filer results by snapshot name or id, that was used for share.', +) @cliutils.arg( - '--host', - metavar='', - default=None, - help='Filter results by host.') + '--host', metavar='', default=None, help='Filter results by host.' +) @cliutils.arg( '--share-network', '--share_network', # alias @@ -2419,7 +2663,8 @@ def do_snapshot_access_list(cs, args): type=str, default=None, action='single_alias', - help='Filter results by share-network name or id.') + help='Filter results by share-network name or id.', +) @cliutils.arg( '--project-id', '--project_id', # alias @@ -2427,35 +2672,43 @@ def do_snapshot_access_list(cs, args): type=str, default=None, action='single_alias', - help="Filter results by project id. Useful with set key '--all-projects'.") + help="Filter results by project id. Useful with set key '--all-projects'.", +) @cliutils.arg( '--public', dest='public', action='store_true', default=False, - help="Add public shares from all projects to result. (Default=False)") + help="Add public shares from all projects to result. (Default=False)", +) @cliutils.arg( - '--share-group', '--share_group', '--group', + '--share-group', + '--share_group', + '--group', metavar='', type=str, default=None, action='single_alias', - help='Filter results by share group name or ID (Default=None).') + help='Filter results by share group name or ID (Default=None).', +) @cliutils.arg( '--columns', metavar='', type=str, default=None, help='Comma separated list of columns to be displayed ' - 'example --columns "export_location,is public".') + 'example --columns "export_location,is public".', +) @cliutils.arg( - '--export-location', '--export_location', + '--export-location', + '--export_location', metavar='', type=str, default=None, action='single_alias', help='ID or path of the share export location. ' - 'Available only for microversion >= 2.35.') + 'Available only for microversion >= 2.35.', +) @cliutils.arg( '--count', dest='count', @@ -2463,42 +2716,57 @@ def do_snapshot_access_list(cs, args): choices=['True', 'False'], default=False, help='Display total number of shares to return. ' - 'Available only for microversion >= 2.42.') + 'Available only for microversion >= 2.42.', +) @cliutils.arg( - '--soft-deleted', '--soft_deleted', + '--soft-deleted', + '--soft_deleted', action='store_true', help='Get shares in recycle bin. If this parameter is set to ' - 'True(Default=False), will only show shares in recycle bin. ' - 'Available only for microversion >= 2.69.') + 'True(Default=False), will only show shares in recycle bin. ' + 'Available only for microversion >= 2.69.', +) @cliutils.service_type('sharev2') def do_list(cs, args): """List NAS shares with filters.""" columns = args.columns all_projects = int( - os.environ.get("ALL_TENANTS", - os.environ.get("ALL_PROJECTS", - args.all_projects)) + os.environ.get( + "ALL_TENANTS", os.environ.get("ALL_PROJECTS", args.all_projects) + ) ) if columns is not None: list_of_keys = _split_columns(columns=columns) else: list_of_keys = [ - 'ID', 'Name', 'Size', 'Share Proto', 'Status', 'Is Public', - 'Share Type Name', 'Host', 'Availability Zone' + 'ID', + 'Name', + 'Size', + 'Share Proto', + 'Status', + 'Is Public', + 'Share Type Name', + 'Host', + 'Availability Zone', ] if all_projects or args.public: list_of_keys.append('Project ID') empty_obj = type('Empty', (object,), {'id': None}) - share_type = (_find_share_type(cs, args.share_type) - if args.share_type else empty_obj) + share_type = ( + _find_share_type(cs, args.share_type) if args.share_type else empty_obj + ) - snapshot = (_find_share_snapshot(cs, args.snapshot) - if args.snapshot else empty_obj) + snapshot = ( + _find_share_snapshot(cs, args.snapshot) if args.snapshot else empty_obj + ) - share_network = (_find_share_network(cs, args.share_network) - if args.share_network else empty_obj) + share_network = ( + _find_share_network(cs, args.share_network) + if args.share_network + else empty_obj + ) share_group = None if args.share_group: @@ -2520,40 +2788,50 @@ def do_list(cs, args): 'project_id': args.project_id, 'is_public': args.public, } - if cs.api_version.matches(api_versions.APIVersion("2.36"), - api_versions.APIVersion()): + if cs.api_version.matches( + api_versions.APIVersion("2.36"), api_versions.APIVersion() + ): search_opts['name~'] = getattr(args, 'name~') search_opts['description~'] = getattr(args, 'description~') search_opts['description'] = getattr(args, 'description') - elif (getattr(args, 'name~') or getattr(args, 'description~') or - getattr(args, 'description')): + elif ( + getattr(args, 'name~') + or getattr(args, 'description~') + or getattr(args, 'description') + ): raise exceptions.CommandError( "Pattern based filtering (name~, description~ and description)" - " is only available with manila API version >= 2.36") + " is only available with manila API version >= 2.36" + ) - if cs.api_version.matches(api_versions.APIVersion("2.35"), - api_versions.APIVersion()): + if cs.api_version.matches( + api_versions.APIVersion("2.35"), api_versions.APIVersion() + ): search_opts['export_location'] = args.export_location elif args.export_location: raise exceptions.CommandError( "Filtering by export location is only " - "available with manila API version >= 2.35") + "available with manila API version >= 2.35" + ) - if (args.count and - cs.api_version.matches( - api_versions.APIVersion(), api_versions.APIVersion("2.41"))): + if args.count and cs.api_version.matches( + api_versions.APIVersion(), api_versions.APIVersion("2.41") + ): raise exceptions.CommandError( "Display total number of shares is only " - "available with manila API version >= 2.42") + "available with manila API version >= 2.42" + ) - if cs.api_version.matches(api_versions.APIVersion("2.69"), - api_versions.APIVersion()): + if cs.api_version.matches( + api_versions.APIVersion("2.69"), api_versions.APIVersion() + ): if args.soft_deleted: search_opts['is_soft_deleted'] = args.soft_deleted elif args.soft_deleted: raise exceptions.CommandError( "Filtering by is_soft_deleted is only " - "available with manila API version >= 2.69") + "available with manila API version >= 2.69" + ) if share_group: search_opts['share_group_id'] = share_group.id @@ -2562,13 +2840,15 @@ def do_list(cs, args): if strutils.bool_from_string(args.count, strict=True): search_opts['with_count'] = args.count shares, total_count = cs.shares.list( - search_opts=search_opts, sort_key=args.sort_key, - sort_dir=args.sort_dir + search_opts=search_opts, + sort_key=args.sort_key, + sort_dir=args.sort_dir, ) else: shares = cs.shares.list( - search_opts=search_opts, sort_key=args.sort_key, - sort_dir=args.sort_dir + search_opts=search_opts, + sort_key=args.sort_key, + sort_dir=args.sort_dir, ) # When shell input is "--metadata None", filter metadata={} if shares and args.metadata: @@ -2577,8 +2857,12 @@ def do_list(cs, args): # NOTE(vponomaryov): usage of 'export_location' and # 'export_locations' columns may cause scaling issue using API 2.9+ and # when lots of shares are returned. - if (shares and columns is not None and 'export_location' in columns and - not hasattr(shares[0], 'export_location')): + if ( + shares + and columns is not None + and 'export_location' in columns + and not hasattr(shares[0], 'export_location') + ): # NOTE(vponomaryov): we will get here only using API 2.9+ for share in shares: els_objs = cs.share_export_locations.list(share) @@ -2589,15 +2873,15 @@ def do_list(cs, args): if args.count: print("Shares in total: %s" % total_count) - with cs.shares.completion_cache('uuid', - manilaclient.v2.shares.Share, - mode="w"): + with cs.shares.completion_cache( + 'uuid', manilaclient.v2.shares.Share, mode="w" + ): for share in shares: cs.shares.write_to_completion_cache('uuid', share.id) - with cs.shares.completion_cache('name', - manilaclient.v2.shares.Share, - mode="w"): + with cs.shares.completion_cache( + 'name', manilaclient.v2.shares.Share, mode="w" + ): for share in shares: if share.name is not None: cs.shares.write_to_completion_cache('name', share.name) @@ -2609,30 +2893,40 @@ def do_list(cs, args): metavar='', default=None, action='single_alias', - help='Filter results by share ID.') + help='Filter results by share ID.', +) @cliutils.arg( '--columns', metavar='', type=str, default=None, help='Comma separated list of columns to be displayed ' - 'example --columns "id,host,status".') + 'example --columns "id,host,status".', +) @cliutils.arg( - '--export-location', '--export_location', + '--export-location', + '--export_location', metavar='', type=str, default=None, action='single_alias', help='ID or path of the share instance export location. ' - 'Available only for microversion >= 2.35.') + 'Available only for microversion >= 2.35.', +) @api_versions.wraps("2.3") def do_share_instance_list(cs, args): """List share instances (Admin only).""" share = _find_share(cs, args.share_id) if args.share_id else None list_of_keys = [ - 'ID', 'Share ID', 'Host', 'Status', 'Availability Zone', - 'Share Network ID', 'Share Server ID', 'Share Type ID', + 'ID', + 'Share ID', + 'Host', + 'Status', + 'Availability Zone', + 'Share Network ID', + 'Share Server ID', + 'Share Type ID', ] if args.columns is not None: @@ -2642,13 +2936,15 @@ def do_share_instance_list(cs, args): instances = cs.shares.list_instances(share) else: if cs.api_version.matches( - api_versions.APIVersion("2.35"), api_versions.APIVersion()): + api_versions.APIVersion("2.35"), api_versions.APIVersion() + ): instances = cs.share_instances.list(args.export_location) else: if args.export_location: raise exceptions.CommandError( "Filtering by export location is only " - "available with manila API version >= 2.35") + "available with manila API version >= 2.35" + ) instances = cs.share_instances.list() cliutils.print_list(instances, list_of_keys) @@ -2656,9 +2952,8 @@ def do_share_instance_list(cs, args): @api_versions.wraps("2.3", "2.8") @cliutils.arg( - 'instance', - metavar='', - help='Name or ID of the share instance.') + 'instance', metavar='', help='Name or ID of the share instance.' +) def do_share_instance_show(cs, args): """Show details about a share instance.""" instance = _find_share_instance(cs, args.instance) @@ -2667,9 +2962,8 @@ def do_share_instance_show(cs, args): @api_versions.wraps("2.9") # noqa @cliutils.arg( - 'instance', - metavar='', - help='Name or ID of the share instance.') + 'instance', metavar='', help='Name or ID of the share instance.' +) def do_share_instance_show(cs, args): # noqa """Show details about a share instance (Admin only).""" instance = _find_share_instance(cs, args.instance) @@ -2682,12 +2976,12 @@ def do_share_instance_show(cs, args): # noqa 'instance', metavar='', nargs='+', - help='Name or ID of the instance(s) to force delete.') + help='Name or ID of the instance(s) to force delete.', +) @api_versions.wraps("2.3") @cliutils.arg( - '--wait', - action='store_true', - help='Wait for share instance deletion') + '--wait', action='store_true', help='Wait for share instance deletion' +) @cliutils.service_type('sharev2') def do_share_instance_force_delete(cs, args): """Force-delete the share instance, regardless of state (Admin only).""" @@ -2700,17 +2994,23 @@ def do_share_instance_force_delete(cs, args): instance_ref.force_delete() except Exception as e: failure_count += 1 - print("Delete for share instance %s failed: %s" % (instance, e), - file=sys.stderr) + print( + "Delete for share instance %s failed: %s" % (instance, e), + file=sys.stderr, + ) if failure_count == len(args.instance): - raise exceptions.CommandError("Unable to force delete any of " - "specified share instances.") + raise exceptions.CommandError( + "Unable to force delete any of specified share instances." + ) if args.wait: for instance in instances_to_delete: try: _wait_for_resource_status( - cs, instance, resource_type='share_instance', - expected_status='deleted') + cs, + instance, + resource_type='share_instance', + expected_status='deleted', + ) except exceptions.CommandError as e: print(e, file=sys.stderr) @@ -2718,14 +3018,18 @@ def do_share_instance_force_delete(cs, args): @cliutils.arg( 'instance', metavar='', - help='Name or ID of the share instance to modify.') + help='Name or ID of the share instance to modify.', +) @cliutils.arg( '--state', metavar='', default='available', - help=('Indicate which state to assign the instance. Options include ' - 'available, error, creating, deleting, error_deleting, migrating,' - 'migrating_to. If no state is provided, available will be used.')) + help=( + 'Indicate which state to assign the instance. Options include ' + 'available, error, creating, deleting, error_deleting, migrating,' + 'migrating_to. If no state is provided, available will be used.' + ), +) @api_versions.wraps("2.3") def do_share_instance_reset_state(cs, args): """Explicitly update the state of a share instance (Admin only).""" @@ -2735,16 +3039,16 @@ def do_share_instance_reset_state(cs, args): @api_versions.wraps("2.9") @cliutils.arg( - 'instance', - metavar='', - help='Name or ID of the share instance.') + 'instance', metavar='', help='Name or ID of the share instance.' +) @cliutils.arg( '--columns', metavar='', type=str, default=None, help='Comma separated list of columns to be displayed ' - 'example --columns "id,host,status".') + 'example --columns "id,host,status".', +) def do_share_instance_export_location_list(cs, args): """List export locations of a given share instance.""" if args.columns is not None: @@ -2763,24 +3067,26 @@ def do_share_instance_export_location_list(cs, args): @api_versions.wraps("2.9") @cliutils.arg( - 'instance', - metavar='', - help='Name or ID of the share instance.') + 'instance', metavar='', help='Name or ID of the share instance.' +) @cliutils.arg( 'export_location', metavar='', - help='ID of the share instance export location.') + help='ID of the share instance export location.', +) def do_share_instance_export_location_show(cs, args): """Show export location for the share instance.""" instance = _find_share_instance(cs, args.instance) export_location = cs.share_instance_export_locations.get( - instance, args.export_location) + instance, args.export_location + ) view_data = export_location._info.copy() cliutils.print_dict(view_data) @cliutils.arg( - '--all-tenants', '--all-projects', + '--all-tenants', + '--all-projects', action='single_alias', dest='all_projects', metavar='<0|1>', @@ -2788,32 +3094,37 @@ def do_share_instance_export_location_show(cs, args): type=int, const=1, default=0, - help='Display information from all projects (Admin only).') + help='Display information from all projects (Admin only).', +) @cliutils.arg( '--name', metavar='', type=str, default=None, - help='Filter results by name.') + help='Filter results by name.', +) @cliutils.arg( '--description', metavar='', type=str, default=None, help='Filter results by description. ' - 'Available only for microversion >= 2.36.') + 'Available only for microversion >= 2.36.', +) @cliutils.arg( '--status', metavar='', default=None, - help='Filter results by status.') + help='Filter results by status.', +) @cliutils.arg( '--share-id', '--share_id', # alias metavar='', default=None, action='single_alias', - help='Filter results by source share ID.') + help='Filter results by source share ID.', +) @cliutils.arg( '--usage', dest='usage', @@ -2822,22 +3133,29 @@ def do_share_instance_export_location_show(cs, args): type=str, const='any', default=None, - choices=['any', 'used', 'unused', ], - help='Either filter or not snapshots by its usage. OPTIONAL: Default=any.') + choices=[ + 'any', + 'used', + 'unused', + ], + help='Either filter or not snapshots by its usage. OPTIONAL: Default=any.', +) @cliutils.arg( '--limit', metavar='', type=int, default=None, help='Maximum number of share snapshots to return. ' - 'OPTIONAL: Default=None.') + 'OPTIONAL: Default=None.', +) @cliutils.arg( '--offset', metavar='', type=int, default=None, help='Set offset to define start point of share snapshots listing. ' - 'OPTIONAL: Default=None.') + 'OPTIONAL: Default=None.', +) @cliutils.arg( '--sort-key', '--sort_key', # alias @@ -2846,7 +3164,8 @@ def do_share_instance_export_location_show(cs, args): default=None, action='single_alias', help='Key to be sorted, available keys are %(keys)s. ' - 'Default=None.' % {'keys': constants.SNAPSHOT_SORT_KEY_VALUES}) + 'Default=None.' % {'keys': constants.SNAPSHOT_SORT_KEY_VALUES}, +) @cliutils.arg( '--sort-dir', '--sort_dir', # alias @@ -2855,28 +3174,32 @@ def do_share_instance_export_location_show(cs, args): default=None, action='single_alias', help='Sort direction, available values are %(values)s. ' - 'OPTIONAL: Default=None.' % {'values': constants.SORT_DIR_VALUES}) + 'OPTIONAL: Default=None.' % {'values': constants.SORT_DIR_VALUES}, +) @cliutils.arg( '--columns', metavar='', type=str, default=None, help='Comma separated list of columns to be displayed ' - 'example --columns "id,name".') + 'example --columns "id,name".', +) @cliutils.arg( '--name~', metavar='', type=str, default=None, help='Filter results matching a share snapshot name pattern. ' - 'Available only for microversion >= 2.36.') + 'Available only for microversion >= 2.36.', +) @cliutils.arg( '--description~', metavar='', type=str, default=None, help='Filter results matching a share snapshot description pattern. ' - 'Available only for microversion >= 2.36.') + 'Available only for microversion >= 2.36.', +) @cliutils.arg( '--metadata', metavar='', @@ -2884,7 +3207,8 @@ def do_share_instance_export_location_show(cs, args): default=None, nargs='*', help='Filters results by a metadata key and value. OPTIONAL: ' - 'Default=None, Available only for microversion >= 2.73. ') + 'Default=None, Available only for microversion >= 2.73. ', +) @cliutils.arg( '--count', dest='count', @@ -2892,19 +3216,24 @@ def do_share_instance_export_location_show(cs, args): choices=['True', 'False'], default=False, help='Display total number of share snapshots to return. ' - 'Available only for microversion >= 2.79.') + 'Available only for microversion >= 2.79.', +) def do_snapshot_list(cs, args): """List all the snapshots.""" all_projects = int( - os.environ.get("ALL_TENANTS", - os.environ.get("ALL_PROJECTS", - args.all_projects)) + os.environ.get( + "ALL_TENANTS", os.environ.get("ALL_PROJECTS", args.all_projects) + ) ) if args.columns is not None: list_of_keys = _split_columns(columns=args.columns) else: list_of_keys = [ - 'ID', 'Share ID', 'Status', 'Name', 'Share Size', + 'ID', + 'Share ID', + 'Status', + 'Name', + 'Share Size', ] if all_projects: list_of_keys.append('Project ID') @@ -2921,23 +3250,29 @@ def do_snapshot_list(cs, args): 'usage': args.usage, 'metadata': _extract_metadata(args), } - if cs.api_version.matches(api_versions.APIVersion("2.36"), - api_versions.APIVersion()): + if cs.api_version.matches( + api_versions.APIVersion("2.36"), api_versions.APIVersion() + ): search_opts['name~'] = getattr(args, 'name~') search_opts['description~'] = getattr(args, 'description~') search_opts['description'] = getattr(args, 'description') - elif (getattr(args, 'name~') or getattr(args, 'description~') or - getattr(args, 'description')): + elif ( + getattr(args, 'name~') + or getattr(args, 'description~') + or getattr(args, 'description') + ): raise exceptions.CommandError( "Pattern based filtering (name~, description~ and description)" - " is only available with manila API version >= 2.36") + " is only available with manila API version >= 2.36" + ) - if (args.count and - cs.api_version.matches( - api_versions.APIVersion(), api_versions.APIVersion("2.78"))): + if args.count and cs.api_version.matches( + api_versions.APIVersion(), api_versions.APIVersion("2.78") + ): raise exceptions.CommandError( "Display total number of share snapshots is only " - "available with manila API version >= 2.79") + "available with manila API version >= 2.79" + ) total_count = 0 if strutils.bool_from_string(args.count, strict=True): @@ -2945,12 +3280,14 @@ def do_snapshot_list(cs, args): snapshots, total_count = cs.share_snapshots.list( search_opts=search_opts, sort_key=args.sort_key, - sort_dir=args.sort_dir) + sort_dir=args.sort_dir, + ) else: snapshots = cs.share_snapshots.list( search_opts=search_opts, sort_key=args.sort_key, - sort_dir=args.sort_dir) + sort_dir=args.sort_dir, + ) cliutils.print_list(snapshots, list_of_keys, sortby_index=None) if args.count: @@ -2958,30 +3295,30 @@ def do_snapshot_list(cs, args): @cliutils.arg( - 'snapshot', - metavar='', - help='Name or ID of the snapshot.') + 'snapshot', metavar='', help='Name or ID of the snapshot.' +) def do_snapshot_show(cs, args): """Show details about a snapshot.""" snapshot = _find_share_snapshot(cs, args.snapshot) export_locations = cs.share_snapshot_export_locations.list( - snapshot=snapshot) + snapshot=snapshot + ) snapshot._info['export_locations'] = export_locations _print_share_snapshot(cs, snapshot) @api_versions.wraps("2.32") @cliutils.arg( - 'snapshot', - metavar='', - help='Name or ID of the snapshot.') + 'snapshot', metavar='', help='Name or ID of the snapshot.' +) @cliutils.arg( '--columns', metavar='', type=str, default=None, help='Comma separated list of columns to be displayed ' - 'example --columns "id,path".') + 'example --columns "id,path".', +) def do_snapshot_export_location_list(cs, args): """List export locations of a given snapshot.""" if args.columns is not None: @@ -2992,8 +3329,7 @@ def do_snapshot_export_location_list(cs, args): 'Path', ] snapshot = _find_share_snapshot(cs, args.snapshot) - export_locations = cs.share_snapshot_export_locations.list( - snapshot) + export_locations = cs.share_snapshot_export_locations.list(snapshot) cliutils.print_list(export_locations, list_of_keys) @@ -3001,14 +3337,16 @@ def do_snapshot_export_location_list(cs, args): @cliutils.arg( 'instance', metavar='', - help='Name or ID of the snapshot instance.') + help='Name or ID of the snapshot instance.', +) @cliutils.arg( '--columns', metavar='', type=str, default=None, help='Comma separated list of columns to be displayed ' - 'example --columns "id,path,is_admin_only".') + 'example --columns "id,path,is_admin_only".', +) def do_snapshot_instance_export_location_list(cs, args): """List export locations of a given snapshot instance.""" if args.columns is not None: @@ -3021,24 +3359,26 @@ def do_snapshot_instance_export_location_list(cs, args): ] instance = _find_share_snapshot_instance(cs, args.instance) export_locations = cs.share_snapshot_instance_export_locations.list( - instance) + instance + ) cliutils.print_list(export_locations, list_of_keys) @api_versions.wraps("2.32") @cliutils.arg( - 'snapshot', - metavar='', - help='Name or ID of the snapshot.') + 'snapshot', metavar='', help='Name or ID of the snapshot.' +) @cliutils.arg( 'export_location', metavar='', - help='ID of the share snapshot export location.') + help='ID of the share snapshot export location.', +) def do_snapshot_export_location_show(cs, args): """Show export location of the share snapshot.""" snapshot = _find_share_snapshot(cs, args.snapshot) export_location = cs.share_snapshot_export_locations.get( - args.export_location, snapshot) + args.export_location, snapshot + ) view_data = export_location._info.copy() cliutils.print_dict(view_data) @@ -3047,78 +3387,83 @@ def do_snapshot_export_location_show(cs, args): @cliutils.arg( 'snapshot_instance', metavar='', - help='ID of the share snapshot instance.') + help='ID of the share snapshot instance.', +) @cliutils.arg( 'export_location', metavar='', - help='ID of the share snapshot instance export location.') + help='ID of the share snapshot instance export location.', +) def do_snapshot_instance_export_location_show(cs, args): """Show export location of the share instance snapshot.""" - snapshot_instance = _find_share_snapshot_instance(cs, - args.snapshot_instance) + snapshot_instance = _find_share_snapshot_instance( + cs, args.snapshot_instance + ) export_location = cs.share_snapshot_instance_export_locations.get( - args.export_location, snapshot_instance) + args.export_location, snapshot_instance + ) view_data = export_location._info.copy() cliutils.print_dict(view_data) @cliutils.arg( - 'share', - metavar='', - help='Name or ID of the share to snapshot.') + 'share', metavar='', help='Name or ID of the share to snapshot.' +) @cliutils.arg( '--force', metavar='', help='Optional flag to indicate whether ' 'to snapshot a share even if it\'s busy. ' '(Default=False)', - default=False) + default=False, +) @cliutils.arg( '--name', metavar='', default=None, - help='Optional snapshot name. (Default=None)') + help='Optional snapshot name. (Default=None)', +) @cliutils.arg( '--description', metavar='', default=None, - help='Optional snapshot description. (Default=None)') + help='Optional snapshot description. (Default=None)', +) @cliutils.arg( '--wait', action='store_true', default=False, - help='Wait for snapshot to be created.') + help='Wait for snapshot to be created.', +) def do_snapshot_create(cs, args): """Add a new snapshot.""" share = _find_share(cs, args.share) - snapshot = cs.share_snapshots.create(share, - args.force, - args.name, - args.description) + snapshot = cs.share_snapshots.create( + share, args.force, args.name, args.description + ) if args.wait: try: - _wait_for_snapshot_status(cs, snapshot, - expected_status='available') + _wait_for_snapshot_status( + cs, snapshot, expected_status='available' + ) except exceptions.CommandError as e: print(e, file=sys.stderr) _print_share_snapshot(cs, snapshot) @cliutils.arg( - 'share', - metavar='', - help='Name or ID of the share to rename.') + 'share', metavar='', help='Name or ID of the share to rename.' +) @cliutils.arg( - '--name', - metavar='', - default=None, - help='New name for the share.') + '--name', metavar='', default=None, help='New name for the share.' +) @cliutils.arg( '--description', metavar='', help='Optional share description. (Default=None)', - default=None) + default=None, +) @cliutils.arg( '--is-public', '--is_public', # alias @@ -3126,7 +3471,8 @@ def do_snapshot_create(cs, args): default=None, type=str, action="single_alias", - help='Public share is visible for all projects.') + help='Public share is visible for all projects.', +) def do_update(cs, args): """Rename a share.""" kwargs = {} @@ -3136,8 +3482,9 @@ def do_update(cs, args): if args.description is not None: kwargs['display_description'] = args.description if args.is_public is not None: - kwargs['is_public'] = strutils.bool_from_string(args.is_public, - strict=True) + kwargs['is_public'] = strutils.bool_from_string( + args.is_public, strict=True + ) if not kwargs: msg = "Must supply name, description or is_public value." raise exceptions.CommandError(msg) @@ -3147,17 +3494,17 @@ def do_update(cs, args): @cliutils.arg( 'snapshot', metavar='', - help='Name or ID of the snapshot to rename.') + help='Name or ID of the snapshot to rename.', +) @cliutils.arg( - 'name', - nargs='?', - metavar='', - help='New name for the snapshot.') + 'name', nargs='?', metavar='', help='New name for the snapshot.' +) @cliutils.arg( '--description', metavar='', help='Optional snapshot description. (Default=None)', - default=None) + default=None, +) def do_snapshot_rename(cs, args): """Rename a snapshot.""" kwargs = {} @@ -3176,43 +3523,48 @@ def do_snapshot_rename(cs, args): 'snapshot', metavar='', nargs='+', - help='Name or ID of the snapshot(s) to delete.') + help='Name or ID of the snapshot(s) to delete.', +) @cliutils.arg( '--wait', action='store_true', default=False, - help='Wait for snapshot to be deleted') + help='Wait for snapshot to be deleted', +) def do_snapshot_delete(cs, args): """Remove one or more snapshots.""" failure_count = 0 for snapshot in args.snapshot: try: - snapshot_ref = _find_share_snapshot( - cs, snapshot) + snapshot_ref = _find_share_snapshot(cs, snapshot) cs.share_snapshots.delete(snapshot_ref) if args.wait: - _wait_for_snapshot_status(cs, snapshot, - expected_status='deleted') + _wait_for_snapshot_status( + cs, snapshot, expected_status='deleted' + ) except Exception as e: failure_count += 1 - print("Delete for snapshot %s failed: %s" % ( - snapshot, e), file=sys.stderr) + print( + "Delete for snapshot %s failed: %s" % (snapshot, e), + file=sys.stderr, + ) if failure_count == len(args.snapshot): - raise exceptions.CommandError("Unable to delete any of the specified " - "snapshots.") + raise exceptions.CommandError( + "Unable to delete any of the specified snapshots." + ) @cliutils.arg( 'snapshot', metavar='', nargs='+', - help='Name or ID of the snapshot(s) to force delete.') + help='Name or ID of the snapshot(s) to force delete.', +) @cliutils.arg( - '--wait', - action='store_true', - help='Wait for snapshot to delete') + '--wait', action='store_true', help='Wait for snapshot to delete' +) @cliutils.service_type('sharev2') def do_snapshot_force_delete(cs, args): """Attempt force-deletion of one or more snapshots. @@ -3224,24 +3576,29 @@ def do_snapshot_force_delete(cs, args): for snapshot in args.snapshot: try: - snapshot_ref = _find_share_snapshot( - cs, snapshot) + snapshot_ref = _find_share_snapshot(cs, snapshot) snapshots_to_delete.append(snapshot_ref) snapshot_ref.force_delete() except Exception as e: failure_count += 1 - print("Delete for snapshot %s failed: %s" % ( - snapshot, e), file=sys.stderr) + print( + "Delete for snapshot %s failed: %s" % (snapshot, e), + file=sys.stderr, + ) if failure_count == len(args.snapshot): - raise exceptions.CommandError("Unable to force delete any of the " - "specified snapshots.") + raise exceptions.CommandError( + "Unable to force delete any of the specified snapshots." + ) if args.wait: for snapshot in snapshots_to_delete: try: _wait_for_resource_status( - cs, snapshot, resource_type='snapshot', - expected_status='deleted') + cs, + snapshot, + resource_type='snapshot', + expected_status='deleted', + ) except exceptions.CommandError as e: print(e, file=sys.stderr) @@ -3249,15 +3606,19 @@ def do_snapshot_force_delete(cs, args): @cliutils.arg( 'snapshot', metavar='', - help='Name or ID of the snapshot to modify.') + help='Name or ID of the snapshot to modify.', +) @cliutils.arg( '--state', metavar='', default='available', - help=('Indicate which state to assign the snapshot. ' - 'Options include available, error, creating, deleting, ' - 'error_deleting. If no state is provided, ' - 'available will be used.')) + help=( + 'Indicate which state to assign the snapshot. ' + 'Options include available, error, creating, deleting, ' + 'error_deleting. If no state is provided, ' + 'available will be used.' + ), +) def do_snapshot_reset_state(cs, args): """Explicitly update the state of a snapshot (Admin only).""" snapshot = _find_share_snapshot(cs, args.snapshot) @@ -3269,35 +3630,47 @@ def do_snapshot_reset_state(cs, args): '--snapshot', metavar='', default=None, - help='Filter results by share snapshot ID.') + help='Filter results by share snapshot ID.', +) @cliutils.arg( '--columns', metavar='', type=str, default=None, help='Comma separated list of columns to be displayed ' - 'example --columns "id".') + 'example --columns "id".', +) @cliutils.arg( '--detailed', metavar='', default=False, - help='Show detailed information about snapshot instances.' - ' (Default=False)') + help='Show detailed information about snapshot instances. (Default=False)', +) def do_snapshot_instance_list(cs, args): """List share snapshot instances.""" - snapshot = (_find_share_snapshot(cs, args.snapshot) - if args.snapshot else None) + snapshot = ( + _find_share_snapshot(cs, args.snapshot) if args.snapshot else None + ) if args.columns is not None: list_of_keys = _split_columns(columns=args.columns) elif args.detailed: - list_of_keys = ['ID', 'Snapshot ID', 'Status', 'Created_at', - 'Updated_at', 'Share_id', 'Share_instance_id', - 'Progress', 'Provider_location'] + list_of_keys = [ + 'ID', + 'Snapshot ID', + 'Status', + 'Created_at', + 'Updated_at', + 'Share_id', + 'Share_instance_id', + 'Progress', + 'Provider_location', + ] else: list_of_keys = ['ID', 'Snapshot ID', 'Status'] instances = cs.share_snapshot_instances.list( - detailed=args.detailed, snapshot=snapshot) + detailed=args.detailed, snapshot=snapshot + ) cliutils.print_list(instances, list_of_keys) @@ -3306,13 +3679,16 @@ def do_snapshot_instance_list(cs, args): @cliutils.arg( 'snapshot_instance', metavar='', - help='ID of the share snapshot instance.') + help='ID of the share snapshot instance.', +) def do_snapshot_instance_show(cs, args): """Show details about a share snapshot instance.""" snapshot_instance = _find_share_snapshot_instance( - cs, args.snapshot_instance) - export_locations = ( - cs.share_snapshot_instance_export_locations.list(snapshot_instance)) + cs, args.snapshot_instance + ) + export_locations = cs.share_snapshot_instance_export_locations.list( + snapshot_instance + ) snapshot_instance._info['export_locations'] = export_locations _print_share_snapshot(cs, snapshot_instance) @@ -3320,34 +3696,41 @@ def do_snapshot_instance_show(cs, args): @cliutils.arg( 'snapshot_instance', metavar='', - help='ID of the snapshot instance to modify.') + help='ID of the snapshot instance to modify.', +) @cliutils.arg( '--state', metavar='', default='available', - help=('Indicate which state to assign the snapshot instance. ' - 'Options include available, error, creating, deleting, ' - 'error_deleting. If no state is provided, available ' - 'will be used.')) + help=( + 'Indicate which state to assign the snapshot instance. ' + 'Options include available, error, creating, deleting, ' + 'error_deleting. If no state is provided, available ' + 'will be used.' + ), +) @api_versions.wraps("2.19") def do_snapshot_instance_reset_state(cs, args): """Explicitly update the state of a share snapshot instance.""" snapshot_instance = _find_share_snapshot_instance( - cs, args.snapshot_instance) + cs, args.snapshot_instance + ) snapshot_instance.reset_state(args.state) @cliutils.arg( - 'share', - metavar='', - help='Name or ID of the share to modify.') + 'share', metavar='', help='Name or ID of the share to modify.' +) @cliutils.arg( '--state', metavar='', default='available', - help=('Indicate which state to assign the share. Options include ' - 'available, error, creating, deleting, error_deleting. If no ' - 'state is provided, available will be used.')) + help=( + 'Indicate which state to assign the share. Options include ' + 'available, error, creating, deleting, error_deleting. If no ' + 'state is provided, available will be used.' + ), +) def do_reset_state(cs, args): """Explicitly update the state of a share (Admin only).""" share = _find_share(cs, args.share) @@ -3357,29 +3740,34 @@ def do_reset_state(cs, args): @api_versions.wraps("1.0", "2.25") @cliutils.arg( '--neutron-net-id', - '--neutron-net_id', '--neutron_net_id', '--neutron_net-id', + '--neutron-net_id', + '--neutron_net_id', + '--neutron_net-id', metavar='', default=None, action='single_alias', - help="Neutron network ID. Used to set up network for share servers.") + help="Neutron network ID. Used to set up network for share servers.", +) @cliutils.arg( '--neutron-subnet-id', - '--neutron-subnet_id', '--neutron_subnet_id', '--neutron_subnet-id', + '--neutron-subnet_id', + '--neutron_subnet_id', + '--neutron_subnet-id', metavar='', default=None, action='single_alias', help="Neutron subnet ID. Used to set up network for share servers. " - "This subnet should belong to specified neutron network.") + "This subnet should belong to specified neutron network.", +) @cliutils.arg( - '--name', - metavar='', - default=None, - help="Share network name.") + '--name', metavar='', default=None, help="Share network name." +) @cliutils.arg( '--description', metavar='', default=None, - help="Share network description.") + help="Share network description.", +) def do_share_network_create(cs, args): """Create a share network to export shares to.""" values = { @@ -3396,39 +3784,47 @@ def do_share_network_create(cs, args): @api_versions.wraps("2.26") # noqa @cliutils.arg( '--neutron-net-id', - '--neutron-net_id', '--neutron_net_id', '--neutron_net-id', + '--neutron-net_id', + '--neutron_net_id', + '--neutron_net-id', metavar='', default=None, action='single_alias', - help="Neutron network ID. Used to set up network for share servers.") + help="Neutron network ID. Used to set up network for share servers.", +) @cliutils.arg( '--neutron-subnet-id', - '--neutron-subnet_id', '--neutron_subnet_id', '--neutron_subnet-id', + '--neutron-subnet_id', + '--neutron_subnet_id', + '--neutron_subnet-id', metavar='', default=None, action='single_alias', help="Neutron subnet ID. Used to set up network for share servers. " - "This subnet should belong to specified neutron network.") + "This subnet should belong to specified neutron network.", +) @cliutils.arg( - '--name', - metavar='', - default=None, - help="Share network name.") + '--name', metavar='', default=None, help="Share network name." +) @cliutils.arg( '--description', metavar='', default=None, - help="Share network description.") + help="Share network description.", +) @cliutils.arg( - '--availability-zone', '--availability_zone', '--az', + '--availability-zone', + '--availability_zone', + '--az', metavar='', default=None, action='single_alias', help="Availability zone in which the subnet should be created. Share " - "networks can have one or more subnets in different availability " - "zones when the driver is operating with " - "'driver_handles_share_servers' extra_spec set to True. Available " - "only for microversion >= 2.51. (Default=None)") + "networks can have one or more subnets in different availability " + "zones when the driver is operating with " + "'driver_handles_share_servers' extra_spec set to True. Available " + "only for microversion >= 2.51. (Default=None)", +) def do_share_network_create(cs, args): # noqa """Create a share network to export shares to.""" values = { @@ -3442,7 +3838,8 @@ def do_share_network_create(cs, args): # noqa elif args.availability_zone: raise exceptions.CommandError( "Creating share networks with a given az is only " - "available with manila API version >= 2.51") + "available with manila API version >= 2.51" + ) share_network = cs.share_networks.create(**values) info = share_network._info.copy() cliutils.print_dict(info) @@ -3452,32 +3849,38 @@ def do_share_network_create(cs, args): # noqa @cliutils.arg( 'share_network', metavar='', - help='Name or ID of share network to update.') + help='Name or ID of share network to update.', +) @cliutils.arg( '--neutron-net-id', - '--neutron-net_id', '--neutron_net_id', '--neutron_net-id', + '--neutron-net_id', + '--neutron_net_id', + '--neutron_net-id', metavar='', default=None, action='single_alias', - help="Neutron network ID. Used to set up network for share servers.") + help="Neutron network ID. Used to set up network for share servers.", +) @cliutils.arg( '--neutron-subnet-id', - '--neutron-subnet_id', '--neutron_subnet_id', '--neutron_subnet-id', + '--neutron-subnet_id', + '--neutron_subnet_id', + '--neutron_subnet-id', metavar='', default=None, action='single_alias', help="Neutron subnet ID. Used to set up network for share servers. " - "This subnet should belong to specified neutron network.") + "This subnet should belong to specified neutron network.", +) @cliutils.arg( - '--name', - metavar='', - default=None, - help="Share network name.") + '--name', metavar='', default=None, help="Share network name." +) @cliutils.arg( '--description', metavar='', default=None, - help="Share network description.") + help="Share network description.", +) def do_share_network_update(cs, args): """Update share network data.""" values = { @@ -3486,8 +3889,9 @@ def do_share_network_update(cs, args): 'name': args.name, 'description': args.description, } - share_network = _find_share_network( - cs, args.share_network).update(**values) + share_network = _find_share_network(cs, args.share_network).update( + **values + ) info = share_network._info.copy() cliutils.print_dict(info) @@ -3496,35 +3900,41 @@ def do_share_network_update(cs, args): @cliutils.arg( 'share_network', metavar='', - help='Name or ID of share network to update.') + help='Name or ID of share network to update.', +) @cliutils.arg( '--neutron-net-id', - '--neutron-net_id', '--neutron_net_id', '--neutron_net-id', + '--neutron-net_id', + '--neutron_net_id', + '--neutron_net-id', metavar='', default=None, action='single_alias', help="Neutron network ID. Used to set up network for share servers. " - "This option is deprecated for microversion >= 2.51.") + "This option is deprecated for microversion >= 2.51.", +) @cliutils.arg( '--neutron-subnet-id', - '--neutron-subnet_id', '--neutron_subnet_id', '--neutron_subnet-id', + '--neutron-subnet_id', + '--neutron_subnet_id', + '--neutron_subnet-id', metavar='', default=None, action='single_alias', help="Neutron subnet ID. Used to set up network for share servers. " - "This subnet should belong to specified neutron network. " - "This option is deprecated for microversion >= 2.51.") + "This subnet should belong to specified neutron network. " + "This option is deprecated for microversion >= 2.51.", +) @cliutils.arg( - '--name', - metavar='', - default=None, - help="Share network name.") + '--name', metavar='', default=None, help="Share network name." +) @cliutils.arg( '--description', metavar='', default=None, - help="Share network description.") -def do_share_network_update(cs, args): # noqa + help="Share network description.", +) +def do_share_network_update(cs, args): # noqa """Update share network data.""" values = { @@ -3533,8 +3943,9 @@ def do_share_network_update(cs, args): # noqa 'name': args.name, 'description': args.description, } - share_network = _find_share_network( - cs, args.share_network).update(**values) + share_network = _find_share_network(cs, args.share_network).update( + **values + ) info = share_network._info.copy() cliutils.print_dict(info) @@ -3542,7 +3953,8 @@ def do_share_network_update(cs, args): # noqa @cliutils.arg( 'share_network', metavar='', - help='Name or ID of the share network to show.') + help='Name or ID of the share network to show.', +) def do_share_network_show(cs, args): """Retrieve details for a share network.""" share_network = _find_share_network(cs, args.share_network) @@ -3552,7 +3964,8 @@ def do_share_network_show(cs, args): @api_versions.wraps("1.0", "2.25") @cliutils.arg( - '--all-tenants', '--all-projects', + '--all-tenants', + '--all-projects', action='single_alias', dest='all_projects', metavar='<0|1>', @@ -3560,19 +3973,19 @@ def do_share_network_show(cs, args): type=int, const=1, default=0, - help='Display information from all projects (Admin only).') + help='Display information from all projects (Admin only).', +) @cliutils.arg( '--project-id', '--project_id', # alias metavar='', action='single_alias', default=None, - help='Filter results by project ID.') + help='Filter results by project ID.', +) @cliutils.arg( - '--name', - metavar='', - default=None, - help='Filter results by name.') + '--name', metavar='', default=None, help='Filter results by name.' +) @cliutils.arg( '--created-since', '--created_since', # alias @@ -3580,7 +3993,8 @@ def do_share_network_show(cs, args): action='single_alias', default=None, help='''Return only share networks created since given date. ''' - '''The date is in the format 'yyyy-mm-dd'.''') + '''The date is in the format 'yyyy-mm-dd'.''', +) @cliutils.arg( '--created-before', '--created_before', # alias @@ -3588,36 +4002,44 @@ def do_share_network_show(cs, args): action='single_alias', default=None, help='''Return only share networks created until given date. ''' - '''The date is in the format 'yyyy-mm-dd'.''') + '''The date is in the format 'yyyy-mm-dd'.''', +) @cliutils.arg( '--security-service', '--security_service', # alias metavar='', action='single_alias', default=None, - help='Filter results by attached security service.') + help='Filter results by attached security service.', +) @cliutils.arg( '--neutron-net-id', - '--neutron_net_id', '--neutron_net-id', '--neutron-net_id', # aliases + '--neutron_net_id', + '--neutron_net-id', + '--neutron-net_id', # aliases metavar='', action='single_alias', default=None, - help='Filter results by neutron net ID.') + help='Filter results by neutron net ID.', +) @cliutils.arg( '--neutron-subnet-id', - '--neutron_subnet_id', '--neutron-subnet_id', # aliases + '--neutron_subnet_id', + '--neutron-subnet_id', # aliases '--neutron_subnet-id', # alias metavar='', action='single_alias', default=None, - help='Filter results by neutron subnet ID.') + help='Filter results by neutron subnet ID.', +) @cliutils.arg( '--network-type', '--network_type', # alias metavar='', action='single_alias', default=None, - help='Filter results by network type.') + help='Filter results by network type.', +) @cliutils.arg( '--segmentation-id', '--segmentation_id', # alias @@ -3625,12 +4047,11 @@ def do_share_network_show(cs, args): type=int, action='single_alias', default=None, - help='Filter results by segmentation ID.') + help='Filter results by segmentation ID.', +) @cliutils.arg( - '--cidr', - metavar='', - default=None, - help='Filter results by CIDR.') + '--cidr', metavar='', default=None, help='Filter results by CIDR.' +) @cliutils.arg( '--ip-version', '--ip_version', # alias @@ -3638,32 +4059,36 @@ def do_share_network_show(cs, args): type=int, action='single_alias', default=None, - help='Filter results by IP version.') + help='Filter results by IP version.', +) @cliutils.arg( '--offset', metavar='', type=int, default=None, - help='Start position of share networks listing.') + help='Start position of share networks listing.', +) @cliutils.arg( '--limit', metavar='', type=int, default=None, - help='Number of share networks to return per request.') + help='Number of share networks to return per request.', +) @cliutils.arg( '--columns', metavar='', type=str, default=None, help='Comma separated list of columns to be displayed ' - 'example --columns "id".') + 'example --columns "id".', +) def do_share_network_list(cs, args): """Get a list of network info.""" all_projects = int( - os.environ.get("ALL_TENANTS", - os.environ.get("ALL_PROJECTS", - args.all_projects)) + os.environ.get( + "ALL_TENANTS", os.environ.get("ALL_PROJECTS", args.all_projects) + ) ) search_opts = { 'all_tenants': all_projects, @@ -3682,7 +4107,8 @@ def do_share_network_list(cs, args): } if args.security_service: search_opts['security_service_id'] = _find_security_service( - cs, args.security_service).id + cs, args.security_service + ).id share_networks = cs.share_networks.list(search_opts=search_opts) fields = ['id', 'name'] @@ -3694,7 +4120,8 @@ def do_share_network_list(cs, args): @api_versions.wraps("2.26") # noqa @cliutils.arg( - '--all-tenants', '--all-projects', + '--all-tenants', + '--all-projects', action='single_alias', dest='all_projects', metavar='<0|1>', @@ -3702,27 +4129,31 @@ def do_share_network_list(cs, args): type=int, const=1, default=0, - help='Display information from all projects (Admin only).') + help='Display information from all projects (Admin only).', +) @cliutils.arg( '--project-id', '--project_id', # alias metavar='', action='single_alias', default=None, - help='Filter results by project ID.') + help='Filter results by project ID.', +) @cliutils.arg( '--name', metavar='', type=str, default=None, - help='Filter results by name.') + help='Filter results by name.', +) @cliutils.arg( '--description', metavar='', type=str, default=None, help='Filter results by description. ' - 'Available only for microversion >= 2.36.') + 'Available only for microversion >= 2.36.', +) @cliutils.arg( '--created-since', '--created_since', # alias @@ -3730,7 +4161,8 @@ def do_share_network_list(cs, args): action='single_alias', default=None, help='''Return only share networks created since given date. ''' - '''The date is in the format 'yyyy-mm-dd'.''') + '''The date is in the format 'yyyy-mm-dd'.''', +) @cliutils.arg( '--created-before', '--created_before', # alias @@ -3738,36 +4170,44 @@ def do_share_network_list(cs, args): action='single_alias', default=None, help='''Return only share networks created until given date. ''' - '''The date is in the format 'yyyy-mm-dd'.''') + '''The date is in the format 'yyyy-mm-dd'.''', +) @cliutils.arg( '--security-service', '--security_service', # alias metavar='', action='single_alias', default=None, - help='Filter results by attached security service.') + help='Filter results by attached security service.', +) @cliutils.arg( '--neutron-net-id', - '--neutron_net_id', '--neutron_net-id', '--neutron-net_id', # aliases + '--neutron_net_id', + '--neutron_net-id', + '--neutron-net_id', # aliases metavar='', action='single_alias', default=None, - help='Filter results by neutron net ID.') + help='Filter results by neutron net ID.', +) @cliutils.arg( '--neutron-subnet-id', - '--neutron_subnet_id', '--neutron-subnet_id', # aliases + '--neutron_subnet_id', + '--neutron-subnet_id', # aliases '--neutron_subnet-id', # alias metavar='', action='single_alias', default=None, - help='Filter results by neutron subnet ID.') + help='Filter results by neutron subnet ID.', +) @cliutils.arg( '--network-type', '--network_type', # alias metavar='', action='single_alias', default=None, - help='Filter results by network type.') + help='Filter results by network type.', +) @cliutils.arg( '--segmentation-id', '--segmentation_id', # alias @@ -3775,12 +4215,11 @@ def do_share_network_list(cs, args): type=int, action='single_alias', default=None, - help='Filter results by segmentation ID.') + help='Filter results by segmentation ID.', +) @cliutils.arg( - '--cidr', - metavar='', - default=None, - help='Filter results by CIDR.') + '--cidr', metavar='', default=None, help='Filter results by CIDR.' +) @cliutils.arg( '--ip-version', '--ip_version', # alias @@ -3788,46 +4227,52 @@ def do_share_network_list(cs, args): type=int, action='single_alias', default=None, - help='Filter results by IP version.') + help='Filter results by IP version.', +) @cliutils.arg( '--offset', metavar='', type=int, default=None, - help='Start position of share networks listing.') + help='Start position of share networks listing.', +) @cliutils.arg( '--limit', metavar='', type=int, default=None, - help='Number of share networks to return per request.') + help='Number of share networks to return per request.', +) @cliutils.arg( '--columns', metavar='', type=str, default=None, help='Comma separated list of columns to be displayed ' - 'example --columns "id".') + 'example --columns "id".', +) @cliutils.arg( '--name~', metavar='', type=str, default=None, help='Filter results matching a share network name pattern. ' - 'Available only for microversion >= 2.36.') + 'Available only for microversion >= 2.36.', +) @cliutils.arg( '--description~', metavar='', type=str, default=None, help='Filter results matching a share network description pattern. ' - 'Available only for microversion >= 2.36.') -def do_share_network_list(cs, args): # noqa + 'Available only for microversion >= 2.36.', +) +def do_share_network_list(cs, args): # noqa """Get a list of share networks""" all_projects = int( - os.environ.get("ALL_TENANTS", - os.environ.get("ALL_PROJECTS", - args.all_projects)) + os.environ.get( + "ALL_TENANTS", os.environ.get("ALL_PROJECTS", args.all_projects) + ) ) search_opts = { 'all_tenants': all_projects, @@ -3844,20 +4289,26 @@ def do_share_network_list(cs, args): # noqa 'offset': args.offset, 'limit': args.limit, } - if cs.api_version.matches(api_versions.APIVersion("2.36"), - api_versions.APIVersion()): + if cs.api_version.matches( + api_versions.APIVersion("2.36"), api_versions.APIVersion() + ): search_opts['name~'] = getattr(args, 'name~') search_opts['description~'] = getattr(args, 'description~') search_opts['description'] = getattr(args, 'description') - elif (getattr(args, 'name~') or getattr(args, 'description~') or - getattr(args, 'description')): + elif ( + getattr(args, 'name~') + or getattr(args, 'description~') + or getattr(args, 'description') + ): raise exceptions.CommandError( "Pattern based filtering (name~, description~ and description)" - " is only available with manila API version >= 2.36") + " is only available with manila API version >= 2.36" + ) if args.security_service: search_opts['security_service_id'] = _find_security_service( - cs, args.security_service).id + cs, args.security_service + ).id share_networks = cs.share_networks.list(search_opts=search_opts) fields = ['id', 'name'] @@ -3870,11 +4321,13 @@ def do_share_network_list(cs, args): # noqa @cliutils.arg( 'share_network', metavar='', - help='Share network name or ID.') + help='Share network name or ID.', +) @cliutils.arg( 'security_service', metavar='', - help='Security service name or ID to associate with.') + help='Security service name or ID to associate with.', +) def do_share_network_security_service_add(cs, args): """Associate security service with share network.""" share_network = _find_share_network(cs, args.share_network) @@ -3885,26 +4338,29 @@ def do_share_network_security_service_add(cs, args): @cliutils.arg( 'share_network', metavar='', - help='Share network name or ID.') + help='Share network name or ID.', +) @cliutils.arg( 'security_service', metavar='', - help='Security service name or ID to associate with.') + help='Security service name or ID to associate with.', +) @cliutils.arg( '--reset', metavar='', choices=['True', 'False'], required=False, default=False, - help='Reset and restart the check operation.' - '(Optional, Default=False)') + help='Reset and restart the check operation.(Optional, Default=False)', +) @api_versions.wraps("2.63") def do_share_network_security_service_add_check(cs, args): """Associate security service with share network.""" share_network = _find_share_network(cs, args.share_network) security_service = _find_security_service(cs, args.security_service) add_sec_service_result = cs.share_networks.add_security_service_check( - share_network, security_service, reset_operation=args.reset) + share_network, security_service, reset_operation=args.reset + ) # result[0] is response code, result[1] is dict body cliutils.print_dict(add_sec_service_result[1]) @@ -3912,11 +4368,13 @@ def do_share_network_security_service_add_check(cs, args): @cliutils.arg( 'share_network', metavar='', - help='Share network name or ID.') + help='Share network name or ID.', +) @cliutils.arg( 'security_service', metavar='', - help='Security service name or ID to dissociate.') + help='Security service name or ID to dissociate.', +) def do_share_network_security_service_remove(cs, args): """Dissociate security service from share network.""" share_network = _find_share_network(cs, args.share_network) @@ -3927,14 +4385,16 @@ def do_share_network_security_service_remove(cs, args): @cliutils.arg( 'share_network', metavar='', - help='Share network name or ID.') + help='Share network name or ID.', +) @cliutils.arg( '--columns', metavar='', type=str, default=None, help='Comma separated list of columns to be displayed ' - 'example --columns "id,name".') + 'example --columns "id,name".', +) def do_share_network_security_service_list(cs, args): """Get list of security services associated with a given share network.""" share_network = _find_share_network(cs, args.share_network) @@ -3942,7 +4402,12 @@ def do_share_network_security_service_list(cs, args): 'share_network_id': share_network.id, } security_services = cs.security_services.list(search_opts=search_opts) - fields = ['id', 'name', 'status', 'type', ] + fields = [ + 'id', + 'name', + 'status', + 'type', + ] if args.columns is not None: fields = _split_columns(columns=args.columns) @@ -3953,47 +4418,56 @@ def do_share_network_security_service_list(cs, args): @cliutils.arg( 'share_network', metavar='', - help='Share network name or ID.') + help='Share network name or ID.', +) @cliutils.arg( 'current_security_service', metavar='', - help='Current security service name or ID.') + help='Current security service name or ID.', +) @cliutils.arg( 'new_security_service', metavar='', - help='New security service name or ID.') + help='New security service name or ID.', +) @api_versions.wraps("2.63") def do_share_network_security_service_update(cs, args): """Update a current security service to a new security service.""" share_network = _find_share_network(cs, args.share_network) current_security_service = _find_security_service( - cs, args.current_security_service) + cs, args.current_security_service + ) new_security_service = _find_security_service( - cs, args.new_security_service) + cs, args.new_security_service + ) cs.share_networks.update_share_network_security_service( - share_network, current_security_service, new_security_service) + share_network, current_security_service, new_security_service + ) @cliutils.arg( 'share_network', metavar='', - help='Share network name or ID.') + help='Share network name or ID.', +) @cliutils.arg( 'current_security_service', metavar='', - help='Current security service name or ID.') + help='Current security service name or ID.', +) @cliutils.arg( 'new_security_service', metavar='', - help='New security service name or ID.') + help='New security service name or ID.', +) @cliutils.arg( '--reset', metavar='', choices=['True', 'False'], required=False, default=False, - help='Reset and start again the check operation.' - '(Optional, Default=False)') + help='Reset and start again the check operation.(Optional, Default=False)', +) @api_versions.wraps("2.63") def do_share_network_security_service_update_check(cs, args): """Check if a security service update on the share network is supported. @@ -4002,13 +4476,19 @@ def do_share_network_security_service_update_check(cs, args): """ share_network = _find_share_network(cs, args.share_network) current_security_service = _find_security_service( - cs, args.current_security_service) + cs, args.current_security_service + ) new_security_service = _find_security_service( - cs, args.new_security_service) + cs, args.new_security_service + ) share_network_update_check = ( cs.share_networks.update_share_network_security_service_check( - share_network, current_security_service, new_security_service, - reset_operation=args.reset)) + share_network, + current_security_service, + new_security_service, + reset_operation=args.reset, + ) + ) # result[0] is response code, result[1] is dict body cliutils.print_dict(share_network_update_check[1]) @@ -4016,14 +4496,18 @@ def do_share_network_security_service_update_check(cs, args): @cliutils.arg( 'share_network', metavar='', - help='Share network name or ID.') + help='Share network name or ID.', +) @cliutils.arg( '--state', metavar='', default=constants.STATUS_ACTIVE, - help=('Indicate which state to assign the share network. Options include ' - 'active, error, network change. If no state is provided, active ' - 'will be used.')) + help=( + 'Indicate which state to assign the share network. Options include ' + 'active, error, network change. If no state is provided, active ' + 'will be used.' + ), +) @api_versions.wraps("2.63") def do_share_network_reset_state(cs, args): """Explicitly update the state of a share network (Admin only).""" @@ -4034,24 +4518,31 @@ def do_share_network_reset_state(cs, args): @cliutils.arg( 'share_network', metavar='', - help='Share network name or ID.') + help='Share network name or ID.', +) @cliutils.arg( '--neutron-net-id', - '--neutron-net_id', '--neutron_net_id', '--neutron_net-id', + '--neutron-net_id', + '--neutron_net_id', + '--neutron_net-id', metavar='', default=None, action='single_alias', help="Neutron network ID. Used to set up network for share servers. " - "Optional, Default = None.") + "Optional, Default = None.", +) @cliutils.arg( '--neutron-subnet-id', - '--neutron-subnet_id', '--neutron_subnet_id', '--neutron_subnet-id', + '--neutron-subnet_id', + '--neutron_subnet_id', + '--neutron_subnet-id', metavar='', default=None, action='single_alias', help="Neutron subnet ID. Used to set up network for share servers. " - "This subnet should belong to specified neutron network. " - "Optional, Default = None.") + "This subnet should belong to specified neutron network. " + "Optional, Default = None.", +) @cliutils.arg( '--availability-zone', '--availability_zone', @@ -4060,14 +4551,16 @@ def do_share_network_reset_state(cs, args): action='single_alias', metavar='', help='Optional availability zone that the subnet is available within ' - '(Default=None). If None, the subnet will be considered as being ' - 'available across all availability zones.') + '(Default=None). If None, the subnet will be considered as being ' + 'available across all availability zones.', +) def do_share_network_subnet_create(cs, args): """Add a new subnet into a share network.""" if xor(bool(args.neutron_net_id), bool(args.neutron_subnet_id)): raise exceptions.CommandError( "Both neutron_net_id and neutron_subnet_id should be specified. " - "Alternatively, neither of them should be specified.") + "Alternatively, neither of them should be specified." + ) share_network = _find_share_network(cs, args.share_network) values = { @@ -4084,24 +4577,31 @@ def do_share_network_subnet_create(cs, args): @cliutils.arg( 'share_network', metavar='', - help='Share network name or ID.') + help='Share network name or ID.', +) @cliutils.arg( '--neutron-net-id', - '--neutron-net_id', '--neutron_net_id', '--neutron_net-id', + '--neutron-net_id', + '--neutron_net_id', + '--neutron_net-id', metavar='', default=None, action='single_alias', help="Neutron network ID. Used to set up network for share servers. " - "Optional, Default = None.") + "Optional, Default = None.", +) @cliutils.arg( '--neutron-subnet-id', - '--neutron-subnet_id', '--neutron_subnet_id', '--neutron_subnet-id', + '--neutron-subnet_id', + '--neutron_subnet_id', + '--neutron_subnet-id', metavar='', default=None, action='single_alias', help="Neutron subnet ID. Used to set up network for share servers. " - "This subnet should belong to specified neutron network. " - "Optional, Default = None.") + "This subnet should belong to specified neutron network. " + "Optional, Default = None.", +) @cliutils.arg( '--availability-zone', '--availability_zone', @@ -4110,23 +4610,25 @@ def do_share_network_subnet_create(cs, args): action='single_alias', metavar='', help='Optional availability zone that the subnet is available within ' - '(Default=None). If None, the subnet will be considered as being ' - 'available across all availability zones.') + '(Default=None). If None, the subnet will be considered as being ' + 'available across all availability zones.', +) @cliutils.arg( '--reset', metavar='', choices=['True', 'False'], required=False, default=False, - help='Reset and start again the check operation.' - '(Optional, Default=False)') + help='Reset and start again the check operation.(Optional, Default=False)', +) @api_versions.wraps("2.70") def do_share_network_subnet_create_check(cs, args): """Check if a new subnet can be added to a share network.""" if xor(bool(args.neutron_net_id), bool(args.neutron_subnet_id)): raise exceptions.CommandError( "Both neutron_net_id and neutron_subnet_id should be specified. " - "Alternatively, neither of them should be specified.") + "Alternatively, neither of them should be specified." + ) share_network = _find_share_network(cs, args.share_network) values = { @@ -4135,9 +4637,9 @@ def do_share_network_subnet_create_check(cs, args): 'availability_zone': args.availability_zone, 'reset_operation': args.reset, } - subnet_create_check = ( - cs.share_networks.share_network_subnet_create_check( - share_network.id, **values)) + subnet_create_check = cs.share_networks.share_network_subnet_create_check( + share_network.id, **values + ) # result[0] is response code, result[1] is dict body cliutils.print_dict(subnet_create_check[1]) @@ -4145,12 +4647,14 @@ def do_share_network_subnet_create_check(cs, args): @cliutils.arg( 'share_network', metavar='', - help='Share network name or ID.') + help='Share network name or ID.', +) @cliutils.arg( 'share_network_subnet', metavar='', nargs='+', - help='Name or ID of share network subnet(s) to be deleted.') + help='Name or ID of share network subnet(s) to be deleted.', +) def do_share_network_subnet_delete(cs, args): """Delete one or more share network subnets.""" failure_count = 0 @@ -4161,27 +4665,33 @@ def do_share_network_subnet_delete(cs, args): cs.share_network_subnets.delete(share_network_ref, subnet) except Exception as e: failure_count += 1 - print("Deletion of share network subnet %s failed: %s" % ( - subnet, e), file=sys.stderr) + print( + "Deletion of share network subnet %s failed: %s" % (subnet, e), + file=sys.stderr, + ) if failure_count == len(args.share_network_subnet): - raise exceptions.CommandError("Unable to delete any of the specified " - "share network subnets.") + raise exceptions.CommandError( + "Unable to delete any of the specified share network subnets." + ) @cliutils.arg( 'share_network', metavar='', - help='Name or ID of share network(s) to which the subnet belongs.') + help='Name or ID of share network(s) to which the subnet belongs.', +) @cliutils.arg( 'share_network_subnet', metavar='', - help='Share network subnet ID to show.') + help='Share network subnet ID to show.', +) def do_share_network_subnet_show(cs, args): """Show share network subnet.""" share_network = _find_share_network(cs, args.share_network) share_network_subnet = cs.share_network_subnets.get( - share_network.id, args.share_network_subnet) + share_network.id, args.share_network_subnet + ) view_data = share_network_subnet._info.copy() cliutils.print_dict(view_data) @@ -4190,78 +4700,88 @@ def do_share_network_subnet_show(cs, args): 'share_network', metavar='', nargs='+', - help='Name or ID of share network(s) to be deleted.') + help='Name or ID of share network(s) to be deleted.', +) def do_share_network_delete(cs, args): """Delete one or more share networks.""" failure_count = 0 for share_network in args.share_network: try: - share_ref = _find_share_network( - cs, share_network) + share_ref = _find_share_network(cs, share_network) cs.share_networks.delete(share_ref) except Exception as e: failure_count += 1 - print("Delete for share network %s failed: %s" % ( - share_network, e), file=sys.stderr) + print( + "Delete for share network %s failed: %s" % (share_network, e), + file=sys.stderr, + ) if failure_count == len(args.share_network): - raise exceptions.CommandError("Unable to delete any of the specified " - "share networks.") + raise exceptions.CommandError( + "Unable to delete any of the specified share networks." + ) @cliutils.arg( 'type', metavar='', - help="Security service type: 'ldap', 'kerberos' or 'active_directory'.") + help="Security service type: 'ldap', 'kerberos' or 'active_directory'.", +) @cliutils.arg( '--dns-ip', metavar='', default=None, - help="DNS IP address used inside project's network.") + help="DNS IP address used inside project's network.", +) @cliutils.arg( '--ou', metavar='', default=None, help="Security service OU (Organizational Unit). Available only for " - "microversion >= 2.44.") + "microversion >= 2.44.", +) @cliutils.arg( '--server', metavar='', default=None, - help="Security service IP address or hostname.") + help="Security service IP address or hostname.", +) @cliutils.arg( '--domain', metavar='', default=None, - help="Security service domain.") + help="Security service domain.", +) @cliutils.arg( '--user', metavar='', default=None, - help="Security service user or group used by project.") + help="Security service user or group used by project.", +) @cliutils.arg( '--password', metavar='', default=None, - help="Password used by user.") + help="Password used by user.", +) @cliutils.arg( - '--name', - metavar='', - default=None, - help="Security service name.") + '--name', metavar='', default=None, help="Security service name." +) @cliutils.arg( '--default-ad-site', metavar='', dest='default_ad_site', default=None, help="Default AD site. Available only for microversion >= 2.76. Can " - "be provided in the place of '--server' but not along with it.") + "be provided in the place of '--server' but not along with it.", +) @cliutils.arg( '--description', metavar='', default=None, - help="Security service description.") + help="Security service description.", +) def do_security_service_create(cs, args): """Create security service used by project.""" values = { @@ -4274,28 +4794,33 @@ def do_security_service_create(cs, args): 'description': args.description, } - if cs.api_version.matches(api_versions.APIVersion("2.44"), - api_versions.APIVersion()): + if cs.api_version.matches( + api_versions.APIVersion("2.44"), api_versions.APIVersion() + ): values['ou'] = args.ou elif args.ou: raise exceptions.CommandError( "Security service Organizational Unit (ou) option " - "is only available with manila API version >= 2.44") + "is only available with manila API version >= 2.44" + ) - if cs.api_version.matches(api_versions.APIVersion("2.76"), - api_versions.APIVersion()): + if cs.api_version.matches( + api_versions.APIVersion("2.76"), api_versions.APIVersion() + ): values['default_ad_site'] = args.default_ad_site elif args.default_ad_site: raise exceptions.CommandError( "Default AD site option is only available with " - "manila API version >= 2.76") + "manila API version >= 2.76" + ) if args.type == 'active_directory': if args.server and args.default_ad_site: raise exceptions.CommandError( "Cannot create security service because both " "server and 'default_ad_site' were provided. " - "Specify either server or 'default_ad_site'.") + "Specify either server or 'default_ad_site'." + ) security_service = cs.security_services.create(args.type, **values) info = security_service._info.copy() @@ -4305,54 +4830,61 @@ def do_security_service_create(cs, args): @cliutils.arg( 'security_service', metavar='', - help='Security service name or ID to update.') + help='Security service name or ID to update.', +) @cliutils.arg( '--dns-ip', metavar='', default=None, - help="DNS IP address used inside project's network.") + help="DNS IP address used inside project's network.", +) @cliutils.arg( '--ou', metavar='', default=None, help="Security service OU (Organizational Unit). Available only for " - "microversion >= 2.44.") + "microversion >= 2.44.", +) @cliutils.arg( '--server', metavar='', default=None, - help="Security service IP address or hostname.") + help="Security service IP address or hostname.", +) @cliutils.arg( '--domain', metavar='', default=None, - help="Security service domain.") + help="Security service domain.", +) @cliutils.arg( '--user', metavar='', default=None, - help="Security service user or group used by project.") + help="Security service user or group used by project.", +) @cliutils.arg( '--password', metavar='', default=None, - help="Password used by user.") + help="Password used by user.", +) @cliutils.arg( - '--name', - metavar='', - default=None, - help="Security service name.") + '--name', metavar='', default=None, help="Security service name." +) @cliutils.arg( '--default-ad-site', metavar='', dest='default_ad_site', default=None, - help="Default AD site. Available only for microversion >= 2.76.") + help="Default AD site. Available only for microversion >= 2.76.", +) @cliutils.arg( '--description', metavar='', default=None, - help="Security service description.") + help="Security service description.", +) def do_security_service_update(cs, args): """Update security service.""" values = { @@ -4365,31 +4897,37 @@ def do_security_service_update(cs, args): 'description': args.description, } - if cs.api_version.matches(api_versions.APIVersion("2.44"), - api_versions.APIVersion()): + if cs.api_version.matches( + api_versions.APIVersion("2.44"), api_versions.APIVersion() + ): values['ou'] = args.ou elif args.ou: raise exceptions.CommandError( "Security service Organizational Unit (ou) option " - "is only available with manila API version >= 2.44") + "is only available with manila API version >= 2.44" + ) - if cs.api_version.matches(api_versions.APIVersion("2.76"), - api_versions.APIVersion()): + if cs.api_version.matches( + api_versions.APIVersion("2.76"), api_versions.APIVersion() + ): values['default_ad_site'] = args.default_ad_site elif args.default_ad_site: raise exceptions.CommandError( "Default AD site option is only available with " - "manila API version >= 2.76") + "manila API version >= 2.76" + ) security_service = _find_security_service( - cs, args.security_service).update(**values) + cs, args.security_service + ).update(**values) cliutils.print_dict(security_service._info) @cliutils.arg( 'security_service', metavar='', - help='Security service name or ID to show.') + help='Security service name or ID to show.', +) def do_security_service_show(cs, args): """Show security service.""" security_service = _find_security_service(cs, args.security_service) @@ -4398,7 +4936,8 @@ def do_security_service_show(cs, args): @cliutils.arg( - '--all-tenants', '--all-projects', + '--all-tenants', + '--all-projects', action='single_alias', dest='all_projects', metavar='<0|1>', @@ -4406,57 +4945,61 @@ def do_security_service_show(cs, args): type=int, const=1, default=0, - help='Display information from all projects (Admin only).') + help='Display information from all projects (Admin only).', +) @cliutils.arg( '--share-network', '--share_network', # alias metavar='', action='single_alias', default=None, - help='Filter results by share network id or name.') + help='Filter results by share network id or name.', +) @cliutils.arg( '--status', metavar='', default=None, - help='Filter results by status.') + help='Filter results by status.', +) @cliutils.arg( - '--name', - metavar='', - default=None, - help='Filter results by name.') + '--name', metavar='', default=None, help='Filter results by name.' +) @cliutils.arg( - '--type', - metavar='', - default=None, - help='Filter results by type.') + '--type', metavar='', default=None, help='Filter results by type.' +) @cliutils.arg( '--user', metavar='', default=None, - help='Filter results by user or group used by projects.') + help='Filter results by user or group used by projects.', +) @cliutils.arg( '--dns-ip', '--dns_ip', # alias metavar='', action='single_alias', default=None, - help="Filter results by DNS IP address used inside project's network.") + help="Filter results by DNS IP address used inside project's network.", +) @cliutils.arg( '--ou', metavar='', default=None, help="Filter results by security service OU (Organizational Unit)." - " Available only for microversion >= 2.44.") + " Available only for microversion >= 2.44.", +) @cliutils.arg( '--server', metavar='', default=None, - help="Filter results by security service IP address or hostname.") + help="Filter results by security service IP address or hostname.", +) @cliutils.arg( '--domain', metavar='', default=None, - help="Filter results by domain.") + help="Filter results by domain.", +) @cliutils.arg( '--detailed', dest='detailed', @@ -4465,36 +5008,41 @@ def do_security_service_show(cs, args): type=int, const=1, default=0, - help="Show detailed information about filtered security services.") + help="Show detailed information about filtered security services.", +) @cliutils.arg( '--offset', metavar="", default=None, - help='Start position of security services listing.') + help='Start position of security services listing.', +) @cliutils.arg( '--limit', metavar="", default=None, - help='Number of security services to return per request.') + help='Number of security services to return per request.', +) @cliutils.arg( '--default-ad-site', metavar='', dest='default_ad_site', default=None, - help="Default AD site. Available only for microversion >= 2.76.") + help="Default AD site. Available only for microversion >= 2.76.", +) @cliutils.arg( '--columns', metavar='', type=str, default=None, help='Comma separated list of columns to be displayed ' - 'example --columns "name,type".') + 'example --columns "name,type".', +) def do_security_service_list(cs, args): """Get a list of security services.""" all_projects = int( - os.environ.get("ALL_TENANTS", - os.environ.get("ALL_PROJECTS", - args.all_projects)) + os.environ.get( + "ALL_TENANTS", os.environ.get("ALL_PROJECTS", args.all_projects) + ) ) search_opts = { 'all_tenants': all_projects, @@ -4509,28 +5057,39 @@ def do_security_service_list(cs, args): 'limit': args.limit, } - if cs.api_version.matches(api_versions.APIVersion("2.44"), - api_versions.APIVersion()): + if cs.api_version.matches( + api_versions.APIVersion("2.44"), api_versions.APIVersion() + ): search_opts['ou'] = args.ou elif args.ou: raise exceptions.CommandError( "Security service Organizational Unit (ou) option " - "is only available with manila API version >= 2.44") + "is only available with manila API version >= 2.44" + ) - if cs.api_version.matches(api_versions.APIVersion("2.76"), - api_versions.APIVersion()): + if cs.api_version.matches( + api_versions.APIVersion("2.76"), api_versions.APIVersion() + ): search_opts['default_ad_site'] = args.default_ad_site elif args.ou: raise exceptions.CommandError( "Security service Default AD site option " - "is only available with manila API version >= 2.76") + "is only available with manila API version >= 2.76" + ) if args.share_network: search_opts['share_network_id'] = _find_share_network( - cs, args.share_network).id - security_services = cs.security_services.list(search_opts=search_opts, - detailed=args.detailed) - fields = ['id', 'name', 'status', 'type', ] + cs, args.share_network + ).id + security_services = cs.security_services.list( + search_opts=search_opts, detailed=args.detailed + ) + fields = [ + 'id', + 'name', + 'status', + 'type', + ] if args.columns is not None: fields = _split_columns(columns=args.columns) @@ -4543,61 +5102,72 @@ def do_security_service_list(cs, args): 'security_service', metavar='', nargs='+', - help='Name or ID of the security service(s) to delete.') + help='Name or ID of the security service(s) to delete.', +) def do_security_service_delete(cs, args): """Delete one or more security services.""" failure_count = 0 for security_service in args.security_service: try: - security_ref = _find_security_service( - cs, security_service) + security_ref = _find_security_service(cs, security_service) cs.security_services.delete(security_ref) except Exception as e: failure_count += 1 - print("Delete for security service %s failed: %s" % ( - security_service, e), file=sys.stderr) + print( + "Delete for security service %s failed: %s" + % (security_service, e), + file=sys.stderr, + ) if failure_count == len(args.security_service): - raise exceptions.CommandError("Unable to delete any of the specified " - "security services.") + raise exceptions.CommandError( + "Unable to delete any of the specified security services." + ) @cliutils.arg( '--host', metavar='', default=None, - help='Filter results by name of host.') + help='Filter results by name of host.', +) @cliutils.arg( '--status', metavar='', default=None, - help='Filter results by status.') + help='Filter results by status.', +) @cliutils.arg( '--share-network', metavar='', default=None, - help='Filter results by share network.') + help='Filter results by share network.', +) @cliutils.arg( '--project-id', metavar='', default=None, - help='Filter results by project ID.') + help='Filter results by project ID.', +) @cliutils.arg( '--columns', metavar='', type=str, default=None, help='Comma separated list of columns to be displayed ' - 'example --columns "id,host,status".') + 'example --columns "id,host,status".', +) @cliutils.arg( - '--share-network-subnet', '--share_network_subnet', + '--share-network-subnet', + '--share_network_subnet', type=str, metavar='', help="Filter results by share network subnet that the share server's " - "network allocation exists whithin. Available for micro version " - ">= 2.51 (Optional, Default=None).", - default=None) + "network allocation exists whithin. Available for micro version " + ">= 2.51 (Optional, Default=None).", + default=None, +) def do_share_server_list(cs, args): """List all share servers (Admin only).""" search_opts = { @@ -4619,14 +5189,17 @@ def do_share_server_list(cs, args): if getattr(args, 'share_network_subnet'): raise exceptions.CommandError( "Share network subnet option is only available with manila " - "API version >= 2.51") + "API version >= 2.51" + ) elif cs.api_version < api_versions.APIVersion("2.70"): - search_opts.update({ - 'share_network_subnet_id': args.share_network_subnet}) + search_opts.update( + {'share_network_subnet_id': args.share_network_subnet} + ) fields.append("Share Network Subnet Id") else: - search_opts.update({ - 'share_network_subnet_id': args.share_network_subnet}) + search_opts.update( + {'share_network_subnet_id': args.share_network_subnet} + ) fields.append("Share Network Subnet IDs") if args.columns is not None: @@ -4636,11 +5209,7 @@ def do_share_server_list(cs, args): cliutils.print_list(share_servers, fields=fields) -@cliutils.arg( - 'id', - metavar='', - type=str, - help='ID of share server.') +@cliutils.arg('id', metavar='', type=str, help='ID of share server.') def do_share_server_show(cs, args): """Show share server info (Admin only).""" share_server = cs.share_servers.get(args.id) @@ -4651,11 +5220,7 @@ def do_share_server_show(cs, args): cliutils.print_dict(share_server._info) -@cliutils.arg( - 'id', - metavar='', - type=str, - help='ID of share server.') +@cliutils.arg('id', metavar='', type=str, help='ID of share server.') def do_share_server_details(cs, args): """Show share server details (Admin only).""" details = cs.share_servers.details(args.id) @@ -4667,11 +5232,11 @@ def do_share_server_details(cs, args): metavar='', nargs='+', type=str, - help='ID of the share server(s) to delete.') + help='ID of the share server(s) to delete.', +) @cliutils.arg( - '--wait', - action='store_true', - help='Wait for share server to delete') + '--wait', action='store_true', help='Wait for share server to delete' +) @cliutils.service_type('sharev2') def do_share_server_delete(cs, args): """Delete one or more share servers (Admin only).""" @@ -4686,19 +5251,25 @@ def do_share_server_delete(cs, args): id_ref.delete() except Exception as e: failure_count += 1 - print("Delete for share server %s failed: %s" % ( - server_id, e), file=sys.stderr) + print( + "Delete for share server %s failed: %s" % (server_id, e), + file=sys.stderr, + ) if failure_count == len(args.id): - raise exceptions.CommandError("Unable to delete any of the specified " - "share servers.") + raise exceptions.CommandError( + "Unable to delete any of the specified share servers." + ) if args.wait: for share_server in share_servers_to_delete: try: _wait_for_resource_status( - cs, share_server, resource_type='share_server', - expected_status='deleted') + cs, + share_server, + resource_type='share_server', + expected_status='deleted', + ) except exceptions.CommandError as e: print(e, file=sys.stderr) @@ -4709,7 +5280,8 @@ def do_share_server_delete(cs, args): type=str, default=None, help='Comma separated list of columns to be displayed ' - 'example --columns "id,name".') + 'example --columns "id,name".', +) def do_availability_zone_list(cs, args): """List all availability zones.""" @@ -4723,37 +5295,31 @@ def do_availability_zone_list(cs, args): @cliutils.arg( - '--host', - metavar='', - default=None, - help='Name of host.') + '--host', metavar='', default=None, help='Name of host.' +) @cliutils.arg( - '--binary', - metavar='', - default=None, - help='Service binary.') + '--binary', metavar='', default=None, help='Service binary.' +) @cliutils.arg( '--status', metavar='', default=None, - help='Filter results by status.') + help='Filter results by status.', +) @cliutils.arg( - '--state', - metavar='', - default=None, - help='Filter results by state.') + '--state', metavar='', default=None, help='Filter results by state.' +) @cliutils.arg( - '--zone', - metavar='', - default=None, - help='Availability zone.') + '--zone', metavar='', default=None, help='Availability zone.' +) @cliutils.arg( '--columns', metavar='', type=str, default=None, help='Comma separated list of columns to be displayed ' - 'example --columns "id,host".') + 'example --columns "id,host".', +) def do_service_list(cs, args): """List all services (Admin only).""" search_opts = { @@ -4775,11 +5341,13 @@ def do_service_list(cs, args): @cliutils.arg( 'host', metavar='', - help="Host name as 'example_host@example_backend'.") + help="Host name as 'example_host@example_backend'.", +) @cliutils.arg( 'binary', metavar='', - help="Service binary, could be 'manila-share' or 'manila-scheduler'.") + help="Service binary, could be 'manila-share' or 'manila-scheduler'.", +) def do_service_enable(cs, args): """Enables 'manila-share' or 'manila-scheduler' services (Admin only).""" columns = ("Host", "Binary", "Enabled") @@ -4791,11 +5359,13 @@ def do_service_enable(cs, args): @cliutils.arg( 'host', metavar='', - help="Host name as 'example_host@example_backend'.") + help="Host name as 'example_host@example_backend'.", +) @cliutils.arg( 'binary', metavar='', - help="Service binary, could be 'manila-share' or 'manila-scheduler'.") + help="Service binary, could be 'manila-share' or 'manila-scheduler'.", +) def do_service_disable(cs, args): """Disables 'manila-share' or 'manila-scheduler' services (Admin only).""" columns = ("Host", "Binary", "Enabled") @@ -4818,41 +5388,50 @@ def _print_dict(data_dict): metavar='', type=str, default='.*', - help='Filter results by host name. Regular expressions are supported.') + help='Filter results by host name. Regular expressions are supported.', +) @cliutils.arg( '--backend', metavar='', type=str, default='.*', - help='Filter results by backend name. Regular expressions are supported.') + help='Filter results by backend name. Regular expressions are supported.', +) @cliutils.arg( '--pool', metavar='', type=str, default='.*', - help='Filter results by pool name. Regular expressions are supported.') + help='Filter results by pool name. Regular expressions are supported.', +) @cliutils.arg( '--columns', metavar='', type=str, default=None, help='Comma separated list of columns to be displayed ' - 'example --columns "name,host".') + 'example --columns "name,host".', +) @cliutils.arg( - '--detail', '--detailed', + '--detail', + '--detailed', action='store_true', help='Show detailed information about pools. If this parameter is set ' - 'to True, --columns parameter will be ignored if present. ' - '(Default=False)') + 'to True, --columns parameter will be ignored if present. ' + '(Default=False)', +) @cliutils.arg( - '--share-type', '--share_type', - '--share-type-id', '--share_type_id', + '--share-type', + '--share_type', + '--share-type-id', + '--share_type_id', metavar='', type=str, default=None, action='single_alias', help='Filter results by share type name or ID. (Default=None)' - 'Available only for microversion >= 2.23.') + 'Available only for microversion >= 2.23.', +) def do_pool_list(cs, args): """List all backend storage pools known to the scheduler (Admin only).""" @@ -4883,21 +5462,22 @@ def do_pool_list(cs, args): cliutils.print_list(pools, fields=fields) -@cliutils.arg('share', metavar='', - help='Name or ID of share to extend.') -@cliutils.arg('new_size', - metavar='', - type=int, - help='New size of share, in GiBs.') @cliutils.arg( - '--wait', - action='store_true', - help='Wait for share extension') + 'share', metavar='', help='Name or ID of share to extend.' +) +@cliutils.arg( + 'new_size', + metavar='', + type=int, + help='New size of share, in GiBs.', +) +@cliutils.arg('--wait', action='store_true', help='Wait for share extension') @cliutils.arg( '--force', action='store_true', help='Force attempt the extension of the share, only available with ' - 'microversion 2.64 and higher. (admin only)') + 'microversion 2.64 and higher. (admin only)', +) @cliutils.service_type('sharev2') def do_extend(cs, args): """Increases the size of an existing share.""" @@ -4907,7 +5487,8 @@ def do_extend(cs, args): if cs.api_version < api_versions.APIVersion("2.64"): raise exceptions.CommandError( "args 'force' is available only starting with " - "'2.64' API microversion.") + "'2.64' API microversion." + ) force = True if force: cs.shares.extend(share, args.new_size, force=force) @@ -4921,16 +5502,16 @@ def do_extend(cs, args): _print_share(cs, share) -@cliutils.arg('share', metavar='', - help='Name or ID of share to shrink.') -@cliutils.arg('new_size', - metavar='', - type=int, - help='New size of share, in GiBs.') @cliutils.arg( - '--wait', - action='store_true', - help='Wait for share shrinkage') + 'share', metavar='', help='Name or ID of share to shrink.' +) +@cliutils.arg( + 'new_size', + metavar='', + type=int, + help='New size of share, in GiBs.', +) +@cliutils.arg('--wait', action='store_true', help='Wait for share shrinkage') @cliutils.service_type('sharev2') def do_shrink(cs, args): """Decreases the size of an existing share.""" @@ -4943,6 +5524,7 @@ def do_shrink(cs, args): share = _find_share(cs, args.share) _print_share(cs, share) + ############################################################################## # # Share types @@ -4976,9 +5558,9 @@ def _is_share_type_public(share_type): return 'public' if share_type.is_public else 'private' -def _print_share_type_list(stypes, default_share_type=None, columns=None, - description=False): - +def _print_share_type_list( + stypes, default_share_type=None, columns=None, description=False +): def _is_default(share_type): if hasattr(share_type, 'is_default'): return 'YES' if share_type.is_default else '-' @@ -5016,7 +5598,6 @@ def _is_default(share_type): def _print_share_type(stype, default_share_type=None, show_des=False): - def _is_default(share_type): if hasattr(share_type, 'is_default'): return 'YES' if share_type.is_default else '-' @@ -5059,7 +5640,8 @@ def _find_share_type(cs, stype): action='store_true', default=False, help='Display all share types whatever public or private ' - 'OPTIONAL: Default=False. (Admin only).') + 'OPTIONAL: Default=False. (Admin only).', +) @cliutils.arg( '--extra-specs', '--extra_specs', @@ -5069,15 +5651,17 @@ def _find_share_type(cs, stype): action='single_alias', default=None, help='Filters results by a extra specs key and value of share type that ' - 'was used for share creation. Available only for microversion >= ' - '2.43. OPTIONAL: Default=None.') + 'was used for share creation. Available only for microversion >= ' + '2.43. OPTIONAL: Default=None.', +) @cliutils.arg( '--columns', metavar='', type=str, default=None, help='Comma separated list of columns to be displayed ' - 'example --columns "id,name".') + 'example --columns "id,name".', +) def do_type_list(cs, args): """Print a list of available 'share types'.""" search_opts = None @@ -5087,34 +5671,39 @@ def do_type_list(cs, args): if cs.api_version < api_versions.APIVersion("2.43"): raise exceptions.CommandError( "Filter by 'extra_specs' is available only starting with " - "'2.43' API microversion.") - search_opts = { - 'extra_specs': extra_specs - } + "'2.43' API microversion." + ) + search_opts = {'extra_specs': extra_specs} - share_types = cs.share_types.list(show_all=show_all, - search_opts=search_opts) + share_types = cs.share_types.list( + show_all=show_all, search_opts=search_opts + ) default = None if share_types and not hasattr(share_types[0], 'is_default'): - if ((args.columns and 'is_default' in args.columns) or - args.columns is None): + if ( + args.columns and 'is_default' in args.columns + ) or args.columns is None: default = cs.share_types.get() show_des = cs.api_version.matches( - api_versions.APIVersion("2.41"), api_versions.APIVersion()) - _print_share_type_list(share_types, default_share_type=default, - columns=args.columns, description=show_des) + api_versions.APIVersion("2.41"), api_versions.APIVersion() + ) + _print_share_type_list( + share_types, + default_share_type=default, + columns=args.columns, + description=show_des, + ) @cliutils.arg( - 'share_type', - metavar='', - help='Name or ID of the share type.') + 'share_type', metavar='', help='Name or ID of the share type.' +) def do_type_show(cs, args): """Show share type details.""" share_type = _find_share_type(cs, args.share_type) default = None - if (share_type and not hasattr(share_type, 'is_default')): + if share_type and not hasattr(share_type, 'is_default'): default = cs.share_types.get() _print_type_show(share_type, default_share_type=default) @@ -5125,58 +5714,62 @@ def do_type_show(cs, args): type=str, default=None, help='Comma separated list of columns to be displayed ' - 'example --columns "id,name".') + 'example --columns "id,name".', +) def do_extra_specs_list(cs, args): """Print a list of current 'share types and extra specs' (Admin Only).""" stypes = cs.share_types.list() _print_type_and_extra_specs_list(stypes, columns=args.columns) -@cliutils.arg( - 'name', - metavar='', - help="Name of the new share type.") +@cliutils.arg('name', metavar='', help="Name of the new share type.") @cliutils.arg( 'spec_driver_handles_share_servers', metavar='', type=str, help="Required extra specification. " - "Valid values are 'true'/'1' and 'false'/'0'.") + "Valid values are 'true'/'1' and 'false'/'0'.", +) @cliutils.arg( '--description', metavar='', type=str, default=None, help='Filter results by description. ' - 'Available only for microversion >= 2.41.') + 'Available only for microversion >= 2.41.', +) @cliutils.arg( '--snapshot_support', '--snapshot-support', metavar='', action='single_alias', help="Boolean extra spec used for filtering of back ends by their " - "capability to create share snapshots.") + "capability to create share snapshots.", +) @cliutils.arg( '--create_share_from_snapshot_support', '--create-share-from-snapshot-support', metavar='', action='single_alias', help="Boolean extra spec used for filtering of back ends by their " - "capability to create shares from snapshots.") + "capability to create shares from snapshots.", +) @cliutils.arg( '--revert_to_snapshot_support', '--revert-to-snapshot-support', metavar='', action='single_alias', help="Boolean extra spec used for filtering of back ends by their " - "capability to revert shares to snapshots. (Default is False).") + "capability to revert shares to snapshots. (Default is False).", +) @cliutils.arg( '--mount_snapshot_support', '--mount-snapshot-support', metavar='', action='single_alias', help="Boolean extra spec used for filtering of back ends by their " - "capability to mount share snapshots. (Default is False).") + "capability to mount share snapshots. (Default is False).", +) @cliutils.arg( '--extra-specs', '--extra_specs', # alias @@ -5185,16 +5778,18 @@ def do_extra_specs_list(cs, args): metavar='', action='single_alias', help="Extra specs key and value of share type that will be" - " used for share type creation. OPTIONAL: Default=None." - " example --extra-specs thin_provisioning=' True', " - "replication_type=readable.", - default=None) + " used for share type creation. OPTIONAL: Default=None." + " example --extra-specs thin_provisioning=' True', " + "replication_type=readable.", + default=None, +) @cliutils.arg( '--is_public', '--is-public', metavar='', action='single_alias', - help="Make type accessible to the public (default true).") + help="Make type accessible to the public (default true).", +) def do_type_create(cs, args): """Create a new share type (Admin only).""" kwargs = { @@ -5204,53 +5799,64 @@ def do_type_create(cs, args): try: kwargs['spec_driver_handles_share_servers'] = ( strutils.bool_from_string( - args.spec_driver_handles_share_servers, strict=True)) + args.spec_driver_handles_share_servers, strict=True + ) + ) except ValueError as e: - msg = ("Argument spec_driver_handles_share_servers " - "argument is not valid: %s" % str(e)) + msg = ( + "Argument spec_driver_handles_share_servers " + "argument is not valid: %s" % str(e) + ) raise exceptions.CommandError(msg) kwargs['extra_specs'] = _extract_extra_specs(args) if 'driver_handles_share_servers' in kwargs['extra_specs']: - msg = ("Argument 'driver_handles_share_servers' is already " - "set via positional argument.") + msg = ( + "Argument 'driver_handles_share_servers' is already " + "set via positional argument." + ) raise exceptions.CommandError(msg) show_des = False - if cs.api_version.matches(api_versions.APIVersion("2.41"), - api_versions.APIVersion()): + if cs.api_version.matches( + api_versions.APIVersion("2.41"), api_versions.APIVersion() + ): show_des = True kwargs['description'] = getattr(args, 'description') elif getattr(args, 'description'): raise exceptions.CommandError( "Pattern based option (description)" - " is only available with manila API version >= 2.41") + " is only available with manila API version >= 2.41" + ) boolean_keys = ( 'snapshot_support', 'create_share_from_snapshot_support', 'revert_to_snapshot_support', - 'mount_snapshot_support' + 'mount_snapshot_support', ) for key in boolean_keys: value = getattr(args, key) if value is not None and key in kwargs['extra_specs']: - msg = ("Argument '%s' value specified twice." % key) + msg = "Argument '%s' value specified twice." % key raise exceptions.CommandError(msg) try: if value: - kwargs['extra_specs'][key] = ( - strutils.bool_from_string(value, strict=True)) + kwargs['extra_specs'][key] = strutils.bool_from_string( + value, strict=True + ) elif key in kwargs['extra_specs']: - kwargs['extra_specs'][key] = ( - strutils.bool_from_string( - kwargs['extra_specs'][key], strict=True)) + kwargs['extra_specs'][key] = strutils.bool_from_string( + kwargs['extra_specs'][key], strict=True + ) except ValueError as e: - msg = ("Argument '%s' is of boolean " - "type and has invalid value: %s" % (key, str(e))) + msg = ( + "Argument '%s' is of boolean " + "type and has invalid value: %s" % (key, str(e)) + ) raise exceptions.CommandError(msg) stype = cs.share_types.create(**kwargs) @@ -5258,27 +5864,26 @@ def do_type_create(cs, args): @cliutils.arg( - 'id', - metavar='', - help="Name or ID of the share type to update.") + 'id', metavar='', help="Name or ID of the share type to update." +) @cliutils.arg( - '--name', - metavar='', - type=str, - help="New name of share type.") + '--name', metavar='', type=str, help="New name of share type." +) @cliutils.arg( '--description', metavar='', type=str, default=None, - help="New description of share type.") + help="New description of share type.", +) @cliutils.arg( '--is-public', '--is_public', metavar='', action='single_alias', help="New visibility of the share type. If set to True, share type will " - "be available to all projects in the cloud.") + "be available to all projects in the cloud.", +) @api_versions.wraps("2.50") def do_type_update(cs, args): """Update share type name, description, and/or visibility. (Admin only).""" @@ -5286,19 +5891,23 @@ def do_type_update(cs, args): description = getattr(args, 'description') is_public = getattr(args, 'is_public') if not name and description is None and is_public is None: - msg = ("A description and/or non-empty name and/or boolean is_public " - "must be supplied to update the respective attributes of the " - "share type.") + msg = ( + "A description and/or non-empty name and/or boolean is_public " + "must be supplied to update the respective attributes of the " + "share type." + ) raise exceptions.CommandError(msg) kwargs = {} kwargs['name'] = name if is_public: try: - kwargs['is_public'] = strutils.bool_from_string(is_public, - strict=True) + kwargs['is_public'] = strutils.bool_from_string( + is_public, strict=True + ) except ValueError as e: - raise exceptions.CommandError("The value of 'is_public' is" - " invalid: %s", str(e)) + raise exceptions.CommandError( + "The value of 'is_public' is invalid: %s", str(e) + ) kwargs['description'] = description stype = _find_share_type(cs, args.id) @@ -5310,7 +5919,8 @@ def do_type_update(cs, args): 'id', metavar='', nargs='+', - help="Name or ID of the share type(s) to delete.") + help="Name or ID of the share type(s) to delete.", +) def do_type_delete(cs, args): """Delete one or more specific share types (Admin only).""" @@ -5322,29 +5932,31 @@ def do_type_delete(cs, args): cs.share_types.delete(id_ref) except Exception as e: failure_count += 1 - print("Delete for share type %s failed: %s" % ( - name_or_id, e), file=sys.stderr) + print( + "Delete for share type %s failed: %s" % (name_or_id, e), + file=sys.stderr, + ) if failure_count == len(args.id): - raise exceptions.CommandError("Unable to delete any of the specified " - "share types.") + raise exceptions.CommandError( + "Unable to delete any of the specified share types." + ) -@cliutils.arg( - 'stype', - metavar='', - help="Name or ID of the share type.") +@cliutils.arg('stype', metavar='', help="Name or ID of the share type.") @cliutils.arg( 'action', metavar='', choices=['set', 'unset'], - help="Actions: 'set' or 'unset'.") + help="Actions: 'set' or 'unset'.", +) @cliutils.arg( 'metadata', metavar='', nargs='*', default=None, - help='Extra_specs to set or unset (only key is necessary to unset).') + help='Extra_specs to set or unset (only key is necessary to unset).', +) def do_type_key(cs, args): """Set or unset extra_spec for a share type (Admin only).""" stype = _find_share_type(cs, args.stype) @@ -5361,13 +5973,15 @@ def do_type_key(cs, args): @cliutils.arg( 'share_type', metavar='', - help="Filter results by share type name or ID.") + help="Filter results by share type name or ID.", +) def do_type_access_list(cs, args): """Print access information about the given share type (Admin only).""" share_type = _find_share_type(cs, args.share_type) if share_type.is_public: - raise exceptions.CommandError("Forbidden to get access list " - "for public share type.") + raise exceptions.CommandError( + "Forbidden to get access list for public share type." + ) access_list = cs.share_type_access.list(share_type) columns = ['Project_ID'] @@ -5377,12 +5991,13 @@ def do_type_access_list(cs, args): @cliutils.arg( 'share_type', metavar='', - help="Share type name or ID to add access" - " for the given project.") + help="Share type name or ID to add access for the given project.", +) @cliutils.arg( 'project_id', metavar='', - help='Project ID to add share type access for.') + help='Project ID to add share type access for.', +) def do_type_access_add(cs, args): """Adds share type access for the given project (Admin only).""" vtype = _find_share_type(cs, args.share_type) @@ -5392,17 +6007,17 @@ def do_type_access_add(cs, args): @cliutils.arg( 'share_type', metavar='', - help=('Share type name or ID to remove access ' - 'for the given project.')) + help=('Share type name or ID to remove access for the given project.'), +) @cliutils.arg( 'project_id', metavar='', - help='Project ID to remove share type access for.') + help='Project ID to remove share type access for.', +) def do_type_access_remove(cs, args): """Removes share type access for the given project (Admin only).""" vtype = _find_share_type(cs, args.share_type) - cs.share_type_access.remove_project_access( - vtype, args.project_id) + cs.share_type_access.remove_project_access(vtype, args.project_id) ############################################################################## @@ -5412,9 +6027,9 @@ def do_type_access_remove(cs, args): ############################################################################## -def _print_share_group_type_list(share_group_types, - default_share_group_type=None, columns=None): - +def _print_share_group_type_list( + share_group_types, default_share_group_type=None, columns=None +): def _is_default(share_group_type): if hasattr(share_group_type, 'is_default'): return 'YES' if share_group_type.is_default else '-' @@ -5442,12 +6057,12 @@ def _is_default(share_group_type): if columns is not None: fields = _split_columns(columns=columns, title=False) - cliutils.print_list(share_group_types, fields, formatters, - sortby_index=None) + cliutils.print_list( + share_group_types, fields, formatters, sortby_index=None + ) def _print_share_group_type(share_group_type, default_share_type=None): - def _is_default(share_group_type): if hasattr(share_group_type, 'is_default'): return 'YES' if share_group_type.is_default else '-' @@ -5457,7 +6072,7 @@ def _is_default(share_group_type): 'ID': share_group_type.id, 'Name': share_group_type.name, 'Visibility': _is_share_type_public(share_group_type), - 'is_default': _is_default(share_group_type) + 'is_default': _is_default(share_group_type), } cliutils.print_dict(share_group_type_dict) @@ -5472,14 +6087,16 @@ def _find_share_group_type(cs, sg_type): dest='all', action='store_true', default=False, - help='Display all share group types (Admin only).') + help='Display all share group types (Admin only).', +) @cliutils.arg( '--columns', metavar='', type=str, default=None, help='Comma separated list of columns to be displayed ' - 'example --columns "id,name".') + 'example --columns "id,name".', +) @cliutils.service_type('sharev2') def do_share_group_type_list(cs, args): """Print a list of available 'share group types'.""" @@ -5488,12 +6105,14 @@ def do_share_group_type_list(cs, args): default = None if sg_types and not hasattr(sg_types[0], 'is_default'): - if ((args.columns and 'is_default' in args.columns) or - args.columns is None): + if ( + args.columns and 'is_default' in args.columns + ) or args.columns is None: default = cs.share_group_types.get() _print_share_group_type_list( - sg_types, default_share_group_type=default, columns=args.columns) + sg_types, default_share_group_type=default, columns=args.columns + ) @cliutils.arg( @@ -5502,7 +6121,8 @@ def do_share_group_type_list(cs, args): type=str, default=None, help='Comma separated list of columns to be displayed ' - 'example --columns "id,name".') + 'example --columns "id,name".', +) @cliutils.service_type('sharev2') def do_share_group_type_specs_list(cs, args): """Print a list of 'share group types specs' (Admin Only).""" @@ -5512,20 +6132,21 @@ def do_share_group_type_specs_list(cs, args): @cliutils.arg( - 'name', - metavar='', - help='Name of the new share group type.') + 'name', metavar='', help='Name of the new share group type.' +) @cliutils.arg( 'share_types', metavar='', type=str, - help='Comma-separated list of share type names or IDs.') + help='Comma-separated list of share type names or IDs.', +) @cliutils.arg( '--is_public', '--is-public', metavar='', action='single_alias', - help='Make type accessible to the public (default true).') + help='Make type accessible to the public (default true).', +) @cliutils.arg( '--group-specs', '--group_specs', @@ -5535,14 +6156,17 @@ def do_share_group_type_specs_list(cs, args): action='single_alias', default=None, help='Share Group type extra specs by key and value. ' - 'OPTIONAL: Default=None. ' - 'Example: "--group-specs consistent_snapshot_support=host".',) + 'OPTIONAL: Default=None. ' + 'Example: "--group-specs consistent_snapshot_support=host".', +) @cliutils.service_type('sharev2') def do_share_group_type_create(cs, args): """Create a new share group type (Admin only).""" - share_types = [_find_share_type(cs, share_type) - for share_type in args.share_types.split(',')] + share_types = [ + _find_share_type(cs, share_type) + for share_type in args.share_types.split(',') + ] kwargs = { 'share_types': share_types, @@ -5557,9 +6181,8 @@ def do_share_group_type_create(cs, args): @cliutils.arg( - 'id', - metavar='', - help="Name or ID of the share group type to delete.") + 'id', metavar='', help="Name or ID of the share group type to delete." +) @cliutils.service_type('sharev2') def do_share_group_type_delete(cs, args): """Delete a specific share group type (Admin only).""" @@ -5570,18 +6193,21 @@ def do_share_group_type_delete(cs, args): @cliutils.arg( 'share_group_type', metavar='', - help="Name or ID of the share group type.") + help="Name or ID of the share group type.", +) @cliutils.arg( 'action', metavar='', choices=['set', 'unset'], - help="Actions: 'set' or 'unset'.") + help="Actions: 'set' or 'unset'.", +) @cliutils.arg( 'group_specs', metavar='', nargs='*', default=None, - help='Group specs to set or unset (only key is necessary to unset).') + help='Group specs to set or unset (only key is necessary to unset).', +) @cliutils.service_type('sharev2') def do_share_group_type_key(cs, args): """Set or unset group_spec for a share group type (Admin only).""" @@ -5597,13 +6223,15 @@ def do_share_group_type_key(cs, args): @cliutils.arg( 'share_group_type', metavar='', - help="Filter results by share group type name or ID.") + help="Filter results by share group type name or ID.", +) def do_share_group_type_access_list(cs, args): """Print access information about a share group type (Admin only).""" share_group_type = _find_share_group_type(cs, args.share_group_type) if share_group_type.is_public: raise exceptions.CommandError( - "Forbidden to get access list for public share group type.") + "Forbidden to get access list for public share group type." + ) access_list = cs.share_group_type_access.list(share_group_type) columns = ['Project_ID'] cliutils.print_list(access_list, columns) @@ -5612,31 +6240,37 @@ def do_share_group_type_access_list(cs, args): @cliutils.arg( 'share_group_type', metavar='', - help='Share group type name or ID to add access for the given project.') + help='Share group type name or ID to add access for the given project.', +) @cliutils.arg( 'project_id', metavar='', - help='Project ID to add share group type access for.') + help='Project ID to add share group type access for.', +) def do_share_group_type_access_add(cs, args): """Adds share group type access for the given project (Admin only).""" share_group_type = _find_share_group_type(cs, args.share_group_type) cs.share_group_type_access.add_project_access( - share_group_type, args.project_id) + share_group_type, args.project_id + ) @cliutils.arg( 'share_group_type', metavar='', - help='Share group type name or ID to remove access for the given project.') + help='Share group type name or ID to remove access for the given project.', +) @cliutils.arg( 'project_id', metavar='', - help='Project ID to remove share group type access for.') + help='Project ID to remove share group type access for.', +) def do_share_group_type_access_remove(cs, args): """Removes share group type access for the given project (Admin only).""" share_group_type = _find_share_group_type(cs, args.share_group_type) cs.share_group_type_access.remove_project_access( - share_group_type, args.project_id) + share_group_type, args.project_id + ) ############################################################################## @@ -5650,27 +6284,34 @@ def do_share_group_type_access_remove(cs, args): '--name', metavar='', help='Optional share group name. (Default=None)', - default=None) + default=None, +) @cliutils.arg( '--description', metavar='', help='Optional share group description. (Default=None)', - default=None) + default=None, +) @cliutils.arg( - '--share-types', '--share_types', + '--share-types', + '--share_types', metavar='', type=str, default=None, action='single_alias', - help='Comma-separated list of share types. (Default=None)') + help='Comma-separated list of share types. (Default=None)', +) @cliutils.arg( - '--share-group-type', '--share_group_type', '--type', + '--share-group-type', + '--share_group_type', + '--type', metavar='', type=str, default=None, action='single_alias', help="Share group type name or ID of the share group to be created. " - "(Default=None)") + "(Default=None)", +) @cliutils.arg( '--share-network', '--share_network', @@ -5678,7 +6319,8 @@ def do_share_group_type_access_remove(cs, args): type=str, default=None, action='single_alias', - help='Specify share network name or id.') + help='Specify share network name or id.', +) @cliutils.arg( '--source-share-group-snapshot', '--source_share_group_snapshot', @@ -5686,8 +6328,9 @@ def do_share_group_type_access_remove(cs, args): type=str, action='single_alias', help='Optional share group snapshot name or ID to create the share group ' - 'from. (Default=None)', - default=None) + 'from. (Default=None)', + default=None, +) @cliutils.arg( '--availability-zone', '--availability_zone', @@ -5696,12 +6339,14 @@ def do_share_group_type_access_remove(cs, args): action='single_alias', metavar='', help='Optional availability zone in which group should be created. ' - '(Default=None)') + '(Default=None)', +) @cliutils.arg( '--wait', action='store_true', default=False, - help='Wait for share group to create') + help='Wait for share group to create', +) @cliutils.service_type('sharev2') def do_share_group_create(cs, args): """Creates a new share group.""" @@ -5723,7 +6368,8 @@ def do_share_group_create(cs, args): share_group_snapshot = None if args.source_share_group_snapshot: share_group_snapshot = _find_share_group_snapshot( - cs, args.source_share_group_snapshot) + cs, args.source_share_group_snapshot + ) kwargs = { 'share_group_type': share_group_type, @@ -5740,8 +6386,11 @@ def do_share_group_create(cs, args): if args.wait: try: share_group = _wait_for_resource_status( - cs, share_group, resource_type='share_group', - expected_status='available') + cs, + share_group, + resource_type='share_group', + expected_status='available', + ) except exceptions.CommandError as e: print(e, file=sys.stderr) @@ -5749,7 +6398,8 @@ def do_share_group_create(cs, args): @cliutils.arg( - '--all-tenants', '--all-projects', + '--all-tenants', + '--all-projects', action='single_alias', dest='all_projects', metavar='<0|1>', @@ -5757,117 +6407,139 @@ def do_share_group_create(cs, args): type=int, const=1, default=0, - help='Display information from all projects (Admin only).') + help='Display information from all projects (Admin only).', +) @cliutils.arg( '--name', metavar='', type=str, default=None, - help='Filter results by name.') + help='Filter results by name.', +) @cliutils.arg( '--description', metavar='', type=str, default=None, help='Filter results by description. ' - 'Available only for microversion >= 2.36.') + 'Available only for microversion >= 2.36.', +) @cliutils.arg( '--status', metavar='', type=str, default=None, - help='Filter results by status.') + help='Filter results by status.', +) @cliutils.arg( - '--share-server-id', '--share-server_id', - '--share_server-id', '--share_server_id', + '--share-server-id', + '--share-server_id', + '--share_server-id', + '--share_server_id', metavar='', type=str, default=None, action='single_alias', - help='Filter results by share server ID (Admin only).') + help='Filter results by share server ID (Admin only).', +) @cliutils.arg( - '--share-group-type', '--share-group-type-id', - '--share_group_type', '--share_group_type_id', + '--share-group-type', + '--share-group-type-id', + '--share_group_type', + '--share_group_type_id', metavar='', type=str, default=None, action='single_alias', help='Filter results by a share group type ID or name that was used for ' - 'share group creation.') + 'share group creation.', +) @cliutils.arg( '--snapshot', metavar='', type=str, default=None, help='Filter results by share group snapshot name or ID that was used to ' - 'create the share group.') + 'create the share group.', +) @cliutils.arg( - '--host', - metavar='', - default=None, - help='Filter results by host.') + '--host', metavar='', default=None, help='Filter results by host.' +) @cliutils.arg( - '--share-network', '--share_network', + '--share-network', + '--share_network', metavar='', type=str, default=None, action='single_alias', - help='Filter results by share-network name or ID.') + help='Filter results by share-network name or ID.', +) @cliutils.arg( - '--project-id', '--project_id', + '--project-id', + '--project_id', metavar='', type=str, default=None, action='single_alias', - help="Filter results by project ID. Useful with set key '--all-projects'.") + help="Filter results by project ID. Useful with set key '--all-projects'.", +) @cliutils.arg( '--limit', metavar='', type=int, default=None, - help='Maximum number of share groups to return. (Default=None)') + help='Maximum number of share groups to return. (Default=None)', +) @cliutils.arg( '--offset', metavar="", default=None, - help='Start position of share group listing.') + help='Start position of share group listing.', +) @cliutils.arg( - '--sort-key', '--sort_key', + '--sort-key', + '--sort_key', metavar='', type=str, default=None, action='single_alias', - help='Key to be sorted, available keys are %(keys)s. Default=None.' % { - 'keys': constants.SHARE_GROUP_SORT_KEY_VALUES}) + help='Key to be sorted, available keys are %(keys)s. Default=None.' + % {'keys': constants.SHARE_GROUP_SORT_KEY_VALUES}, +) @cliutils.arg( - '--sort-dir', '--sort_dir', + '--sort-dir', + '--sort_dir', metavar='', type=str, default=None, action='single_alias', help='Sort direction, available values are %(values)s. ' - 'OPTIONAL: Default=None.' % {'values': constants.SORT_DIR_VALUES}) + 'OPTIONAL: Default=None.' % {'values': constants.SORT_DIR_VALUES}, +) @cliutils.arg( '--columns', metavar='', type=str, default=None, help='Comma separated list of columns to be displayed ' - 'example --columns "id,name".') + 'example --columns "id,name".', +) @cliutils.arg( '--name~', metavar='', type=str, default=None, help='Filter results matching a share group name pattern. ' - 'Available only for microversion >= 2.36.') + 'Available only for microversion >= 2.36.', +) @cliutils.arg( '--description~', metavar='', type=str, default=None, help='Filter results matching a share group description pattern. ' - 'Available only for microversion >= 2.36.') + 'Available only for microversion >= 2.36.', +) @cliutils.service_type('sharev2') def do_share_group_list(cs, args): """List share groups with filters.""" @@ -5877,17 +6549,24 @@ def do_share_group_list(cs, args): list_of_keys = ('ID', 'Name', 'Status', 'Description') all_projects = int( - os.environ.get("ALL_TENANTS", - os.environ.get("ALL_PROJECTS", - args.all_projects)) + os.environ.get( + "ALL_TENANTS", os.environ.get("ALL_PROJECTS", args.all_projects) + ) ) empty_obj = type('Empty', (object,), {'id': None}) - sg_type = (_find_share_group_type(cs, args.share_group_type) - if args.share_group_type else empty_obj) - snapshot = (_find_share_snapshot(cs, args.snapshot) - if args.snapshot else empty_obj) - share_network = (_find_share_network(cs, args.share_network) - if args.share_network else empty_obj) + sg_type = ( + _find_share_group_type(cs, args.share_group_type) + if args.share_group_type + else empty_obj + ) + snapshot = ( + _find_share_snapshot(cs, args.snapshot) if args.snapshot else empty_obj + ) + share_network = ( + _find_share_network(cs, args.share_network) + if args.share_network + else empty_obj + ) search_opts = { 'offset': args.offset, @@ -5902,28 +6581,33 @@ def do_share_group_list(cs, args): 'share_network_id': share_network.id, 'project_id': args.project_id, } - if cs.api_version.matches(api_versions.APIVersion("2.36"), - api_versions.APIVersion()): + if cs.api_version.matches( + api_versions.APIVersion("2.36"), api_versions.APIVersion() + ): search_opts['name~'] = getattr(args, 'name~') search_opts['description~'] = getattr(args, 'description~') search_opts['description'] = getattr(args, 'description') - elif (getattr(args, 'name~') or getattr(args, 'description~') or - getattr(args, 'description')): + elif ( + getattr(args, 'name~') + or getattr(args, 'description~') + or getattr(args, 'description') + ): raise exceptions.CommandError( "Pattern based filtering (name~, description~ and description)" - " is only available with manila API version >= 2.36") + " is only available with manila API version >= 2.36" + ) share_groups = cs.share_groups.list( - search_opts=search_opts, sort_key=args.sort_key, - sort_dir=args.sort_dir) - cliutils.print_list(share_groups, fields=list_of_keys, - sortby_index=None) + search_opts=search_opts, sort_key=args.sort_key, sort_dir=args.sort_dir + ) + cliutils.print_list(share_groups, fields=list_of_keys, sortby_index=None) @cliutils.arg( 'share_group', metavar='', - help='Name or ID of the share group.') + help='Name or ID of the share group.', +) @cliutils.service_type('sharev2') def do_share_group_show(cs, args): """Show details about a share group.""" @@ -5934,17 +6618,20 @@ def do_share_group_show(cs, args): @cliutils.arg( 'share_group', metavar='', - help='Name or ID of the share group to update.') + help='Name or ID of the share group to update.', +) @cliutils.arg( '--name', metavar='', default=None, - help='Optional new name for the share group. (Default=None)') + help='Optional new name for the share group. (Default=None)', +) @cliutils.arg( '--description', metavar='', help='Optional share group description. (Default=None)', - default=None) + default=None, +) @cliutils.service_type('sharev2') def do_share_group_update(cs, args): """Update a share group.""" @@ -5967,18 +6654,21 @@ def do_share_group_update(cs, args): 'share_group', metavar='', nargs='+', - help='Name or ID of the share group(s).') + help='Name or ID of the share group(s).', +) @cliutils.arg( '--force', action='store_true', default=False, help='Attempt to force delete the share group (Default=False)' - ' (Admin only).') + ' (Admin only).', +) @cliutils.arg( '--wait', action='store_true', default=False, - help='Wait for share group to delete') + help='Wait for share group to delete', +) @cliutils.service_type('sharev2') def do_share_group_delete(cs, args): """Delete one or more share groups.""" @@ -5992,19 +6682,25 @@ def do_share_group_delete(cs, args): share_group_ref.delete(args.force) except Exception as e: failure_count += 1 - print("Delete for share group %s failed: %s" % ( - share_group, e), file=sys.stderr) + print( + "Delete for share group %s failed: %s" % (share_group, e), + file=sys.stderr, + ) if failure_count == len(args.share_group): - raise exceptions.CommandError("Unable to delete any of the specified " - "share groups.") + raise exceptions.CommandError( + "Unable to delete any of the specified share groups." + ) if args.wait: for share_group in share_group_to_delete: try: _wait_for_resource_status( - cs, share_group, resource_type='share_group', - expected_status='deleted') + cs, + share_group, + resource_type='share_group', + expected_status='deleted', + ) except exceptions.CommandError as e: print(e, file=sys.stderr) @@ -6012,15 +6708,19 @@ def do_share_group_delete(cs, args): @cliutils.arg( 'share_group', metavar='', - help='Name or ID of the share group to modify.') + help='Name or ID of the share group to modify.', +) @cliutils.arg( '--state', metavar='', default='available', - help=('Indicate which state to assign the share group. ' - 'Options include available, error, creating, deleting, ' - 'error_deleting. If no state is provided, ' - 'available will be used.')) + help=( + 'Indicate which state to assign the share group. ' + 'Options include available, error, creating, deleting, ' + 'error_deleting. If no state is provided, ' + 'available will be used.' + ), +) @cliutils.service_type('sharev2') def do_share_group_reset_state(cs, args): """Explicitly update the state of a share group @@ -6041,22 +6741,26 @@ def do_share_group_reset_state(cs, args): @cliutils.arg( 'share_group', metavar='', - help='Name or ID of the share group.') + help='Name or ID of the share group.', +) @cliutils.arg( '--name', metavar='', help='Optional share group snapshot name. (Default=None)', - default=None) + default=None, +) @cliutils.arg( '--description', metavar='', help='Optional share group snapshot description. (Default=None)', - default=None) + default=None, +) @cliutils.arg( '--wait', action='store_true', default=False, - help='Wait for share group snapshot to be created') + help='Wait for share group snapshot to be created', +) @cliutils.service_type('sharev2') def do_share_group_snapshot_create(cs, args): """Creates a new share group snapshot.""" @@ -6065,13 +6769,17 @@ def do_share_group_snapshot_create(cs, args): sg_snapshot = cs.share_group_snapshots.create(share_group.id, **kwargs) if args.wait: _wait_for_resource_status( - cs, sg_snapshot, resource_type='share_group_snapshot', - expected_status='available') + cs, + sg_snapshot, + resource_type='share_group_snapshot', + expected_status='available', + ) _print_share_group_snapshot(cs, sg_snapshot) @cliutils.arg( - '--all-tenants', '--all-projects', + '--all-tenants', + '--all-projects', action='single_alias', dest='all_projects', metavar='<0|1>', @@ -6079,63 +6787,72 @@ def do_share_group_snapshot_create(cs, args): type=int, const=1, default=0, - help='Display information from all projects (Admin only).') + help='Display information from all projects (Admin only).', +) @cliutils.arg( - '--name', - metavar='', - default=None, - help='Filter results by name.') + '--name', metavar='', default=None, help='Filter results by name.' +) @cliutils.arg( '--status', metavar='', default=None, - help='Filter results by status.') + help='Filter results by status.', +) @cliutils.arg( - '--share-group-id', '--share_group_id', + '--share-group-id', + '--share_group_id', metavar='', default=None, action='single_alias', - help='Filter results by share group ID.') + help='Filter results by share group ID.', +) @cliutils.arg( '--limit', metavar='', type=int, default=None, - help='Maximum number of share group snapshots to return. ' - '(Default=None)') + help='Maximum number of share group snapshots to return. (Default=None)', +) @cliutils.arg( '--offset', metavar="", default=None, - help='Start position of share group snapshot listing.') + help='Start position of share group snapshot listing.', +) @cliutils.arg( - '--sort-key', '--sort_key', + '--sort-key', + '--sort_key', metavar='', type=str, default=None, action='single_alias', - help='Key to be sorted, available keys are %(keys)s. Default=None.' % { - 'keys': constants.SHARE_GROUP_SNAPSHOT_SORT_KEY_VALUES}) + help='Key to be sorted, available keys are %(keys)s. Default=None.' + % {'keys': constants.SHARE_GROUP_SNAPSHOT_SORT_KEY_VALUES}, +) @cliutils.arg( - '--sort-dir', '--sort_dir', + '--sort-dir', + '--sort_dir', metavar='', type=str, default=None, action='single_alias', help='Sort direction, available values are %(values)s. ' - 'OPTIONAL: Default=None.' % {'values': constants.SORT_DIR_VALUES}) + 'OPTIONAL: Default=None.' % {'values': constants.SORT_DIR_VALUES}, +) @cliutils.arg( '--detailed', dest='detailed', default=True, - help='Show detailed information about share group snapshots.') + help='Show detailed information about share group snapshots.', +) @cliutils.arg( '--columns', metavar='', type=str, default=None, help='Comma separated list of columns to be displayed ' - 'example --columns "id,name".') + 'example --columns "id,name".', +) @cliutils.service_type('sharev2') def do_share_group_snapshot_list(cs, args): """List share group snapshots with filters.""" @@ -6145,9 +6862,9 @@ def do_share_group_snapshot_list(cs, args): list_of_keys = ('id', 'name', 'status', 'description') all_projects = int( - os.environ.get("ALL_TENANTS", - os.environ.get("ALL_PROJECTS", - args.all_projects)) + os.environ.get( + "ALL_TENANTS", os.environ.get("ALL_PROJECTS", args.all_projects) + ) ) search_opts = { @@ -6159,16 +6876,21 @@ def do_share_group_snapshot_list(cs, args): 'share_group_id': args.share_group_id, } share_group_snapshots = cs.share_group_snapshots.list( - detailed=args.detailed, search_opts=search_opts, - sort_key=args.sort_key, sort_dir=args.sort_dir) - cliutils.print_list(share_group_snapshots, fields=list_of_keys, - sortby_index=None) + detailed=args.detailed, + search_opts=search_opts, + sort_key=args.sort_key, + sort_dir=args.sort_dir, + ) + cliutils.print_list( + share_group_snapshots, fields=list_of_keys, sortby_index=None + ) @cliutils.arg( 'share_group_snapshot', metavar='', - help='Name or ID of the share group snapshot.') + help='Name or ID of the share group snapshot.', +) @cliutils.service_type('sharev2') def do_share_group_snapshot_show(cs, args): """Show details about a share group snapshot.""" @@ -6179,14 +6901,16 @@ def do_share_group_snapshot_show(cs, args): @cliutils.arg( 'share_group_snapshot', metavar='', - help='Name or ID of the share group snapshot.') + help='Name or ID of the share group snapshot.', +) @cliutils.arg( '--columns', metavar='', type=str, default=None, help='Comma separated list of columns to be displayed ' - 'example --columns "id,name".') + 'example --columns "id,name".', +) @cliutils.service_type('sharev2') def do_share_group_snapshot_list_members(cs, args): """List members of a share group snapshot.""" @@ -6196,8 +6920,10 @@ def do_share_group_snapshot_list_members(cs, args): list_of_keys = ('Share ID', 'Size') sg_snapshot = _find_share_group_snapshot(cs, args.share_group_snapshot) - members = [type('ShareGroupSnapshotMember', (object,), member) - for member in sg_snapshot._info.get('members', [])] + members = [ + type('ShareGroupSnapshotMember', (object,), member) + for member in sg_snapshot._info.get('members', []) + ] cliutils.print_list(members, fields=list_of_keys) @@ -6205,14 +6931,18 @@ def do_share_group_snapshot_list_members(cs, args): '--state', metavar='', default='available', - help=('Indicate which state to assign the share group snapshot. ' - 'Options include available, error, creating, deleting, ' - 'error_deleting. If no state is provided, ' - 'available will be used.')) + help=( + 'Indicate which state to assign the share group snapshot. ' + 'Options include available, error, creating, deleting, ' + 'error_deleting. If no state is provided, ' + 'available will be used.' + ), +) @cliutils.arg( 'share_group_snapshot', metavar='', - help='Name or ID of the share group snapshot.') + help='Name or ID of the share group snapshot.', +) @cliutils.service_type('sharev2') def do_share_group_snapshot_reset_state(cs, args): """Explicitly update the state of a share group snapshot @@ -6226,17 +6956,20 @@ def do_share_group_snapshot_reset_state(cs, args): @cliutils.arg( 'share_group_snapshot', metavar='', - help='Name or ID of the share group snapshot to update.') + help='Name or ID of the share group snapshot to update.', +) @cliutils.arg( '--name', metavar='', default=None, - help='Optional new name for the share group snapshot. (Default=None)') + help='Optional new name for the share group snapshot. (Default=None)', +) @cliutils.arg( '--description', metavar='', help='Optional share group snapshot description. (Default=None)', - default=None) + default=None, +) @cliutils.service_type('sharev2') def do_share_group_snapshot_update(cs, args): """Update a share group snapshot.""" @@ -6260,18 +6993,21 @@ def do_share_group_snapshot_update(cs, args): 'share_group_snapshot', metavar='', nargs='+', - help='Name or ID of the share group snapshot(s) to delete.') + help='Name or ID of the share group snapshot(s) to delete.', +) @cliutils.arg( '--force', action='store_true', default=False, help='Attempt to force delete the share group snapshot(s) (Default=False)' - ' (Admin only).') + ' (Admin only).', +) @cliutils.arg( '--wait', action='store_true', default=False, - help='Wait for share group snapshot to be deleted') + help='Wait for share group snapshot to be deleted', +) @cliutils.service_type('sharev2') def do_share_group_snapshot_delete(cs, args): """Remove one or more share group snapshots.""" @@ -6286,16 +7022,23 @@ def do_share_group_snapshot_delete(cs, args): cs.share_group_snapshots.delete(sg_snapshot_ref, **kwargs) if args.wait: _wait_for_resource_status( - cs, sg_snapshot, resource_type='share_group_snapshot', - expected_status='deleted') + cs, + sg_snapshot, + resource_type='share_group_snapshot', + expected_status='deleted', + ) except Exception as e: failure_count += 1 - print("Delete for share group snapshot %s failed: %s" % ( - sg_snapshot, e), file=sys.stderr) + print( + "Delete for share group snapshot %s failed: %s" + % (sg_snapshot, e), + file=sys.stderr, + ) if failure_count == len(args.share_group_snapshot): - raise exceptions.CommandError("Unable to delete any of the specified " - "share group snapshots.") + raise exceptions.CommandError( + "Unable to delete any of the specified share group snapshots." + ) ############################################################################## @@ -6312,14 +7055,16 @@ def do_share_group_snapshot_delete(cs, args): metavar='', default=None, action='single_alias', - help='List replicas belonging to share.') + help='List replicas belonging to share.', +) @cliutils.arg( '--columns', metavar='', type=str, default=None, help='Comma separated list of columns to be displayed ' - 'example --columns "replica_state,id".') + 'example --columns "replica_state,id".', +) @api_versions.wraps("2.11") def do_share_replica_list(cs, args): """List share replicas.""" @@ -6348,9 +7093,8 @@ def do_share_replica_list(cs, args): @api_versions.wraps("2.11", "2.66") @cliutils.arg( - 'share', - metavar='', - help='Name or ID of the share to replicate.') + 'share', metavar='', help='Name or ID of the share to replicate.' +) @cliutils.arg( '--availability-zone', '--availability_zone', @@ -6358,7 +7102,8 @@ def do_share_replica_list(cs, args): default=None, action='single_alias', metavar='', - help='Optional Availability zone in which replica should be created.') + help='Optional Availability zone in which replica should be created.', +) def do_share_replica_create(cs, args): """Create a share replica.""" share = _find_share(cs, args.share) @@ -6373,9 +7118,8 @@ def do_share_replica_create(cs, args): @api_versions.wraps("2.67", "2.71") @cliutils.arg( - 'share', - metavar='', - help='Name or ID of the share to replicate.') + 'share', metavar='', help='Name or ID of the share to replicate.' +) @cliutils.arg( '--availability-zone', '--availability_zone', @@ -6383,7 +7127,8 @@ def do_share_replica_create(cs, args): default=None, action='single_alias', metavar='', - help='Optional Availability zone in which replica should be created.') + help='Optional Availability zone in which replica should be created.', +) @cliutils.arg( '--scheduler-hints', '--scheduler_hints', @@ -6391,8 +7136,9 @@ def do_share_replica_create(cs, args): metavar='', nargs='*', help='Scheduler hints for the share replica as key=value pairs, ' - 'Supported key is only_host. Available for microversion >= 2.67. ', - default=None) + 'Supported key is only_host. Available for microversion >= 2.67. ', + default=None, +) def do_share_replica_create(cs, args): # noqa """Create a share replica.""" share = _find_share(cs, args.share) @@ -6403,7 +7149,8 @@ def do_share_replica_create(cs, args): # noqa if 'only_host' not in hints.keys() or len(hints) > 1: raise exceptions.CommandError( "The only valid key supported with the --scheduler-hints " - "argument is 'only_host'.") + "argument is 'only_host'." + ) scheduler_hints['only_host'] = hints.get('only_host') body = { @@ -6419,9 +7166,8 @@ def do_share_replica_create(cs, args): # noqa @api_versions.wraps("2.72") @cliutils.arg( - 'share', - metavar='', - help='Name or ID of the share to replicate.') + 'share', metavar='', help='Name or ID of the share to replicate.' +) @cliutils.arg( '--availability-zone', '--availability_zone', @@ -6429,7 +7175,8 @@ def do_share_replica_create(cs, args): # noqa default=None, action='single_alias', metavar='', - help='Optional Availability zone in which replica should be created.') + help='Optional Availability zone in which replica should be created.', +) @cliutils.arg( '--scheduler-hints', '--scheduler_hints', @@ -6437,8 +7184,9 @@ def do_share_replica_create(cs, args): # noqa metavar='', nargs='*', help='Scheduler hints for the share replica as key=value pairs, ' - 'Supported key is only_host. Available for microversion >= 2.67. ', - default=None) + 'Supported key is only_host. Available for microversion >= 2.67. ', + default=None, +) @cliutils.arg( '--share-network', '--share_network', @@ -6446,12 +7194,14 @@ def do_share_replica_create(cs, args): # noqa default=None, action='single_alias', help='Optional network info ID or name. ' - 'Available only for microversion >= 2.72') + 'Available only for microversion >= 2.72', +) @cliutils.arg( '--wait', action='store_true', default=False, - help='Wait for share replica to be created') + help='Wait for share replica to be created', +) def do_share_replica_create(cs, args): # noqa """Create a share replica.""" share = _find_share(cs, args.share) @@ -6462,7 +7212,8 @@ def do_share_replica_create(cs, args): # noqa if 'only_host' not in hints.keys() or len(hints) > 1: raise exceptions.CommandError( "The only valid key supported with the --scheduler-hints " - "argument is 'only_host'.") + "argument is 'only_host'." + ) scheduler_hints['only_host'] = hints.get('only_host') share_network = None @@ -6482,15 +7233,15 @@ def do_share_replica_create(cs, args): # noqa replica = cs.share_replicas.create(**body) if args.wait: _wait_for_resource_status( - cs, replica, resource_type='share_replica', - expected_status='available') + cs, + replica, + resource_type='share_replica', + expected_status='available', + ) _print_share_replica(cs, replica) -@cliutils.arg( - 'replica', - metavar='', - help='ID of the share replica.') +@cliutils.arg('replica', metavar='', help='ID of the share replica.') @api_versions.wraps("2.11", "2.46") def do_share_replica_show(cs, args): """Show details about a replica.""" @@ -6500,10 +7251,7 @@ def do_share_replica_show(cs, args): @api_versions.wraps("2.47") # noqa -@cliutils.arg( - 'replica', - metavar='', - help='ID of the share replica.') +@cliutils.arg('replica', metavar='', help='ID of the share replica.') def do_share_replica_show(cs, args): # noqa """Show details about a replica.""" @@ -6514,29 +7262,27 @@ def do_share_replica_show(cs, args): # noqa @cliutils.arg( - 'replica', - metavar='', - nargs='+', - help='ID of the share replica.') + 'replica', metavar='', nargs='+', help='ID of the share replica.' +) @cliutils.arg( '--force', action='store_true', default=False, help='Attempt to force deletion of a replica on its backend. Using ' - 'this option will purge the replica from Manila even if it ' - 'is not cleaned up on the backend. Defaults to False.') + 'this option will purge the replica from Manila even if it ' + 'is not cleaned up on the backend. Defaults to False.', +) @cliutils.arg( '--wait', action='store_true', default=False, - help='Wait for share replica to be deleted') + help='Wait for share replica to be deleted', +) @api_versions.wraps("2.11") def do_share_replica_delete(cs, args): """Remove one or more share replicas.""" failure_count = 0 - kwargs = { - "force": args.force - } + kwargs = {"force": args.force} for replica in args.replica: try: @@ -6544,22 +7290,25 @@ def do_share_replica_delete(cs, args): cs.share_replicas.delete(replica_ref, **kwargs) if args.wait: _wait_for_resource_status( - cs, replica_ref, resource_type='share_replica', - expected_status='deleted') + cs, + replica_ref, + resource_type='share_replica', + expected_status='deleted', + ) except Exception as e: failure_count += 1 - print("Delete for share replica %s failed: %s" % (replica, e), - file=sys.stderr) + print( + "Delete for share replica %s failed: %s" % (replica, e), + file=sys.stderr, + ) if failure_count == len(args.replica): - raise exceptions.CommandError("Unable to delete any of the specified " - "replicas.") + raise exceptions.CommandError( + "Unable to delete any of the specified replicas." + ) -@cliutils.arg( - 'replica', - metavar='', - help='ID of the share replica.') +@cliutils.arg('replica', metavar='', help='ID of the share replica.') @api_versions.wraps("2.11", "2.74") def do_share_replica_promote(cs, args): """Promote specified replica to 'active' replica_state.""" @@ -6567,21 +7316,19 @@ def do_share_replica_promote(cs, args): cs.share_replicas.promote(replica) -@cliutils.arg( - 'replica', - metavar='', - help='ID of the share replica.') +@cliutils.arg('replica', metavar='', help='ID of the share replica.') @cliutils.arg( '--quiesce-wait-time', metavar='', default=None, - help='Quiesce wait time in seconds. Available for ' - 'microversion >= 2.75') + help='Quiesce wait time in seconds. Available for microversion >= 2.75', +) @cliutils.arg( '--wait', action='store_true', default=False, - help='Wait for share replica to be promoted') + help='Wait for share replica to be promoted', +) @api_versions.wraps("2.75") # noqa def do_share_replica_promote(cs, args): # noqa """Promote specified replica to 'active' replica_state.""" @@ -6593,24 +7340,24 @@ def do_share_replica_promote(cs, args): # noqa cs.share_replicas.promote(replica, quiesce_wait_time) if args.wait: _wait_for_resource_status( - cs, replica, + cs, + replica, resource_type='share_replica', expected_status='active', - status_attr='replica_state') + status_attr='replica_state', + ) @api_versions.wraps("2.47") -@cliutils.arg( - 'replica', - metavar='', - help='ID of the share replica.') +@cliutils.arg('replica', metavar='', help='ID of the share replica.') @cliutils.arg( '--columns', metavar='', type=str, default=None, help='Comma separated list of columns to be displayed ' - 'example --columns "id,path,replica_state".') + 'example --columns "id,path,replica_state".', +) def do_share_replica_export_location_list(cs, args): """List export locations of a share replica.""" if args.columns is not None: @@ -6630,33 +7377,36 @@ def do_share_replica_export_location_list(cs, args): @api_versions.wraps("2.47") @cliutils.arg( - 'replica', - metavar='', - help='Name or ID of the share replica.') + 'replica', metavar='', help='Name or ID of the share replica.' +) @cliutils.arg( 'export_location', metavar='', - help='ID of the share replica export location.') + help='ID of the share replica export location.', +) def do_share_replica_export_location_show(cs, args): """Show details of a share replica's export location.""" replica = _find_share_replica(cs, args.replica) export_location = cs.share_replica_export_locations.get( - replica, args.export_location) + replica, args.export_location + ) view_data = export_location._info.copy() cliutils.print_dict(view_data) @cliutils.arg( - 'replica', - metavar='', - help='ID of the share replica to modify.') + 'replica', metavar='', help='ID of the share replica to modify.' +) @cliutils.arg( '--state', metavar='', default='available', - help=('Indicate which state to assign the replica. Options include ' - 'available, error, creating, deleting, error_deleting. If no ' - 'state is provided, available will be used.')) + help=( + 'Indicate which state to assign the replica. Options include ' + 'available, error, creating, deleting, error_deleting. If no ' + 'state is provided, available will be used.' + ), +) @api_versions.wraps("2.11") def do_share_replica_reset_state(cs, args): """Explicitly update the 'status' of a share replica.""" @@ -6665,9 +7415,8 @@ def do_share_replica_reset_state(cs, args): @cliutils.arg( - 'replica', - metavar='', - help='ID of the share replica to modify.') + 'replica', metavar='', help='ID of the share replica to modify.' +) @cliutils.arg( '--replica-state', '--replica_state', @@ -6675,9 +7424,12 @@ def do_share_replica_reset_state(cs, args): metavar='', default='out_of_sync', action='single_alias', - help=('Indicate which replica_state to assign the replica. Options ' - 'include in_sync, out_of_sync, active, error. If no ' - 'state is provided, out_of_sync will be used.')) + help=( + 'Indicate which replica_state to assign the replica. Options ' + 'include in_sync, out_of_sync, active, error. If no ' + 'state is provided, out_of_sync will be used.' + ), +) @api_versions.wraps("2.11") def do_share_replica_reset_replica_state(cs, args): """Explicitly update the 'replica_state' of a share replica.""" @@ -6686,9 +7438,8 @@ def do_share_replica_reset_replica_state(cs, args): @cliutils.arg( - 'replica', - metavar='', - help='ID of the share replica to resync.') + 'replica', metavar='', help='ID of the share replica to resync.' +) @api_versions.wraps("2.11") def do_share_replica_resync(cs, args): """Attempt to update the share replica with its 'active' mirror.""" @@ -6712,19 +7463,18 @@ def _print_share_transfer(transfer): @api_versions.wraps("2.77") @cliutils.arg( - 'share', - metavar='', - help='Name or ID of share to transfer.') + 'share', metavar='', help='Name or ID of share to transfer.' +) @cliutils.arg( '--name', metavar='', default=None, - help='Transfer name. Default=None.') + help='Transfer name. Default=None.', +) def do_share_transfer_create(cs, args): """Creates a share transfer.""" share = _find_share(cs, args.share) - transfer = cs.transfers.create(share.id, - args.name) + transfer = cs.transfers.create(share.id, args.name) _print_share_transfer(transfer) @@ -6733,7 +7483,8 @@ def do_share_transfer_create(cs, args): 'transfer', metavar='', nargs='+', - help='ID or name of the transfer(s).') + help='ID or name of the transfer(s).', +) def do_share_transfer_delete(cs, args): """Remove one or more transfers.""" failure_count = 0 @@ -6744,23 +7495,26 @@ def do_share_transfer_delete(cs, args): transfer_ref.delete() except Exception as e: failure_count += 1 - print("Delete for share transfer %s failed: %s" % (transfer, e), - file=sys.stderr) + print( + "Delete for share transfer %s failed: %s" % (transfer, e), + file=sys.stderr, + ) if failure_count == len(args.transfer): - raise exceptions.CommandError("Unable to delete any of the specified " - "transfers.") + raise exceptions.CommandError( + "Unable to delete any of the specified transfers." + ) @api_versions.wraps("2.77") @cliutils.arg( - 'transfer', - metavar='', - help='ID of transfer to accept.') + 'transfer', metavar='', help='ID of transfer to accept.' +) @cliutils.arg( 'auth_key', metavar='', - help='Authentication key of transfer to accept.') + help='Authentication key of transfer to accept.', +) @cliutils.arg( '--clear-rules', '--clear_rules', @@ -6768,16 +7522,19 @@ def do_share_transfer_delete(cs, args): action='store_true', default=False, help="Whether manila should clean up the access rules after the " - "transfer is complete. (Default=False)") + "transfer is complete. (Default=False)", +) def do_share_transfer_accept(cs, args): """Accepts a share transfer.""" - cs.transfers.accept(args.transfer, args.auth_key, - clear_access_rules=args.clear_rules) + cs.transfers.accept( + args.transfer, args.auth_key, clear_access_rules=args.clear_rules + ) @api_versions.wraps("2.77") @cliutils.arg( - '--all-tenants', '--all-projects', + '--all-tenants', + '--all-projects', action='single_alias', dest='all_projects', metavar='<0|1>', @@ -6785,64 +7542,79 @@ def do_share_transfer_accept(cs, args): type=int, const=1, default=0, - help='Shows details for all tenants. (Admin only).') + help='Shows details for all tenants. (Admin only).', +) @cliutils.arg( '--name', metavar='', default=None, action='single_alias', - help='Transfer name. Default=None.') + help='Transfer name. Default=None.', +) @cliutils.arg( '--id', metavar='', default=None, action='single_alias', - help='Transfer ID. Default=None.') + help='Transfer ID. Default=None.', +) @cliutils.arg( - '--resource-type', '--resource_type', + '--resource-type', + '--resource_type', metavar='', default=None, action='single_alias', - help='Transfer type, which can be share or network. Default=None.') + help='Transfer type, which can be share or network. Default=None.', +) @cliutils.arg( - '--resource-id', '--resource_id', + '--resource-id', + '--resource_id', metavar='', default=None, action='single_alias', - help='Transfer resource id. Default=None.') + help='Transfer resource id. Default=None.', +) @cliutils.arg( - '--source-project-id', '--source_project_id', + '--source-project-id', + '--source_project_id', metavar='', default=None, action='single_alias', - help='Transfer source project id. Default=None.') + help='Transfer source project id. Default=None.', +) @cliutils.arg( '--limit', metavar='', type=int, default=None, - help='Maximum number of messages to return. (Default=None)') + help='Maximum number of messages to return. (Default=None)', +) @cliutils.arg( '--offset', metavar="", default=None, - help='Start position of message listing.') + help='Start position of message listing.', +) @cliutils.arg( - '--sort-key', '--sort_key', + '--sort-key', + '--sort_key', metavar='', type=str, default=None, action='single_alias', help='Key to be sorted, available keys are %(keys)s. Default=None.' - % {'keys': constants.SHARE_TRANSFER_SORT_KEY_VALUES}) + % {'keys': constants.SHARE_TRANSFER_SORT_KEY_VALUES}, +) @cliutils.arg( - '--sort-dir', '--sort_dir', + '--sort-dir', + '--sort_dir', metavar='', type=str, default=None, action='single_alias', help='Sort direction, available values are %(values)s. ' - 'Optional: Default=None.' % {'values': constants.SORT_DIR_VALUES}) + 'Optional: Default=None.' % {'values': constants.SORT_DIR_VALUES}, +) @cliutils.arg( '--detailed', dest='detailed', @@ -6851,14 +7623,16 @@ def do_share_transfer_accept(cs, args): type=int, const=1, default=0, - help="Show detailed information about filtered share transfers.") + help="Show detailed information about filtered share transfers.", +) @cliutils.arg( '--columns', metavar='', type=str, default=None, help='Comma separated list of columns to be displayed ' - 'example --columns "id,resource_id".') + 'example --columns "id,resource_id".', +) def do_share_transfer_list(cs, args): """Lists all transfers.""" if args.columns is not None: @@ -6867,13 +7641,20 @@ def do_share_transfer_list(cs, args): list_of_keys = ['ID', 'Name', 'Resource Type', 'Resource Id'] if args.detailed: - list_of_keys.extend(['Created At', 'Expires At', 'Source Project Id', - 'Destination Project Id', 'Accepted']) + list_of_keys.extend( + [ + 'Created At', + 'Expires At', + 'Source Project Id', + 'Destination Project Id', + 'Accepted', + ] + ) all_projects = int( - os.environ.get("ALL_TENANTS", - os.environ.get("ALL_PROJECTS", - args.all_projects)) + os.environ.get( + "ALL_TENANTS", os.environ.get("ALL_PROJECTS", args.all_projects) + ) ) search_opts = { @@ -6887,21 +7668,26 @@ def do_share_transfer_list(cs, args): 'source_project_id': args.source_project_id, } share_transfers = cs.transfers.list( - detailed=args.detailed, search_opts=search_opts, - sort_key=args.sort_key, sort_dir=args.sort_dir) - cliutils.print_list(share_transfers, fields=list_of_keys, - sortby_index=None) + detailed=args.detailed, + search_opts=search_opts, + sort_key=args.sort_key, + sort_dir=args.sort_dir, + ) + cliutils.print_list( + share_transfers, fields=list_of_keys, sortby_index=None + ) @api_versions.wraps("2.77") @cliutils.arg( - 'transfer', - metavar='', - help='Name or ID of transfer to show.') + 'transfer', metavar='', help='Name or ID of transfer to show.' +) def do_share_transfer_show(cs, args): """Delete a transfer.""" transfer = _find_share_transfer(cs, args.transfer) _print_share_transfer(transfer) + + ############################################################################## # # User Messages @@ -6917,7 +7703,8 @@ def do_share_transfer_show(cs, args): metavar='', default=None, action='single_alias', - help='Filters results by a resource uuid. Default=None.') + help='Filters results by a resource uuid. Default=None.', +) @cliutils.arg( '--resource_type', '--resource-type', @@ -6925,7 +7712,8 @@ def do_share_transfer_show(cs, args): default=None, action='single_alias', help='Filters results by a resource type. Default=None. ' - 'Example: "manila message-list --resource_type share"') + 'Example: "manila message-list --resource_type share"', +) @cliutils.arg( '--action_id', '--action-id', @@ -6933,7 +7721,8 @@ def do_share_transfer_show(cs, args): metavar='', default=None, action='single_alias', - help='Filters results by action id. Default=None.') + help='Filters results by action id. Default=None.', +) @cliutils.arg( '--detail_id', '--detail-id', @@ -6941,7 +7730,8 @@ def do_share_transfer_show(cs, args): metavar='', default=None, action='single_alias', - help='Filters results by detail id. Default=None.') + help='Filters results by detail id. Default=None.', +) @cliutils.arg( '--request_id', '--request-id', @@ -6949,7 +7739,8 @@ def do_share_transfer_show(cs, args): metavar='', default=None, action='single_alias', - help='Filters results by request id. Default=None.') + help='Filters results by request id. Default=None.', +) @cliutils.arg( '--level', '--message_level', @@ -6958,62 +7749,79 @@ def do_share_transfer_show(cs, args): default=None, action='single_alias', help='Filters results by the message level. Default=None. ' - 'Example: "manila message-list --level ERROR".') + 'Example: "manila message-list --level ERROR".', +) @cliutils.arg( '--limit', metavar='', type=int, default=None, - help='Maximum number of messages to return. (Default=None)') + help='Maximum number of messages to return. (Default=None)', +) @cliutils.arg( '--offset', metavar="", default=None, - help='Start position of message listing.') + help='Start position of message listing.', +) @cliutils.arg( - '--sort-key', '--sort_key', + '--sort-key', + '--sort_key', metavar='', type=str, default=None, action='single_alias', - help='Key to be sorted, available keys are %(keys)s. Default=desc.' % { - 'keys': constants.MESSAGE_SORT_KEY_VALUES}) + help='Key to be sorted, available keys are %(keys)s. Default=desc.' + % {'keys': constants.MESSAGE_SORT_KEY_VALUES}, +) @cliutils.arg( - '--sort-dir', '--sort_dir', + '--sort-dir', + '--sort_dir', metavar='', type=str, default=None, action='single_alias', help='Sort direction, available values are %(values)s. ' - 'OPTIONAL: Default=None.' % {'values': constants.SORT_DIR_VALUES}) + 'OPTIONAL: Default=None.' % {'values': constants.SORT_DIR_VALUES}, +) @cliutils.arg( '--columns', metavar='', type=str, default=None, help='Comma separated list of columns to be displayed ' - 'example --columns "resource_id,user_message".') + 'example --columns "resource_id,user_message".', +) @cliutils.arg( '--since', metavar='', default=None, help='Return only user messages created since given date. ' - 'The date format must be conforming to ISO8601. ' - 'Available only for microversion >= 2.52.') + 'The date format must be conforming to ISO8601. ' + 'Available only for microversion >= 2.52.', +) @cliutils.arg( '--before', metavar='', default=None, help='Return only user messages created before given date. ' - 'The date format must be conforming to ISO8601. ' - 'Available only for microversion >= 2.52.') + 'The date format must be conforming to ISO8601. ' + 'Available only for microversion >= 2.52.', +) def do_message_list(cs, args): """Lists all messages.""" if args.columns is not None: list_of_keys = _split_columns(columns=args.columns) else: - list_of_keys = ['ID', 'Resource Type', 'Resource ID', 'Action ID', - 'User Message', 'Detail ID', 'Created At'] + list_of_keys = [ + 'ID', + 'Resource Type', + 'Resource ID', + 'Action ID', + 'User Message', + 'Detail ID', + 'Created At', + ] search_opts = { 'offset': args.offset, @@ -7023,11 +7831,13 @@ def do_message_list(cs, args): 'resource_id': args.resource_id, 'action_id': args.action_id, 'detail_id': args.detail_id, - 'message_level': args.level + 'message_level': args.level, } if cs.api_version < api_versions.APIVersion("2.52"): - msg = ("Filtering messages by 'since' and 'before' is possible only " - "with Manila API version >=2.52") + msg = ( + "Filtering messages by 'since' and 'before' is possible only " + "with Manila API version >=2.52" + ) if getattr(args, 'since') or getattr(args, 'before'): raise exceptions.CommandError(msg) else: @@ -7035,15 +7845,12 @@ def do_message_list(cs, args): search_opts['created_before'] = args.before messages = cs.messages.list( - search_opts=search_opts, sort_key=args.sort_key, - sort_dir=args.sort_dir) + search_opts=search_opts, sort_key=args.sort_key, sort_dir=args.sort_dir + ) cliutils.print_list(messages, fields=list_of_keys, sortby_index=None) -@cliutils.arg( - 'message', - metavar='', - help='ID of the message.') +@cliutils.arg('message', metavar='', help='ID of the message.') @api_versions.wraps("2.37") def do_message_show(cs, args): """Show details about a message.""" @@ -7054,10 +7861,8 @@ def do_message_show(cs, args): @api_versions.wraps("2.37") @cliutils.arg( - 'message', - metavar='', - nargs='+', - help='ID of the message(s).') + 'message', metavar='', nargs='+', help='ID of the message(s).' +) def do_message_delete(cs, args): """Remove one or more messages.""" failure_count = 0 @@ -7068,12 +7873,15 @@ def do_message_delete(cs, args): cs.messages.delete(message_ref) except Exception as e: failure_count += 1 - print("Delete for message %s failed: %s" % (message, e), - file=sys.stderr) + print( + "Delete for message %s failed: %s" % (message, e), + file=sys.stderr, + ) if failure_count == len(args.message): - raise exceptions.CommandError("Unable to delete any of the specified " - "messages.") + raise exceptions.CommandError( + "Unable to delete any of the specified messages." + ) def _print_message(message): diff --git a/pyproject.toml b/pyproject.toml index 18567e1e..a85d4bfc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -198,3 +198,22 @@ omit = [ "manilaclient/tests/*", ] branch = true + +[tool.ruff] +line-length = 79 + +[tool.ruff.format] +quote-style = "preserve" +docstring-code-format = true + +[tool.ruff.lint] +select = ["E4", "E7", "E9", "F", "S", "U"] +# The following will be addressed in subsequent commits +# F821 +# UP031 +# S110 +# S113 +ignore = ["F821", "UP031", "S110", "S113"] + +[tool.ruff.lint.per-file-ignores] +"manilaclient/tests/*" = ["S"] diff --git a/releasenotes/source/conf.py b/releasenotes/source/conf.py index 8ff2ac89..ec17975f 100644 --- a/releasenotes/source/conf.py +++ b/releasenotes/source/conf.py @@ -190,10 +190,8 @@ latex_elements = { # The paper size ('letterpaper' or 'a4paper'). # 'papersize': 'letterpaper', - # The font size ('10pt', '11pt' or '12pt'). # 'pointsize': '10pt', - # Additional stuff for the LaTeX preamble. # 'preamble': '', } @@ -202,9 +200,13 @@ # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - ('index', 'PythonManilaclientReleaseNotes.tex', - 'python-manilaclient Release Notes Documentation', - 'Manila Developers', 'manual'), + ( + 'index', + 'PythonManilaclientReleaseNotes.tex', + 'python-manilaclient Release Notes Documentation', + 'Manila Developers', + 'manual', + ), ] # The name of an image file (relative to this directory) to place at the top of @@ -233,9 +235,13 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - ('index', 'python-manilaclientreleasenotes', - 'python-manilaclient Release Notes Documentation', - ['Manila Developers'], 1) + ( + 'index', + 'python-manilaclientreleasenotes', + 'python-manilaclient Release Notes Documentation', + ['Manila Developers'], + 1, + ) ] # If true, show URL addresses after external links. @@ -248,11 +254,15 @@ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - ('index', 'PythonManilaclientReleaseNotes', - 'python-manilaclient Release Notes Documentation', - 'Manila Developers', 'PythonManilaclientReleaseNotes', - 'One line description of project.', - 'Miscellaneous'), + ( + 'index', + 'PythonManilaclientReleaseNotes', + 'python-manilaclient Release Notes Documentation', + 'Manila Developers', + 'PythonManilaclientReleaseNotes', + 'One line description of project.', + 'Miscellaneous', + ), ] # Documents to append as an appendix to all manuals. diff --git a/setup.py b/setup.py index cd35c3c3..481505b0 100644 --- a/setup.py +++ b/setup.py @@ -15,6 +15,4 @@ import setuptools -setuptools.setup( - setup_requires=['pbr>=2.0.0'], - pbr=True) +setuptools.setup(setup_requires=['pbr>=2.0.0'], pbr=True) diff --git a/tox.ini b/tox.ini index 72c8a2ce..ddaecb7c 100644 --- a/tox.ini +++ b/tox.ini @@ -1,14 +1,8 @@ [tox] -distribute = False envlist = py3,pep8 minversion = 4.11.0 -# Automatic envs (pyXX) will only use the python version appropriate to that -# env and ignore basepython inherited from [testenv] if we set -# ignore_basepython_conflict. -ignore_basepython_conflict = true [testenv] -basepython = python3 usedevelop = true setenv = VIRTUAL_ENV={envdir} OS_STDOUT_CAPTURE=1 @@ -31,11 +25,11 @@ deps = commands = reno new {posargs} [testenv:pep8] +skip_install = true deps = - pre-commit - + pre-commit commands = - pre-commit run --all-files --show-diff-on-failure + pre-commit run --all-files --show-diff-on-failure [testenv:venv] commands = {posargs} @@ -98,13 +92,16 @@ deps = bandit commands = bandit -r manilaclient -x manilaclient/tests/* -n5 -ll [flake8] -# F821: undefined name -# W503 line break before binary operator -# W504 line break after binary operator -ignore = F821,W503,W504 -builtins = _ -# [H106] Don't put vim configuration in source files. -# [H203] Use assertIs(Not)None to check for None. -# [H904] Delay string interpolations at logging calls. +show-source = true +exclude = .venv,.git,.tox,dist,doc,*lib/python*,*egg,build,tools,releasenotes +# We only enable the hacking (H) checks +select = H +# H301 Black will put commas after imports that can't fit on one line +# H701 Hacking doesn't understand f-strings +# H703 Multiple placeholders are fine +ignore = H301,H701,H703 +# H106 Don't put vim configuration in source files. +# H203 Use assertIs(Not)None to check for None. +# H904 Delay string interpolations at logging calls. enable-extensions = H106,H203,H904 -exclude = .venv,.tox,dist,doc,*egg,build +application_import_names = manilaclient From 95bd3aca64ddec062b884521349914866ddb4672 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Fri, 10 Oct 2025 11:07:54 +0100 Subject: [PATCH 19/52] Fix outstanding ruff issues Some of these are genuine bugs caused by missing imports. Change-Id: Iae120aaf0f2849ec6af941d764b8bd0ef8375a96 Signed-off-by: Stephen Finucane --- manilaclient/base.py | 2 + manilaclient/common/httpclient.py | 4 +- manilaclient/osc/plugin.py | 3 +- manilaclient/osc/v2/resource_locks.py | 1 + manilaclient/osc/v2/share_groups.py | 2 +- manilaclient/shell.py | 2 +- manilaclient/tests/functional/osc/base.py | 8 +- .../tests/functional/test_share_access.py | 8 +- .../tests/functional/test_snapshot_access.py | 6 +- manilaclient/tests/unit/osc/v2/fakes.py | 1 + manilaclient/tests/unit/v2/test_shell.py | 217 +++++++++--------- manilaclient/v2/shell.py | 109 ++++----- pyproject.toml | 6 - 13 files changed, 175 insertions(+), 194 deletions(-) diff --git a/manilaclient/base.py b/manilaclient/base.py index eb79dfe4..079fc0c5 100644 --- a/manilaclient/base.py +++ b/manilaclient/base.py @@ -25,6 +25,8 @@ import hashlib import os +from oslo_utils import strutils + from manilaclient import api_versions from manilaclient.common import cliutils from manilaclient import exceptions diff --git a/manilaclient/common/httpclient.py b/manilaclient/common/httpclient.py index ba4ab548..0337cc17 100644 --- a/manilaclient/common/httpclient.py +++ b/manilaclient/common/httpclient.py @@ -32,7 +32,7 @@ try: osprofiler_web = importutils.try_import("osprofiler.web") -except Exception: +except ImportError: pass @@ -136,7 +136,7 @@ def request(self, url, method, **kwargs): options['data'] = jsonutils.dumps(kwargs['body']) self.log_request(method, url, headers, options.get('data', None)) - resp = requests.request(method, url, headers=headers, **options) + resp = requests.request(method, url, headers=headers, **options) # noqa: S113 self.log_response(resp) body = None diff --git a/manilaclient/osc/plugin.py b/manilaclient/osc/plugin.py index 9da1ec50..65acb761 100644 --- a/manilaclient/osc/plugin.py +++ b/manilaclient/osc/plugin.py @@ -32,9 +32,8 @@ LATEST_VERSION = api_versions.MAX_VERSION LATEST_MINOR_VERSION = api_versions.MAX_VERSION.split('.')[-1] - API_VERSIONS = { - '2.%d' % i: CLIENT_CLASS for i in range(0, int(LATEST_MINOR_VERSION) + 1) + f'2.{i}': CLIENT_CLASS for i in range(0, int(LATEST_MINOR_VERSION) + 1) } diff --git a/manilaclient/osc/v2/resource_locks.py b/manilaclient/osc/v2/resource_locks.py index d1f5b1e6..35c2ca58 100644 --- a/manilaclient/osc/v2/resource_locks.py +++ b/manilaclient/osc/v2/resource_locks.py @@ -279,6 +279,7 @@ def get_parser(self, prog_name): def take_action(self, parsed_args): share_client = self.app.client_manager.share + identity_client = self.app.client_manager.identity columns = ( LOCK_SUMMARY_ATTRIBUTES diff --git a/manilaclient/osc/v2/share_groups.py b/manilaclient/osc/v2/share_groups.py index 7e3371b9..2b23bcb4 100644 --- a/manilaclient/osc/v2/share_groups.py +++ b/manilaclient/osc/v2/share_groups.py @@ -368,7 +368,7 @@ def take_action(self, parsed_args): snapshot = None if parsed_args.snapshot: - snapshot = apiutils.find_resource( + snapshot = osc_utils.find_resource( share_client.share_snapshots, parsed_args.snapshot ).id diff --git a/manilaclient/shell.py b/manilaclient/shell.py index 926de18f..ac60bb6a 100644 --- a/manilaclient/shell.py +++ b/manilaclient/shell.py @@ -46,7 +46,7 @@ try: osprofiler_profiler = importutils.try_import("osprofiler.profiler") -except Exception: +except ImportError: pass diff --git a/manilaclient/tests/functional/osc/base.py b/manilaclient/tests/functional/osc/base.py index 31706fec..4c29fdee 100644 --- a/manilaclient/tests/functional/osc/base.py +++ b/manilaclient/tests/functional/osc/base.py @@ -101,8 +101,8 @@ def _wait_for_object_status( time.sleep(interval) else: self.fail( - "%s %s did not reach status %s after %d seconds." - % (object_name, object_id, status, timeout) + f"{object_name} {object_id} did not reach status {status} " + f"after {timeout} seconds." ) def check_object_deleted( @@ -122,8 +122,8 @@ def check_object_deleted( time.sleep(interval) else: self.fail( - "%s %s not deleted after %d seconds." - % (object_name, object_id, timeout) + f"{object_name} {object_id} not deleted after {timeout} " + f"seconds." ) def openstack( diff --git a/manilaclient/tests/functional/test_share_access.py b/manilaclient/tests/functional/test_share_access.py index 772d2330..be268293 100644 --- a/manilaclient/tests/functional/test_share_access.py +++ b/manilaclient/tests/functional/test_share_access.py @@ -63,13 +63,13 @@ def setUp(self): # NOTE(vponomaryov): list of unique values is required for ability # to create lots of access rules for one share using different # API microversions. - 'ip': ['99.88.77.%d' % i for i in int_range], + 'ip': [f'99.88.77.{i}' for i in int_range], # NOTE(vponomaryov): following users are fakes and access rules # that use it are expected to fail, but they are used only for # API testing. - 'user': ['foo_user_%d' % i for i in int_range], - 'cert': ['tenant_%d.example.com' % i for i in int_range], - 'ipv6': ['2001:db8::%d' % i for i in int_range], + 'user': [f'foo_user_{i}' for i in int_range], + 'cert': [f'tenant_{i}.example.com' for i in int_range], + 'ipv6': [f'2001:db8::{i}' for i in int_range], } def _test_create_list_access_rule_for_share( diff --git a/manilaclient/tests/functional/test_snapshot_access.py b/manilaclient/tests/functional/test_snapshot_access.py index fee71473..817d0088 100644 --- a/manilaclient/tests/functional/test_snapshot_access.py +++ b/manilaclient/tests/functional/test_snapshot_access.py @@ -46,9 +46,9 @@ def setUp(self): int_range = range(0, 10) self.access_to = { - 'ip': ['99.88.77.%d' % i for i in int_range], - 'user': ['foo_user_%d' % i for i in int_range], - 'cert': ['tenant_%d.example.com' % i for i in int_range], + 'ip': [f'99.88.77.{i}' for i in int_range], + 'user': [f'foo_user_{i}' for i in int_range], + 'cert': [f'tenant_{i}.example.com' for i in int_range], } def _test_create_list_access_rule_for_snapshot(self, snapshot_id): diff --git a/manilaclient/tests/unit/osc/v2/fakes.py b/manilaclient/tests/unit/osc/v2/fakes.py index 62328d8c..4048d83b 100644 --- a/manilaclient/tests/unit/osc/v2/fakes.py +++ b/manilaclient/tests/unit/osc/v2/fakes.py @@ -18,6 +18,7 @@ import uuid from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes +from osc_lib.cli import format_columns from manilaclient.tests.unit.osc import osc_fakes from manilaclient.tests.unit.osc import osc_utils diff --git a/manilaclient/tests/unit/v2/test_shell.py b/manilaclient/tests/unit/v2/test_shell.py index 5a0d04e8..82148499 100644 --- a/manilaclient/tests/unit/v2/test_shell.py +++ b/manilaclient/tests/unit/v2/test_shell.py @@ -667,8 +667,9 @@ def test_share_instance_force_delete_wait(self, instances_to_delete): ), ) self.run_command( - 'share-instance-force-delete %s --wait' - % ' '.join(instances_to_delete) + 'share-instance-force-delete {} --wait'.format( + ' '.join(instances_to_delete) + ) ) shell_v2._find_share_instance.assert_has_calls( [ @@ -754,7 +755,7 @@ def test_type_create_with_access(self, public): } } self.run_command( - 'type-create test-type-3 false --is-public %s' % str(public) + f'type-create test-type-3 false --is-public {str(public)}' ) self.assert_called('POST', '/types', body=expected) @@ -1068,18 +1069,17 @@ def test_share_server_manage_wait( self.mock_object(shell_v2, '_wait_for_resource_status', mock.Mock()) command = ( 'share-server-manage ' - '%(host)s ' - '%(share_network_id)s ' - '%(identifier)s ' - '%(driver_args)s ' - % { - 'host': 'fake_host', - 'share_network_id': fake_share_network.id, - 'identifier': '88-as-23-f3-45', - 'driver_args': driver_args, - } + '{host} ' + '{share_network_id} ' + '{identifier} ' + '{driver_args} '.format( + host='fake_host', + share_network_id=fake_share_network.id, + identifier='88-as-23-f3-45', + driver_args=driver_args, + ) ) - command += '--share-network-subnet %s' % subnet_id if subnet_id else '' + command += f'--share-network-subnet {subnet_id}' if subnet_id else '' self.run_command(command, version=version) @@ -1117,7 +1117,7 @@ def test_share_server_manage_wait( constants.STATUS_CREATING, ) def test_share_server_reset_state(self, status): - self.run_command('share-server-reset-state 1234 --state %s ' % status) + self.run_command(f'share-server-reset-state 1234 --state {status} ') expected = {'reset_status': {'status': status}} self.assert_called('POST', '/share-servers/1234/action', body=expected) @@ -1153,14 +1153,14 @@ def test_unmanage(self, wait_option): shares.ShareManager, 'get', mock.Mock(return_value=fake_share) ) - self.run_command('unmanage %s xyzzyspoon' % wait_option) + self.run_command(f'unmanage {wait_option} xyzzyspoon') expected_get_share_calls = 4 if wait_option else 1 shell_v2._find_share.assert_has_calls( [mock.call(self.shell.cs, fake_share.id)] * expected_get_share_calls ) - uri = '/shares/%s/action' % fake_share.id + uri = f'/shares/{fake_share.id}/action' api.client.post.assert_called_once_with(uri, body={'unmanage': None}) def test_share_server_unmanage(self): @@ -1372,7 +1372,7 @@ def test_delete_with_share_group(self, sg_cmd): fake_sg = type('FakeShareGroup', (object,), {'id': sg_cmd.split()[-1]}) shell_v2._find_share_group.return_value = fake_sg - self.run_command('delete 1234 %s' % sg_cmd) + self.run_command(f'delete 1234 {sg_cmd}') self.assert_called('DELETE', '/shares/1234?share_group_id=sg1313') self.assertTrue(shell_v2._find_share_group.called) @@ -1401,13 +1401,13 @@ def test_delete_wait(self, shares_to_delete): mock.Mock(side_effect=(fake_shares + shares_are_not_found_errors)), ) - self.run_command('delete %s --wait' % ' '.join(shares_to_delete)) + self.run_command('delete {} --wait'.format(' '.join(shares_to_delete))) shell_v2._find_share.assert_has_calls( [mock.call(self.shell.cs, share) for share in shares_to_delete] ) for share in fake_shares: - uri = '/shares/%s' % share.id + uri = f'/shares/{share.id}' self.assert_called_anytime('DELETE', uri, clear_callstack=False) @ddt.data(('share_xyz',), ('share_abc', 'share_xyz')) @@ -1430,7 +1430,9 @@ def test_force_delete_wait(self, shares_to_delete): '_find_share', mock.Mock(side_effect=(fake_shares + shares_are_not_found_errors)), ) - self.run_command('force-delete %s --wait' % ' '.join(shares_to_delete)) + self.run_command( + 'force-delete {} --wait'.format(' '.join(shares_to_delete)) + ) shell_v2._find_share.assert_has_calls( [mock.call(self.shell.cs, share) for share in shares_to_delete] ) @@ -1658,8 +1660,8 @@ def test_type_create_duplicate_dhss(self, value): @ddt.unpack def test_type_create_duplicate_switch_and_extra_spec(self, key, value): cmd = ( - 'type-create test True --%(key)s %(value)s --extra-specs ' - '%(key)s=%(value)s' % {'key': key, 'value': value} + f'type-create test True --{key} {value} --extra-specs ' + f'{key}={value}' ) self.assertRaises(exceptions.CommandError, self.run_command, cmd) @@ -1826,7 +1828,7 @@ def test_type_create_invalid_switch_value(self, value): self.assertRaises( exceptions.CommandError, self.run_command, - 'type-create test false --%s fake' % value, + f'type-create test false --{value} fake', ) @ddt.data('snapshot_support', 'create_share_from_snapshot_support') @@ -1834,7 +1836,7 @@ def test_type_create_invalid_extra_spec_value(self, value): self.assertRaises( exceptions.CommandError, self.run_command, - 'type-create test false --extra-specs %s=fake' % value, + f'type-create test false --extra-specs {value}=fake', ) @ddt.unpack @@ -1938,10 +1940,7 @@ def test_update(self, alias): # update is_public attr valid_is_public_values = strutils.TRUE_STRINGS + strutils.FALSE_STRINGS for is_public in valid_is_public_values: - self.run_command( - 'update 1234 %(alias)s %(value)s' - % {'alias': alias, 'value': is_public} - ) + self.run_command(f'update 1234 {alias} {is_public}') expected = { 'share': { 'is_public': strutils.bool_from_string( @@ -1954,14 +1953,13 @@ def test_update(self, alias): self.assertRaises( ValueError, self.run_command, - 'update 1234 %(alias)s %(value)s' - % {'alias': alias, 'value': invalid_val}, + f'update 1234 {alias} {invalid_val}', ) # update all attributes self.run_command( 'update 1234 --name new-name ' '--description=new-description ' - '%s True' % alias + f'{alias} True' ) expected = { 'share': { @@ -2066,7 +2064,7 @@ def test_extend_with_wait_option(self, wait_option): shell_v2, '_find_share', mock.Mock(side_effect=fake_shares) ) expected_extend_body = {'extend': {'new_size': 77}} - self.run_command('extend 1234 77 %s' % wait_option) + self.run_command(f'extend 1234 77 {wait_option}') self.assert_called_anytime( 'POST', '/shares/1234/action', @@ -2105,7 +2103,7 @@ def test_shrink_with_wait_option(self, wait_option): shell_v2, '_find_share', mock.Mock(side_effect=fake_shares) ) expected_shrink_body = {'shrink': {'new_size': 77}} - self.run_command('shrink 1234 77 %s' % wait_option) + self.run_command(f'shrink 1234 77 {wait_option}') self.assert_called_anytime( 'POST', '/shares/1234/action', @@ -2247,13 +2245,10 @@ def test_share_network_list_filter_by_security_service(self): ss = type('FakeSecurityService', (object,), {'id': 'fake-ss-id'}) shell_v2._find_security_service.return_value = ss for command in ['--security_service', '--security-service']: - self.run_command( - 'share-network-list %(command)s %(ss_id)s' - % {'command': command, 'ss_id': ss.id} - ) + self.run_command(f'share-network-list {command} {ss.id}') self.assert_called( 'GET', - '/share-networks/detail?security_service_id=%s' % ss.id, + f'/share-networks/detail?security_service_id={ss.id}', ) shell_v2._find_security_service.assert_called_with(mock.ANY, ss.id) cliutils.print_list.assert_called_with( @@ -2263,7 +2258,7 @@ def test_share_network_list_filter_by_security_service(self): @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_share_network_list_project_id_aliases(self): for command in ['--project-id', '--project_id']: - self.run_command('share-network-list %s 1234' % command) + self.run_command(f'share-network-list {command} 1234') self.assert_called( 'GET', '/share-networks/detail?project_id=1234', @@ -2275,7 +2270,7 @@ def test_share_network_list_project_id_aliases(self): @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_share_network_list_created_before_aliases(self): for command in ['--created-before', '--created_before']: - self.run_command('share-network-list %s 2001-01-01' % command) + self.run_command(f'share-network-list {command} 2001-01-01') self.assert_called( 'GET', '/share-networks/detail?created_before=2001-01-01', @@ -2287,7 +2282,7 @@ def test_share_network_list_created_before_aliases(self): @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_share_network_list_created_since_aliases(self): for command in ['--created-since', '--created_since']: - self.run_command('share-network-list %s 2001-01-01' % command) + self.run_command(f'share-network-list {command} 2001-01-01') self.assert_called( 'GET', '/share-networks/detail?created_since=2001-01-01', @@ -2304,7 +2299,7 @@ def test_share_network_list_neutron_net_id_aliases(self): '--neutron_net-id', '--neutron_net_id', ]: - self.run_command('share-network-list %s fake-id' % command) + self.run_command(f'share-network-list {command} fake-id') self.assert_called( 'GET', '/share-networks/detail?neutron_net_id=fake-id', @@ -2321,7 +2316,7 @@ def test_share_network_list_neutron_subnet_id_aliases(self): '--neutron_subnet-id', '--neutron_subnet_id', ]: - self.run_command('share-network-list %s fake-id' % command) + self.run_command(f'share-network-list {command} fake-id') self.assert_called( 'GET', '/share-networks/detail?neutron_subnet_id=fake-id', @@ -2333,7 +2328,7 @@ def test_share_network_list_neutron_subnet_id_aliases(self): @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_share_network_list_network_type_aliases(self): for command in ['--network_type', '--network-type']: - self.run_command('share-network-list %s local' % command) + self.run_command(f'share-network-list {command} local') self.assert_called( 'GET', '/share-networks/detail?network_type=local', @@ -2345,7 +2340,7 @@ def test_share_network_list_network_type_aliases(self): @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_share_network_list_segmentation_id_aliases(self): for command in ['--segmentation-id', '--segmentation_id']: - self.run_command('share-network-list %s 1234' % command) + self.run_command(f'share-network-list {command} 1234') self.assert_called( 'GET', '/share-networks/detail?segmentation_id=1234', @@ -2357,7 +2352,7 @@ def test_share_network_list_segmentation_id_aliases(self): @mock.patch.object(cliutils, 'print_list', mock.Mock()) def test_share_network_list_ip_version_aliases(self): for command in ['--ip-version', '--ip_version']: - self.run_command('share-network-list %s 4' % command) + self.run_command(f'share-network-list {command} 4') self.assert_called( 'GET', '/share-networks/detail?ip_version=4', @@ -2384,17 +2379,14 @@ def test_share_network_list_all_filters(self): } command_str = 'share-network-list' for key, value in filters.items(): - command_str += ' --%(key)s=%(value)s' % { - 'key': key, - 'value': value, - } + command_str += f' --{key}={value}' self.run_command(command_str) query = utils.safe_urlencode( sorted([(k.replace('-', '_'), v) for (k, v) in filters.items()]) ) self.assert_called( 'GET', - '/share-networks/detail?%s' % query, + f'/share-networks/detail?{query}', ) cliutils.print_list.assert_called_once_with( mock.ANY, fields=['id', 'name'] @@ -2573,11 +2565,10 @@ def test_share_network_subnet_delete(self, subnet_ids): ] self.run_command( - 'share-network-subnet-delete %(network_id)s %(subnet_ids)s' - % { - 'network_id': fake_share_network.id, - 'subnet_ids': ' '.join(subnet_ids), - } + 'share-network-subnet-delete {network_id} {subnet_ids}'.format( + network_id=fake_share_network.id, + subnet_ids=' '.join(subnet_ids), + ) ) shell_v2._find_share_network.assert_called_once_with( @@ -2586,15 +2577,15 @@ def test_share_network_subnet_delete(self, subnet_ids): for subnet in fake_share_network_subnets: self.assert_called_anytime( 'DELETE', - '/share-networks/1234/subnets/%s' % subnet.id, + f'/share-networks/1234/subnets/{subnet.id}', clear_callstack=False, ) def test_share_network_subnet_delete_invalid_share_network(self): - command = 'share-network-subnet-delete %(net_id)s %(subnet_id)s' % { - 'net_id': 'not-found-id', - 'subnet_id': '1234', - } + command = 'share-network-subnet-delete {net_id} {subnet_id}'.format( + net_id='not-found-id', + subnet_id='1234', + ) self.assertRaises(exceptions.CommandError, self.run_command, command) @@ -2607,10 +2598,10 @@ def test_share_network_subnet_delete_invalid_share_network_subnet(self): '_find_share_network', mock.Mock(return_value=fake_share_network), ) - command = 'share-network-subnet-delete %(net_id)s %(subnet_id)s' % { - 'net_id': fake_share_network.id, - 'subnet_id': 'not-found-id', - } + command = 'share-network-subnet-delete {net_id} {subnet_id}'.format( + net_id=fake_share_network.id, + subnet_id='not-found-id', + ) self.assertRaises(exceptions.CommandError, self.run_command, command) @@ -2630,20 +2621,24 @@ def test_share_network_subnet_show(self): } self.run_command( - 'share-network-subnet-show %(share_net_id)s %(subnet_id)s' % args + 'share-network-subnet-show {share_net_id} {subnet_id}'.format( + **args + ) ) self.assert_called( 'GET', - '/share-networks/%(share_net_id)s/subnets/%(subnet_id)s' % args, + '/share-networks/{share_net_id}/subnets/{subnet_id}'.format( + **args + ), ) cliutils.print_dict.assert_called_once_with(mock.ANY) def test_share_network_subnet_show_invalid_share_network(self): - command = 'share-network-subnet-show %(net_id)s %(subnet_id)s' % { - 'net_id': 'not-found-id', - 'subnet_id': 1234, - } + command = 'share-network-subnet-show {net_id} {subnet_id}'.format( + net_id='not-found-id', + subnet_id=1234, + ) self.assertRaises(exceptions.CommandError, self.run_command, command) @@ -2676,7 +2671,7 @@ def test_create_with_share_network(self): shell_v2, "_find_share_network", mock.Mock(return_value=sn) ): self.run_command( - "create nfs 1 --share-type test_type --share-network %s" % sn + f"create nfs 1 --share-type test_type --share-network {sn}" ) expected = self.create_share_body.copy() expected['share']['share_network_id'] = sn @@ -2714,7 +2709,7 @@ def test_create_share_with_the_name_none(self, name): self.assertRaises( exceptions.CommandError, self.run_command, - "create nfs 1 --name %s --share-type test_type" % name, + f"create nfs 1 --name {name} --share-type test_type", ) def test_allow_access_cert(self): @@ -2733,7 +2728,7 @@ def test_allow_access_cert_error_gt64(self): self.assertRaises( exceptions.CommandError, self.run_command, - ("access-allow 1234 cert %s" % common_name), + (f"access-allow 1234 cert {common_name}"), ) def test_allow_access_cert_error_zero(self): @@ -2999,13 +2994,10 @@ class FakeShareNetwork: sn = FakeShareNetwork() shell_v2._find_share_network.return_value = sn for command in ['--share-network', '--share_network']: - self.run_command( - 'security-service-list %(command)s %(sn_id)s' - % {'command': command, 'sn_id': sn.id} - ) + self.run_command(f'security-service-list {command} {sn.id}') self.assert_called( 'GET', - '/security-services?share_network_id=%s' % sn.id, + f'/security-services?share_network_id={sn.id}', ) shell_v2._find_share_network.assert_called_with(mock.ANY, sn.id) cliutils.print_list.assert_called_with( @@ -3050,10 +3042,7 @@ def test_security_service_list_all_filters(self): } command_str = 'security-service-list' for key, value in filters.items(): - command_str += ' --%(key)s=%(value)s' % { - 'key': key, - 'value': value, - } + command_str += f' --{key}={value}' self.run_command(command_str) self.assert_called( 'GET', @@ -3179,12 +3168,12 @@ def test_quota_show_with_user_id(self): @mock.patch('manilaclient.common.cliutils.print_dict') def test_quota_show_with_share_type(self, share_type_id, mock_print_dict): self.run_command( - 'quota-show --tenant 1234 --share_type %s' % share_type_id + f'quota-show --tenant 1234 --share_type {share_type_id}' ) self.assert_called( 'GET', - '/quota-sets/1234?share_type=%s' % share_type_id, + f'/quota-sets/1234?share_type={share_type_id}', ) mock_print_dict.assert_called_once_with(mock.ANY) @@ -3204,7 +3193,7 @@ def test_quota_show_with_share_type(self, share_type_id, mock_print_dict): ) @ddt.unpack def test_quota_update(self, cmd, expected_body): - self.run_command('quota-update 1234 %s' % cmd) + self.run_command(f'quota-update 1234 {cmd}') expected = {'quota_set': dict(expected_body, tenant_id='1234')} self.assert_called('PUT', '/quota-sets/1234', body=expected) @@ -3293,7 +3282,7 @@ def test_pool_list_with_filters(self, param): self.assert_called( 'GET', '/scheduler-stats/pools?backend=backend1&host=host1&' - 'pool=pool1&share_type=%s' % param.split()[-1], + f'pool=pool1&share_type={param.split()[-1]}', ) cliutils.print_list.assert_called_with( mock.ANY, fields=["Name", "Host", "Backend", "Pool"] @@ -3532,7 +3521,7 @@ def test_share_group_update(self, cmd, expected_body): mock.Mock(side_effect=[fake_share_group]), ) - self.run_command('share-group-update 1234 %s' % cmd) + self.run_command(f'share-group-update 1234 {cmd}') shell_v2._find_share_group.assert_has_calls( [mock.call(self.shell.cs, '1234')] @@ -3576,7 +3565,9 @@ def test_share_group_delete_wait(self, share_group_to_delete): ) self.mock_object(shell_v2, '_wait_for_resource_status', mock.Mock()) self.run_command( - 'share-group-delete %s --wait' % ' '.join(share_group_to_delete) + 'share-group-delete {} --wait'.format( + ' '.join(share_group_to_delete) + ) ) shell_v2._find_share_group.assert_has_calls( [ @@ -3784,7 +3775,7 @@ def test_share_group_snapshot_reset_state_with_flag(self): ) @ddt.unpack def test_share_group_snapshot_update(self, cmd, expected_body): - self.run_command('share-group-snapshot-update 1234 %s' % cmd) + self.run_command(f'share-group-snapshot-update 1234 {cmd}') expected = {'share_group_snapshot': expected_body} self.assert_called('PUT', '/share-group-snapshots/1234', body=expected) @@ -3937,8 +3928,8 @@ def test_share_group_type_create_with_access_and_group_specs(self, public): self.run_command( 'share-group-type-create test-group-type-1 ' - 'type1,type2 --is-public %s --group-specs ' - 'spec1=value1' % str(public) + f'type1,type2 --is-public {str(public)} --group-specs ' + 'spec1=value1' ) self.assert_called_anytime('POST', '/share-group-types', body=expected) @@ -4092,7 +4083,7 @@ def test_quota_class_update(self, data): cmd = 'quota-class-update test' expected = dict() for k, v in data.items(): - cmd += ' %(arg)s %(val)s' % {'arg': k, 'val': v} + cmd += f' {k} {v}' expected[k[2:].replace('-', '_')] = v expected['class_name'] = 'test' expected = dict(quota_class_set=expected) @@ -4159,7 +4150,7 @@ def __call__(self, cs, replica): all_replicas = [] existing_replicas = [] for counter in range(replica_count): - replica = 'fake-replica-%d' % counter + replica = f'fake-replica-{counter}' if counter >= replica_errors: existing_replicas.append(replica) all_replicas.append(replica) @@ -4167,7 +4158,7 @@ def __call__(self, cs, replica): shell_v2._find_share_replica.side_effect = StubbedFindWithErrors( existing_replicas ) - cmd = 'share-replica-delete %s' % ' '.join(all_replicas) + cmd = 'share-replica-delete {}'.format(' '.join(all_replicas)) if replica_count == replica_errors: self.assertRaises(exceptions.CommandError, self.run_command, cmd) @@ -4308,7 +4299,7 @@ def test_share_replica_export_location_list(self, columns): shell_v2._find_share_replica.return_value = fake_replica cmd = 'share-replica-export-location-list ' + fake_replica.id if columns is not None: - cmd = cmd + ' --columns=%s' % columns + cmd = cmd + f' --columns={columns}' expected_columns = list( map(lambda x: x.strip().title(), columns.split(",")) ) @@ -4454,7 +4445,7 @@ def test_security_service_delete(self, ss_ids): mock.Mock(side_effect=fake_security_services), ) - self.run_command('security-service-delete %s' % ' '.join(ss_ids)) + self.run_command('security-service-delete {}'.format(' '.join(ss_ids))) shell_v2._find_security_service.assert_has_calls( [mock.call(self.shell.cs, ss_id) for ss_id in ss_ids] @@ -4462,7 +4453,7 @@ def test_security_service_delete(self, ss_ids): for ss in fake_security_services: self.assert_called_anytime( 'DELETE', - '/security-services/%s' % ss.id, + f'/security-services/{ss.id}', clear_callstack=False, ) @@ -4481,14 +4472,14 @@ def test_share_network_delete(self, sn_ids): mock.Mock(side_effect=fake_share_networks), ) - self.run_command('share-network-delete %s' % ' '.join(sn_ids)) + self.run_command('share-network-delete {}'.format(' '.join(sn_ids))) shell_v2._find_share_network.assert_has_calls( [mock.call(self.shell.cs, sn_id) for sn_id in sn_ids] ) for sn in fake_share_networks: self.assert_called_anytime( - 'DELETE', '/share-networks/%s' % sn.id, clear_callstack=False + 'DELETE', f'/share-networks/{sn.id}', clear_callstack=False ) @mock.patch.object(shell_v2, '_find_share', mock.Mock()) @@ -4539,14 +4530,14 @@ def test_snapshot_delete(self, snapshot_ids): mock.Mock(side_effect=fake_snapshots), ) - self.run_command('snapshot-delete %s' % ' '.join(snapshot_ids)) + self.run_command('snapshot-delete {}'.format(' '.join(snapshot_ids))) shell_v2._find_share_snapshot.assert_has_calls( [mock.call(self.shell.cs, s_id) for s_id in snapshot_ids] ) for snapshot in fake_snapshots: self.assert_called_anytime( - 'DELETE', '/snapshots/%s' % snapshot.id, clear_callstack=False + 'DELETE', f'/snapshots/{snapshot.id}', clear_callstack=False ) @mock.patch.object(shell_v2, '_find_share_snapshot', mock.Mock()) @@ -4596,7 +4587,9 @@ def test_snapshot_force_delete_wait(self, snapshots_to_delete): ), ) self.run_command( - 'snapshot-force-delete %s --wait' % ' '.join(snapshots_to_delete) + 'snapshot-force-delete {} --wait'.format( + ' '.join(snapshots_to_delete) + ) ) shell_v2._find_share_snapshot.assert_has_calls( [ @@ -4623,7 +4616,7 @@ def test_share_type_delete(self, type_ids): mock.Mock(side_effect=fake_share_types), ) - self.run_command('type-delete %s' % ' '.join(type_ids)) + self.run_command('type-delete {}'.format(' '.join(type_ids))) shell_v2._find_share_type.assert_has_calls( [mock.call(self.shell.cs, t_id) for t_id in type_ids] @@ -4631,7 +4624,7 @@ def test_share_type_delete(self, type_ids): for fake_share_type in fake_share_types: self.assert_called_anytime( 'DELETE', - '/types/%s' % fake_share_type.id, + f'/types/{fake_share_type.id}', clear_callstack=False, ) @@ -4666,7 +4659,9 @@ def test_share_server_delete_wait(self, share_servers_to_delete): self.mock_object(shell_v2, '_wait_for_resource_status', mock.Mock()) self.run_command( - 'share-server-delete %s --wait' % ' '.join(share_servers_to_delete) + 'share-server-delete {} --wait'.format( + ' '.join(share_servers_to_delete) + ) ) shell_v2._find_share_server.assert_has_calls( @@ -4772,7 +4767,7 @@ def _find_message_with_errors(cs, mid): mock.Mock(side_effect=_find_message_with_errors), ) - cmd = 'message-delete %s' % ' '.join(ids) + cmd = 'message-delete {}'.format(' '.join(ids)) if len(fake_messages) == 0: self.assertRaises(exceptions.CommandError, self.run_command, cmd) @@ -4785,7 +4780,7 @@ def _find_message_with_errors(cs, mid): for fake_message in fake_messages.values(): self.assert_called_anytime( 'DELETE', - '/messages/%s' % fake_message.id, + f'/messages/{fake_message.id}', clear_callstack=False, ) @@ -4827,10 +4822,10 @@ def test_share_server_unmanage_some_fail(self): @ddt.data('migration-start', 'migration-check') def test_share_server_migration_start_and_check(self, method): command = ( - "share-server-%s " + f"share-server-{method} " "1234 host@backend --new-share-network 1111 " "--writable False --nondisruptive True " - "--preserve-snapshots True" % method + "--preserve-snapshots True" ) self.run_command(command) method = method.replace('-', '_') diff --git a/manilaclient/v2/shell.py b/manilaclient/v2/shell.py index d4e05a20..7ea0ed04 100644 --- a/manilaclient/v2/shell.py +++ b/manilaclient/v2/shell.py @@ -372,7 +372,7 @@ def _quota_set_pretty_show(quotas): for quota_k, quota_v in sorted(quotas.to_dict().items()): if isinstance(quota_v, dict): quota_v = '\n'.join( - ['%s = %s' % (k, v) for k, v in sorted(quota_v.items())] + [f'{k} = {v}' for k, v in sorted(quota_v.items())] ) new_quotas[quota_k] = quota_v @@ -452,7 +452,7 @@ def _extract_key_value_options(args, option_name, allow_empty_key=True): if len(duplicate_options) > 0: duplicate_str = ', '.join(duplicate_options) - msg = "Following options were duplicated: %s" % duplicate_str + msg = f"Following options were duplicated: {duplicate_str}" raise exceptions.CommandError(msg) return result_dict @@ -1974,7 +1974,7 @@ def do_share_server_unmanage(cs, args): except Exception as e: failure_count += 1 print( - "Unmanage for share server %s failed: %s" % (server, e), + f"Unmanage for share server {server} failed: {e}", file=sys.stderr, ) @@ -2011,7 +2011,7 @@ def do_snapshot_unmanage(cs, args): except Exception as e: failure_count += 1 print( - "Unmanage for share snapshot %s failed: %s" % (snapshot, e), + f"Unmanage for share snapshot {snapshot} failed: {e}", file=sys.stderr, ) @@ -2073,9 +2073,7 @@ def do_delete(cs, args): cs.shares.delete(share_ref) except Exception as e: failure_count += 1 - print( - "Delete for share %s failed: %s" % (share, e), file=sys.stderr - ) + print(f"Delete for share {share} failed: {e}", file=sys.stderr) if failure_count == len(args.share): raise exceptions.CommandError( @@ -2109,9 +2107,7 @@ def do_force_delete(cs, args): share_ref.force_delete() except Exception as e: failure_count += 1 - print( - "Delete for share %s failed: %s" % (share, e), file=sys.stderr - ) + print(f"Delete for share {share} failed: {e}", file=sys.stderr) if failure_count == len(args.share): raise exceptions.CommandError( "Unable to force delete any of specified shares." @@ -2140,7 +2136,7 @@ def do_soft_delete(cs, args): except Exception as e: failure_count += 1 print( - "Soft deletion of share %s failed: %s" % (share, e), + f"Soft deletion of share {share} failed: {e}", file=sys.stderr, ) @@ -2166,7 +2162,7 @@ def do_restore(cs, args): except Exception as e: failure_count += 1 print( - "Restoration of share %s failed: %s" % (share, e), + f"Restoration of share {share} failed: {e}", file=sys.stderr, ) @@ -2369,8 +2365,7 @@ def do_snapshot_access_deny(cs, args): except Exception as e: failure_count += 1 print( - "Failed to remove rule %(access)s: %(reason)s." - % {'access': access_id, 'reason': e}, + f"Failed to remove rule {access_id}: {e}.", file=sys.stderr, ) @@ -2633,8 +2628,8 @@ def do_snapshot_access_list(cs, args): type=str, default=None, action='single_alias', - help='Key to be sorted, available keys are %(keys)s. ' - 'OPTIONAL: Default=None.' % {'keys': constants.SHARE_SORT_KEY_VALUES}, + help=f'Key to be sorted, available keys are {constants.SHARE_SORT_KEY_VALUES}. ' + 'OPTIONAL: Default=None.', ) @cliutils.arg( '--sort-dir', @@ -2643,8 +2638,8 @@ def do_snapshot_access_list(cs, args): type=str, default=None, action='single_alias', - help='Sort direction, available values are %(values)s. ' - 'OPTIONAL: Default=None.' % {'values': constants.SORT_DIR_VALUES}, + help=f'Sort direction, available values are {constants.SORT_DIR_VALUES}. ' + 'OPTIONAL: Default=None.', ) @cliutils.arg( '--snapshot', @@ -2871,7 +2866,7 @@ def do_list(cs, args): setattr(share, 'export_location', els[0] if els else None) cliutils.print_list(shares, list_of_keys, sortby_index=None) if args.count: - print("Shares in total: %s" % total_count) + print(f"Shares in total: {total_count}") with cs.shares.completion_cache( 'uuid', manilaclient.v2.shares.Share, mode="w" @@ -2995,7 +2990,7 @@ def do_share_instance_force_delete(cs, args): except Exception as e: failure_count += 1 print( - "Delete for share instance %s failed: %s" % (instance, e), + f"Delete for share instance {instance} failed: {e}", file=sys.stderr, ) if failure_count == len(args.instance): @@ -3163,8 +3158,8 @@ def do_share_instance_export_location_show(cs, args): type=str, default=None, action='single_alias', - help='Key to be sorted, available keys are %(keys)s. ' - 'Default=None.' % {'keys': constants.SNAPSHOT_SORT_KEY_VALUES}, + help=f'Key to be sorted, available keys are {constants.SNAPSHOT_SORT_KEY_VALUES}. ' + 'Default=None.', ) @cliutils.arg( '--sort-dir', @@ -3173,8 +3168,8 @@ def do_share_instance_export_location_show(cs, args): type=str, default=None, action='single_alias', - help='Sort direction, available values are %(values)s. ' - 'OPTIONAL: Default=None.' % {'values': constants.SORT_DIR_VALUES}, + help=f'Sort direction, available values are {constants.SORT_DIR_VALUES}. ' + 'OPTIONAL: Default=None.', ) @cliutils.arg( '--columns', @@ -3291,7 +3286,7 @@ def do_snapshot_list(cs, args): cliutils.print_list(snapshots, list_of_keys, sortby_index=None) if args.count: - print("Share snapshots in total: %s" % total_count) + print(f"Share snapshots in total: {total_count}") @cliutils.arg( @@ -3546,7 +3541,7 @@ def do_snapshot_delete(cs, args): except Exception as e: failure_count += 1 print( - "Delete for snapshot %s failed: %s" % (snapshot, e), + f"Delete for snapshot {snapshot} failed: {e}", file=sys.stderr, ) @@ -3582,7 +3577,7 @@ def do_snapshot_force_delete(cs, args): except Exception as e: failure_count += 1 print( - "Delete for snapshot %s failed: %s" % (snapshot, e), + f"Delete for snapshot {snapshot} failed: {e}", file=sys.stderr, ) @@ -4666,7 +4661,7 @@ def do_share_network_subnet_delete(cs, args): except Exception as e: failure_count += 1 print( - "Deletion of share network subnet %s failed: %s" % (subnet, e), + f"Deletion of share network subnet {subnet} failed: {e}", file=sys.stderr, ) @@ -4713,7 +4708,7 @@ def do_share_network_delete(cs, args): except Exception as e: failure_count += 1 print( - "Delete for share network %s failed: %s" % (share_network, e), + f"Delete for share network {share_network} failed: {e}", file=sys.stderr, ) @@ -5115,8 +5110,7 @@ def do_security_service_delete(cs, args): except Exception as e: failure_count += 1 print( - "Delete for security service %s failed: %s" - % (security_service, e), + f"Delete for security service {security_service} failed: {e}", file=sys.stderr, ) @@ -5252,7 +5246,7 @@ def do_share_server_delete(cs, args): except Exception as e: failure_count += 1 print( - "Delete for share server %s failed: %s" % (server_id, e), + f"Delete for share server {server_id} failed: {e}", file=sys.stderr, ) @@ -5378,7 +5372,7 @@ def _print_dict(data_dict): formatted_data = [] for date in data_dict: - formatted_data.append("%s : %s" % (date, data_dict[date])) + formatted_data.append(f"{date} : {data_dict[date]}") return "\n".join(formatted_data) @@ -5805,7 +5799,7 @@ def do_type_create(cs, args): except ValueError as e: msg = ( "Argument spec_driver_handles_share_servers " - "argument is not valid: %s" % str(e) + f"argument is not valid: {str(e)}" ) raise exceptions.CommandError(msg) @@ -5840,7 +5834,7 @@ def do_type_create(cs, args): value = getattr(args, key) if value is not None and key in kwargs['extra_specs']: - msg = "Argument '%s' value specified twice." % key + msg = f"Argument '{key}' value specified twice." raise exceptions.CommandError(msg) try: @@ -5854,8 +5848,8 @@ def do_type_create(cs, args): ) except ValueError as e: msg = ( - "Argument '%s' is of boolean " - "type and has invalid value: %s" % (key, str(e)) + f"Argument '{key}' is of boolean " + f"type and has invalid value: {str(e)}" ) raise exceptions.CommandError(msg) @@ -5933,7 +5927,7 @@ def do_type_delete(cs, args): except Exception as e: failure_count += 1 print( - "Delete for share type %s failed: %s" % (name_or_id, e), + f"Delete for share type {name_or_id} failed: {e}", file=sys.stderr, ) @@ -6503,8 +6497,7 @@ def do_share_group_create(cs, args): type=str, default=None, action='single_alias', - help='Key to be sorted, available keys are %(keys)s. Default=None.' - % {'keys': constants.SHARE_GROUP_SORT_KEY_VALUES}, + help=f'Key to be sorted, available keys are {constants.SHARE_GROUP_SORT_KEY_VALUES}. Default=None.', ) @cliutils.arg( '--sort-dir', @@ -6513,8 +6506,8 @@ def do_share_group_create(cs, args): type=str, default=None, action='single_alias', - help='Sort direction, available values are %(values)s. ' - 'OPTIONAL: Default=None.' % {'values': constants.SORT_DIR_VALUES}, + help=f'Sort direction, available values are {constants.SORT_DIR_VALUES}. ' + 'OPTIONAL: Default=None.', ) @cliutils.arg( '--columns', @@ -6683,7 +6676,7 @@ def do_share_group_delete(cs, args): except Exception as e: failure_count += 1 print( - "Delete for share group %s failed: %s" % (share_group, e), + f"Delete for share group {share_group} failed: {e}", file=sys.stderr, ) @@ -6826,8 +6819,7 @@ def do_share_group_snapshot_create(cs, args): type=str, default=None, action='single_alias', - help='Key to be sorted, available keys are %(keys)s. Default=None.' - % {'keys': constants.SHARE_GROUP_SNAPSHOT_SORT_KEY_VALUES}, + help=f'Key to be sorted, available keys are {constants.SHARE_GROUP_SNAPSHOT_SORT_KEY_VALUES}. Default=None.', ) @cliutils.arg( '--sort-dir', @@ -6836,8 +6828,8 @@ def do_share_group_snapshot_create(cs, args): type=str, default=None, action='single_alias', - help='Sort direction, available values are %(values)s. ' - 'OPTIONAL: Default=None.' % {'values': constants.SORT_DIR_VALUES}, + help=f'Sort direction, available values are {constants.SORT_DIR_VALUES}. ' + 'OPTIONAL: Default=None.', ) @cliutils.arg( '--detailed', @@ -7030,8 +7022,7 @@ def do_share_group_snapshot_delete(cs, args): except Exception as e: failure_count += 1 print( - "Delete for share group snapshot %s failed: %s" - % (sg_snapshot, e), + f"Delete for share group snapshot {sg_snapshot} failed: {e}", file=sys.stderr, ) @@ -7298,7 +7289,7 @@ def do_share_replica_delete(cs, args): except Exception as e: failure_count += 1 print( - "Delete for share replica %s failed: %s" % (replica, e), + f"Delete for share replica {replica} failed: {e}", file=sys.stderr, ) @@ -7496,7 +7487,7 @@ def do_share_transfer_delete(cs, args): except Exception as e: failure_count += 1 print( - "Delete for share transfer %s failed: %s" % (transfer, e), + f"Delete for share transfer {transfer} failed: {e}", file=sys.stderr, ) @@ -7602,8 +7593,7 @@ def do_share_transfer_accept(cs, args): type=str, default=None, action='single_alias', - help='Key to be sorted, available keys are %(keys)s. Default=None.' - % {'keys': constants.SHARE_TRANSFER_SORT_KEY_VALUES}, + help=f'Key to be sorted, available keys are {constants.SHARE_TRANSFER_SORT_KEY_VALUES}. Default=None.', ) @cliutils.arg( '--sort-dir', @@ -7612,8 +7602,8 @@ def do_share_transfer_accept(cs, args): type=str, default=None, action='single_alias', - help='Sort direction, available values are %(values)s. ' - 'Optional: Default=None.' % {'values': constants.SORT_DIR_VALUES}, + help=f'Sort direction, available values are {constants.SORT_DIR_VALUES}. ' + 'Optional: Default=None.', ) @cliutils.arg( '--detailed', @@ -7771,8 +7761,7 @@ def do_share_transfer_show(cs, args): type=str, default=None, action='single_alias', - help='Key to be sorted, available keys are %(keys)s. Default=desc.' - % {'keys': constants.MESSAGE_SORT_KEY_VALUES}, + help=f'Key to be sorted, available keys are {constants.MESSAGE_SORT_KEY_VALUES}. Default=desc.', ) @cliutils.arg( '--sort-dir', @@ -7781,8 +7770,8 @@ def do_share_transfer_show(cs, args): type=str, default=None, action='single_alias', - help='Sort direction, available values are %(values)s. ' - 'OPTIONAL: Default=None.' % {'values': constants.SORT_DIR_VALUES}, + help=f'Sort direction, available values are {constants.SORT_DIR_VALUES}. ' + 'OPTIONAL: Default=None.', ) @cliutils.arg( '--columns', @@ -7874,7 +7863,7 @@ def do_message_delete(cs, args): except Exception as e: failure_count += 1 print( - "Delete for message %s failed: %s" % (message, e), + f"Delete for message {message} failed: {e}", file=sys.stderr, ) diff --git a/pyproject.toml b/pyproject.toml index a85d4bfc..536b2a7c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -208,12 +208,6 @@ docstring-code-format = true [tool.ruff.lint] select = ["E4", "E7", "E9", "F", "S", "U"] -# The following will be addressed in subsequent commits -# F821 -# UP031 -# S110 -# S113 -ignore = ["F821", "UP031", "S110", "S113"] [tool.ruff.lint.per-file-ignores] "manilaclient/tests/*" = ["S"] From 16aaa8e7439bb8441c7a9ceff8d398fda276c553 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Fri, 10 Oct 2025 12:04:17 +0100 Subject: [PATCH 20/52] Fix outstanding hacking issues Change-Id: I920dc4922056a807b4d25728560fb4f58cbf14c2 Signed-off-by: Stephen Finucane --- manilaclient/osc/utils.py | 2 +- manilaclient/osc/v2/quotas.py | 12 ++++-- manilaclient/osc/v2/services.py | 15 +++---- manilaclient/osc/v2/share.py | 31 ++++++++------ manilaclient/osc/v2/share_access_rules.py | 17 ++++---- manilaclient/osc/v2/share_group_types.py | 41 +++++++++---------- manilaclient/osc/v2/share_groups.py | 5 ++- manilaclient/osc/v2/share_replicas.py | 10 ++--- manilaclient/osc/v2/share_servers.py | 19 +++++---- .../osc/v2/share_snapshot_instances.py | 4 +- manilaclient/osc/v2/share_snapshots.py | 18 ++++---- tox.ini | 4 +- 12 files changed, 89 insertions(+), 89 deletions(-) diff --git a/manilaclient/osc/utils.py b/manilaclient/osc/utils.py index 67583aab..fe7d93db 100644 --- a/manilaclient/osc/utils.py +++ b/manilaclient/osc/utils.py @@ -89,7 +89,7 @@ def extract_extra_specs( else: extra_specs[key] = value except ValueError: - msg = LOG.error(_("Wrong format: specs should be key=value pairs.")) + msg = _("Wrong format: specs should be key=value pairs.") raise exceptions.CommandError(msg) return extra_specs diff --git a/manilaclient/osc/v2/quotas.py b/manilaclient/osc/v2/quotas.py index b851f68d..d8003757 100644 --- a/manilaclient/osc/v2/quotas.py +++ b/manilaclient/osc/v2/quotas.py @@ -275,9 +275,11 @@ def take_action(self, parsed_args): try: share_client.quota_classes.update(**kwargs) except Exception as e: + msg = _( + "Failed to set quotas for class '%(project)s': '%(e)s'" + ) raise exceptions.CommandError( - _("Failed to set quotas for %s class: '%s'") - % (parsed_args.project, e) + msg % {'project': parsed_args.project, 'e': e} ) else: project_id = utils.find_resource( @@ -295,9 +297,11 @@ def take_action(self, parsed_args): try: share_client.quotas.update(**kwargs) except Exception as e: + msg = _( + "Failed to set quotas for project '%(project)s': '%(e)s'" + ) raise exceptions.CommandError( - _("Failed to set quotas for project '%s' : '%s'") - % (parsed_args.project, e) + msg % {'project': parsed_args.project, 'e': e} ) diff --git a/manilaclient/osc/v2/services.py b/manilaclient/osc/v2/services.py index dd4cab76..4206dcac 100644 --- a/manilaclient/osc/v2/services.py +++ b/manilaclient/osc/v2/services.py @@ -74,9 +74,8 @@ def take_action(self, parsed_args): parsed_args.host, parsed_args.binary ) except Exception as e: - raise exceptions.CommandError( - _(f"Failed to enable service: {e}") - ) + msg = _("Failed to enable service: %(e)s") + raise exceptions.CommandError(msg % {'e': e}) if parsed_args.disable: if parsed_args.disable_reason: @@ -97,9 +96,8 @@ def take_action(self, parsed_args): parsed_args.host, parsed_args.binary ) except Exception as e: - raise exceptions.CommandError( - _(f"Failed to disable service: {e}") - ) + msg = _("Failed to disable service: %(e)s") + raise exceptions.CommandError(msg % {'e': e}) class ListShareService(command.Lister): @@ -205,6 +203,5 @@ def take_action(self, parsed_args): try: share_client.services.ensure_shares(parsed_args.host) except Exception as e: - raise exceptions.CommandError( - _(f"Failed to run ensure shares: {e}") - ) + msg = _("Failed to ensure shares: %(e)s") + raise exceptions.CommandError(msg % {'e': e}) diff --git a/manilaclient/osc/v2/share.py b/manilaclient/osc/v2/share.py index 83454d06..9e09d8d8 100644 --- a/manilaclient/osc/v2/share.py +++ b/manilaclient/osc/v2/share.py @@ -1065,7 +1065,8 @@ def take_action(self, parsed_args): try: share_client.shares.shrink(share, new_size) except Exception as e: - raise exceptions.CommandError(_("Share resize failed: %s") % e) + msg = _("Share resize failed: %(e)s") + raise exceptions.CommandError(msg % {'e': e}) elif share_size < new_size: force = False if parsed_args.force: @@ -1081,11 +1082,11 @@ def take_action(self, parsed_args): else: share_client.shares.extend(share, new_size) except Exception as e: - raise exceptions.CommandError(_("Share resize failed: %s") % e) + msg = _("Share resize failed: %(e)s") + raise exceptions.CommandError(msg % {'e': e}) else: - raise exceptions.CommandError( - _("Share size is already at %s GiBs") % new_size - ) + msg = _("Share size is already at %(new_size)s GiBs") + raise exceptions.CommandError(msg % {'new_size': new_size}) if parsed_args.wait: if not oscutils.wait_for_status( status_f=share_client.shares.get, @@ -1544,9 +1545,8 @@ def take_action(self, parsed_args): try: share.revert_to_snapshot(snapshot) except Exception as e: - raise exceptions.CommandError( - _("Failed to revert share to snapshot: %s") % e - ) + msg = _("Failed to revert share to snapshot: %(e)s") + raise exceptions.CommandError(msg % {'e': e}) if parsed_args.wait: if not oscutils.wait_for_status( status_f=share_client.shares.get, @@ -1784,12 +1784,17 @@ def take_action(self, parsed_args): {'share': share, 'e': e}, ) if failure_count > 0: - total = len(parsed_args.share) - msg = ( - f"Failed to restore {failure_count} out of {total} shares." + msg = _( + "Failed to restore %(failure_count)s out of %(total)s " + "shares." + ) + raise exceptions.CommandError( + msg + % { + 'failure_count': failure_count, + 'total': len(parsed_args.share), + }, ) - msg = _(msg) - raise exceptions.CommandError(msg) else: raise exceptions.CommandError( "Restoring a share from the recycle bin is only " diff --git a/manilaclient/osc/v2/share_access_rules.py b/manilaclient/osc/v2/share_access_rules.py index bb3c5076..422a2dad 100644 --- a/manilaclient/osc/v2/share_access_rules.py +++ b/manilaclient/osc/v2/share_access_rules.py @@ -246,7 +246,6 @@ def take_action(self, parsed_args): ) kwargs['unrestrict'] = True - error = None try: share.deny(parsed_args.id, **kwargs) if parsed_args.wait: @@ -254,17 +253,15 @@ def take_action(self, parsed_args): manager=share_client.share_access_rules, res_id=parsed_args.id, ): - error = _( - f"Failed to delete share access rule with ID: {parsed_args.id}" - ) + raise Exception('timed out while waiting for deletion') except Exception as e: - error = e - if error: + msg = _( + "Failed to delete share access rule %(id)s for share " + "%(share)s: %(e)s" + ) raise exceptions.CommandError( - _( - "Failed to delete share access rule for share " - f"'{share}': {error}" - ) + msg + % {'id': parsed_args.id, 'share': parsed_args.share, 'e': e} ) diff --git a/manilaclient/osc/v2/share_group_types.py b/manilaclient/osc/v2/share_group_types.py index 71117adb..6b756be4 100644 --- a/manilaclient/osc/v2/share_group_types.py +++ b/manilaclient/osc/v2/share_group_types.py @@ -92,14 +92,13 @@ def take_action(self, parsed_args): share_types_list.append(share_type_obj.name) except Exception as e: - msg = LOG.error( - _( - "Failed to find the share type with " - "name or ID '%(share_type)s': %(e)s" - ), - {'share_type': share_type, 'e': e}, + msg = _( + "Failed to find the share type with name or ID " + "'%(share_type)s': %(e)s" + ) + raise exceptions.CommandError( + msg % {'share_type': share_type, 'e': e} ) - raise exceptions.CommandError(msg) kwargs['share_types'] = share_types_list @@ -310,14 +309,14 @@ def take_action(self, parsed_args): share_client.share_group_types, parsed_args.share_group_type ) except Exception as e: - msg = LOG.error( - _( - "Failed to find the share group type with " - "name or ID '%(share_group_type)s': %(e)s" - ), - {'share_group_type': parsed_args.share_group_type, 'e': e}, + msg = _( + "Failed to find the share group type with " + "name or ID '%(share_group_type)s': %(e)s" + ) + raise exceptions.CommandError( + msg + % {'share_group_type': parsed_args.share_group_type, 'e': e} ) - raise exceptions.CommandError(msg) kwargs = {} if kwargs: @@ -365,14 +364,14 @@ def take_action(self, parsed_args): share_client.share_group_types, parsed_args.share_group_type ) except Exception as e: - msg = LOG.error( - _( - "Failed to find the share group type with " - "name or ID '%(share_group_type)s': %(e)s" - ), - {'share_group_type': parsed_args.share_group_type, 'e': e}, + msg = _( + "Failed to find the share group type with " + "name or ID '%(share_group_type)s': %(e)s" + ) + raise exceptions.CommandError( + msg + % {'share_group_type': parsed_args.share_group_type, 'e': e} ) - raise exceptions.CommandError(msg) if parsed_args.group_specs: try: diff --git a/manilaclient/osc/v2/share_groups.py b/manilaclient/osc/v2/share_groups.py index 2b23bcb4..175a29d9 100644 --- a/manilaclient/osc/v2/share_groups.py +++ b/manilaclient/osc/v2/share_groups.py @@ -577,6 +577,7 @@ def take_action(self, parsed_args): try: share_client.share_groups.update(share_group, **kwargs) except Exception as e: - raise exceptions.CommandError( - _(f"Failed to unset share_group name or description : {e}") + msg = _( + "Failed to unset share_group name or description: %(e)s" ) + raise exceptions.CommandError(msg % {'e': e}) diff --git a/manilaclient/osc/v2/share_replicas.py b/manilaclient/osc/v2/share_replicas.py index ca77e1bb..96e1aeb9 100644 --- a/manilaclient/osc/v2/share_replicas.py +++ b/manilaclient/osc/v2/share_replicas.py @@ -439,9 +439,8 @@ def take_action(self, parsed_args): LOG.error(_("ERROR: Share replica is in error state.")) except Exception as e: - raise exceptions.CommandError( - _(f"Failed to promote replica to 'active': {e}") - ) + msg = "Failed to promote replica to 'active': %(e)s" + raise exceptions.CommandError(msg % {'e': e}) class ResyncShareReplica(command.Command): @@ -470,6 +469,5 @@ def take_action(self, parsed_args): try: share_client.share_replicas.resync(replica) except Exception as e: - raise exceptions.CommandError( - _(f"Failed to resync share replica: {e}") - ) + msg = "Failed to resync share replica: %(e)s" + raise exceptions.CommandError(msg % {'e': e}) diff --git a/manilaclient/osc/v2/share_servers.py b/manilaclient/osc/v2/share_servers.py index dab754f8..7b17bf00 100644 --- a/manilaclient/osc/v2/share_servers.py +++ b/manilaclient/osc/v2/share_servers.py @@ -77,9 +77,11 @@ def take_action(self, parsed_args): ) if result > 0: - total = len(parsed_args.share_servers) - msg = f'Failed to delete {result} servers out of {total}.' - raise exceptions.CommandError(_(msg)) + msg = "Failed to delete %(result)d servers out %(total)d" + raise exceptions.CommandError( + msg + % {'result': result, 'total': len(parsed_args.share_servers)}, + ) class ShowShareServer(command.ShowOne): @@ -433,9 +435,11 @@ def take_action(self, parsed_args): ) if result > 0: - total = len(parsed_args.share_server) - msg = f'Failed to abandon {result} of {total} servers.' - raise exceptions.CommandError(_(msg)) + msg = _('Failed to abandon %(result)s of %(total)s servers.') + raise exceptions.CommandError( + msg + % {'result': result, 'total': len(parsed_args.share_server)} + ) class SetShareServer(command.Command): @@ -444,7 +448,6 @@ class SetShareServer(command.Command): _description = _("Set share server properties (Admin only).") def get_parser(self, prog_name): - parser = super().get_parser(prog_name) allowed_update_choices = [ 'unmanage_starting', 'server_migrating_to', @@ -459,6 +462,8 @@ def get_parser(self, prog_name): 'network_change', ] allowed_update_choices_str = ', '.join(allowed_update_choices) + + parser = super().get_parser(prog_name) parser.add_argument( "share_server", metavar="", diff --git a/manilaclient/osc/v2/share_snapshot_instances.py b/manilaclient/osc/v2/share_snapshot_instances.py index a6ad8b60..ccb94fe0 100644 --- a/manilaclient/osc/v2/share_snapshot_instances.py +++ b/manilaclient/osc/v2/share_snapshot_instances.py @@ -160,5 +160,5 @@ def take_action(self, parsed_args): parsed_args.snapshot_instance, parsed_args.status ) except Exception as e: - msg = _(f"Failed to update share snapshot instance status: {e}") - raise exceptions.CommandError(msg) + msg = _("Failed to update share snapshot instance status: %(e)s") + raise exceptions.CommandError(msg % {'e': e}) diff --git a/manilaclient/osc/v2/share_snapshots.py b/manilaclient/osc/v2/share_snapshots.py index 4f52164c..88bc7396 100644 --- a/manilaclient/osc/v2/share_snapshots.py +++ b/manilaclient/osc/v2/share_snapshots.py @@ -393,24 +393,20 @@ def take_action(self, parsed_args): try: share_client.share_snapshots.update(share_snapshot, **kwargs) except Exception as e: - raise exceptions.CommandError( - _( - "Failed to unset snapshot display name " - f"or display description : {e}" - ) + msg = _( + "Failed to unset snapshot display name or display " + "description: %(e)s" ) + raise exceptions.CommandError(msg % {'e': e}) if parsed_args.property: for key in parsed_args.property: try: share_snapshot.delete_metadata([key]) except Exception as e: - raise exceptions.CommandError( - _( - "Failed to unset snapshot property " - "'%(key)s': %(e)s" - ), - {'key': key, 'e': e}, + msg = _( + "Failed to unset snapshot property '%(key)s': %(e)s" ) + raise exceptions.CommandError(msg % {'key': key, 'e': e}) class ListShareSnapshot(command.Lister): diff --git a/tox.ini b/tox.ini index ddaecb7c..e787e52c 100644 --- a/tox.ini +++ b/tox.ini @@ -97,9 +97,7 @@ exclude = .venv,.git,.tox,dist,doc,*lib/python*,*egg,build,tools,releasenotes # We only enable the hacking (H) checks select = H # H301 Black will put commas after imports that can't fit on one line -# H701 Hacking doesn't understand f-strings -# H703 Multiple placeholders are fine -ignore = H301,H701,H703 +ignore = H301 # H106 Don't put vim configuration in source files. # H203 Use assertIs(Not)None to check for None. # H904 Delay string interpolations at logging calls. From 3e3b385c8c20b94b57255a3f34b39a249ba0a3ae Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Fri, 31 Oct 2025 13:37:41 +0000 Subject: [PATCH 21/52] Re-enable E501 errors Change-Id: Id6ca5075bd11765f00b62b44f91635ef68205175 Signed-off-by: Stephen Finucane --- manilaclient/api_versions.py | 15 +++++--- manilaclient/common/constants.py | 3 +- manilaclient/osc/v2/quotas.py | 33 ++++++++--------- manilaclient/osc/v2/resource_locks.py | 12 ++++--- manilaclient/osc/v2/security_services.py | 4 +-- manilaclient/osc/v2/share.py | 10 +++--- manilaclient/osc/v2/share_backups.py | 12 ++++--- manilaclient/osc/v2/share_networks.py | 2 +- manilaclient/osc/v2/share_pools.py | 4 +-- manilaclient/osc/v2/share_replicas.py | 4 +-- manilaclient/osc/v2/share_servers.py | 2 +- manilaclient/osc/v2/share_transfers.py | 14 +++++--- manilaclient/shell.py | 5 +-- manilaclient/tests/functional/client.py | 35 +++++++++++++------ manilaclient/tests/functional/test_quotas.py | 30 ++++++++++++---- manilaclient/tests/unit/fakes.py | 3 +- .../unit/osc/v2/test_availability_zones.py | 2 +- .../unit/osc/v2/test_security_services.py | 10 +++--- .../unit/osc/v2/test_share_group_snapshots.py | 14 ++++---- .../test_share_instance_export_locations.py | 6 ++-- .../tests/unit/osc/v2/test_share_instances.py | 5 ++- .../tests/unit/osc/v2/test_share_networks.py | 2 +- ...hare_snapshot_instance_export_locations.py | 22 ++++++------ .../osc/v2/test_share_snapshot_instances.py | 12 ++++--- manilaclient/tests/unit/v2/fakes.py | 4 ++- manilaclient/v2/client.py | 2 +- manilaclient/v2/shell.py | 34 +++++++++++++----- pyproject.toml | 2 +- 28 files changed, 190 insertions(+), 113 deletions(-) diff --git a/manilaclient/api_versions.py b/manilaclient/api_versions.py index 19f34544..09eb8fd1 100644 --- a/manilaclient/api_versions.py +++ b/manilaclient/api_versions.py @@ -177,7 +177,10 @@ def __init__(self, name, start_version, end_version, func): self.func = func def __str__(self): - return f"Version Method {self.name}: min: {self.start_version}, max: {self.end_version}" + return ( + f"Version Method {self.name}: min: {self.start_version}, " + f"max: {self.end_version}" + ) def __repr__(self): return f"" @@ -323,8 +326,8 @@ def _validate_requested_version( else: raise exceptions.UnsupportedVersion( _( - "The specified version isn't supported by server. The valid " - "version range is '%(min)s' to '%(max)s'" + "The specified version isn't supported by server. " + "The valid version range is '%(min)s' to '%(max)s'" ) % { "min": server_start_version.get_string(), @@ -349,7 +352,8 @@ def _validate_server_version(server_start_version, server_end_version): if manilaclient.API_MIN_VERSION > server_end_version: raise exceptions.UnsupportedVersion( _( - "Server's version is too old. The client's valid version range " + "Server's version is too old. " + "The client's valid version range " "is '%(client_min)s' to '%(client_max)s'. The server valid " "version range is '%(server_min)s' to '%(server_max)s'." ) @@ -363,7 +367,8 @@ def _validate_server_version(server_start_version, server_end_version): elif manilaclient.API_MAX_VERSION < server_start_version: raise exceptions.UnsupportedVersion( _( - "Server's version is too new. The client's valid version range " + "Server's version is too new. " + "The client's valid version range " "is '%(client_min)s' to '%(client_max)s'. The server valid " "version range is '%(server_min)s' to '%(server_max)s'." ) diff --git a/manilaclient/common/constants.py b/manilaclient/common/constants.py index 08d6a70e..d738dd9a 100644 --- a/manilaclient/common/constants.py +++ b/manilaclient/common/constants.py @@ -96,7 +96,8 @@ 'updated_at', 'resource_id', 'resource_type', - 'resource_actionlock_reason', + 'resource_action', + 'lock_reason', ) BACKUP_SORT_KEY_VALUES = ( diff --git a/manilaclient/osc/v2/quotas.py b/manilaclient/osc/v2/quotas.py index d8003757..c9bd7c32 100644 --- a/manilaclient/osc/v2/quotas.py +++ b/manilaclient/osc/v2/quotas.py @@ -148,8 +148,8 @@ def get_parser(self, prog_name): type=int, default=None, help=_( - "New value for the 'per-share-gigabytes' quota." - "Available only for microversion >= 2.62" + 'New value for the "per-share-gigabytes" quota. ' + 'Available only for microversion >= 2.62' ), ) parser.add_argument( @@ -158,8 +158,8 @@ def get_parser(self, prog_name): type=int, default=None, help=_( - "New value for the 'encryption-keys' quota." - "Available only for microversion >= 2.90" + 'New value for the "encryption-keys" quota. ' + 'Available only for microversion >= 2.90' ), ) parser.add_argument( @@ -202,8 +202,8 @@ def take_action(self, parsed_args): if share_client.api_version < api_versions.APIVersion('2.40'): raise exceptions.CommandError( _( - "'share group' quotas are available only starting with " - "'2.40' API microversion." + "'share group' quotas are available only " + "starting with '2.40' API microversion." ) ) kwargs["share_groups"] = parsed_args.share_groups @@ -220,8 +220,8 @@ def take_action(self, parsed_args): if share_client.api_version < api_versions.APIVersion('2.53'): raise exceptions.CommandError( _( - "setting the number of 'share replicas' is available only " - "starting with API microversion '2.53'." + "setting the number of 'share replicas' is available " + "only starting with API microversion '2.53'." ) ) kwargs["share_replicas"] = parsed_args.share_replicas @@ -230,7 +230,8 @@ def take_action(self, parsed_args): raise exceptions.CommandError( _( "setting the capacity of share replicas in total " - "is available only starting with API microversion '2.53'." + "is available only starting with API microversion " + "'2.53'." ) ) kwargs["replica_gigabytes"] = parsed_args.replica_gigabytes @@ -257,12 +258,12 @@ def take_action(self, parsed_args): raise exceptions.CommandError( _( "Nothing to set. " - "New quota must be specified to at least one of the following " - "resources: 'shares', 'snapshots', 'gigabytes', " + "New quota must be specified to at least one of the " + "following resources: 'shares', 'snapshots', 'gigabytes', " "'snapshot-gigabytes', 'share-networks', 'share-type', " - "'share-groups', 'share-group-snapshots', 'share-replicas', " - "'replica-gigabytes', 'per-share-gigabytes', " - "'encryption_keys'" + "'share-groups', 'share-group-snapshots', " + "'share-replicas', 'replica-gigabytes', " + "'per-share-gigabytes', 'encryption_keys'" ) ) @@ -383,8 +384,8 @@ def take_action(self, parsed_args): if share_client.api_version < api_versions.APIVersion("2.39"): raise exceptions.CommandError( _( - "'share type' quotas are available only starting with " - "'2.39' API microversion." + "'share type' quotas are available only " + "starting with '2.39' API microversion." ) ) kwargs["share_type"] = parsed_args.share_type diff --git a/manilaclient/osc/v2/resource_locks.py b/manilaclient/osc/v2/resource_locks.py index 35c2ca58..c262b0fc 100644 --- a/manilaclient/osc/v2/resource_locks.py +++ b/manilaclient/osc/v2/resource_locks.py @@ -252,8 +252,10 @@ def get_parser(self, prog_name): type=str, default=None, choices=constants.RESOURCE_LOCK_SORT_KEY_VALUES, - help=f'Key to be sorted, available keys are {constants.RESOURCE_LOCK_SORT_KEY_VALUES}. ' - 'Default=None.', + help=( + f'Key to be sorted, available keys are ' + f'{constants.RESOURCE_LOCK_SORT_KEY_VALUES}. Default=None.' + ), ) parser.add_argument( '--sort-dir', @@ -262,8 +264,10 @@ def get_parser(self, prog_name): type=str, default=None, choices=constants.SORT_DIR_VALUES, - help=f'Sort direction, available values are {constants.SORT_DIR_VALUES}. ' - 'OPTIONAL: Default=None.', + help=( + f'Sort direction, available values are ' + f'{constants.SORT_DIR_VALUES}. OPTIONAL: Default=None.' + ), ) parser.add_argument( '--detailed', diff --git a/manilaclient/osc/v2/security_services.py b/manilaclient/osc/v2/security_services.py index f27cafdf..0daa84c6 100644 --- a/manilaclient/osc/v2/security_services.py +++ b/manilaclient/osc/v2/security_services.py @@ -616,8 +616,8 @@ def take_action(self, parsed_args): elif parsed_args.ou: raise exceptions.CommandError( _( - "Filtering results by security service Organizational Unit is " - "available only for microversion >= 2.44" + "Filtering results by security service Organizational " + "Unit is available only for microversion >= 2.44" ) ) diff --git a/manilaclient/osc/v2/share.py b/manilaclient/osc/v2/share.py index 9e09d8d8..de269894 100644 --- a/manilaclient/osc/v2/share.py +++ b/manilaclient/osc/v2/share.py @@ -195,7 +195,7 @@ def get_parser(self, prog_name): action=parseractions.KeyValueAction, help=_( "Set Scheduler hints for the share as key=value pairs, " - "possible keys are same_host, different_host." + "possible keys are same_host, different_host. " "(repeat option to set multiple hints)" ), ) @@ -1595,7 +1595,7 @@ def get_parser(self, prog_name): choices=['True', 'False'], help=_( "Enforces migration to preserve all file metadata when " - "moving its contents. If set to True, host-assisted" + "moving its contents. If set to True, host-assisted " "migration will not be attempted." ), ) @@ -1606,7 +1606,7 @@ def get_parser(self, prog_name): choices=['True', 'False'], help=_( "Enforces migration of the share snapshots to the " - "destination. If set to True, host-assisted migration" + "destination. If set to True, host-assisted migration " "will not be attempted." ), ) @@ -1617,7 +1617,7 @@ def get_parser(self, prog_name): choices=['True', 'False'], help=_( "Enforces migration to keep the share writable while " - "contents are being moved. If set to True, host-assisted" + "contents are being moved. If set to True, host-assisted " "migration will not be attempted." ), ) @@ -1637,7 +1637,7 @@ def get_parser(self, prog_name): default=None, help=_( "Specify the new share network for the share. Do not " - "specify this parameter if the migrating share has to be" + "specify this parameter if the migrating share has to be " "retained within its current share network." ), ) diff --git a/manilaclient/osc/v2/share_backups.py b/manilaclient/osc/v2/share_backups.py index 5dfc2547..f3934a5c 100644 --- a/manilaclient/osc/v2/share_backups.py +++ b/manilaclient/osc/v2/share_backups.py @@ -205,8 +205,10 @@ def get_parser(self, prog_name): metavar='', type=str, default=None, - help=f'Key to be sorted, available keys are {constants.BACKUP_SORT_KEY_VALUES}. ' - 'Default=None.', + help=( + f'Key to be sorted, available keys are ' + f'{constants.BACKUP_SORT_KEY_VALUES}. Default=None.' + ), ) parser.add_argument( '--sort-dir', @@ -214,8 +216,10 @@ def get_parser(self, prog_name): metavar='', type=str, default=None, - help=f'Sort direction, available values are {constants.SORT_DIR_VALUES}. ' - 'OPTIONAL: Default=None.', + help=( + f'Sort direction, available values are ' + f'{constants.SORT_DIR_VALUES}. OPTIONAL: Default=None.' + ), ) parser.add_argument( '--detail', diff --git a/manilaclient/osc/v2/share_networks.py b/manilaclient/osc/v2/share_networks.py index 08eaa4db..b2a3b0a4 100644 --- a/manilaclient/osc/v2/share_networks.py +++ b/manilaclient/osc/v2/share_networks.py @@ -677,7 +677,7 @@ def take_action(self, parsed_args): if new_security_service and current_security_service: try: if parsed_args.check_only: - check_result = share_client.share_networks.update_share_network_security_service_check( + check_result = share_client.share_networks.update_share_network_security_service_check( # noqa: E501 share_network, current_security_service, new_security_service, diff --git a/manilaclient/osc/v2/share_pools.py b/manilaclient/osc/v2/share_pools.py index 1805ec00..2eb2b35b 100644 --- a/manilaclient/osc/v2/share_pools.py +++ b/manilaclient/osc/v2/share_pools.py @@ -83,8 +83,8 @@ def take_action(self, parsed_args): else: raise exceptions.CommandError( _( - "Filtering results by share type is only available with " - "manila API version >= 2.23" + "Filtering results by share type is only " + "available with manila API version >= 2.23" ) ) diff --git a/manilaclient/osc/v2/share_replicas.py b/manilaclient/osc/v2/share_replicas.py index 96e1aeb9..1bbbbd61 100644 --- a/manilaclient/osc/v2/share_replicas.py +++ b/manilaclient/osc/v2/share_replicas.py @@ -81,8 +81,8 @@ def take_action(self, parsed_args): if share_client.api_version < api_versions.APIVersion("2.67"): raise exceptions.CommandError( _( - "arg '--scheduler_hint' is available only starting with " - "API microversion '2.67'." + "arg '--scheduler_hint' is available only starting " + "with API microversion '2.67'." ) ) diff --git a/manilaclient/osc/v2/share_servers.py b/manilaclient/osc/v2/share_servers.py index 7b17bf00..8db3e2bb 100644 --- a/manilaclient/osc/v2/share_servers.py +++ b/manilaclient/osc/v2/share_servers.py @@ -587,7 +587,7 @@ def take_action(self, parsed_args): class ShareServerMigrationComplete(command.Command): - """Completes migration for a given share server (Admin only, Experimental).""" + """Completes migration for a share server (Admin only, Experimental).""" _description = _("Completes migration for a given share server") diff --git a/manilaclient/osc/v2/share_transfers.py b/manilaclient/osc/v2/share_transfers.py index cb650d18..a6aa059b 100644 --- a/manilaclient/osc/v2/share_transfers.py +++ b/manilaclient/osc/v2/share_transfers.py @@ -178,8 +178,11 @@ def get_parser(self, prog_name): metavar='', type=str, default=None, - help=f'Key to be sorted, available keys are {constants.SHARE_TRANSFER_SORT_KEY_VALUES}. ' - 'Default=None.', + help=( + f'Key to be sorted, available keys are ' + f'{constants.SHARE_TRANSFER_SORT_KEY_VALUES}. ' + f'Default=None.' + ), ) parser.add_argument( '--sort-dir', @@ -187,8 +190,11 @@ def get_parser(self, prog_name): metavar='', type=str, default=None, - help=f'Sort direction, available values are {constants.SORT_DIR_VALUES}. ' - 'OPTIONAL: Default=None.', + help=( + f'Sort direction, available values are ' + f'{constants.SORT_DIR_VALUES}. ' + f'OPTIONAL: Default=None.' + ), ) parser.add_argument( '--detailed', diff --git a/manilaclient/shell.py b/manilaclient/shell.py index ac60bb6a..4455defb 100644 --- a/manilaclient/shell.py +++ b/manilaclient/shell.py @@ -95,8 +95,9 @@ def error(self, message): progparts = self.prog.partition(' ') self.exit( 2, - f"error: {message.split(choose_from)[0]}\nTry '{progparts[0]} help {progparts[2]}'" - " for more information.\n", + f"error: {message.split(choose_from)[0]}\n" + f"Try '{progparts[0]} help {progparts[2]}' " + f"for more information.\n", ) def _get_option_tuples(self, option_string): diff --git a/manilaclient/tests/functional/client.py b/manilaclient/tests/functional/client.py index c0324365..da712fb5 100644 --- a/manilaclient/tests/functional/client.py +++ b/manilaclient/tests/functional/client.py @@ -394,7 +394,10 @@ def get_project_id(self, name_or_id): if identity_api_version == "3": if CONF.admin_project_domain_name: - flags += f"--os-project-domain-name {CONF.admin_project_domain_name} " + flags += ( + f"--os-project-domain-name " + f"{CONF.admin_project_domain_name} " + ) elif CONF.admin_project_domain_id: flags += ( f"--os-project-domain-id {CONF.admin_project_domain_id} " @@ -840,7 +843,8 @@ def delete_share_network_subnet( ): """Delete a share_network.""" self.manila( - f'share-network-subnet-delete {share_network} {share_network_subnet}', + f'share-network-subnet-delete {share_network} ' + f'{share_network_subnet}', microversion=microversion, ) @@ -1513,7 +1517,8 @@ def wait_for_snapshot_status(self, snapshot, status, microversion=None): if int(time.time()) - start >= self.build_timeout: message = ( f"Snapshot {snapshot_name} failed to reach {status} " - f"status within the required time ({self.build_timeout} s)." + f"status within the required time " + f"({self.build_timeout} s)." ) raise tempest_lib_exc.TimeoutException(message) @@ -1619,8 +1624,8 @@ def access_allow( microversion=None, ): cmd = ( - f'access-allow --access-level {access_level} {share_id} {access_type} ' - f'{access_to}' + f'access-allow --access-level {access_level} {share_id} ' + f'{access_type} {access_to}' ) if metadata: metadata_cli = '' @@ -1739,7 +1744,10 @@ def migration_start( f'--preserve-snapshots {preserve_snapshots}' ) if force_host_assisted_migration: - cmd += f' --force-host-assisted-migration {force_host_assisted_migration}' + cmd += ( + f' --force-host-assisted-migration ' + f'{force_host_assisted_migration}' + ) if new_share_network: cmd += f' --new-share-network {new_share_network}' if new_share_type: @@ -1918,7 +1926,8 @@ def get_snapshot_instance_export_location( :param microversion: API microversion to be used for request. """ snapshot_raw = self.manila( - f'snapshot-instance-export-location-show {snapshot} {export_location_uuid}', + f'snapshot-instance-export-location-show {snapshot} ' + f'{export_location_uuid}', microversion=microversion, ) snapshot = output_parser.details(snapshot_raw) @@ -2056,7 +2065,10 @@ def share_server_manage( self, host, share_network, identifier, driver_options=None ): if driver_options: - command = f'share-server-manage {host} {share_network} {identifier} {driver_options}' + command = ( + f'share-server-manage {host} {share_network} {identifier} ' + f'{driver_options}' + ) else: command = ( f'share-server-manage {host} {share_network} {identifier}' @@ -2067,7 +2079,8 @@ def share_server_manage( def manage_share(self, host, protocol, export_location, share_server): managed_share_raw = self.manila( - f'manage {host} {protocol} {export_location} --share-server-id {share_server}' + f'manage {host} {protocol} {export_location} ' + f'--share-server-id {share_server}' ) managed_share = output_parser.details(managed_share_raw) return managed_share['id'] @@ -2175,8 +2188,8 @@ def wait_for_message(self, resource_id): if int(time.time()) - start >= self.build_timeout: message = ( - f'No message for resource with id {resource_id} was created in' - f' the required time ({self.build_timeout} s).' + f'No message for resource with id {resource_id} was ' + f'created in the required time ({self.build_timeout} s).' ) raise tempest_lib_exc.TimeoutException(message) diff --git a/manilaclient/tests/functional/test_quotas.py b/manilaclient/tests/functional/test_quotas.py index dd6efb04..ed5663c4 100644 --- a/manilaclient/tests/functional/test_quotas.py +++ b/manilaclient/tests/functional/test_quotas.py @@ -58,7 +58,10 @@ def setUp(self): def _verify_current_st_quotas_equal_to(self, quotas, microversion): # Read share type quotas - cmd = f'quota-show --tenant-id {self.project_id} --share-type {self.st_id}' + cmd = ( + f'quota-show --tenant-id {self.project_id} ' + f'--share-type {self.st_id}' + ) st_quotas_raw = self.admin_client.manila( cmd, microversion=microversion ) @@ -143,7 +146,10 @@ def test_update_quotas_for_share_groups(self, microversion): self._verify_current_quotas_equal_to(p_custom_quotas, microversion) # Reset quotas - cmd = f'quota-delete --tenant-id {self.project_id} --share-type {self.st_id}' + cmd = ( + f'quota-delete --tenant-id {self.project_id} ' + f'--share-type {self.st_id}' + ) self.admin_client.manila(cmd, microversion=microversion) # Verify quotas after reset @@ -191,7 +197,10 @@ def test_update_quotas_for_share_replicas_using_too_old_microversion( @ddt.data('--share-groups', '--share-group-snapshots') @utils.skip_if_microversion_not_supported("2.40") def test_update_share_type_quotas_for_share_groups(self, arg): - cmd = f'quota-update {self.project_id} --share-type {self.st_id} {arg} 13' + cmd = ( + f'quota-update {self.project_id} --share-type {self.st_id} ' + f'{arg} 13' + ) self.assertRaises( exceptions.CommandFailed, self.admin_client.manila, @@ -268,7 +277,10 @@ def test_update_share_type_quotas_positive(self, microversion): self._verify_current_st_quotas_equal_to(st_custom_quotas, microversion) # Reset share type quotas - cmd = f'quota-delete --tenant-id {self.project_id} --share-type {self.st_id}' + cmd = ( + f'quota-delete --tenant-id {self.project_id} ' + f'--share-type {self.st_id}' + ) self.admin_client.manila(cmd, microversion=microversion) # Verify share type quotas after reset @@ -276,7 +288,10 @@ def test_update_share_type_quotas_positive(self, microversion): @utils.skip_if_microversion_not_supported("2.38") def test_read_share_type_quotas_with_too_old_microversion(self): - cmd = f'quota-show --tenant-id {self.project_id} --share-type {self.st_id}' + cmd = ( + f'quota-show --tenant-id {self.project_id} ' + f'--share-type {self.st_id}' + ) self.assertRaises( exceptions.CommandFailed, self.admin_client.manila, @@ -298,7 +313,10 @@ def test_update_share_type_quotas_with_too_old_microversion(self): @utils.skip_if_microversion_not_supported("2.38") def test_delete_share_type_quotas_with_too_old_microversion(self): - cmd = f'quota-delete --tenant-id {self.project_id} --share-type {self.st_id}' + cmd = ( + f'quota-delete --tenant-id {self.project_id} ' + f'--share-type {self.st_id}' + ) self.assertRaises( exceptions.CommandFailed, self.admin_client.manila, diff --git a/manilaclient/tests/unit/fakes.py b/manilaclient/tests/unit/fakes.py index 8576c9a8..d8d469e2 100644 --- a/manilaclient/tests/unit/fakes.py +++ b/manilaclient/tests/unit/fakes.py @@ -67,7 +67,8 @@ def assert_called_anytime( break assert found, ( - f'Expected {expected[0]} {expected[1]}; got {self.client.callstack}' + f'Expected {expected[0]} {expected[1]}; ' + f'got {self.client.callstack}' ) if body is not None: diff --git a/manilaclient/tests/unit/osc/v2/test_availability_zones.py b/manilaclient/tests/unit/osc/v2/test_availability_zones.py index 741523fe..90de3c18 100644 --- a/manilaclient/tests/unit/osc/v2/test_availability_zones.py +++ b/manilaclient/tests/unit/osc/v2/test_availability_zones.py @@ -26,7 +26,7 @@ def setUp(self): class TestShareAvailabilityZoneList(TestAvailabilityZones): - availability_zones = manila_fakes.FakeShareAvailabilityZones.create_share_availability_zones() + availability_zones = manila_fakes.FakeShareAvailabilityZones.create_share_availability_zones() # noqa: E501 COLUMNS = ("Id", "Name", "Created At", "Updated At") def setUp(self): diff --git a/manilaclient/tests/unit/osc/v2/test_security_services.py b/manilaclient/tests/unit/osc/v2/test_security_services.py index b41cb6bd..cdd707c2 100644 --- a/manilaclient/tests/unit/osc/v2/test_security_services.py +++ b/manilaclient/tests/unit/osc/v2/test_security_services.py @@ -42,7 +42,7 @@ class TestShareSecurityServiceCreate(TestShareSecurityService): def setUp(self): super().setUp() - self.security_service = manila_fakes.FakeShareSecurityService.create_fake_security_service() + self.security_service = manila_fakes.FakeShareSecurityService.create_fake_security_service() # noqa: E501 self.security_services_mock.create.return_value = self.security_service self.cmd = osc_security_services.CreateShareSecurityService( self.app, None @@ -154,10 +154,10 @@ class TestShareSecurityServiceDelete(TestShareSecurityService): def setUp(self): super().setUp() - self.security_service = manila_fakes.FakeShareSecurityService.create_fake_security_service() + self.security_service = manila_fakes.FakeShareSecurityService.create_fake_security_service() # noqa: E501 self.security_services_mock.get.return_value = self.security_service - self.security_services = manila_fakes.FakeShareSecurityService.create_fake_security_services() + self.security_services = manila_fakes.FakeShareSecurityService.create_fake_security_services() # noqa: E501 self.cmd = osc_security_services.DeleteShareSecurityService( self.app, None @@ -218,7 +218,7 @@ class TestShareSecurityServiceShow(TestShareSecurityService): def setUp(self): super().setUp() - self.security_service = manila_fakes.FakeShareSecurityService.create_fake_security_service() + self.security_service = manila_fakes.FakeShareSecurityService.create_fake_security_service() # noqa: E501 self.security_services_mock.get.return_value = self.security_service self.cmd = osc_security_services.ShowShareSecurityService( @@ -510,7 +510,7 @@ def setUp(self): manila_fakes.FakeShareNetwork.create_one_share_network() ) self.share_networks_mock.get.return_value = self.share_network - self.services_list = manila_fakes.FakeShareSecurityService.create_fake_security_services() + self.services_list = manila_fakes.FakeShareSecurityService.create_fake_security_services() # noqa: E501 self.security_services_mock.list.return_value = self.services_list self.values = ( oscutils.get_dict_properties(i._info, self.columns) diff --git a/manilaclient/tests/unit/osc/v2/test_share_group_snapshots.py b/manilaclient/tests/unit/osc/v2/test_share_group_snapshots.py index 4644f3cc..2860cf79 100644 --- a/manilaclient/tests/unit/osc/v2/test_share_group_snapshots.py +++ b/manilaclient/tests/unit/osc/v2/test_share_group_snapshots.py @@ -53,7 +53,7 @@ def setUp(self): self.share_group = manila_fakes.FakeShareGroup.create_one_share_group() self.groups_mock.get.return_value = self.share_group - self.share_group_snapshot = manila_fakes.FakeShareGroupSnapshot.create_one_share_group_snapshot() + self.share_group_snapshot = manila_fakes.FakeShareGroupSnapshot.create_one_share_group_snapshot() # noqa: E501 self.group_snapshot_mocks.create.return_value = ( self.share_group_snapshot ) @@ -171,7 +171,7 @@ class TestDeleteShareGroupSnapshot(TestShareGroupSnapshot): def setUp(self): super().setUp() - self.share_group_snapshot = manila_fakes.FakeShareGroupSnapshot.create_one_share_group_snapshot() + self.share_group_snapshot = manila_fakes.FakeShareGroupSnapshot.create_one_share_group_snapshot() # noqa: E501 self.group_snapshot_mocks.get.return_value = self.share_group_snapshot self.cmd = osc_share_group_snapshots.DeleteShareGroupSnapshot( @@ -294,7 +294,7 @@ class TestShowShareGroupSnapshot(TestShareGroupSnapshot): def setUp(self): super().setUp() - self.share_group_snapshot = manila_fakes.FakeShareGroupSnapshot.create_one_share_group_snapshot() + self.share_group_snapshot = manila_fakes.FakeShareGroupSnapshot.create_one_share_group_snapshot() # noqa: E501 self.group_snapshot_mocks.get.return_value = self.share_group_snapshot self.cmd = osc_share_group_snapshots.ShowShareGroupSnapshot( @@ -336,7 +336,7 @@ class TestSetShareGroupSnapshot(TestShareGroupSnapshot): def setUp(self): super().setUp() - self.share_group_snapshot = manila_fakes.FakeShareGroupSnapshot.create_one_share_group_snapshot() + self.share_group_snapshot = manila_fakes.FakeShareGroupSnapshot.create_one_share_group_snapshot() # noqa: E501 self.group_snapshot_mocks.get.return_value = self.share_group_snapshot self.cmd = osc_share_group_snapshots.SetShareGroupSnapshot( @@ -408,7 +408,7 @@ class TestUnsetShareGroupSnapshot(TestShareGroupSnapshot): def setUp(self): super().setUp() - self.share_group_snapshot = manila_fakes.FakeShareGroupSnapshot.create_one_share_group_snapshot() + self.share_group_snapshot = manila_fakes.FakeShareGroupSnapshot.create_one_share_group_snapshot() # noqa: E501 self.group_snapshot_mocks.get.return_value = self.share_group_snapshot self.cmd = osc_share_group_snapshots.UnsetShareGroupSnapshot( @@ -463,7 +463,7 @@ def setUp(self): self.share_group = manila_fakes.FakeShareGroup.create_one_share_group() self.groups_mock.get.return_value = self.share_group - self.share_group_snapshot = manila_fakes.FakeShareGroupSnapshot.create_one_share_group_snapshot( + self.share_group_snapshot = manila_fakes.FakeShareGroupSnapshot.create_one_share_group_snapshot( # noqa: E501 {'share_group_id': self.share_group.id} ) @@ -593,7 +593,7 @@ def setUp(self): self.share = manila_fakes.FakeShare.create_one_share() - self.share_group_snapshot = manila_fakes.FakeShareGroupSnapshot.create_one_share_group_snapshot( + self.share_group_snapshot = manila_fakes.FakeShareGroupSnapshot.create_one_share_group_snapshot( # noqa: E501 {'members': [{'share_id': self.share.id, 'size': self.share.size}]} ) diff --git a/manilaclient/tests/unit/osc/v2/test_share_instance_export_locations.py b/manilaclient/tests/unit/osc/v2/test_share_instance_export_locations.py index 484a5077..1017b42d 100644 --- a/manilaclient/tests/unit/osc/v2/test_share_instance_export_locations.py +++ b/manilaclient/tests/unit/osc/v2/test_share_instance_export_locations.py @@ -53,7 +53,7 @@ def setUp(self): ) self.instances_mock.get.return_value = self.instance - self.instance_export_locations = manila_fakes.FakeShareExportLocation.create_share_export_locations() + self.instance_export_locations = manila_fakes.FakeShareExportLocation.create_share_export_locations() # noqa: E501 self.instance_export_locations_mock.list.return_value = ( self.instance_export_locations ) @@ -63,7 +63,7 @@ def setUp(self): for i in self.instance_export_locations ) - self.cmd = osc_share_instance_export_locations.ShareInstanceListExportLocation( + self.cmd = osc_share_instance_export_locations.ShareInstanceListExportLocation( # noqa: E501 self.app, None ) @@ -114,7 +114,7 @@ def setUp(self): ) self.instances_mock.get.return_value = self.instance - self.cmd = osc_share_instance_export_locations.ShareInstanceShowExportLocation( + self.cmd = osc_share_instance_export_locations.ShareInstanceShowExportLocation( # noqa: E501 self.app, None ) diff --git a/manilaclient/tests/unit/osc/v2/test_share_instances.py b/manilaclient/tests/unit/osc/v2/test_share_instances.py index c8fcbc06..271c894f 100644 --- a/manilaclient/tests/unit/osc/v2/test_share_instances.py +++ b/manilaclient/tests/unit/osc/v2/test_share_instances.py @@ -124,9 +124,8 @@ def test_share_instance_list_by_export_location_invalid_version(self): fake_export_location = '10.1.1.0:/fake_share_el' argslist = ['--export-location', fake_export_location] verifylist = [('export_location', fake_export_location)] - self.app.client_manager.share.api_version = api_versions.APIVersion( - '2.34' - ) + api_version = api_versions.APIVersion('2.34') + self.app.client_manager.share.api_version = api_version parsed_args = self.check_parser(self.cmd, argslist, verifylist) diff --git a/manilaclient/tests/unit/osc/v2/test_share_networks.py b/manilaclient/tests/unit/osc/v2/test_share_networks.py index d7af09ba..d68cee9f 100644 --- a/manilaclient/tests/unit/osc/v2/test_share_networks.py +++ b/manilaclient/tests/unit/osc/v2/test_share_networks.py @@ -860,7 +860,7 @@ def test_set_share_network_add_new_security_service_check_reset( def test_set_share_network_update_security_service_check_reset( self, check_only, restart_check ): - self.share_networks_mock.update_share_network_security_service_check = mock.Mock( + self.share_networks_mock.update_share_network_security_service_check = mock.Mock( # noqa: E501 return_value=(200, {'compatible': True}) ) diff --git a/manilaclient/tests/unit/osc/v2/test_share_snapshot_instance_export_locations.py b/manilaclient/tests/unit/osc/v2/test_share_snapshot_instance_export_locations.py index af93f970..91c5a095 100644 --- a/manilaclient/tests/unit/osc/v2/test_share_snapshot_instance_export_locations.py +++ b/manilaclient/tests/unit/osc/v2/test_share_snapshot_instance_export_locations.py @@ -15,9 +15,7 @@ from osc_lib import utils as osc_lib_utils -from manilaclient.osc.v2 import ( - share_snapshot_instance_export_locations as osc_snapshot_instance_locations, -) +from manilaclient.osc.v2 import share_snapshot_instance_export_locations from manilaclient.tests.unit.osc import osc_utils from manilaclient.tests.unit.osc.v2 import fakes as manila_fakes @@ -33,7 +31,9 @@ def setUp(self): ) self.share_snapshot_instances_mock.reset_mock() - self.share_snapshot_instances_el_mock = self.app.client_manager.share.share_snapshot_instance_export_locations + self.share_snapshot_instances_el_mock = ( + self.app.client_manager.share.share_snapshot_instance_export_locations # noqa: E501 + ) self.share_snapshot_instances_el_mock.reset_mock() @@ -43,9 +43,9 @@ class TestShareSnapshotInstanceExportLocationList( def setUp(self): super().setUp() - self.share_snapshot_instance = manila_fakes.FakeShareSnapshotIntances.create_one_snapshot_instance() + self.share_snapshot_instance = manila_fakes.FakeShareSnapshotIntances.create_one_snapshot_instance() # noqa: E501 - self.share_snapshot_instances_export_locations = manila_fakes.FakeShareSnapshotInstancesExportLocations.create_share_snapshot_instances( + self.share_snapshot_instances_export_locations = manila_fakes.FakeShareSnapshotInstancesExportLocations.create_share_snapshot_instances( # noqa: E501 count=2 ) @@ -57,7 +57,7 @@ def setUp(self): self.share_snapshot_instances_export_locations ) - self.cmd = osc_snapshot_instance_locations.ShareSnapshotInstanceExportLocationList( + self.cmd = share_snapshot_instance_export_locations.ShareSnapshotInstanceExportLocationList( # noqa: E501 self.app, None ) @@ -94,9 +94,11 @@ class TestShareSnapshotInstanceExportLocationShow( def setUp(self): super().setUp() - self.share_snapshot_instance = manila_fakes.FakeShareSnapshotIntances.create_one_snapshot_instance() + self.share_snapshot_instance = manila_fakes.FakeShareSnapshotIntances.create_one_snapshot_instance() # noqa: E501 - self.share_snapshot_instances_export_location = manila_fakes.FakeShareSnapshotInstancesExportLocations.create_one_snapshot_instance() + self.share_snapshot_instances_export_location = ( + manila_fakes.FakeShareSnapshotInstancesExportLocations.create_one_snapshot_instance() # noqa: E501 + ) self.share_snapshot_instances_mock.get.return_value = ( self.share_snapshot_instance @@ -106,7 +108,7 @@ def setUp(self): self.share_snapshot_instances_export_location ) - self.cmd = osc_snapshot_instance_locations.ShareSnapshotInstanceExportLocationShow( + self.cmd = share_snapshot_instance_export_locations.ShareSnapshotInstanceExportLocationShow( # noqa: E501 self.app, None ) diff --git a/manilaclient/tests/unit/osc/v2/test_share_snapshot_instances.py b/manilaclient/tests/unit/osc/v2/test_share_snapshot_instances.py index 789e2daa..58e9de07 100644 --- a/manilaclient/tests/unit/osc/v2/test_share_snapshot_instances.py +++ b/manilaclient/tests/unit/osc/v2/test_share_snapshot_instances.py @@ -53,7 +53,9 @@ def setUp(self): ) self.share_snapshot_instances_mock.reset_mock() - self.share_snapshot_instances_el_mock = self.app.client_manager.share.share_snapshot_instance_export_locations + self.share_snapshot_instances_el_mock = ( + self.app.client_manager.share.share_snapshot_instance_export_locations # noqa: E501 + ) self.share_snapshot_instances_el_mock.reset_mock() @@ -61,7 +63,7 @@ class TestShareSnapshotInstanceList(TestShareSnapshotInstance): def setUp(self): super().setUp() - self.share_snapshot_instances = manila_fakes.FakeShareSnapshotIntances.create_share_snapshot_instances( + self.share_snapshot_instances = manila_fakes.FakeShareSnapshotIntances.create_share_snapshot_instances( # noqa: E501 count=2 ) @@ -136,13 +138,13 @@ class TestShareSnapshotInstanceShow(TestShareSnapshotInstance): def setUp(self): super().setUp() - self.share_snapshot_instance = manila_fakes.FakeShareSnapshotIntances.create_one_snapshot_instance() + self.share_snapshot_instance = manila_fakes.FakeShareSnapshotIntances.create_one_snapshot_instance() # noqa: E501 self.share_snapshot_instances_mock.get.return_value = ( self.share_snapshot_instance ) - self.share_snapshot_instances_el_list = manila_fakes.FakeShareSnapshotInstancesExportLocations.create_share_snapshot_instances( + self.share_snapshot_instances_el_list = manila_fakes.FakeShareSnapshotInstancesExportLocations.create_share_snapshot_instances( # noqa: E501 count=2 ) @@ -192,7 +194,7 @@ class TestShareSnapshotInstanceSet(TestShareSnapshotInstance): def setUp(self): super().setUp() - self.share_snapshot_instance = manila_fakes.FakeShareSnapshotIntances.create_one_snapshot_instance() + self.share_snapshot_instance = manila_fakes.FakeShareSnapshotIntances.create_one_snapshot_instance() # noqa: E501 self.snapshot_instance_status = 'available' diff --git a/manilaclient/tests/unit/v2/fakes.py b/manilaclient/tests/unit/v2/fakes.py index 8c715979..8484831a 100644 --- a/manilaclient/tests/unit/v2/fakes.py +++ b/manilaclient/tests/unit/v2/fakes.py @@ -1243,7 +1243,9 @@ def get_types_3_os_share_type_access(self, **kw): { 'share_type_access': [ { - 'share_type_id': '11111111-1111-1111-1111-111111111111', + 'share_type_id': ( + '11111111-1111-1111-1111-111111111111' + ), 'project_id': '00000000-0000-0000-0000-000000000000', } ] diff --git a/manilaclient/v2/client.py b/manilaclient/v2/client.py index 000d1568..6fc214e4 100644 --- a/manilaclient/v2/client.py +++ b/manilaclient/v2/client.py @@ -263,7 +263,7 @@ def __init__( self ) ) - self.share_snapshot_instance_export_locations = share_snapshot_instance_export_locations.ShareSnapshotInstanceExportLocationManager( + self.share_snapshot_instance_export_locations = share_snapshot_instance_export_locations.ShareSnapshotInstanceExportLocationManager( # noqa: E501 self ) diff --git a/manilaclient/v2/shell.py b/manilaclient/v2/shell.py index 7ea0ed04..b2275b64 100644 --- a/manilaclient/v2/shell.py +++ b/manilaclient/v2/shell.py @@ -2628,8 +2628,11 @@ def do_snapshot_access_list(cs, args): type=str, default=None, action='single_alias', - help=f'Key to be sorted, available keys are {constants.SHARE_SORT_KEY_VALUES}. ' - 'OPTIONAL: Default=None.', + help=( + f'Key to be sorted, available keys are ' + f'{constants.SHARE_SORT_KEY_VALUES}. ' + 'OPTIONAL: Default=None.' + ), ) @cliutils.arg( '--sort-dir', @@ -3158,8 +3161,11 @@ def do_share_instance_export_location_show(cs, args): type=str, default=None, action='single_alias', - help=f'Key to be sorted, available keys are {constants.SNAPSHOT_SORT_KEY_VALUES}. ' - 'Default=None.', + help=( + f'Key to be sorted, available keys are ' + f'{constants.SNAPSHOT_SORT_KEY_VALUES}. ' + 'Default=None.' + ), ) @cliutils.arg( '--sort-dir', @@ -6497,7 +6503,10 @@ def do_share_group_create(cs, args): type=str, default=None, action='single_alias', - help=f'Key to be sorted, available keys are {constants.SHARE_GROUP_SORT_KEY_VALUES}. Default=None.', + help=( + f'Key to be sorted, available keys are ' + f'{constants.SHARE_GROUP_SORT_KEY_VALUES}. Default=None.' + ), ) @cliutils.arg( '--sort-dir', @@ -6819,7 +6828,10 @@ def do_share_group_snapshot_create(cs, args): type=str, default=None, action='single_alias', - help=f'Key to be sorted, available keys are {constants.SHARE_GROUP_SNAPSHOT_SORT_KEY_VALUES}. Default=None.', + help=( + f'Key to be sorted, available keys are ' + f'{constants.SHARE_GROUP_SNAPSHOT_SORT_KEY_VALUES}. Default=None.' + ), ) @cliutils.arg( '--sort-dir', @@ -7593,7 +7605,10 @@ def do_share_transfer_accept(cs, args): type=str, default=None, action='single_alias', - help=f'Key to be sorted, available keys are {constants.SHARE_TRANSFER_SORT_KEY_VALUES}. Default=None.', + help=( + f'Key to be sorted, available keys are ' + f'{constants.SHARE_TRANSFER_SORT_KEY_VALUES}. Default=None.' + ), ) @cliutils.arg( '--sort-dir', @@ -7761,7 +7776,10 @@ def do_share_transfer_show(cs, args): type=str, default=None, action='single_alias', - help=f'Key to be sorted, available keys are {constants.MESSAGE_SORT_KEY_VALUES}. Default=desc.', + help=( + f'Key to be sorted, available keys are ' + f'{constants.MESSAGE_SORT_KEY_VALUES}. Default=desc.' + ), ) @cliutils.arg( '--sort-dir', diff --git a/pyproject.toml b/pyproject.toml index 536b2a7c..6a419e41 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -207,7 +207,7 @@ quote-style = "preserve" docstring-code-format = true [tool.ruff.lint] -select = ["E4", "E7", "E9", "F", "S", "U"] +select = ["E4", "E5", "E7", "E9", "F", "S", "U"] [tool.ruff.lint.per-file-ignores] "manilaclient/tests/*" = ["S"] From f5ef2c69e4b9bacf43c6df49ed7004063a6cd964 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Fri, 10 Oct 2025 12:40:22 +0100 Subject: [PATCH 22/52] Remove unnecessary call Change-Id: Ia48b37fa766d6dab98e43f1df78bd62d78f8a8db Signed-off-by: Stephen Finucane --- manilaclient/osc/v2/share_group_types.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/manilaclient/osc/v2/share_group_types.py b/manilaclient/osc/v2/share_group_types.py index 6b756be4..3edb2a32 100644 --- a/manilaclient/osc/v2/share_group_types.py +++ b/manilaclient/osc/v2/share_group_types.py @@ -317,10 +317,6 @@ def take_action(self, parsed_args): msg % {'share_group_type': parsed_args.share_group_type, 'e': e} ) - kwargs = {} - - if kwargs: - share_group_type_obj.set_keys(**kwargs) if parsed_args.group_specs: group_specs = utils.extract_group_specs( From 3162ce4f21d13c6e28f9d3260818121d84dcdefb Mon Sep 17 00:00:00 2001 From: OpenStack Release Bot Date: Wed, 5 Nov 2025 13:58:11 +0000 Subject: [PATCH 23/52] reno: Update master for unmaintained/2024.1 Update the 2024.1 release notes configuration to build from unmaintained/2024.1. Change-Id: Ic076881d52bb2d667836064f50164e4722e8399c Signed-off-by: OpenStack Release Bot Generated-By: openstack/project-config:roles/copy-release-tools-scripts/files/release-tools/change_reno_branch_to_unmaintained.sh --- releasenotes/source/2024.1.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/releasenotes/source/2024.1.rst b/releasenotes/source/2024.1.rst index 4977a4f1..6896656b 100644 --- a/releasenotes/source/2024.1.rst +++ b/releasenotes/source/2024.1.rst @@ -3,4 +3,4 @@ =========================== .. release-notes:: - :branch: stable/2024.1 + :branch: unmaintained/2024.1 From c4b53ce179fcf003aae914b90b0501eae26e3524 Mon Sep 17 00:00:00 2001 From: Goutham Pacha Ravi Date: Fri, 7 Nov 2025 10:47:33 -0800 Subject: [PATCH 24/52] Add a git-blame-ignore-revs file Signed-off-by: Goutham Pacha Ravi Change-Id: If06e552bedded917a404a15ca5a2e2c25d14be96 --- .git-blame-ignore-revs | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 .git-blame-ignore-revs diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 00000000..64251efc --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1,12 @@ +# Git blame ignore revisions +# This file contains commit hashes that should be ignored by git blame +# to avoid showing formatting/style changes in blame output. +# +# To use this file, run: +# git config blame.ignoreRevsFile .git-blame-ignore-revs + +# Ruff formatting commits to ignore +0ef57c0f49b9c0a6be358a87fff67869c0dc95b4 +95bd3aca64ddec062b884521349914866ddb4672 +16aaa8e7439bb8441c7a9ceff8d398fda276c553 +3e3b385c8c20b94b57255a3f34b39a249ba0a3ae From e5a56f2827bf755dd96cf5e628204ed0517e9713 Mon Sep 17 00:00:00 2001 From: Riane Torres Date: Fri, 18 Jul 2025 14:26:07 -0400 Subject: [PATCH 25/52] Test for share instances Added functional tests for share instances; setup, positive, and negative. Change-Id: Ib33e0e53e19506930bbf8cd02762e66be3b3bd81 Signed-off-by: Riane Torres --- .../functional/osc/test_share_instances.py | 101 ++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 manilaclient/tests/functional/osc/test_share_instances.py diff --git a/manilaclient/tests/functional/osc/test_share_instances.py b/manilaclient/tests/functional/osc/test_share_instances.py new file mode 100644 index 00000000..b867e4de --- /dev/null +++ b/manilaclient/tests/functional/osc/test_share_instances.py @@ -0,0 +1,101 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from tempest.lib import exceptions + +from manilaclient.tests.functional.osc import base + + +class ShareInstancesCLITest(base.OSCClientTestBase): + def setUp(self): + super().setUp() + # Create a share to test with + self.share = self.create_share() + # Get share instances for testing + self.share_instances = self.listing_result('share instance', 'list') + self.share_instance = ( + self.share_instances[0] if self.share_instances else None + ) + self.non_existent_id = '76a7dd8e-7564-41d4-a184-06dc20e13d7a' + self.invalid_id = 'invalid-format' + + def test_share_instance_list(self): + # Test basic listing + instances = self.listing_result('share instance', 'list') + self.assertTableStruct( + instances, + [ + 'ID', + 'Share ID', + 'Host', + 'Status', + 'Availability Zone', + 'Share Network ID', + 'Share Server ID', + 'Share Type ID', + ], + ) + + def test_share_instance_show(self): + result = self.dict_result( + 'share instance', f'show {self.share_instance["ID"]}' + ) + self.assertEqual(self.share_instance['ID'], result['id']) + + def test_share_instance_delete_non_existent(self): + self.assertRaises( + exceptions.CommandFailed, + self.openstack, + f'share instance delete {self.non_existent_id}', + ) + + def test_share_instance_set_non_existent(self): + self.assertRaises( + exceptions.CommandFailed, + self.openstack, + f'share instance set {self.non_existent_id} --status available', + ) + + def test_share_instance_set_invalid_status(self): + self.assertRaises( + exceptions.CommandFailed, + self.openstack, + f'share instance set {self.invalid_id} --status available', + ) + + def test_share_instance_show_non_existent(self): + self.assertRaises( + exceptions.CommandFailed, + self.openstack, + f'share instance show {self.non_existent_id}', + ) + + def test_share_instance_show_invalid_id_format(self): + self.assertRaises( + exceptions.CommandFailed, + self.openstack, + f'share instance show {self.invalid_id}', + ) + + def test_share_instance_list_invalid_filter_share_id_format(self): + self.assertRaises( + exceptions.CommandFailed, + self.openstack, + f'share instance list --share {self.invalid_id}', + ) + + def test_share_instance_list_invalid_filter_non_existent(self): + self.assertRaises( + exceptions.CommandFailed, + self.openstack, + f'share instance list --share {self.non_existent_id}', + ) From c87b2277de9792df2eb57a50bb523c7b9321aeb3 Mon Sep 17 00:00:00 2001 From: Christian Espinal Date: Fri, 17 Oct 2025 14:27:50 -0400 Subject: [PATCH 26/52] Add func test for share instance export locations Change-Id: I801f6e71da47bcc6f94054f10c25b6f6782757b8 Signed-off-by: Christian Espinal --- .../test_share_instance_export_locations.py | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 manilaclient/tests/functional/osc/test_share_instance_export_locations.py diff --git a/manilaclient/tests/functional/osc/test_share_instance_export_locations.py b/manilaclient/tests/functional/osc/test_share_instance_export_locations.py new file mode 100644 index 00000000..9917aaf6 --- /dev/null +++ b/manilaclient/tests/functional/osc/test_share_instance_export_locations.py @@ -0,0 +1,23 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +from tempest.lib import exceptions + +from manilaclient.tests.functional.osc import base + + +class ShareInstanceExportLocationsCLITest(base.OSCClientTestBase): + def test_share_instance_export_locations_list_invalid_id(self): + self.assertRaises( + exceptions.CommandFailed, + self.openstack, + 'share instance export location list wrong_ID', + ) From 875a29ed93895efc5ad2ecc296fa3c5536fa3ee8 Mon Sep 17 00:00:00 2001 From: Jan Jasek Date: Wed, 26 Nov 2025 10:15:28 +0100 Subject: [PATCH 27/52] Add missing api_versions decorator for _update_share_group Add missing api_versions.experimental_api decorator for _update_share_group Closes-Bug: 2132937 Change-Id: Ic196c7bf8326b1e97d51241fbf0e30342f5e437b Signed-off-by: Jan Jasek --- manilaclient/v2/share_groups.py | 1 + ...g-2132937-update-share-group-fix-41558fef427c84a2.yaml | 8 ++++++++ 2 files changed, 9 insertions(+) create mode 100644 releasenotes/notes/bug-2132937-update-share-group-fix-41558fef427c84a2.yaml diff --git a/manilaclient/v2/share_groups.py b/manilaclient/v2/share_groups.py index e5903bd1..462abc5a 100644 --- a/manilaclient/v2/share_groups.py +++ b/manilaclient/v2/share_groups.py @@ -275,6 +275,7 @@ def _update_share_group(self, share_group, **kwargs): return self._update(url, body, RESOURCE_NAME) @api_versions.wraps("2.31", "2.54") + @api_versions.experimental_api def update(self, share_group, **kwargs): return self._update_share_group(share_group, **kwargs) diff --git a/releasenotes/notes/bug-2132937-update-share-group-fix-41558fef427c84a2.yaml b/releasenotes/notes/bug-2132937-update-share-group-fix-41558fef427c84a2.yaml new file mode 100644 index 00000000..80d6a0d8 --- /dev/null +++ b/releasenotes/notes/bug-2132937-update-share-group-fix-41558fef427c84a2.yaml @@ -0,0 +1,8 @@ +--- +fixes: + - | + Fixed an issue where the ``share group update`` command (and the + underlying ``share_groups.update()`` python binding) was missing + the experimental API flag. The client now correctly treats this + action as experimental and sends the required headers. (Bug `2132937 + `_) From 203851673785688f6cb5eccc9a5cbecb7b9308f3 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Fri, 5 Dec 2025 17:27:13 +0000 Subject: [PATCH 28/52] Remove dead code Change-Id: I79e6ce553f969cc815b44f47847c603f31db019f Signed-off-by: Stephen Finucane --- manilaclient/tests/unit/osc/v2/fakes.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/manilaclient/tests/unit/osc/v2/fakes.py b/manilaclient/tests/unit/osc/v2/fakes.py index 4048d83b..7387e2c5 100644 --- a/manilaclient/tests/unit/osc/v2/fakes.py +++ b/manilaclient/tests/unit/osc/v2/fakes.py @@ -66,17 +66,6 @@ def __init__(self, **kwargs): self.resource_locks = mock.Mock() -class ManilaParseException(Exception): - """The base exception class for all exceptions this library raises.""" - - def __init__(self, message=None, details=None): - self.message = message or "Argument parse exception" - self.details = details or None - - def __str__(self): - return self.message - - class TestShare(osc_utils.TestCommand): def setUp(self): super().setUp() From 67483f3d02f3b24fa8066344ba9b8871be79ac5c Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Fri, 5 Dec 2025 17:27:44 +0000 Subject: [PATCH 29/52] ruff: Use more specific name to enable pyupgrade rule UP is the exact name of the rule, instead of U. Use the exact name to avoid potential problems caused by any UX rules which can be added in the future. Change-Id: I1b5eb7b2ca182e176e2a5efed66c3bbf4c5d8024 Signed-off-by: Stephen Finucane --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 6a419e41..7b114c9b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -207,7 +207,7 @@ quote-style = "preserve" docstring-code-format = true [tool.ruff.lint] -select = ["E4", "E5", "E7", "E9", "F", "S", "U"] +select = ["E4", "E5", "E7", "E9", "F", "S", "UP"] [tool.ruff.lint.per-file-ignores] "manilaclient/tests/*" = ["S"] From 678d8edb2437fbef61813587efc36a0ac190bc6f Mon Sep 17 00:00:00 2001 From: Takashi Kajinami Date: Wed, 7 Jan 2026 22:57:31 +0900 Subject: [PATCH 30/52] Drop workaround for Python < 3.10 ... because 3.10 is the current minimum version. Change-Id: I346219086b27410fc95613f12ed9790bd281c347 Signed-off-by: Takashi Kajinami --- manilaclient/tests/functional/test_common.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/manilaclient/tests/functional/test_common.py b/manilaclient/tests/functional/test_common.py index 0c6cb98a..ac274514 100644 --- a/manilaclient/tests/functional/test_common.py +++ b/manilaclient/tests/functional/test_common.py @@ -34,11 +34,7 @@ def test_help(self, role): commands = [] cmds_start = lines.index('Positional arguments:') - try: - # TODO(gouthamr): Drop when py3.10 becomes min supported version - cmds_end = lines.index('Optional arguments:') - except ValueError: - cmds_end = lines.index('Options:') + cmds_end = lines.index('Options:') command_pattern = re.compile(r'^ {4}([a-z0-9\-\_]+)') for line in lines[cmds_start:cmds_end]: match = command_pattern.match(line) From e448fc88bf625f660d11a508ca48732e7ae3d411 Mon Sep 17 00:00:00 2001 From: Goutham Pacha Ravi Date: Fri, 16 Jan 2026 15:28:15 -0800 Subject: [PATCH 31/52] Remove the legacy "manila" CLI The "manila" CLI was deprecated during the 2023.2 release (4.6.0 [1]). All new manila API changes were supported via the "openstack" CLI. After an extended deprecation window, we're now officially removing this CLI utility. [1] https://docs.openstack.org/releasenotes/python-manilaclient/2023.2.html#relnotes-4-6-0-stable-2023-2 Change-Id: Ifbdf8f9385b855c1e5f273bac31cb3b4a538a5ae Signed-off-by: Goutham Pacha Ravi --- doc/source/cli/decoder.rst | 6 +- doc/source/index.rst | 27 +- doc/source/user/shell.rst | 59 - manilaclient/osc/v2/data/manila.csv | 2 + manilaclient/shell.py | 858 -- manilaclient/tests/functional/base.py | 649 -- manilaclient/tests/functional/client.py | 2379 ----- .../functional/test_availability_zones.py | 59 - manilaclient/tests/functional/test_common.py | 73 - .../tests/functional/test_export_locations.py | 173 - manilaclient/tests/functional/test_limits.py | 29 - .../tests/functional/test_messages.py | 80 - manilaclient/tests/functional/test_quotas.py | 395 - .../tests/functional/test_scheduler_stats.py | 49 - .../functional/test_security_services.py | 80 - .../tests/functional/test_services.py | 44 - .../tests/functional/test_share_access.py | 384 - .../functional/test_share_network_subnets.py | 129 - .../tests/functional/test_share_networks.py | 695 -- .../test_share_replica_export_locations.py | 122 - .../tests/functional/test_share_replicas.py | 51 - .../tests/functional/test_share_servers.py | 405 - .../tests/functional/test_share_transfers.py | 100 - .../tests/functional/test_share_types.py | 627 -- manilaclient/tests/functional/test_shares.py | 339 - .../tests/functional/test_shares_listing.py | 414 - .../tests/functional/test_shares_metadata.py | 155 - .../tests/functional/test_snapshot_access.py | 221 - .../functional/test_snapshot_instances.py | 140 - ...est_snapshot_instances_export_locations.py | 131 - .../test_snapshots_export_locations.py | 96 - manilaclient/tests/unit/test_shell.py | 556 -- manilaclient/tests/unit/v2/test_shell.py | 4859 ---------- manilaclient/v2/shell.py | 7907 ----------------- pyproject.toml | 3 - ...remove-python-client-a142b99ccc89731c.yaml | 5 + tools/manila.bash_completion | 15 - 37 files changed, 17 insertions(+), 22299 deletions(-) delete mode 100644 doc/source/user/shell.rst delete mode 100644 manilaclient/shell.py delete mode 100644 manilaclient/tests/functional/base.py delete mode 100644 manilaclient/tests/functional/client.py delete mode 100644 manilaclient/tests/functional/test_availability_zones.py delete mode 100644 manilaclient/tests/functional/test_common.py delete mode 100644 manilaclient/tests/functional/test_export_locations.py delete mode 100644 manilaclient/tests/functional/test_limits.py delete mode 100644 manilaclient/tests/functional/test_messages.py delete mode 100644 manilaclient/tests/functional/test_quotas.py delete mode 100644 manilaclient/tests/functional/test_scheduler_stats.py delete mode 100644 manilaclient/tests/functional/test_security_services.py delete mode 100644 manilaclient/tests/functional/test_services.py delete mode 100644 manilaclient/tests/functional/test_share_access.py delete mode 100644 manilaclient/tests/functional/test_share_network_subnets.py delete mode 100644 manilaclient/tests/functional/test_share_networks.py delete mode 100644 manilaclient/tests/functional/test_share_replica_export_locations.py delete mode 100644 manilaclient/tests/functional/test_share_replicas.py delete mode 100644 manilaclient/tests/functional/test_share_servers.py delete mode 100644 manilaclient/tests/functional/test_share_transfers.py delete mode 100644 manilaclient/tests/functional/test_share_types.py delete mode 100644 manilaclient/tests/functional/test_shares.py delete mode 100644 manilaclient/tests/functional/test_shares_listing.py delete mode 100644 manilaclient/tests/functional/test_shares_metadata.py delete mode 100644 manilaclient/tests/functional/test_snapshot_access.py delete mode 100644 manilaclient/tests/functional/test_snapshot_instances.py delete mode 100644 manilaclient/tests/functional/test_snapshot_instances_export_locations.py delete mode 100644 manilaclient/tests/functional/test_snapshots_export_locations.py delete mode 100644 manilaclient/tests/unit/test_shell.py delete mode 100644 manilaclient/tests/unit/v2/test_shell.py delete mode 100644 manilaclient/v2/shell.py create mode 100644 releasenotes/notes/remove-python-client-a142b99ccc89731c.yaml delete mode 100644 tools/manila.bash_completion diff --git a/doc/source/cli/decoder.rst b/doc/source/cli/decoder.rst index 2c336df4..b97d745e 100644 --- a/doc/source/cli/decoder.rst +++ b/doc/source/cli/decoder.rst @@ -2,10 +2,14 @@ OpenStackClient Mapping Guide ============================= +.. note:: + + The legacy ``manila`` CLI has been removed. This guide is maintained for + historical reference to help users upgrading from older versions. + The following is a mapping between the legacy ``manila`` CLI client and OpenStackClient. Command options are only shown when necessary. - .. only:: html .. csv-table:: diff --git a/doc/source/index.rst b/doc/source/index.rst index bbd0c7f3..934e83e3 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -2,26 +2,17 @@ Python bindings to the OpenStack Manila API =========================================== This is a client for OpenStack Manila API. There's :doc:`a Python API -` (the :mod:`manilaclient` module), and a :doc:`command-line script -` (installed as :program:`manila`). Each implements the entire -OpenStack Manila API. See :ref:`project-structure` for more information. +` (the :mod:`manilaclient` module) for programmatic access, and +a command-line interface via the OpenStack CLI client. See +:ref:`project-structure` for more information. You'll need credentials for an OpenStack cloud that implements the Manila API in order to use the manila client. Command-Line Reference ~~~~~~~~~~~~~~~~~~~~~~ -There are two shell implementations in python-manilaclient. - -.. important:: - - The legacy "manila" shell client is deprecated as of version ``5.0.0``. - A future version of python-manilaclient may not ship this legacy shell - client. If you rely on it, it is highly recommended that you begin using - the openstack CLI client right away. Refer to the `mapping guide - `_ to help with this transition. - -The "openstack" CLI client intends to be fully compatible with the manila API: +Use the "openstack" CLI client to interact with the Manila API from the +command line: .. toctree:: :maxdepth: 1 @@ -29,14 +20,6 @@ The "openstack" CLI client intends to be fully compatible with the manila API: cli/osc_plugin_cli cli/decoder -The legacy "manila" client is deprecated and may not support newer API -features: - -.. toctree:: - :maxdepth: 2 - - user/shell - Using the python module ~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/source/user/shell.rst b/doc/source/user/shell.rst deleted file mode 100644 index 13553ae7..00000000 --- a/doc/source/user/shell.rst +++ /dev/null @@ -1,59 +0,0 @@ -The :program:`manila` shell utility -========================================= - -.. important:: - - This shell client is deprecated as of version ``5.0.0``. A future - version of python-manilaclient may not ship this legacy shell client. If - you rely on it, it is highly recommended that you begin using the - openstack CLI client right away. Refer to the `mapping guide - <../cli/decoder.html>`_ to help with this transition. - -.. program:: manila -.. highlight:: bash - -The :program:`manila` shell utility interacts with the OpenStack Manila API -from the command line. It supports the entirety of the OpenStack Manila API. - -You'll need to provide :program:`manila` with your OpenStack username and API -key. You can do this with the `--os-username`, `--os-password` and -`--os-tenant-name` options, but it's easier to just set them as environment -variables by setting two environment variables: - -.. envvar:: OS_USERNAME or MANILA_USERNAME - - Your OpenStack Manila username. - -.. envvar:: OS_PASSWORD or MANILA_PASSWORD - - Your password. - -.. envvar:: OS_TENANT_NAME or MANILA_PROJECT_ID - - Project for work. - -.. envvar:: OS_AUTH_URL or MANILA_URL - - The OpenStack API server URL. - -.. envvar:: OS_SHARE_API_VERSION - - The OpenStack Shared Filesystems API version. - -For example, in Bash you'd use:: - - export OS_USERNAME=foo - export OS_PASSWORD=bar - export OS_TENANT_NAME=foobarproject - export OS_AUTH_URL=http://... - export OS_SHARE_API_VERSION=2 - -From there, all shell commands take the form:: - - manila [arguments...] - -Run :program:`manila help` to get a full list of all possible commands, -and run :program:`manila help ` to get detailed help for that -command. - -.. program-output:: manila --help diff --git a/manilaclient/osc/v2/data/manila.csv b/manilaclient/osc/v2/data/manila.csv index dbfeba34..24199a7e 100644 --- a/manilaclient/osc/v2/data/manila.csv +++ b/manilaclient/osc/v2/data/manila.csv @@ -1,3 +1,5 @@ +# NOTE: The legacy "manila" CLI has been removed. This file is maintained +# for historical reference and migration purposes. manila command,openstack command,command description --version,module list,List the client software version absolute-limits,share limits show --absolute,Print a list of absolute limits for a user diff --git a/manilaclient/shell.py b/manilaclient/shell.py deleted file mode 100644 index 4455defb..00000000 --- a/manilaclient/shell.py +++ /dev/null @@ -1,858 +0,0 @@ -# Copyright 2011 OpenStack Foundation -# Copyright 2014 Mirantis, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -""" -Command-line interface to the OpenStack Manila API. -""" - -import argparse -import csv -import glob -from importlib import util as importlib_util -import itertools -import logging -import os -import pkgutil -import sys - -from oslo_utils import importutils - -from manilaclient import api_versions -from manilaclient import client -from manilaclient.common import cliutils -from manilaclient.common import constants -from manilaclient import exceptions as exc -import manilaclient.extension -from manilaclient.v2 import shell as shell_v2 - -DEFAULT_OS_SHARE_API_VERSION = api_versions.MAX_VERSION -DEFAULT_MANILA_ENDPOINT_TYPE = 'publicURL' -DEFAULT_MAJOR_OS_SHARE_API_VERSION = "2" -V1_MAJOR_VERSION = '1' -V2_MAJOR_VERSION = '2' - -try: - osprofiler_profiler = importutils.try_import("osprofiler.profiler") -except ImportError: - pass - - -logger = logging.getLogger(__name__) - - -class AllowOnlyOneAliasAtATimeAction(argparse.Action): - """Allows only one alias of argument to be used at a time.""" - - def __call__(self, parser, namespace, values, option_string=None): - # NOTE(vponomaryov): this method is redefinition of - # argparse.Action.__call__ interface - - if not hasattr(self, 'calls'): - self.calls = {} - - if self.dest not in self.calls: - self.calls[self.dest] = set() - - local_values = sorted(values) if isinstance(values, list) else values - self.calls[self.dest].add(str(local_values)) - - if len(self.calls[self.dest]) == 1: - setattr(namespace, self.dest, local_values) - else: - msg = "Only one alias is allowed at a time." - raise argparse.ArgumentError(self, msg) - - -class ManilaClientArgumentParser(argparse.ArgumentParser): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - # NOTE(vponomaryov): Register additional action to be used by arguments - # with multiple aliases. - self.register('action', 'single_alias', AllowOnlyOneAliasAtATimeAction) - - def error(self, message): - """error(message: string) - - Prints a usage message incorporating the message to stderr and - exits. - """ - self.print_usage(sys.stderr) - # FIXME(lzyeval): if changes occur in argparse.ArgParser._check_value - choose_from = ' (choose from' - progparts = self.prog.partition(' ') - self.exit( - 2, - f"error: {message.split(choose_from)[0]}\n" - f"Try '{progparts[0]} help {progparts[2]}' " - f"for more information.\n", - ) - - def _get_option_tuples(self, option_string): - """Avoid ambiguity in argument abbreviation. - - Manilaclient uses aliases for command parameters and this method - is used for avoiding parameter ambiguity alert. - """ - option_tuples = super()._get_option_tuples(option_string) - if len(option_tuples) > 1: - opt_strings_list = [] - opts = [] - for opt in option_tuples: - if opt[0].option_strings not in opt_strings_list: - opt_strings_list.append(opt[0].option_strings) - opts.append(opt) - return opts - return option_tuples - - -class OpenStackManilaShell: - def get_base_parser(self): - parser = ManilaClientArgumentParser( - prog='manila', - description=__doc__.strip(), - epilog='See "manila help COMMAND" for help on a specific command.', - add_help=False, - formatter_class=OpenStackHelpFormatter, - ) - - # Global arguments - parser.add_argument( - '-h', '--help', action='store_true', help=argparse.SUPPRESS - ) - - parser.add_argument( - '--version', action='version', version=manilaclient.__version__ - ) - - parser.add_argument( - '-d', - '--debug', - action='store_true', - default=cliutils.env( - 'manilaclient_DEBUG', 'MANILACLIENT_DEBUG', default=False - ), - help="Print debugging output.", - ) - - parser.add_argument( - '--os-cache', - default=cliutils.env('OS_CACHE', default=False), - action='store_true', - help='Use the auth token cache. Defaults to env[OS_CACHE].', - ) - - parser.add_argument( - '--os-reset-cache', - default=False, - action='store_true', - help='Delete cached password and auth token.', - ) - - parser.add_argument( - '--os-user-id', - metavar='', - default=cliutils.env('OS_USER_ID'), - help=('Defaults to env [OS_USER_ID].'), - ) - parser.add_argument('--os_user_id', help=argparse.SUPPRESS) - - parser.add_argument( - '--os-username', - metavar='', - default=cliutils.env('OS_USERNAME', 'MANILA_USERNAME'), - help='Defaults to env[OS_USERNAME].', - ) - parser.add_argument('--os_username', help=argparse.SUPPRESS) - - parser.add_argument( - '--os-password', - metavar='', - default=cliutils.env('OS_PASSWORD', 'MANILA_PASSWORD'), - help='Defaults to env[OS_PASSWORD].', - ) - parser.add_argument('--os_password', help=argparse.SUPPRESS) - - parser.add_argument( - '--os-tenant-name', - metavar='', - default=cliutils.env('OS_TENANT_NAME', 'MANILA_PROJECT_ID'), - help='Defaults to env[OS_TENANT_NAME].', - ) - parser.add_argument('--os_tenant_name', help=argparse.SUPPRESS) - - parser.add_argument( - '--os-project-name', - metavar='', - default=cliutils.env('OS_PROJECT_NAME'), - help=( - 'Another way to specify tenant name. ' - 'This option is mutually exclusive with ' - '--os-tenant-name. ' - 'Defaults to env[OS_PROJECT_NAME].' - ), - ) - parser.add_argument('--os_project_name', help=argparse.SUPPRESS) - - parser.add_argument( - '--os-tenant-id', - metavar='', - default=cliutils.env('OS_TENANT_ID', 'MANILA_TENANT_ID'), - help='Defaults to env[OS_TENANT_ID].', - ) - parser.add_argument('--os_tenant_id', help=argparse.SUPPRESS) - - parser.add_argument( - '--os-project-id', - metavar='', - default=cliutils.env('OS_PROJECT_ID'), - help=( - 'Another way to specify tenant ID. ' - 'This option is mutually exclusive with ' - '--os-tenant-id. ' - 'Defaults to env[OS_PROJECT_ID].' - ), - ) - parser.add_argument('--os_project_id', help=argparse.SUPPRESS) - - parser.add_argument( - '--os-user-domain-id', - metavar='', - default=cliutils.env('OS_USER_DOMAIN_ID'), - help=( - 'OpenStack user domain ID. Defaults to env[OS_USER_DOMAIN_ID].' - ), - ) - parser.add_argument('--os_user_domain_id', help=argparse.SUPPRESS) - - parser.add_argument( - '--os-user-domain-name', - metavar='', - default=cliutils.env('OS_USER_DOMAIN_NAME'), - help=( - 'OpenStack user domain name. ' - 'Defaults to env[OS_USER_DOMAIN_NAME].' - ), - ) - parser.add_argument('--os_user_domain_name', help=argparse.SUPPRESS) - - parser.add_argument( - '--os-project-domain-id', - metavar='', - default=cliutils.env('OS_PROJECT_DOMAIN_ID'), - help='Defaults to env[OS_PROJECT_DOMAIN_ID].', - ) - parser.add_argument('--os_project_domain_id', help=argparse.SUPPRESS) - - parser.add_argument( - '--os-project-domain-name', - metavar='', - default=cliutils.env('OS_PROJECT_DOMAIN_NAME'), - help='Defaults to env[OS_PROJECT_DOMAIN_NAME].', - ) - parser.add_argument('--os_project_domain_name', help=argparse.SUPPRESS) - - parser.add_argument( - '--os-auth-url', - metavar='', - default=cliutils.env('OS_AUTH_URL', 'MANILA_URL'), - help='Defaults to env[OS_AUTH_URL].', - ) - parser.add_argument('--os_auth_url', help=argparse.SUPPRESS) - - parser.add_argument( - '--os-region-name', - metavar='', - default=cliutils.env('OS_REGION_NAME', 'MANILA_REGION_NAME'), - help='Defaults to env[OS_REGION_NAME].', - ) - parser.add_argument('--os_region_name', help=argparse.SUPPRESS) - - parser.add_argument( - '--os-token', - metavar='', - default=cliutils.env('OS_TOKEN'), - help='Defaults to env[OS_TOKEN].', - ) - parser.add_argument('--os_token', help=argparse.SUPPRESS) - - parser.add_argument( - '--bypass-url', - metavar='', - default=cliutils.env( - 'OS_MANILA_BYPASS_URL', 'MANILACLIENT_BYPASS_URL' - ), - help=( - "Use this API endpoint instead of the " - "Service Catalog. Defaults to " - "env[OS_MANILA_BYPASS_URL]." - ), - ) - parser.add_argument('--bypass_url', help=argparse.SUPPRESS) - - parser.add_argument( - '--service-type', - metavar='', - help='Defaults to compute for most actions.', - ) - parser.add_argument('--service_type', help=argparse.SUPPRESS) - - parser.add_argument( - '--service-name', - metavar='', - default=cliutils.env( - 'OS_MANILA_SERVICE_NAME', 'MANILA_SERVICE_NAME' - ), - help='Defaults to env[OS_MANILA_SERVICE_NAME].', - ) - parser.add_argument('--service_name', help=argparse.SUPPRESS) - - parser.add_argument( - '--share-service-name', - metavar='', - default=cliutils.env( - 'OS_MANILA_SHARE_SERVICE_NAME', 'MANILA_share_service_name' - ), - help='Defaults to env[OS_MANILA_SHARE_SERVICE_NAME].', - ) - parser.add_argument('--share_service_name', help=argparse.SUPPRESS) - - parser.add_argument( - '--endpoint-type', - metavar='', - default=cliutils.env( - 'OS_MANILA_ENDPOINT_TYPE', - 'MANILA_ENDPOINT_TYPE', - default=DEFAULT_MANILA_ENDPOINT_TYPE, - ), - help='Defaults to env[OS_MANILA_ENDPOINT_TYPE] or ' - + DEFAULT_MANILA_ENDPOINT_TYPE - + '.', - ) - parser.add_argument('--endpoint_type', help=argparse.SUPPRESS) - - parser.add_argument( - '--os-share-api-version', - metavar='', - default=cliutils.env( - 'OS_SHARE_API_VERSION', default=DEFAULT_OS_SHARE_API_VERSION - ), - help='Accepts 1.x to override default ' - 'to env[OS_SHARE_API_VERSION].', - ) - parser.add_argument('--os_share_api_version', help=argparse.SUPPRESS) - - parser.add_argument( - '--os-cacert', - metavar='', - default=cliutils.env('OS_CACERT', default=None), - help='Specify a CA bundle file to use in ' - 'verifying a TLS (https) server certificate. ' - 'Defaults to env[OS_CACERT].', - ) - - parser.add_argument( - '--insecure', - default=cliutils.env( - 'manilaclient_INSECURE', 'MANILACLIENT_INSECURE', default=False - ), - action='store_true', - help=argparse.SUPPRESS, - ) - - parser.add_argument( - '--retries', - metavar='', - type=int, - default=0, - help='Number of retries.', - ) - - parser.add_argument( - '--os-cert', - metavar='', - default=cliutils.env('OS_CERT'), - help='Defaults to env[OS_CERT].', - ) - parser.add_argument('--os_cert', help=argparse.SUPPRESS) - - parser.add_argument( - '--os-key', - metavar='', - default=cliutils.env('OS_KEY'), - help='Defaults to env[OS_KEY].', - ) - parser.add_argument('--os_key', help=argparse.SUPPRESS) - - if osprofiler_profiler: - parser.add_argument( - '--profile', - metavar='HMAC_KEY', - default=cliutils.env('OS_PROFILE'), - help='HMAC key to use for encrypting ' - 'context data for performance profiling ' - 'of operation. This key needs to match the ' - 'one configured on the manila api server. ' - 'Without key the profiling will not be ' - 'triggered even if osprofiler is enabled ' - 'on server side. Defaults to ' - 'env[OS_PROFILE].', - ) - - parser.set_defaults(func=self.do_help) - parser.set_defaults(command='') - - return parser - - def get_subcommand_parser(self, version): - parser = self.get_base_parser() - - self.subcommands = {} - subparsers = parser.add_subparsers(metavar='') - - try: - actions_module = { - V2_MAJOR_VERSION: shell_v2, - }[version] - except KeyError: - actions_module = shell_v2 - - self._find_actions(subparsers, actions_module) - self._find_actions(subparsers, self) - - for extension in self.extensions: - self._find_actions(subparsers, extension.module) - - self._add_bash_completion_subparser(subparsers) - - return parser - - def _discover_extensions(self, api_version): - extensions = [] - for name, module in itertools.chain( - self._discover_via_python_path(), - self._discover_via_contrib_path(api_version), - ): - extension = manilaclient.extension.Extension(name, module) - extensions.append(extension) - - return extensions - - def _discover_via_python_path(self): - for module_loader, name, ispkg in pkgutil.iter_modules(): - if name.endswith('python_manilaclient_ext'): - if not hasattr(module_loader, 'load_module'): - # Python 2.6 compat: actually get an ImpImporter obj - module_loader = module_loader.find_module(name) - - module = module_loader.load_module(name) - yield name, module - - def _load_module(self, name, path): - module_spec = importlib_util.spec_from_file_location(name, path) - module = importlib_util.module_from_spec(module_spec) - module_spec.loader.exec_module(module) - return module - - def _discover_via_contrib_path(self, api_version): - module_path = os.path.dirname(os.path.abspath(__file__)) - version_str = 'v' + api_version.get_major_version() - ext_path = os.path.join(module_path, version_str, 'contrib') - ext_glob = os.path.join(ext_path, "*.py") - - for ext_path in glob.iglob(ext_glob): - name = os.path.basename(ext_path)[:-3] - - if name == "__init__": - continue - - module = self._load_module(name, ext_path) - yield name, module - - def _add_bash_completion_subparser(self, subparsers): - subparser = subparsers.add_parser( - 'bash_completion', - add_help=False, - formatter_class=OpenStackHelpFormatter, - ) - - self.subcommands['bash_completion'] = subparser - subparser.set_defaults(func=self.do_bash_completion) - - def _find_actions(self, subparsers, actions_module): - for attr in (a for a in dir(actions_module) if a.startswith('do_')): - # I prefer to be hypen-separated instead of underscores. - command = attr[3:].replace('_', '-') - callback = getattr(actions_module, attr) - desc = callback.__doc__ or '' - help = desc.strip() - arguments = getattr(callback, 'arguments', []) - - subparser = subparsers.add_parser( - command, - help=help, - description=desc, - add_help=False, - formatter_class=OpenStackHelpFormatter, - ) - - subparser.add_argument( - '-h', - '--help', - action='help', - help=argparse.SUPPRESS, - ) - - self.subcommands[command] = subparser - for args, kwargs in arguments: - subparser.add_argument(*args, **kwargs) - subparser.set_defaults(func=callback) - - def setup_debugging(self, debug): - if not debug: - return - - streamformat = "%(levelname)s (%(module)s:%(lineno)d) %(message)s" - logging.basicConfig(level=logging.DEBUG, format=streamformat) - logging.getLogger('requests.packages.urllib3.connectionpool').setLevel( - logging.WARNING - ) - logging.getLogger('keystoneauth1.session').setLevel(logging.WARNING) - - def _build_subcommands_and_extensions(self, os_api_version, argv, options): - self.extensions = self._discover_extensions(os_api_version) - self._run_extension_hooks('__pre_parse_args__') - - self.parser = self.get_subcommand_parser( - os_api_version.get_major_version() - ) - - if argv and len(argv) > 1 and '--help' in argv: - argv = [x for x in argv if x != '--help'] - if argv[0] in self.subcommands: - self.subcommands[argv[0]].print_help() - return False - - if options.help or not argv: - self.parser.print_help() - return False - - args = self.parser.parse_args(argv) - self._run_extension_hooks('__post_parse_args__', args) - - return args - - def main(self, argv): - # Parse args once to find version and debug settings - parser = self.get_base_parser() - (options, args) = parser.parse_known_args(argv) - self.setup_debugging(options.debug) - - os_api_version = self._validate_input_api_version(options) - - # build available subcommands based on version - args = self._build_subcommands_and_extensions( - os_api_version, argv, options - ) - if not args: - return 0 - - # Short-circuit and deal with help right away. - if args.func == self.do_help: - self.do_help(args) - return 0 - elif args.func == self.do_bash_completion: - self.do_bash_completion(args) - return 0 - - if not options.os_share_api_version: - api_version = api_versions.get_api_version( - DEFAULT_MAJOR_OS_SHARE_API_VERSION - ) - else: - api_version = api_versions.get_api_version( - options.os_share_api_version - ) - - major_version_string = str(api_version.ver_major) - os_service_type = args.service_type - if not os_service_type: - os_service_type = constants.SERVICE_TYPES[major_version_string] - - os_endpoint_type = args.endpoint_type or DEFAULT_MANILA_ENDPOINT_TYPE - cert = args.os_cert or None - if cert and args.os_key: - cert = cert, args.os_key - - client_args = dict( - username=args.os_username, - password=args.os_password, - project_name=args.os_project_name or args.os_tenant_name, - auth_url=args.os_auth_url, - insecure=args.insecure, - region_name=args.os_region_name, - tenant_id=args.os_project_id or args.os_tenant_id, - endpoint_type=os_endpoint_type, - extensions=self.extensions, - service_type=os_service_type, - service_name=args.service_name, - retries=options.retries, - http_log_debug=args.debug, - cacert=args.os_cacert, - use_keyring=args.os_cache, - force_new_token=args.os_reset_cache, - user_id=args.os_user_id, - user_domain_id=args.os_user_domain_id, - user_domain_name=args.os_user_domain_name, - project_domain_id=args.os_project_domain_id, - project_domain_name=args.os_project_domain_name, - cert=cert, - input_auth_token=args.os_token, - service_catalog_url=args.bypass_url, - ) - - # Handle deprecated parameters - if args.share_service_name: - client_args['share_service_name'] = args.share_service_name - - self._validate_required_options( - args.os_tenant_name, - args.os_tenant_id, - args.os_project_name, - args.os_project_id, - args.os_token, - args.bypass_url, - client_args['auth_url'], - ) - - # This client is needed to discover the server api version. - temp_client = client.Client( - manilaclient.API_MAX_VERSION, **client_args - ) - - self.cs, discovered_version = self._discover_client( - temp_client, - os_api_version, - os_endpoint_type, - os_service_type, - client_args, - ) - - args = self._build_subcommands_and_extensions( - discovered_version, argv, options - ) - - profile = osprofiler_profiler and options.profile - if profile: - osprofiler_profiler.init(options.profile) - - try: - decoder_path = '{}/{}'.format( - os.path.dirname(os.path.abspath(__file__)), - 'osc/v2/data/manila.csv', - ) - with open(decoder_path) as f: - decoder_data = { - r['manila command']: r['openstack command'] - for r in csv.DictReader(f, skipinitialspace=True) - } - except Exception: - # this is fine - decoder_data = {} - - deprecation_message = ( - "manila CLI is deprecated and will be removed " - "in the future. Use openstack CLI instead." - ) - cmd = args.func.__name__.lstrip('do_').replace("_", "-") - if decoder_data and cmd in decoder_data: - deprecation_message = " ".join( - [ - deprecation_message, - "The equivalent command is \" openstack", - f"{decoder_data[cmd]}", - "\"", - ] - ) - - print(deprecation_message, file=sys.stderr) - - args.func(self.cs, args) - - if profile: - trace_id = osprofiler_profiler.get().get_base_id() - print(f"Profiling trace ID: {trace_id}") - print( - "To display trace use next command:\n" - f"osprofiler trace show --html {trace_id} " - ) - - def _discover_client( - self, - current_client, - os_api_version, - os_endpoint_type, - os_service_type, - client_args, - ): - if os_api_version == manilaclient.API_DEPRECATED_VERSION: - discovered_version = manilaclient.API_DEPRECATED_VERSION - os_service_type = constants.V1_SERVICE_TYPE - else: - discovered_version = api_versions.discover_version( - current_client, os_api_version - ) - - if not os_endpoint_type: - os_endpoint_type = DEFAULT_MANILA_ENDPOINT_TYPE - - if not os_service_type: - os_service_type = self._discover_service_type(discovered_version) - - if ( - discovered_version != manilaclient.API_MAX_VERSION - or os_service_type != constants.V1_SERVICE_TYPE - or os_endpoint_type != DEFAULT_MANILA_ENDPOINT_TYPE - ): - client_args['version'] = discovered_version - client_args['service_type'] = os_service_type - client_args['endpoint_type'] = os_endpoint_type - - return ( - client.Client(discovered_version, **client_args), - discovered_version, - ) - else: - return current_client, discovered_version - - def _discover_service_type(self, discovered_version): - major_version = discovered_version.get_major_version() - service_type = constants.SERVICE_TYPES[major_version] - return service_type - - def _validate_input_api_version(self, options): - if not options.os_share_api_version: - api_version = manilaclient.API_MAX_VERSION - else: - api_version = api_versions.get_api_version( - options.os_share_api_version - ) - return api_version - - def _validate_required_options( - self, - tenant_name, - tenant_id, - project_name, - project_id, - token, - service_catalog_url, - auth_url, - ): - if token and not service_catalog_url: - raise exc.CommandError( - "bypass_url missing: When specifying a token the bypass_url " - "must be set via --bypass-url or env[OS_MANILA_BYPASS_URL]" - ) - if service_catalog_url and not token: - raise exc.CommandError( - "Token missing: When specifying a bypass_url a token must be " - "set via --os-token or env[OS_TOKEN]" - ) - if token and service_catalog_url: - return - - if not (tenant_name or tenant_id or project_name or project_id): - raise exc.CommandError( - "You must provide a tenant_name, tenant_id, " - "project_id or project_name (with " - "project_domain_name or project_domain_id) via " - "--os-tenant-name or env[OS_TENANT_NAME], " - "--os-tenant-id or env[OS_TENANT_ID], " - "--os-project-id or env[OS_PROJECT_ID], " - "--os-project-name or env[OS_PROJECT_NAME], " - "--os-project-domain-id or env[OS_PROJECT_DOMAIN_ID] and " - "--os-project-domain-name or env[OS_PROJECT_DOMAIN_NAME]." - ) - - if not auth_url: - raise exc.CommandError( - "You must provide an auth url " - "via either --os-auth-url or env[OS_AUTH_URL]" - ) - - def _run_extension_hooks(self, hook_type, *args, **kwargs): - """Run hooks for all registered extensions.""" - for extension in self.extensions: - extension.run_hooks(hook_type, *args, **kwargs) - - def do_bash_completion(self, args): - """Print arguments for bash_completion. - - Prints all of the commands and options to stdout so that the - manila.bash_completion script doesn't have to hard code them. - """ - commands = set() - options = set() - for sc_str, sc in list(self.subcommands.items()): - commands.add(sc_str) - for option in sc._optionals._option_string_actions: - options.add(option) - - commands.remove('bash-completion') - commands.remove('bash_completion') - print(' '.join(commands | options)) - - @cliutils.arg( - 'command', - metavar='', - nargs='?', - help='Display help for ', - ) - def do_help(self, args): - """Display help about this program or one of its subcommands.""" - if args.command: - if args.command in self.subcommands: - self.subcommands[args.command].print_help() - else: - raise exc.CommandError( - f"'{args.command}' is not a valid subcommand" - ) - else: - self.parser.print_help() - - -# I'm picky about my shell help. -class OpenStackHelpFormatter(argparse.HelpFormatter): - def start_section(self, heading): - # Title-case the headings - heading = f'{heading[0].upper()}{heading[1:]}' - super().start_section(heading) - - -def main(): - try: - OpenStackManilaShell().main(sys.argv[1:]) - except KeyboardInterrupt: - print("... terminating manila client", file=sys.stderr) - sys.exit(130) - except Exception as e: - logger.debug(e, exc_info=1) - print(f"ERROR: {str(e)}", file=sys.stderr) - sys.exit(1) - - -if __name__ == "__main__": - main() diff --git a/manilaclient/tests/functional/base.py b/manilaclient/tests/functional/base.py deleted file mode 100644 index c77ee7b1..00000000 --- a/manilaclient/tests/functional/base.py +++ /dev/null @@ -1,649 +0,0 @@ -# Copyright 2014 Mirantis Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import re -import traceback - -from oslo_log import log -from tempest.lib.cli import base -from tempest.lib.common.utils import data_utils -from tempest.lib import exceptions as lib_exc - -from manilaclient.common import constants -from manilaclient import config -from manilaclient.tests.functional import client -from manilaclient.tests.functional import utils - -CONF = config.CONF -LOG = log.getLogger(__name__) - - -class handle_cleanup_exceptions: - """Handle exceptions raised with cleanup operations. - - Always suppress errors when lib_exc.NotFound or lib_exc.Forbidden - are raised. - Suppress all other exceptions only in case config opt - 'suppress_errors_in_cleanup' is True. - """ - - def __enter__(self): - return self - - def __exit__(self, exc_type, exc_value, exc_traceback): - if isinstance(exc_value, (lib_exc.NotFound, lib_exc.Forbidden)): - return True - elif CONF.suppress_errors_in_cleanup: - LOG.error("Suppressed cleanup error: \n%s", traceback.format_exc()) - return True - return False # Don't suppress cleanup errors - - -class BaseTestCase(base.ClientTestBase): - # Will be cleaned up after test suite run - class_resources = [] - - # Will be cleaned up after single test run - method_resources = [] - - def setUp(self): - super().setUp() - self.addCleanup(self.clear_resources) - - @classmethod - def tearDownClass(cls): - super().tearDownClass() - cls.clear_resources(cls.class_resources) - - @classmethod - def clear_resources(cls, resources=None): - """Deletes resources, that were created in test suites. - - This method tries to remove resources from resource list, - if it is not found, assume it was deleted in test itself. - It is expected, that all resources were added as LIFO - due to restriction of deletion resources, that are in the chain. - :param resources: dict with keys 'type','id','client', - 'deletion_params' and 'deleted'. Optional 'deletion_params' - contains additional data needed to delete some type of resources. - Ex: - params = { - 'type': 'share_network_subnet', - 'id': 'share-network-subnet-id', - 'client': None, - 'deletion_params': { - 'share_network': 'share-network-id', - }, - 'deleted': False, - } - """ - - if resources is None: - resources = cls.method_resources - for res in resources: - if "deleted" not in res: - res["deleted"] = False - if "client" not in res: - res["client"] = cls.get_cleanup_client() - if not res["deleted"]: - res_id = res["id"] - client = res["client"] - deletion_params = res.get("deletion_params") - with handle_cleanup_exceptions(): - # TODO(vponomaryov): add support for other resources - if res["type"] == "share_type": - client.delete_share_type( - res_id, microversion=res["microversion"] - ) - client.wait_for_share_type_deletion( - res_id, microversion=res["microversion"] - ) - elif res["type"] == "share_network": - client.delete_share_network( - res_id, microversion=res["microversion"] - ) - client.wait_for_share_network_deletion( - res_id, microversion=res["microversion"] - ) - elif res["type"] == "share_network_subnet": - client.delete_share_network_subnet( - share_network_subnet=res_id, - share_network=deletion_params["share_network"], - microversion=res["microversion"], - ) - client.wait_for_share_network_subnet_deletion( - share_network_subnet=res_id, - share_network=deletion_params["share_network"], - microversion=res["microversion"], - ) - elif res["type"] == "share": - client.delete_share( - res_id, microversion=res["microversion"] - ) - client.wait_for_share_deletion( - res_id, microversion=res["microversion"] - ) - elif res["type"] == "snapshot": - client.delete_snapshot( - res_id, microversion=res["microversion"] - ) - client.wait_for_snapshot_deletion( - res_id, microversion=res["microversion"] - ) - elif res["type"] == "share_replica": - client.delete_share_replica( - res_id, microversion=res["microversion"] - ) - client.wait_for_share_replica_deletion( - res_id, microversion=res["microversion"] - ) - else: - LOG.warning( - "Provided unsupported resource type for " - "cleanup '%s'. Skipping.", - res["type"], - ) - res["deleted"] = True - - @classmethod - def get_admin_client(cls): - manilaclient = client.ManilaCLIClient( - username=CONF.admin_username, - password=CONF.admin_password, - tenant_name=CONF.admin_tenant_name, - project_domain_name=CONF.admin_project_domain_name or None, - project_domain_id=CONF.admin_project_domain_id or None, - user_domain_name=CONF.admin_user_domain_name or None, - user_domain_id=CONF.admin_user_domain_id or None, - uri=CONF.admin_auth_url or CONF.auth_url, - insecure=CONF.insecure, - cli_dir=CONF.manila_exec_dir, - ) - # Set specific for admin project share network - manilaclient.share_network = CONF.admin_share_network - return manilaclient - - @classmethod - def get_user_client(cls): - manilaclient = client.ManilaCLIClient( - username=CONF.username, - password=CONF.password, - tenant_name=CONF.tenant_name, - project_domain_name=CONF.project_domain_name or None, - project_domain_id=CONF.project_domain_id or None, - user_domain_name=CONF.user_domain_name or None, - user_domain_id=CONF.user_domain_id or None, - uri=CONF.auth_url, - insecure=CONF.insecure, - cli_dir=CONF.manila_exec_dir, - ) - # Set specific for user project share network - manilaclient.share_network = CONF.share_network - return manilaclient - - @property - def admin_client(self): - if not hasattr(self, '_admin_client'): - self._admin_client = self.get_admin_client() - return self._admin_client - - @property - def user_client(self): - if not hasattr(self, '_user_client'): - self._user_client = self.get_user_client() - return self._user_client - - def _get_clients(self): - return {'admin': self.admin_client, 'user': self.user_client} - - def skip_if_microversion_not_supported(self, microversion): - if not utils.is_microversion_supported(microversion): - raise self.skipException( - f"Microversion '{microversion}' is not supported." - ) - - @classmethod - def create_share_type( - cls, - name=None, - driver_handles_share_servers=True, - snapshot_support=None, - create_share_from_snapshot=None, - revert_to_snapshot=None, - mount_snapshot=None, - is_public=True, - client=None, - cleanup_in_class=False, - microversion=None, - extra_specs=None, - description=None, - ): - if client is None: - client = cls.get_admin_client() - data = { - "name": name, - "driver_handles_share_servers": driver_handles_share_servers, - "snapshot_support": snapshot_support, - "is_public": is_public, - "microversion": microversion, - "extra_specs": extra_specs, - "create_share_from_snapshot": create_share_from_snapshot, - "revert_to_snapshot": revert_to_snapshot, - "mount_snapshot": mount_snapshot, - } - if description: - data["description"] = description - share_type = client.create_share_type(**data) - resource = { - "type": "share_type", - "id": share_type["ID"], - "client": client, - "microversion": microversion, - } - if cleanup_in_class: - cls.class_resources.insert(0, resource) - else: - cls.method_resources.insert(0, resource) - return share_type - - @classmethod - def update_share_type( - cls, - share_type_id, - name=None, - is_public=None, - client=None, - microversion=None, - description=None, - ): - if client is None: - client = cls.get_admin_client() - data = { - "share_type_id": share_type_id, - "microversion": microversion, - } - if name is not None: - data["name"] = name - if description is not None: - data["description"] = description - if is_public is not None: - data["is_public"] = is_public - share_type = client.update_share_type(**data) - return share_type - - @classmethod - def create_share_network( - cls, - name=None, - description=None, - neutron_net_id=None, - neutron_subnet_id=None, - availability_zone=None, - client=None, - cleanup_in_class=False, - microversion=None, - ): - if client is None: - client = cls.get_admin_client() - share_network = client.create_share_network( - name=name, - description=description, - neutron_net_id=neutron_net_id, - neutron_subnet_id=neutron_subnet_id, - availability_zone=availability_zone, - microversion=microversion, - ) - resource = { - "type": "share_network", - "id": share_network["id"], - "client": client, - "microversion": microversion, - } - if cleanup_in_class: - cls.class_resources.insert(0, resource) - else: - cls.method_resources.insert(0, resource) - return share_network - - @classmethod - def add_share_network_subnet( - cls, - share_network, - neutron_net_id=None, - neutron_subnet_id=None, - availability_zone=None, - client=None, - cleanup_in_class=False, - microversion=None, - ): - if client is None: - client = cls.get_admin_client() - share_network_subnet = client.add_share_network_subnet( - share_network, neutron_net_id, neutron_subnet_id, availability_zone - ) - resource = { - "type": "share_network_subnet", - "id": share_network_subnet["id"], - "client": client, - "deletion_params": { - "share_network": share_network, - }, - "microversion": microversion, - } - if cleanup_in_class: - cls.class_resources.insert(0, resource) - else: - cls.method_resources.insert(0, resource) - return share_network_subnet - - @classmethod - def create_share( - cls, - share_protocol=None, - size=None, - share_network=None, - share_type=None, - name=None, - description=None, - public=False, - snapshot=None, - metadata=None, - client=None, - use_wait_option=False, - cleanup_in_class=False, - wait_for_creation=True, - microversion=None, - ): - client = client or cls.get_admin_client() - data = { - 'share_protocol': share_protocol or client.share_protocol, - 'size': size or 1, - 'name': name, - 'description': description, - 'public': public, - 'snapshot': snapshot, - 'metadata': metadata or {}, - 'microversion': microversion, - 'wait': use_wait_option, - } - - share_type = share_type or CONF.share_type - share_network = share_network or cls._determine_share_network_to_use( - client, share_type, microversion=microversion - ) - - data['share_type'] = share_type - data['share_network'] = share_network - share = client.create_share(**data) - resource = { - "type": "share", - "id": share["id"], - "client": client, - "microversion": microversion, - } - if cleanup_in_class: - cls.class_resources.insert(0, resource) - else: - cls.method_resources.insert(0, resource) - if wait_for_creation and not use_wait_option: - client.wait_for_resource_status( - share['id'], constants.STATUS_AVAILABLE - ) - return share - - @classmethod - def delete_share( - cls, - shares_to_delete, - share_group_id=None, - wait=False, - client=None, - microversion=None, - ): - client = client or cls.get_admin_client() - client.delete_share( - shares_to_delete, - share_group_id=share_group_id, - wait=wait, - microversion=microversion, - ) - - @classmethod - def soft_delete_share( - cls, shares_to_soft_delete, client=None, microversion=None - ): - client = client or cls.get_admin_client() - client.soft_delete_share( - shares_to_soft_delete, microversion=microversion - ) - - @classmethod - def restore_share(cls, shares_to_restore, client=None, microversion=None): - client = client or cls.get_admin_client() - client.restore_share(shares_to_restore, microversion=microversion) - - @classmethod - def create_share_transfer( - cls, share_id, name=None, client=None, microversion=None - ): - client = client or cls.get_admin_client() - return client.create_share_transfer( - share_id, name=name, microversion=microversion - ) - - @classmethod - def delete_share_transfer(cls, transfer, client=None, microversion=None): - client = client or cls.get_admin_client() - client.delete_share_transfer(transfer, microversion=microversion) - - @classmethod - def get_share_transfer(cls, transfer, client=None, microversion=None): - client = client or cls.get_admin_client() - return client.get_share_transfer(transfer, microversion=microversion) - - @classmethod - def list_share_transfer(cls, client=None, microversion=None): - client = client or cls.get_admin_client() - return client.list_share_transfer(microversion=microversion) - - @classmethod - def accept_share_transfer( - cls, transfer, auth_key, client=None, microversion=None - ): - client = client or cls.get_admin_client() - client.accept_share_transfer( - transfer, auth_key, microversion=microversion - ) - - @classmethod - def _determine_share_network_to_use( - cls, client, share_type, microversion=None - ): - """Determine what share network we need from the share type.""" - - # Get share type, determine if we need the share network - share_type = client.get_share_type( - share_type, microversion=microversion - ) - dhss_pattern = re.compile('driver_handles_share_servers : ([a-zA-Z]+)') - dhss = dhss_pattern.search(share_type['required_extra_specs']).group(1) - return client.share_network if dhss.lower() == 'true' else None - - @classmethod - def create_security_service( - cls, - type='ldap', - name=None, - description=None, - dns_ip=None, - ou=None, - server=None, - domain=None, - user=None, - password=None, - default_ad_site=None, - client=None, - cleanup_in_class=False, - microversion=None, - ): - if client is None: - client = cls.get_admin_client() - data = { - 'type': type, - 'name': name, - 'description': description, - 'user': user, - 'password': password, - 'server': server, - 'domain': domain, - 'dns_ip': dns_ip, - 'ou': ou, - 'microversion': microversion, - 'default_ad_site': default_ad_site, - } - ss = client.create_security_service(**data) - resource = { - "type": "share", - "id": ss["id"], - "client": client, - "microversion": microversion, - } - if cleanup_in_class: - cls.class_resources.insert(0, resource) - else: - cls.method_resources.insert(0, resource) - return ss - - @classmethod - def create_snapshot( - cls, - share, - name=None, - description=None, - force=False, - client=None, - wait_for_creation=True, - cleanup_in_class=False, - microversion=None, - ): - if client is None: - client = cls.get_admin_client() - data = { - 'share': share, - 'name': name, - 'description': description, - 'force': force, - 'microversion': microversion, - } - snapshot = client.create_snapshot(**data) - resource = { - "type": "snapshot", - "id": snapshot["id"], - "client": client, - "microversion": microversion, - } - if cleanup_in_class: - cls.class_resources.insert(0, resource) - else: - cls.method_resources.insert(0, resource) - if wait_for_creation: - client.wait_for_snapshot_status(snapshot['id'], 'available') - return snapshot - - @classmethod - def create_message( - cls, - client=None, - wait_for_creation=True, - cleanup_in_class=False, - microversion=None, - ): - """Trigger a 'no valid host' situation to generate a message.""" - if client is None: - client = cls.get_admin_client() - - extra_specs = { - 'vendor_name': 'foobar', - } - share_type_name = data_utils.rand_name("share-type") - cls.create_share_type( - name=share_type_name, - extra_specs=extra_specs, - driver_handles_share_servers=False, - client=client, - cleanup_in_class=cleanup_in_class, - microversion=microversion, - ) - - share_name = data_utils.rand_name("share") - share = cls.create_share( - name=share_name, - share_type=share_type_name, - cleanup_in_class=cleanup_in_class, - microversion=microversion, - wait_for_creation=False, - client=client, - ) - - client.wait_for_resource_status(share['id'], constants.STATUS_ERROR) - message = client.wait_for_message(share['id']) - - resource = { - "type": "message", - "id": message["ID"], - "client": client, - "microversion": microversion, - } - if cleanup_in_class: - cls.class_resources.insert(0, resource) - else: - cls.method_resources.insert(0, resource) - return message - - @classmethod - def create_share_replica( - cls, - share_id, - client=None, - wait_for_creation=True, - cleanup_in_class=False, - availability_zone=None, - share_network=None, - microversion=None, - ): - client = client or cls.get_user_client() - - share_replica = client.create_share_replica( - share_id, - availability_zone=availability_zone, - share_network=share_network, - microversion=microversion, - ) - if wait_for_creation: - share_replica = client.wait_for_share_replica_status( - share_replica['id'] - ) - - resource = { - "type": "share_replica", - "id": share_replica["id"], - "client": client, - "microversion": microversion, - } - if cleanup_in_class: - cls.class_resources.insert(0, resource) - else: - cls.method_resources.insert(0, resource) - return share_replica diff --git a/manilaclient/tests/functional/client.py b/manilaclient/tests/functional/client.py deleted file mode 100644 index da712fb5..00000000 --- a/manilaclient/tests/functional/client.py +++ /dev/null @@ -1,2379 +0,0 @@ -# Copyright 2014 Mirantis Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import ast -import re -import time - -from oslo_utils import strutils -from tempest.lib.cli import base -from tempest.lib.cli import output_parser -from tempest.lib.common.utils import data_utils -from tempest.lib import exceptions as tempest_lib_exc - -from manilaclient.common import constants -from manilaclient import config -from manilaclient.tests.functional import exceptions -from manilaclient.tests.functional import utils - -CONF = config.CONF -MESSAGE = 'message' -SHARE = 'share' -SHARE_TYPE = 'share_type' -SHARE_NETWORK = 'share_network' -SHARE_NETWORK_SUBNET = 'share_network_subnet' -SHARE_SERVER = 'share_server' -SNAPSHOT = 'snapshot' -SHARE_REPLICA = 'share_replica' -TRANSFER = 'transfer' - - -def not_found_wrapper(f): - def wrapped_func(self, *args, **kwargs): - try: - return f(self, *args, **kwargs) - except tempest_lib_exc.CommandFailed as e: - for regexp in ( - r'No (\w+) with a name or ID', - r'not(.*){0,5}found', - ): - if re.search(regexp, str(e.stderr)): - # Raise appropriate 'NotFound' error - raise tempest_lib_exc.NotFound() - raise - - return wrapped_func - - -def forbidden_wrapper(f): - def wrapped_func(self, *args, **kwargs): - try: - return f(self, *args, **kwargs) - except tempest_lib_exc.CommandFailed as e: - if re.search('HTTP 403', str(e.stderr)): - # Raise appropriate 'Forbidden' error. - raise tempest_lib_exc.Forbidden() - raise - - return wrapped_func - - -class ManilaCLIClient(base.CLIClient): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - if CONF.enable_protocols: - self.share_protocol = CONF.enable_protocols[0] - else: - msg = "Configuration option 'enable_protocols' is not defined." - raise exceptions.InvalidConfiguration(reason=msg) - self.build_interval = CONF.build_interval - self.build_timeout = CONF.build_timeout - - def manila( - self, - action, - flags='', - params='', - fail_ok=False, - endpoint_type='publicURL', - merge_stderr=False, - microversion=None, - ): - """Executes manila command for the given action. - - :param action: the cli command to run using manila - :type action: string - :param flags: any optional cli flags to use. For specifying - microversion, please, use 'microversion' param - :type flags: string - :param params: any optional positional args to use - :type params: string - :param fail_ok: if True an exception is not raised when the - cli return code is non-zero - :type fail_ok: boolean - :param endpoint_type: the type of endpoint for the service - :type endpoint_type: string - :param merge_stderr: if True the stderr buffer is merged into stdout - :type merge_stderr: boolean - :param microversion: API microversion to be used for request - :type microversion: str - """ - flags += f' --endpoint-type {endpoint_type}' - if not microversion: - # NOTE(vponomaryov): use max API version from config - microversion = CONF.max_api_microversion - - # NOTE(vponomaryov): it is possible that param 'flags' already - # can contain '--os-share-api-version' key. If it is so and we - # reached this part then value of 'microversion' param will be - # used and existing one in 'flags' param will be ignored. - flags += f' --os-share-api-version {microversion}' - return self.cmd_with_auth( - 'manila', action, flags, params, fail_ok, merge_stderr - ) - - def wait_for_resource_deletion( - self, - res_type, - res_id, - interval=3, - timeout=180, - microversion=None, - **kwargs, - ): - """Resource deletion waiter. - - :param res_type: text -- type of resource - :param res_id: text -- ID of resource to use for deletion check - :param interval: int -- interval between requests in seconds - :param timeout: int -- total time in seconds to wait for deletion - :param args: dict -- additional keyword arguments for deletion func - """ - if res_type == SHARE_TYPE: - func = self.is_share_type_deleted - elif res_type == SHARE_NETWORK: - func = self.is_share_network_deleted - elif res_type == SHARE_NETWORK_SUBNET: - func = self.is_share_network_subnet_deleted - elif res_type == SHARE_SERVER: - func = self.is_share_server_deleted - elif res_type == SHARE: - func = self.is_share_deleted - elif res_type == SNAPSHOT: - func = self.is_snapshot_deleted - elif res_type == MESSAGE: - func = self.is_message_deleted - elif res_type == SHARE_REPLICA: - func = self.is_share_replica_deleted - elif res_type == TRANSFER: - func = self.is_share_transfer_deleted - else: - raise exceptions.InvalidResource(message=res_type) - - end_loop_time = time.time() + timeout - deleted = func(res_id, microversion=microversion, **kwargs) - - while not (deleted or time.time() > end_loop_time): - time.sleep(interval) - deleted = func(res_id, microversion=microversion, **kwargs) - - if not deleted: - raise exceptions.ResourceReleaseFailed( - res_type=res_type, res_id=res_id - ) - - def list_availability_zones(self, columns=None, microversion=None): - """List availability zones. - - :param columns: comma separated string of columns. - Example, "--columns id,name" - :param microversion: API microversion that should be used. - """ - cmd = 'availability-zone-list' - if columns is not None: - cmd += ' --columns ' + columns - azs_raw = self.manila(cmd, microversion=microversion) - azs = output_parser.listing(azs_raw) - return azs - - # Share types - - def create_share_type( - self, - name=None, - driver_handles_share_servers=True, - snapshot_support=None, - create_share_from_snapshot=None, - revert_to_snapshot=None, - mount_snapshot=None, - is_public=True, - microversion=None, - extra_specs=None, - description=None, - ): - """Creates share type. - - :param name: text -- name of share type to use, if not set then - autogenerated will be used - :param description: text -- description of share type to use. - Default is None. - :param driver_handles_share_servers: bool/str -- boolean or its - string alias. Default is True. - :param snapshot_support: bool/str -- boolean or its - string alias. Default is None. - :param is_public: bool/str -- boolean or its string alias. Default is - True. - :param extra_specs: -- dictionary of extra specs Default is None. - :param create_share_from_snapshot: -- boolean or its string - alias. Default is None. - :param revert_to_snapshot: -- boolean or its string alias. Default is - None. - :param mount_snapshot: -- boolean or its string alias. Default is None. - """ - if name is None: - name = data_utils.rand_name('manilaclient_functional_test') - dhss = driver_handles_share_servers - if not isinstance(dhss, str): - dhss = str(dhss) - if not isinstance(is_public, str): - is_public = str(is_public) - - cmd = f'type-create {name} {dhss} --is-public {is_public} ' - - if description is not None: - cmd += " --description " + description - - if snapshot_support is not None: - if not isinstance(snapshot_support, str): - snapshot_support = str(snapshot_support) - cmd += " --snapshot-support " + snapshot_support - - if create_share_from_snapshot is not None: - if not isinstance(create_share_from_snapshot, str): - create_share_from_snapshot = str(create_share_from_snapshot) - cmd += ( - " --create-share-from-snapshot-support " - + create_share_from_snapshot - ) - - if revert_to_snapshot is not None: - if not isinstance(revert_to_snapshot, str): - revert_to_snapshot = str(revert_to_snapshot) - cmd += " --revert-to-snapshot-support " + revert_to_snapshot - - if mount_snapshot is not None: - if not isinstance(mount_snapshot, str): - mount_snapshot = str(mount_snapshot) - cmd += " --mount-snapshot-support " + mount_snapshot - - if extra_specs is not None: - extra_spec_str = '' - for k, v in extra_specs.items(): - if not isinstance(v, str): - extra_specs[k] = str(v) - extra_spec_str += f"{k}='{v}' " - cmd += " --extra_specs " + extra_spec_str - - share_type_raw = self.manila(cmd, microversion=microversion) - share_type = utils.details(share_type_raw) - return share_type - - def update_share_type( - self, - share_type_id, - name=None, - is_public=None, - microversion=None, - description=None, - ): - """Update share type. - - :param share_type_id: text -- id of share type. - :param name: text -- new name of share type, if not set then - it will not be updated. - :param description: text -- new description of share type. - if not set then it will not be updated. - :param is_public: bool/str -- boolean or its string alias. - new visibility of the share type.If set to True, share - type will be available to all tenants in the cloud. - """ - - cmd = f'type-update {share_type_id} ' - - if is_public is not None: - if not isinstance(is_public, str): - is_public = str(is_public) - cmd += " --is_public " + is_public - - if description: - cmd += " --description " + description - elif description == "": - cmd += ' --description "" ' - - if name: - cmd += " --name " + name - - share_type_raw = self.manila(cmd, microversion=microversion) - share_type = utils.details(share_type_raw) - return share_type - - @not_found_wrapper - def delete_share_type(self, share_type, microversion=None): - """Deletes share type by its Name or ID.""" - return self.manila( - f'type-delete {share_type}', microversion=microversion - ) - - def list_share_types( - self, list_all=True, columns=None, search_opts=None, microversion=None - ): - """List share types. - - :param list_all: bool -- whether to list all share types or only public - :param search_opts: dict search_opts for filter search. - :param columns: comma separated string of columns. - Example, "--columns id,name" - """ - cmd = 'type-list' - if list_all: - cmd += ' --all' - if search_opts is not None: - extra_specs = search_opts.get('extra_specs') - if extra_specs: - cmd += ' --extra_specs' - for spec_key in extra_specs.keys(): - cmd += ' ' + spec_key + '=' + extra_specs[spec_key] - if columns is not None: - cmd += ' --columns ' + columns - share_types_raw = self.manila(cmd, microversion=microversion) - share_types = output_parser.listing(share_types_raw) - return share_types - - def get_share_type(self, share_type, microversion=None): - """Get share type. - - :param share_type: str -- Name or ID of share type, or None to - retrieve default share type - """ - share_types = self.list_share_types(True, microversion=microversion) - for stype in share_types: - if share_type is None and stype["is_default"] == 'YES': - return stype - elif share_type in (stype['ID'], stype['Name']): - return stype - raise tempest_lib_exc.NotFound() - - def is_share_type_deleted(self, share_type, microversion=None): - """Says whether share type is deleted or not. - - :param share_type: text -- Name or ID of share type - """ - # NOTE(vponomaryov): we use 'list' operation because there is no - # 'get/show' operation for share-types available for CLI - share_types = self.list_share_types( - list_all=True, microversion=microversion - ) - for list_element in share_types: - if share_type in (list_element['ID'], list_element['Name']): - return False - return True - - def wait_for_share_type_deletion(self, share_type, microversion=None): - """Wait for share type deletion by its Name or ID. - - :param share_type: text -- Name or ID of share type - """ - self.wait_for_resource_deletion( - SHARE_TYPE, - res_id=share_type, - interval=2, - timeout=6, - microversion=microversion, - ) - - def get_project_id(self, name_or_id): - identity_api_version = '3' - flags = ( - f"--os-username {CONF.admin_username} " - f"--os-project-name {CONF.admin_tenant_name} " - f"--os-password {CONF.admin_password} " - f"--os-identity-api-version {identity_api_version} " - ) - - if identity_api_version == "3": - if CONF.admin_project_domain_name: - flags += ( - f"--os-project-domain-name " - f"{CONF.admin_project_domain_name} " - ) - elif CONF.admin_project_domain_id: - flags += ( - f"--os-project-domain-id {CONF.admin_project_domain_id} " - ) - - if CONF.admin_user_domain_name: - flags += ( - f"--os-user-domain-name {CONF.admin_user_domain_name} " - ) - elif CONF.admin_user_domain_id: - flags += f"--os-user-domain-id {CONF.admin_user_domain_id} " - - project_id = self.openstack( - f'project show -f value -c id {name_or_id}', flags=flags - ) - return project_id.strip() - - @not_found_wrapper - def add_share_type_access( - self, share_type_name_or_id, project_id, microversion=None - ): - data = dict(st=share_type_name_or_id, project=project_id) - self.manila( - 'type-access-add {st} {project}'.format(**data), - microversion=microversion, - ) - - @not_found_wrapper - def remove_share_type_access( - self, share_type_name_or_id, project_id, microversion=None - ): - data = dict(st=share_type_name_or_id, project=project_id) - self.manila( - 'type-access-remove {st} {project}'.format(**data), - microversion=microversion, - ) - - @not_found_wrapper - def list_share_type_access(self, share_type_id, microversion=None): - projects_raw = self.manila( - f'type-access-list {share_type_id}', microversion=microversion - ) - projects = output_parser.listing(projects_raw) - project_ids = [pr['Project_ID'] for pr in projects] - return project_ids - - @not_found_wrapper - def set_share_type_extra_specs( - self, share_type_name_or_id, extra_specs, microversion=None - ): - """Set key-value pair for share type.""" - if not (isinstance(extra_specs, dict) and extra_specs): - raise exceptions.InvalidData( - message=f'Provided invalid extra specs - {extra_specs}' - ) - cmd = f'type-key {share_type_name_or_id} set ' - for key, value in extra_specs.items(): - cmd += f'{key}={value} ' - return self.manila(cmd, microversion=microversion) - - @not_found_wrapper - def unset_share_type_extra_specs( - self, share_type_name_or_id, extra_specs_keys, microversion=None - ): - """Unset key-value pair for share type.""" - if not ( - isinstance(extra_specs_keys, (list, tuple, set)) - and extra_specs_keys - ): - raise exceptions.InvalidData( - message=f'Provided invalid extra specs - {extra_specs_keys}' - ) - cmd = f'type-key {share_type_name_or_id} unset ' - for key in extra_specs_keys: - cmd += f'{key} ' - return self.manila(cmd, microversion=microversion) - - def list_all_share_type_extra_specs(self, microversion=None): - """List extra specs for all share types.""" - extra_specs_raw = self.manila( - 'extra-specs-list', microversion=microversion - ) - extra_specs = utils.listing(extra_specs_raw) - return extra_specs - - def list_share_type_extra_specs( - self, share_type_name_or_id, microversion=None - ): - """List extra specs for specific share type by its Name or ID.""" - all_share_types = self.list_all_share_type_extra_specs( - microversion=microversion - ) - for share_type in all_share_types: - if share_type_name_or_id in (share_type['ID'], share_type['Name']): - return share_type['all_extra_specs'] - raise exceptions.ShareTypeNotFound(share_type=share_type_name_or_id) - - # Share networks - - def create_share_network( - self, - name=None, - description=None, - neutron_net_id=None, - neutron_subnet_id=None, - availability_zone=None, - microversion=None, - ): - """Creates share network. - - :param name: text -- desired name of new share network - :param description: text -- desired description of new share network - :param neutron_net_id: text -- ID of Neutron network - :param neutron_subnet_id: text -- ID of Neutron subnet - """ - params = self._combine_share_network_data( - name=name, - description=description, - neutron_net_id=neutron_net_id, - neutron_subnet_id=neutron_subnet_id, - availability_zone=availability_zone, - ) - share_network_raw = self.manila( - f'share-network-create {params}', microversion=microversion - ) - share_network = output_parser.details(share_network_raw) - return share_network - - def _combine_share_network_data( - self, - name=None, - description=None, - neutron_net_id=None, - neutron_subnet_id=None, - availability_zone=None, - ): - """Combines params for share network operations 'create' and 'update'. - - :returns: text -- set of CLI parameters - """ - data = dict() - if name is not None: - data['--name'] = name - if description is not None: - data['--description'] = description - if neutron_net_id is not None: - data['--neutron_net_id'] = neutron_net_id - if neutron_subnet_id is not None: - data['--neutron_subnet_id'] = neutron_subnet_id - if availability_zone is not None: - data['--availability_zone'] = availability_zone - cmd = '' - for key, value in data.items(): - cmd += f"{key}={value} " - return cmd - - @not_found_wrapper - def get_share_network(self, share_network, microversion=None): - """Returns share network by its Name or ID.""" - share_network_raw = self.manila( - f'share-network-show {share_network}', microversion=microversion - ) - share_network = output_parser.details(share_network_raw) - return share_network - - @not_found_wrapper - def update_share_network( - self, - share_network, - name=None, - description=None, - neutron_net_id=None, - neutron_subnet_id=None, - microversion=None, - ): - """Updates share-network by its name or ID. - - :param name: text -- new name for share network - :param description: text -- new description for share network - :param neutron_net_id: text -- ID of some Neutron network - :param neutron_subnet_id: text -- ID of some Neutron subnet - """ - sn_params = self._combine_share_network_data( - name=name, - description=description, - neutron_net_id=neutron_net_id, - neutron_subnet_id=neutron_subnet_id, - ) - share_network_raw = self.manila( - 'share-network-update {sn} {params}'.format( - **dict(sn=share_network, params=sn_params) - ), - microversion=microversion, - ) - share_network = output_parser.details(share_network_raw) - return share_network - - @not_found_wrapper - def delete_share_network(self, share_network, microversion=None): - """Deletes share network by its Name or ID.""" - return self.manila( - f'share-network-delete {share_network}', microversion=microversion - ) - - @staticmethod - def _stranslate_to_cli_optional_param(param): - if len(param) < 1 or not isinstance(param, str): - raise exceptions.InvalidData( - 'Provided wrong parameter for translation.' - ) - while not param[0:2] == '--': - param = '-' + param - return param.replace('_', '-') - - def list_share_networks( - self, all_tenants=False, filters=None, columns=None, microversion=None - ): - """List share networks. - - :param all_tenants: bool -- whether to list share-networks that belong - only to current project or for all tenants. - :param filters: dict -- filters for listing of share networks. - Example, input: - {'project_id': 'foo'} - {'-project_id': 'foo'} - {'--project_id': 'foo'} - {'project-id': 'foo'} - will be transformed to filter parameter "--project-id=foo" - :param columns: comma separated string of columns. - Example, "--columns id" - """ - cmd = 'share-network-list ' - if columns is not None: - cmd += ' --columns ' + columns - if all_tenants: - cmd += ' --all-tenants ' - if filters and isinstance(filters, dict): - for k, v in filters.items(): - cmd += f'{self._stranslate_to_cli_optional_param(k)}={v} ' - share_networks_raw = self.manila(cmd, microversion=microversion) - share_networks = utils.listing(share_networks_raw) - return share_networks - - def share_network_reset_state( - self, id=None, state=None, microversion=None - ): - cmd = f'share-network-reset-state {id} ' - if state: - cmd += f'--state {state}' - share_network_raw = self.manila(cmd, microversion=microversion) - share_network = utils.listing(share_network_raw) - return share_network - - def share_network_security_service_add( - self, share_network_id, security_service_id, microversion=None - ): - cmd = ( - f'share-network-security-service-add {share_network_id} ' - f'{security_service_id}' - ) - self.manila(cmd, microversion=microversion) - - def share_network_security_service_update( - self, - share_network_id, - current_security_service_id, - new_security_service_id, - microversion=None, - ): - cmd = ( - f'share-network-security-service-update {share_network_id} ' - f'{current_security_service_id} {new_security_service_id}' - ) - self.manila(cmd, microversion=microversion) - - def share_network_security_service_add_check( - self, - share_network_id, - security_service_id, - reset=False, - microversion=None, - ): - cmd = ( - f'share-network-security-service-add-check {share_network_id} ' - f'{security_service_id}' - ) - - if reset: - cmd += f'--reset {reset}' - - return output_parser.details( - self.manila(cmd, microversion=microversion) - ) - - def share_network_security_service_update_check( - self, - share_network_id, - current_security_service_id, - new_security_service_id, - reset=False, - microversion=None, - ): - cmd = ( - f'share-network-security-service-update-check {share_network_id} ' - f'{current_security_service_id} {new_security_service_id} ' - ) - - if reset: - cmd += f'--reset {reset}' - - return output_parser.details( - self.manila(cmd, microversion=microversion) - ) - - def share_network_security_service_list( - self, share_network_id, microversion=None - ): - cmd = f'share-network-security-service-list {share_network_id}' - share_networks_raw = self.manila(cmd, microversion=microversion) - network_services = utils.listing(share_networks_raw) - return network_services - - def is_share_network_deleted(self, share_network, microversion=None): - """Says whether share network is deleted or not. - - :param share_network: text -- Name or ID of share network - """ - share_types = self.list_share_networks(True, microversion=microversion) - for list_element in share_types: - if share_network in (list_element['id'], list_element['name']): - return False - return True - - def wait_for_share_network_deletion( - self, share_network, microversion=None - ): - """Wait for share network deletion by its Name or ID. - - :param share_network: text -- Name or ID of share network - """ - self.wait_for_resource_deletion( - SHARE_NETWORK, - res_id=share_network, - interval=2, - timeout=6, - microversion=microversion, - ) - - def share_network_subnet_create_check( - self, - share_network_id, - neutron_net_id=None, - neutron_subnet_id=None, - availability_zone=None, - reset=False, - microversion=None, - ): - params = self._combine_share_network_subnet_data( - neutron_net_id=neutron_net_id, - neutron_subnet_id=neutron_subnet_id, - availability_zone=availability_zone, - ) - cmd = f'share-network-subnet-create-check {share_network_id} {params}' - - if reset: - cmd += f'--reset {reset}' - - return output_parser.details( - self.manila(cmd, microversion=microversion) - ) - - # Share Network Subnets - - def _combine_share_network_subnet_data( - self, - neutron_net_id=None, - neutron_subnet_id=None, - availability_zone=None, - ): - """Combines params for share network subnet 'create' operation. - - :returns: text -- set of CLI parameters - """ - data = dict() - if neutron_net_id is not None: - data['--neutron_net_id'] = neutron_net_id - if neutron_subnet_id is not None: - data['--neutron_subnet_id'] = neutron_subnet_id - if availability_zone is not None: - data['--availability_zone'] = availability_zone - cmd = '' - for key, value in data.items(): - cmd += "{k}={v} ".format(**dict(k=key, v=value)) - return cmd - - def add_share_network_subnet( - self, - share_network, - neutron_net_id=None, - neutron_subnet_id=None, - availability_zone=None, - microversion=None, - ): - """Create new share network subnet for the given share network.""" - params = self._combine_share_network_subnet_data( - neutron_net_id=neutron_net_id, - neutron_subnet_id=neutron_subnet_id, - availability_zone=availability_zone, - ) - share_network_subnet_raw = self.manila( - f'share-network-subnet-create {share_network} {params}', - microversion=microversion, - ) - share_network_subnet = output_parser.details(share_network_subnet_raw) - return share_network_subnet - - def get_share_network_subnet( - self, share_network, share_network_subnet, microversion=None - ): - """Returns share network subnet by share network ID and subnet ID.""" - - share_network_subnet_raw = self.manila( - f'share-network-subnet-show {share_network} {share_network_subnet}' - ) - share_network_subnet = output_parser.details(share_network_subnet_raw) - return share_network_subnet - - def get_share_network_subnets(self, share_network, microversion=None): - share_network = self.get_share_network( - share_network, microversion=microversion - ) - raw_subnets = share_network.get('share_network_subnets') - subnets = ast.literal_eval(raw_subnets) - # NOTE(lseki): convert literal None to string 'None' - for subnet in subnets: - for k, v in subnet.items(): - subnet[k] = str(v) if v is None else v - return subnets - - @not_found_wrapper - def delete_share_network_subnet( - self, share_network, share_network_subnet, microversion=None - ): - """Delete a share_network.""" - self.manila( - f'share-network-subnet-delete {share_network} ' - f'{share_network_subnet}', - microversion=microversion, - ) - - def is_share_network_subnet_deleted( - self, share_network_subnet, share_network, microversion=None - ): - # NOTE(lseki): the parameter share_network_subnet comes before - # share_network, because the wrapper method wait_for_resource_deletion - # expects the resource id in first place (subnet ID in this case). - """Says whether share network subnet is deleted or not. - - :param share_network_subnet: text -- Name or ID of share network subnet - :param share_network: text -- Name or ID of share network the subnet - belongs to - """ - subnets = self.get_share_network_subnets(share_network) - return not any( - subnet['id'] == share_network_subnet for subnet in subnets - ) - - def wait_for_share_network_subnet_deletion( - self, share_network_subnet, share_network, microversion=None - ): - # NOTE(lseki): the parameter share_network_subnet comes before - # share_network, because the wrapper method wait_for_resource_deletion - # expects the resource id in first place (subnet ID in this case). - """Wait for share network subnet deletion by its Name or ID. - - :param share_network_subnet: text -- Name or ID of share network subnet - :param share_network: text -- Name or ID of share network the subnet - belongs to - """ - args = {'share_network': share_network} - self.wait_for_resource_deletion( - SHARE_NETWORK_SUBNET, - res_id=share_network_subnet, - interval=2, - timeout=6, - microversion=microversion, - **args, - ) - - # Shares - - def create_share( - self, - share_protocol, - size, - share_network=None, - share_type=None, - name=None, - description=None, - public=False, - snapshot=None, - metadata=None, - wait=False, - microversion=None, - ): - """Creates a share. - - :param share_protocol: str -- share protocol of a share. - :param size: int/str -- desired size of a share. - :param share_network: str -- Name or ID of share network to use. - :param share_type: str -- Name or ID of share type to use. - :param name: str -- desired name of new share. - :param description: str -- desired description of new share. - :param public: bool -- should a share be public or not. - Default is False. - :param snapshot: str -- Name or ID of a snapshot to use as source. - :param metadata: dict -- key-value data to provide with share creation. - :param wait: bool - the client must wait for "available" state - :param microversion: str -- API microversion that should be used. - """ - cmd = f'create {share_protocol} {size} ' - if share_network is not None: - cmd += f'--share-network {share_network} ' - if share_type is not None: - cmd += f'--share-type {share_type} ' - if name is None: - name = data_utils.rand_name('autotest_share_name') - cmd += f'--name {name} ' - if description is None: - description = data_utils.rand_name('autotest_share_description') - cmd += f'--description {description} ' - if public: - cmd += '--public ' - if snapshot is not None: - cmd += f'--snapshot {snapshot} ' - if metadata: - metadata_cli = '' - for k, v in metadata.items(): - metadata_cli += f'{k}={v} ' - if metadata_cli: - cmd += f'--metadata {metadata_cli} ' - if wait: - cmd += '--wait ' - share_raw = self.manila(cmd, microversion=microversion) - share = output_parser.details(share_raw) - return share - - @not_found_wrapper - def get_share(self, share, microversion=None): - """Returns a share by its Name or ID.""" - share_raw = self.manila(f'show {share}', microversion=microversion) - share = output_parser.details(share_raw) - return share - - @not_found_wrapper - def update_share( - self, - share, - name=None, - description=None, - is_public=False, - microversion=None, - ): - """Updates a share. - - :param share: str -- name or ID of a share that should be updated. - :param name: str -- desired name of new share. - :param description: str -- desired description of new share. - :param is_public: bool -- should a share be public or not. - Default is False. - """ - cmd = f'update {share} ' - if name: - cmd += f'--name {name} ' - if description: - cmd += f'--description {description} ' - is_public = strutils.bool_from_string(is_public, strict=True) - cmd += f'--is-public {is_public} ' - - return self.manila(cmd, microversion=microversion) - - @not_found_wrapper - @forbidden_wrapper - def delete_share( - self, shares, share_group_id=None, wait=False, microversion=None - ): - """Deletes share[s] by Names or IDs. - - :param shares: either str or list of str that can be either Name - or ID of a share(s) that should be deleted. - :param share_group_id: a common share group ID for the shares being - deleted - :param wait: bool -- whether to wait for the shares to be deleted - """ - if not isinstance(shares, list): - shares = [shares] - cmd = 'delete ' - for share in shares: - cmd += f'{share} ' - if share_group_id: - cmd += f'--share-group-id {share_group_id} ' - if wait: - cmd += '--wait ' - return self.manila(cmd, microversion=microversion) - - @not_found_wrapper - @forbidden_wrapper - def soft_delete_share(self, shares, microversion=None): - """Soft Delete share[s] by Names or IDs. - - :param shares: either str or list of str that can be either Name - or ID of a share(s) that should be soft deleted. - """ - if not isinstance(shares, list): - shares = [shares] - cmd = 'soft-delete ' - for share in shares: - cmd += f'{share} ' - return self.manila(cmd, microversion=microversion) - - @not_found_wrapper - @forbidden_wrapper - def restore_share(self, shares, microversion=None): - """Restore share[s] by Names or IDs. - - :param shares: either str or list of str that can be either Name - or ID of a share(s) that should be soft deleted. - """ - if not isinstance(shares, list): - shares = [shares] - cmd = 'restore ' - for share in shares: - cmd += f'{share} ' - return self.manila(cmd, microversion=microversion) - - def create_share_transfer(self, share_id, name=None, microversion=None): - """Create a share transfer. - - :param share_id: ID of share. - ":param name: name of transfer. - """ - cmd = f'share-transfer-create {share_id} ' - if name: - cmd += f'--name {name}' - transfer_raw = self.manila(cmd, microversion=microversion) - transfer = output_parser.details(transfer_raw) - return transfer - - def delete_share_transfer(self, transfer, microversion=None): - """Delete a share transfer. - - :param transfer: ID or name of share transfer. - """ - cmd = f'share-transfer-delete {transfer} ' - self.manila(cmd, microversion=microversion) - - def get_share_transfer(self, transfer, microversion=None): - """Get a share transfer. - - :param transfer: ID or name of share transfer. - """ - cmd = f'share-transfer-show {transfer} ' - transfer_raw = self.manila(cmd, microversion=microversion) - transfer = output_parser.details(transfer_raw) - return transfer - - def list_share_transfer(self, microversion=None): - """Get a share transfer.""" - - cmd = 'share-transfer-list ' - transfer_raw = self.manila(cmd, microversion=microversion) - transfers = utils.listing(transfer_raw) - return transfers - - def accept_share_transfer(self, transfer, auth_key, microversion=None): - """Accept a share transfer. - - :param transfer: ID or name of share transfer. - """ - cmd = f'share-transfer-accept {transfer} {auth_key}' - self.manila(cmd, microversion=microversion) - - def list_shares( - self, - all_tenants=False, - is_soft_deleted=False, - filters=None, - columns=None, - is_public=False, - microversion=None, - ): - """List shares. - - :param all_tenants: bool -- whether to list shares that belong - only to current project or for all tenants. - :param is_soft_deleted: bool -- whether to list shares that has - been soft deleted to recycle bin. - :param filters: dict -- filters for listing of shares. - Example, input: - {'project_id': 'foo'} - {-'project_id': 'foo'} - {--'project_id': 'foo'} - {'project-id': 'foo'} - will be transformed to filter parameter "--project-id=foo" - :param columns: comma separated string of columns. - Example, "--columns Name,Size" - :param is_public: bool -- should list public shares or not. - Default is False. - :param microversion: str -- the request api version. - """ - cmd = 'list ' - if all_tenants: - cmd += '--all-tenants ' - if is_public: - cmd += '--public ' - if is_soft_deleted: - cmd += '--soft-deleted ' - if filters and isinstance(filters, dict): - for k, v in filters.items(): - cmd += f'{self._stranslate_to_cli_optional_param(k)}={v} ' - if columns is not None: - cmd += '--columns ' + columns - shares_raw = self.manila(cmd, microversion=microversion) - shares = utils.listing(shares_raw) - return shares - - def list_share_instances( - self, share_id=None, filters=None, microversion=None - ): - """List share instances. - - :param share_id: ID of a share to filter by. - :param filters: dict -- filters for listing of shares. - Example, input: - {'project_id': 'foo'} - {-'project_id': 'foo'} - {--'project_id': 'foo'} - {'project-id': 'foo'} - will be transformed to filter parameter "--export-location=foo" - :param microversion: API microversion to be used for request. - """ - cmd = 'share-instance-list ' - if share_id: - cmd += f'--share-id {share_id}' - if filters and isinstance(filters, dict): - for k, v in filters.items(): - cmd += f'{self._stranslate_to_cli_optional_param(k)}={v} ' - share_instances_raw = self.manila(cmd, microversion=microversion) - share_instances = utils.listing(share_instances_raw) - return share_instances - - def is_share_deleted(self, share, microversion=None): - """Says whether share is deleted or not. - - :param share: str -- Name or ID of share - """ - try: - self.get_share(share, microversion=microversion) - return False - except tempest_lib_exc.NotFound: - return True - - def wait_for_share_deletion(self, share, microversion=None): - """Wait for share deletion by its Name or ID. - - :param share: str -- Name or ID of share - """ - self.wait_for_resource_deletion( - SHARE, - res_id=share, - interval=5, - timeout=300, - microversion=microversion, - ) - - def is_share_transfer_deleted(self, transfer, microversion=None): - """Says whether transfer is deleted or not. - - :param transfer: str -- Name or ID of transfer - """ - try: - self.get_transfer(transfer, microversion=microversion) - return False - except tempest_lib_exc.NotFound: - return True - - def wait_for_transfer_deletion(self, transfer, microversion=None): - """Wait for transfer deletion by its Name or ID. - - :param transfer: str -- Name or ID of transfer. - """ - self.wait_for_resource_deletion( - SHARE, - res_id=transfer, - interval=5, - timeout=300, - microversion=microversion, - ) - - def wait_for_share_soft_deletion(self, share_id, microversion=None): - body = self.get_share(share_id, microversion=microversion) - is_soft_deleted = body['is_soft_deleted'] - start = int(time.time()) - - while is_soft_deleted == "False": - time.sleep(self.build_interval) - body = self.get_share(share_id, microversion=microversion) - is_soft_deleted = body['is_soft_deleted'] - - if is_soft_deleted == "True": - return - - if int(time.time()) - start >= self.build_timeout: - message = ( - f"Share {share_id} failed to be soft deleted " - f"within the required time {self.build_timeout}." - ) - raise tempest_lib_exc.TimeoutException(message) - - def wait_for_share_restore(self, share_id, microversion=None): - body = self.get_share(share_id, microversion=microversion) - is_soft_deleted = body['is_soft_deleted'] - start = int(time.time()) - - while is_soft_deleted == "True": - time.sleep(self.build_interval) - body = self.get_share(share_id, microversion=microversion) - is_soft_deleted = body['is_soft_deleted'] - - if is_soft_deleted == "False": - return - - if int(time.time()) - start >= self.build_timeout: - message = ( - f"Share {share_id} failed to be restored " - f"within the required time {self.build_timeout}." - ) - raise tempest_lib_exc.TimeoutException(message) - - def wait_for_resource_status( - self, resource_id, status, microversion=None, resource_type="share" - ): - """Waits for a share to reach a given status.""" - get_func = getattr(self, 'get_' + resource_type) - body = get_func(resource_id, microversion=microversion) - share_status = body['status'] - start = int(time.time()) - - while share_status != status: - time.sleep(self.build_interval) - body = get_func(resource_id, microversion=microversion) - share_status = body['status'] - - if share_status == status: - return - elif 'error' in share_status.lower(): - raise exceptions.ShareBuildErrorException(share=resource_id) - - if int(time.time()) - start >= self.build_timeout: - message = ( - f"Resource {resource_id} failed to reach " - f"{status} status within the required time " - f"({self.build_timeout})." - ) - raise tempest_lib_exc.TimeoutException(message) - - def wait_for_migration_task_state( - self, share_id, dest_host, task_state_to_wait, microversion=None - ): - """Waits for a share to migrate to a certain host.""" - statuses = ( - (task_state_to_wait,) - if not isinstance(task_state_to_wait, (tuple, list, set)) - else task_state_to_wait - ) - share = self.get_share(share_id, microversion=microversion) - start = int(time.time()) - while share['task_state'] not in statuses: - time.sleep(self.build_interval) - share = self.get_share(share_id, microversion=microversion) - if share['task_state'] in statuses: - break - elif share['task_state'] == constants.TASK_STATE_MIGRATION_ERROR: - raise exceptions.ShareMigrationException( - share_id=share['id'], src=share['host'], dest=dest_host - ) - elif int(time.time()) - start >= self.build_timeout: - message = ( - 'Share {share_id} failed to reach a status in' - '{status} when migrating from host {src} to ' - 'host {dest} within the required time ' - '{timeout}.'.format( - src=share['host'], - dest=dest_host, - share_id=share['id'], - timeout=self.build_timeout, - status=str(statuses), - ) - ) - raise tempest_lib_exc.TimeoutException(message) - return share - - @not_found_wrapper - def _set_share_metadata( - self, share, data, update_all=False, microversion=None - ): - """Sets a share metadata. - - :param share: str -- Name or ID of a share. - :param data: dict -- key-value pairs to set as metadata. - :param update_all: bool -- if set True then all keys except provided - will be deleted. - """ - if not (isinstance(data, dict) and data): - msg = ( - f'Provided invalid data for setting of share metadata - {data}' - ) - raise exceptions.InvalidData(message=msg) - if update_all: - cmd = f'metadata-update-all {share} ' - else: - cmd = f'metadata {share} set ' - for k, v in data.items(): - cmd += f'{k}={v} ' - return self.manila(cmd, microversion=microversion) - - def update_all_share_metadata(self, share, data, microversion=None): - metadata_raw = self._set_share_metadata( - share, data, True, microversion=microversion - ) - metadata = output_parser.details(metadata_raw) - return metadata - - def set_share_metadata(self, share, data, microversion=None): - return self._set_share_metadata( - share, data, False, microversion=microversion - ) - - @not_found_wrapper - def unset_share_metadata(self, share, keys, microversion=None): - """Unsets some share metadata by keys. - - :param share: str -- Name or ID of a share - :param keys: str/list -- key or list of keys to unset. - """ - if not (isinstance(keys, list) and keys): - msg = ( - 'Provided invalid data for unsetting of share metadata - ' - f'{keys}' - ) - raise exceptions.InvalidData(message=msg) - cmd = f'metadata {share} unset ' - for key in keys: - cmd += f'{key} ' - return self.manila(cmd, microversion=microversion) - - @not_found_wrapper - def get_share_metadata(self, share, microversion=None): - """Returns list of all share metadata. - - :param share: str -- Name or ID of a share. - """ - metadata_raw = self.manila( - f'metadata-show {share}', microversion=microversion - ) - metadata = output_parser.details(metadata_raw) - return metadata - - def create_snapshot( - self, - share, - name=None, - description=None, - force=False, - microversion=None, - ): - """Creates a snapshot.""" - cmd = f'snapshot-create {share} ' - if name is None: - name = data_utils.rand_name('autotest_snapshot_name') - cmd += f'--name {name} ' - if description is None: - description = data_utils.rand_name('autotest_snapshot_description') - cmd += f'--description {description} ' - if force: - cmd += f'--force {force}' - snapshot_raw = self.manila(cmd, microversion=microversion) - snapshot = output_parser.details(snapshot_raw) - return snapshot - - @not_found_wrapper - def get_snapshot(self, snapshot, microversion=None): - """Retrieves a snapshot by its Name or ID.""" - snapshot_raw = self.manila( - f'snapshot-show {snapshot}', microversion=microversion - ) - snapshot = output_parser.details(snapshot_raw) - return snapshot - - @not_found_wrapper - def list_snapshot_export_locations( - self, snapshot, columns=None, microversion=None - ): - """List snapshot export locations. - - :param snapshot: str -- Name or ID of a snapshot. - :param columns: str -- comma separated string of columns. - Example, "--columns uuid,path". - :param microversion: API microversion to be used for request. - """ - cmd = f"snapshot-export-location-list {snapshot}" - if columns is not None: - cmd += " --columns " + columns - export_locations_raw = self.manila(cmd, microversion=microversion) - export_locations = utils.listing(export_locations_raw) - return export_locations - - @not_found_wrapper - @forbidden_wrapper - def list_snapshot_instance_export_locations( - self, snapshot_instance, columns=None, microversion=None - ): - """List snapshot instance export locations. - - :param snapshot_instance: str -- Name or ID of a snapshot instance. - :param columns: str -- comma separated string of columns. - Example, "--columns uuid,path". - :param microversion: API microversion to be used for request. - """ - cmd = f"snapshot-instance-export-location-list {snapshot_instance}" - if columns is not None: - cmd += " --columns " + columns - export_locations_raw = self.manila(cmd, microversion=microversion) - export_locations = utils.listing(export_locations_raw) - return export_locations - - @not_found_wrapper - @forbidden_wrapper - def delete_snapshot(self, snapshot, microversion=None): - """Deletes snapshot by Names or IDs.""" - return self.manila( - f"snapshot-delete {snapshot}", microversion=microversion - ) - - def list_snapshot_instances( - self, snapshot_id=None, columns=None, detailed=None, microversion=None - ): - """List snapshot instances.""" - cmd = 'snapshot-instance-list ' - if snapshot_id: - cmd += f'--snapshot {snapshot_id}' - if columns is not None: - cmd += ' --columns ' + columns - if detailed: - cmd += ' --detailed True ' - snapshot_instances_raw = self.manila(cmd, microversion=microversion) - snapshot_instances = utils.listing(snapshot_instances_raw) - return snapshot_instances - - def get_snapshot_instance(self, id=None, microversion=None): - """Get snapshot instance.""" - cmd = f'snapshot-instance-show {id} ' - snapshot_instance_raw = self.manila(cmd, microversion=microversion) - snapshot_instance = output_parser.details(snapshot_instance_raw) - return snapshot_instance - - def reset_snapshot_instance(self, id=None, state=None, microversion=None): - """Reset snapshot instance status.""" - cmd = f'snapshot-instance-reset-state {id} ' - if state: - cmd += f'--state {state}' - snapshot_instance_raw = self.manila(cmd, microversion=microversion) - snapshot_instance = utils.listing(snapshot_instance_raw) - return snapshot_instance - - def is_snapshot_deleted(self, snapshot, microversion=None): - """Indicates whether snapshot is deleted or not. - - :param snapshot: str -- Name or ID of snapshot - """ - try: - self.get_snapshot(snapshot, microversion=microversion) - return False - except tempest_lib_exc.NotFound: - return True - - def wait_for_snapshot_deletion(self, snapshot, microversion=None): - """Wait for snapshot deletion by its Name or ID. - - :param snapshot: str -- Name or ID of snapshot - """ - self.wait_for_resource_deletion( - SNAPSHOT, - res_id=snapshot, - interval=5, - timeout=300, - microversion=microversion, - ) - - def wait_for_snapshot_status(self, snapshot, status, microversion=None): - """Waits for a snapshot to reach a given status.""" - body = self.get_snapshot(snapshot, microversion=microversion) - snapshot_name = body['name'] - snapshot_status = body['status'] - start = int(time.time()) - - while snapshot_status != status: - time.sleep(self.build_interval) - body = self.get_snapshot(snapshot, microversion=microversion) - snapshot_status = body['status'] - - if snapshot_status == status: - return - elif 'error' in snapshot_status.lower(): - raise exceptions.SnapshotBuildErrorException(snapshot=snapshot) - - if int(time.time()) - start >= self.build_timeout: - message = ( - f"Snapshot {snapshot_name} failed to reach {status} " - f"status within the required time " - f"({self.build_timeout} s)." - ) - raise tempest_lib_exc.TimeoutException(message) - - @not_found_wrapper - def list_access( - self, - entity_id, - columns=None, - microversion=None, - is_snapshot=False, - metadata=None, - ): - """Returns list of access rules for a share. - - :param entity_id: str -- Name or ID of a share or snapshot. - :param columns: comma separated string of columns. - Example, "--columns access_type,access_to" - :param is_snapshot: Boolean value to determine if should list - access of a share or snapshot. - """ - if is_snapshot: - cmd = f'snapshot-access-list {entity_id} ' - else: - cmd = f'access-list {entity_id} ' - if columns is not None: - cmd += ' --columns ' + columns - if metadata: - metadata_cli = '' - for k, v in metadata.items(): - metadata_cli += f'{k}={v} ' - if metadata_cli: - cmd += f' --metadata {metadata_cli} ' - access_list_raw = self.manila(cmd, microversion=microversion) - return output_parser.listing(access_list_raw) - - @not_found_wrapper - def get_access( - self, share_id, access_id, microversion=None, is_snapshot=False - ): - for access in self.list_access( - share_id, microversion=microversion, is_snapshot=is_snapshot - ): - if access['id'] == access_id: - return access - raise tempest_lib_exc.NotFound() - - @not_found_wrapper - def access_show(self, access_id, microversion=None): - raw_access = self.manila( - f"access-show {access_id}", microversion=microversion - ) - return output_parser.details(raw_access) - - @not_found_wrapper - def access_set_metadata(self, access_id, metadata, microversion=None): - if not (isinstance(metadata, dict) and metadata): - msg = ( - 'Provided invalid metadata for setting of access rule' - f' metadata - {metadata}' - ) - raise exceptions.InvalidData(message=msg) - cmd = f"access-metadata {access_id} set " - for k, v in metadata.items(): - cmd += f'{k}={v} ' - return self.manila(cmd, microversion=microversion) - - @not_found_wrapper - def access_unset_metadata(self, access_id, keys, microversion=None): - if not (isinstance(keys, (list, tuple, set)) and keys): - raise exceptions.InvalidData( - message=f'Provided invalid keys - {keys}' - ) - cmd = f'access-metadata {access_id} unset ' - for key in keys: - cmd += f'{key} ' - return self.manila(cmd, microversion=microversion) - - @not_found_wrapper - def snapshot_access_allow( - self, snapshot_id, access_type, access_to, microversion=None - ): - raw_access = self.manila( - f'snapshot-access-allow {snapshot_id} {access_type} {access_to}', - microversion=microversion, - ) - return output_parser.details(raw_access) - - @not_found_wrapper - def snapshot_access_deny(self, snapshot_id, access_id, microversion=None): - return self.manila( - f'snapshot-access-deny {snapshot_id} {access_id}', - microversion=microversion, - ) - - @not_found_wrapper - def access_allow( - self, - share_id, - access_type, - access_to, - access_level, - metadata=None, - microversion=None, - ): - cmd = ( - f'access-allow --access-level {access_level} {share_id} ' - f'{access_type} {access_to}' - ) - if metadata: - metadata_cli = '' - for k, v in metadata.items(): - metadata_cli += f'{k}={v} ' - if metadata_cli: - cmd += f' --metadata {metadata_cli} ' - raw_access = self.manila(cmd, microversion=microversion) - return output_parser.details(raw_access) - - @not_found_wrapper - def access_deny(self, share_id, access_id, microversion=None): - return self.manila( - f'access-deny {share_id} {access_id}', microversion=microversion - ) - - def wait_for_access_rule_status( - self, - share_id, - access_id, - state='active', - microversion=None, - is_snapshot=False, - ): - access = self.get_access( - share_id, - access_id, - microversion=microversion, - is_snapshot=is_snapshot, - ) - - start = int(time.time()) - while access['state'] != state: - time.sleep(self.build_interval) - access = self.get_access( - share_id, - access_id, - microversion=microversion, - is_snapshot=is_snapshot, - ) - - if access['state'] == state: - return - elif access['state'] == 'error': - raise exceptions.AccessRuleCreateErrorException( - access=access_id - ) - - if int(time.time()) - start >= self.build_timeout: - message = ( - f"Access rule {access_id} failed to reach {state} state " - f"within the required time ({self.build_timeout} s)." - ) - raise tempest_lib_exc.TimeoutException(message) - - def wait_for_access_rule_deletion( - self, share_id, access_id, microversion=None, is_snapshot=False - ): - try: - access = self.get_access( - share_id, - access_id, - microversion=microversion, - is_snapshot=is_snapshot, - ) - except tempest_lib_exc.NotFound: - return - - start = int(time.time()) - while True: - time.sleep(self.build_interval) - try: - access = self.get_access( - share_id, - access_id, - microversion=microversion, - is_snapshot=is_snapshot, - ) - except tempest_lib_exc.NotFound: - return - - if access['state'] == 'error': - raise exceptions.AccessRuleDeleteErrorException( - access=access_id - ) - - if int(time.time()) - start >= self.build_timeout: - message = ( - f"Access rule {access_id} failed to reach deleted state " - f"within the required time ({self.build_timeout} s)." - ) - raise tempest_lib_exc.TimeoutException(message) - - def reset_task_state(self, share_id, state, version=None): - state = f'--task_state {state}' if state else '' - return self.manila( - f'reset-task-state {state} {share_id}', microversion=version - ) - - def migration_start( - self, - share_id, - dest_host, - writable, - nondisruptive, - preserve_metadata, - preserve_snapshots, - force_host_assisted_migration, - new_share_network=None, - new_share_type=None, - ): - cmd = ( - f'migration-start {share_id} {dest_host} ' - f'--writable {writable} --nondisruptive {nondisruptive} ' - f'--preserve-metadata {preserve_metadata} ' - f'--preserve-snapshots {preserve_snapshots}' - ) - if force_host_assisted_migration: - cmd += ( - f' --force-host-assisted-migration ' - f'{force_host_assisted_migration}' - ) - if new_share_network: - cmd += f' --new-share-network {new_share_network}' - if new_share_type: - cmd += f' --new-share-type {new_share_type}' - return self.manila(cmd) - - def migration_complete(self, share_id): - return self.manila(f'migration-complete {share_id}') - - def migration_cancel(self, share_id): - return self.manila(f'migration-cancel {share_id}') - - def migration_get_progress(self, share_id): - result = self.manila(f'migration-get-progress {share_id}') - return output_parser.details(result) - - def pool_list(self, detail=False): - cmd = 'pool-list' - if detail: - cmd += ' --column name,host,backend,pool,capabilities' - response = self.manila(cmd) - return output_parser.listing(response) - - def create_security_service( - self, - type='ldap', - name=None, - description=None, - dns_ip=None, - ou=None, - server=None, - domain=None, - user=None, - password=None, - default_ad_site=None, - microversion=None, - ): - """Creates security service. - - :param type: security service type (ldap, kerberos or active_directory) - :param name: desired name of new security service. - :param description: desired description of new security service. - :param dns_ip: DNS IP address inside tenant's network. - :param ou: security service organizational unit - :param server: security service IP address or hostname. - :param domain: security service domain. - :param user: user of the new security service. - :param password: password used by user. - :param default_ad_site: default AD site - """ - - cmd = f'security-service-create {type} ' - cmd += self._combine_security_service_data( - name=name, - description=description, - dns_ip=dns_ip, - ou=ou, - server=server, - domain=domain, - user=user, - password=password, - default_ad_site=default_ad_site, - ) - - ss_raw = self.manila(cmd, microversion=microversion) - security_service = output_parser.details(ss_raw) - return security_service - - @not_found_wrapper - def update_security_service( - self, - security_service, - name=None, - description=None, - dns_ip=None, - ou=None, - server=None, - domain=None, - user=None, - password=None, - default_ad_site=None, - microversion=None, - ): - cmd = f'security-service-update {security_service} ' - cmd += self._combine_security_service_data( - name=name, - description=description, - dns_ip=dns_ip, - ou=ou, - server=server, - domain=domain, - user=user, - password=password, - default_ad_site=default_ad_site, - ) - return output_parser.details( - self.manila(cmd, microversion=microversion) - ) - - def _combine_security_service_data( - self, - name=None, - description=None, - dns_ip=None, - ou=None, - server=None, - domain=None, - user=None, - password=None, - default_ad_site=None, - ): - data = '' - if name is not None: - data += f'--name {name} ' - if description is not None: - data += f'--description {description} ' - if dns_ip is not None: - data += f'--dns-ip {dns_ip} ' - if ou is not None: - data += f'--ou {ou} ' - if server is not None: - data += f'--server {server} ' - if domain is not None: - data += f'--domain {domain} ' - if user is not None: - data += f'--user {user} ' - if password is not None: - data += f'--password {password} ' - if default_ad_site is not None: - data += f'--default-ad-site {default_ad_site} ' - return data - - @not_found_wrapper - def list_share_export_locations( - self, share, columns=None, microversion=None - ): - """List share export locations. - - :param share: str -- Name or ID of a share. - :param columns: str -- comma separated string of columns. - Example, "--columns uuid,path". - :param microversion: API microversion to be used for request. - """ - cmd = f"share-export-location-list {share}" - if columns is not None: - cmd += " --columns " + columns - export_locations_raw = self.manila(cmd, microversion=microversion) - export_locations = utils.listing(export_locations_raw) - return export_locations - - @not_found_wrapper - def get_snapshot_export_location( - self, snapshot, export_location_uuid, microversion=None - ): - """Returns an export location by snapshot and its UUID. - - :param snapshot: str -- Name or ID of a snapshot. - :param export_location_uuid: str -- UUID of an export location. - :param microversion: API microversion to be used for request. - """ - snapshot_raw = self.manila( - f'snapshot-export-location-show {snapshot} {export_location_uuid}', - microversion=microversion, - ) - snapshot = output_parser.details(snapshot_raw) - return snapshot - - @not_found_wrapper - def get_snapshot_instance_export_location( - self, snapshot, export_location_uuid, microversion=None - ): - """Returns an export location by snapshot instance and its UUID. - - :param snapshot: str -- Name or ID of a snapshot instance. - :param export_location_uuid: str -- UUID of an export location. - :param microversion: API microversion to be used for request. - """ - snapshot_raw = self.manila( - f'snapshot-instance-export-location-show {snapshot} ' - f'{export_location_uuid}', - microversion=microversion, - ) - snapshot = output_parser.details(snapshot_raw) - return snapshot - - @not_found_wrapper - def get_share_export_location( - self, share, export_location_uuid, microversion=None - ): - """Returns an export location by share and its UUID. - - :param share: str -- Name or ID of a share. - :param export_location_uuid: str -- UUID of an export location. - :param microversion: API microversion to be used for request. - """ - share_raw = self.manila( - f'share-export-location-show {share} {export_location_uuid}', - microversion=microversion, - ) - share = output_parser.details(share_raw) - return share - - @not_found_wrapper - @forbidden_wrapper - def list_share_instance_export_locations( - self, share_instance, columns=None, microversion=None - ): - """List share instance export locations. - - :param share_instance: str -- Name or ID of a share instance. - :param columns: str -- comma separated string of columns. - Example, "--columns uuid,path". - :param microversion: API microversion to be used for request. - """ - cmd = f"share-instance-export-location-list {share_instance}" - if columns is not None: - cmd += " --columns " + columns - export_locations_raw = self.manila(cmd, microversion=microversion) - export_locations = utils.listing(export_locations_raw) - return export_locations - - @not_found_wrapper - @forbidden_wrapper - def get_share_instance_export_location( - self, share_instance, export_location_uuid, microversion=None - ): - """Returns an export location by share instance and its UUID. - - :param share_instance: str -- Name or ID of a share instance. - :param export_location_uuid: str -- UUID of an export location. - :param microversion: API microversion to be used for request. - """ - share_raw = self.manila( - 'share-instance-export-location-show ' - f'{share_instance} {export_location_uuid}', - microversion=microversion, - ) - share = output_parser.details(share_raw) - return share - - # Share servers - - @not_found_wrapper - def get_share_server(self, share_server, microversion=None): - """Returns share server by its Name or ID.""" - share_server_raw = self.manila( - f'share-server-show {share_server}', microversion=microversion - ) - share_server = output_parser.details(share_server_raw) - return share_server - - def list_share_servers( - self, filters=None, columns=None, microversion=None - ): - """List share servers. - - :param filters: dict -- filters for listing of share servers. - Example, input: - {'project_id': 'foo'} - {'-project_id': 'foo'} - {'--project_id': 'foo'} - {'project-id': 'foo'} - will be transformed to filter parameter "--project-id=foo" - :param columns: comma separated string of columns. - Example, "--columns id" - """ - cmd = 'share-server-list ' - if columns is not None: - cmd += ' --columns ' + columns - if filters and isinstance(filters, dict): - for k, v in filters.items(): - cmd += f'{self._stranslate_to_cli_optional_param(k)}={v} ' - share_servers_raw = self.manila(cmd, microversion=microversion) - share_servers = utils.listing(share_servers_raw) - return share_servers - - @not_found_wrapper - def delete_share_server(self, share_server, microversion=None): - """Deletes share server by its Name or ID.""" - return self.manila( - f'share-server-delete {share_server}', microversion=microversion - ) - - def is_share_server_deleted(self, share_server_id, microversion=None): - """Says whether share server is deleted or not. - - :param share_server: text -- ID of the share server - """ - servers = self.list_share_servers(microversion=microversion) - for list_element in servers: - if share_server_id == list_element['Id']: - return False - return True - - def wait_for_share_server_deletion(self, share_server, microversion=None): - """Wait for share server deletion by its Name or ID. - - :param share_server: text -- Name or ID of share server - """ - self.wait_for_resource_deletion( - SHARE_SERVER, - res_id=share_server, - interval=3, - timeout=60, - microversion=microversion, - ) - - def unmanage_share(self, server_id): - return self.manila(f'unmanage {server_id} ') - - def unmanage_server(self, share_server_id): - return self.manila(f'share-server-unmanage {share_server_id} ') - - def share_server_manage( - self, host, share_network, identifier, driver_options=None - ): - if driver_options: - command = ( - f'share-server-manage {host} {share_network} {identifier} ' - f'{driver_options}' - ) - else: - command = ( - f'share-server-manage {host} {share_network} {identifier}' - ) - managed_share_server_raw = self.manila(command) - managed_share_server = output_parser.details(managed_share_server_raw) - return managed_share_server['id'] - - def manage_share(self, host, protocol, export_location, share_server): - managed_share_raw = self.manila( - f'manage {host} {protocol} {export_location} ' - f'--share-server-id {share_server}' - ) - managed_share = output_parser.details(managed_share_raw) - return managed_share['id'] - - def share_server_migration_check( - self, - server_id, - dest_host, - writable, - nondisruptive, - preserve_snapshots, - new_share_network=None, - ): - cmd = ( - f'share-server-migration-check {server_id} {dest_host} ' - f'--writable {writable} --nondisruptive {nondisruptive} ' - f'--preserve-snapshots {preserve_snapshots}' - ) - if new_share_network: - cmd += f' --new-share-network {new_share_network}' - result = self.manila(cmd) - return output_parser.details(result) - - def share_server_migration_start( - self, - server_id, - dest_host, - writable=False, - nondisruptive=False, - preserve_snapshots=False, - new_share_network=None, - ): - cmd = ( - f'share-server-migration-start {server_id} {dest_host} ' - f'--writable {writable} --nondisruptive {nondisruptive} ' - f'--preserve-snapshots {preserve_snapshots}' - ) - if new_share_network: - cmd += f' --new-share-network {new_share_network}' - return self.manila(cmd) - - def share_server_migration_complete(self, server_id): - return self.manila(f'share-server-migration-complete {server_id}') - - def share_server_migration_cancel(self, server_id): - return self.manila(f'share-server-migration-cancel {server_id}') - - def share_server_migration_get_progress(self, server_id): - result = self.manila( - f'share-server-migration-get-progress {server_id}' - ) - return output_parser.details(result) - - def wait_for_server_migration_task_state( - self, share_server_id, dest_host, task_state_to_wait, microversion=None - ): - """Waits for a certain server task state.""" - statuses = ( - (task_state_to_wait,) - if not isinstance(task_state_to_wait, (tuple, list, set)) - else task_state_to_wait - ) - server = self.get_share_server( - share_server=share_server_id, microversion=microversion - ) - start = int(time.time()) - while server['task_state'] not in statuses: - time.sleep(self.build_interval) - server = self.get_share_server( - share_server=share_server_id, microversion=microversion - ) - if server['task_state'] in statuses: - return server - elif server['task_state'] == constants.TASK_STATE_MIGRATION_ERROR: - raise exceptions.ShareServerMigrationException( - server_id=server['id'] - ) - elif int(time.time()) - start >= self.build_timeout: - message = ( - 'Server {share_server_id} failed to reach the ' - 'status in {status} while migrating from host ' - '{src} to host {dest} within the required time ' - '{timeout}.'.format( - src=server['host'], - dest=dest_host, - share_server_id=server['id'], - timeout=self.build_timeout, - status=str(statuses), - ) - ) - raise tempest_lib_exc.TimeoutException(message) - - # user messages - - def wait_for_message(self, resource_id): - """Waits until a message for a resource with given id exists""" - start = int(time.time()) - message = None - - while not message: - time.sleep(self.build_interval) - for msg in self.list_messages(): - if msg['Resource ID'] == resource_id: - return msg - - if int(time.time()) - start >= self.build_timeout: - message = ( - f'No message for resource with id {resource_id} was ' - f'created in the required time ({self.build_timeout} s).' - ) - raise tempest_lib_exc.TimeoutException(message) - - def list_messages(self, columns=None, microversion=None): - """List messages. - - :param columns: str -- comma separated string of columns. - Example, "--columns id,resource_id". - :param microversion: API microversion to be used for request. - """ - cmd = "message-list" - if columns is not None: - cmd += " --columns " + columns - messages_raw = self.manila(cmd, microversion=microversion) - messages = utils.listing(messages_raw) - return messages - - @not_found_wrapper - def get_message(self, message, microversion=None): - """Returns share server by its Name or ID.""" - message_raw = self.manila( - f'message-show {message}', microversion=microversion - ) - message = output_parser.details(message_raw) - return message - - @not_found_wrapper - def delete_message(self, message, microversion=None): - """Deletes message by its ID.""" - return self.manila( - f'message-delete {message}', microversion=microversion - ) - - def is_message_deleted(self, message, microversion=None): - """Indicates whether message is deleted or not. - - :param message: str -- ID of message - """ - try: - self.get_message(message, microversion=microversion) - return False - except tempest_lib_exc.NotFound: - return True - - def wait_for_message_deletion(self, message, microversion=None): - """Wait for message deletion by its ID. - - :param message: text -- ID of message - """ - self.wait_for_resource_deletion( - MESSAGE, - res_id=message, - interval=3, - timeout=60, - microversion=microversion, - ) - - # Share replicas - - def create_share_replica( - self, - share, - availability_zone=None, - share_network=None, - microversion=None, - ): - """Create a share replica. - - :param share: str -- Name or ID of a share to create a replica of - """ - cmd = f"share-replica-create {share}" - if availability_zone is not None: - cmd += " --availability_zone " + availability_zone - if share_network is not None: - cmd += " --share_network " + share_network - - replica = self.manila(cmd, microversion=microversion) - return output_parser.details(replica) - - @not_found_wrapper - def get_share_replica(self, replica, microversion=None): - cmd = f"share-replica-show {replica}" - replica = self.manila(cmd, microversion=microversion) - return output_parser.details(replica) - - @not_found_wrapper - @forbidden_wrapper - def delete_share_replica(self, share_replica, microversion=None): - """Deletes share replica by ID.""" - return self.manila( - f"share-replica-delete {share_replica}", microversion=microversion - ) - - def is_share_replica_deleted(self, replica, microversion=None): - """Indicates whether a share replica is deleted or not. - - :param replica: str -- ID of share replica - """ - try: - self.get_share_replica(replica, microversion=microversion) - return False - except tempest_lib_exc.NotFound: - return True - - def wait_for_share_replica_deletion(self, replica, microversion=None): - """Wait for share replica deletion by its ID. - - :param replica: text -- ID of share replica - """ - self.wait_for_resource_deletion( - SHARE_REPLICA, - res_id=replica, - interval=3, - timeout=60, - microversion=microversion, - ) - - def wait_for_share_replica_status( - self, share_replica, status="available", microversion=None - ): - """Waits for a share replica to reach a given status.""" - replica = self.get_share_replica( - share_replica, microversion=microversion - ) - share_replica_status = replica['status'] - start = int(time.time()) - - while share_replica_status != status: - time.sleep(self.build_interval) - replica = self.get_share_replica( - share_replica, microversion=microversion - ) - share_replica_status = replica['status'] - - if share_replica_status == status: - return replica - elif 'error' in share_replica_status.lower(): - raise exceptions.ShareReplicaBuildErrorException( - replica=share_replica - ) - - if int(time.time()) - start >= self.build_timeout: - message = ( - f"Share replica {share_replica} failed to reach {status} " - "status within the required time " - f"({self.build_timeout} s)." - ) - raise tempest_lib_exc.TimeoutException(message) - return replica - - @not_found_wrapper - @forbidden_wrapper - def list_share_replica_export_locations( - self, share_replica, columns=None, microversion=None - ): - """List share replica export locations. - - :param share_replica: str -- ID of share replica. - :param columns: str -- comma separated string of columns. - Example, "--columns id,path". - :param microversion: API microversion to be used for request. - """ - cmd = f"share-replica-export-location-list {share_replica}" - if columns is not None: - cmd += " --columns " + columns - export_locations_raw = self.manila(cmd, microversion=microversion) - export_locations = utils.listing(export_locations_raw) - return export_locations - - @not_found_wrapper - @forbidden_wrapper - def get_share_replica_export_location( - self, share_replica, export_location_uuid, microversion=None - ): - """Returns an export location by share replica and export location ID. - - :param share_replica: str -- ID of share replica. - :param export_location_uuid: str -- UUID of an export location. - :param microversion: API microversion to be used for request. - """ - export_raw = self.manila( - 'share-replica-export-location-show ' - f'{share_replica} {export_location_uuid}', - microversion=microversion, - ) - export = output_parser.details(export_raw) - return export diff --git a/manilaclient/tests/functional/test_availability_zones.py b/manilaclient/tests/functional/test_availability_zones.py deleted file mode 100644 index 425c0afc..00000000 --- a/manilaclient/tests/functional/test_availability_zones.py +++ /dev/null @@ -1,59 +0,0 @@ -# Copyright 2016 Mirantis Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import ddt -from oslo_utils import uuidutils - -from manilaclient.tests.functional import base - - -@ddt.ddt -class ManilaClientTestAvailabilityZonesReadOnly(base.BaseTestCase): - @ddt.data("2.6", "2.7", "2.22") - def test_availability_zone_list(self, microversion): - self.skip_if_microversion_not_supported(microversion) - - azs = self.user_client.list_availability_zones( - microversion=microversion - ) - - for az in azs: - self.assertEqual(4, len(az)) - for key in ('Id', 'Name', 'Created_At', 'Updated_At'): - self.assertIn(key, az) - self.assertTrue(uuidutils.is_uuid_like(az['Id'])) - self.assertIsNotNone(az['Name']) - self.assertIsNotNone(az['Created_At']) - - @ddt.data( - ('name', ['Name']), - ('name,id', ['Name', 'Id']), - ('name,created_at', ['Name', 'Created_At']), - ('name,id,created_at', ['Name', 'Id', 'Created_At']), - ) - @ddt.unpack - def test_availability_zone_list_with_columns(self, columns_arg, expected): - azs = self.user_client.list_availability_zones(columns=columns_arg) - - for az in azs: - self.assertEqual(len(expected), len(az)) - for key in expected: - self.assertIn(key, az) - if 'Id' in expected: - self.assertTrue(uuidutils.is_uuid_like(az['Id'])) - if 'Name' in expected: - self.assertIsNotNone(az['Name']) - if 'Created_At' in expected: - self.assertIsNotNone(az['Created_At']) diff --git a/manilaclient/tests/functional/test_common.py b/manilaclient/tests/functional/test_common.py deleted file mode 100644 index ac274514..00000000 --- a/manilaclient/tests/functional/test_common.py +++ /dev/null @@ -1,73 +0,0 @@ -# Copyright 2015 Mirantis Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import re - -import ddt - -from manilaclient.tests.functional import base - - -@ddt.ddt -class ManilaClientTestCommonReadOnly(base.BaseTestCase): - @ddt.data('admin', 'user') - def test_manila_version(self, role): - self.clients[role].manila('', flags='--version') - - @ddt.data('admin', 'user') - def test_help(self, role): - help_text = self.clients[role].manila('help') - lines = help_text.split('\n') - self.assertFirstLineStartsWith(lines, 'usage: manila') - - commands = [] - cmds_start = lines.index('Positional arguments:') - cmds_end = lines.index('Options:') - command_pattern = re.compile(r'^ {4}([a-z0-9\-\_]+)') - for line in lines[cmds_start:cmds_end]: - match = command_pattern.match(line) - if match: - commands.append(match.group(1)) - commands = set(commands) - wanted_commands = set( - ( - 'absolute-limits', - 'list', - 'help', - 'quota-show', - 'access-list', - 'snapshot-list', - 'access-allow', - 'access-deny', - 'share-network-list', - 'security-service-list', - ) - ) - self.assertFalse(wanted_commands - commands) - - @ddt.data('admin', 'user') - def test_credentials(self, role): - self.clients[role].manila('credentials') - - @ddt.data('admin', 'user') - def test_list_extensions(self, role): - roles = self.parser.listing( - self.clients[role].manila('list-extensions') - ) - self.assertTableStruct(roles, ['Name', 'Summary', 'Alias', 'Updated']) - - @ddt.data('admin', 'user') - def test_endpoints(self, role): - self.clients[role].manila('endpoints') diff --git a/manilaclient/tests/functional/test_export_locations.py b/manilaclient/tests/functional/test_export_locations.py deleted file mode 100644 index 0bf6e0ae..00000000 --- a/manilaclient/tests/functional/test_export_locations.py +++ /dev/null @@ -1,173 +0,0 @@ -# Copyright 2015 Mirantis Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import ddt -from oslo_utils import uuidutils - -from manilaclient.tests.functional import base - - -@ddt.ddt -class ExportLocationReadWriteTest(base.BaseTestCase): - def setUp(self): - super().setUp() - self.share = self.create_share(client=self.get_user_client()) - - @ddt.data('admin', 'user') - def test_list_share_export_locations(self, role): - self.skip_if_microversion_not_supported('2.14') - - client = self.admin_client if role == 'admin' else self.user_client - export_locations = client.list_share_export_locations(self.share['id']) - - self.assertGreater(len(export_locations), 0) - expected_keys = ('ID', 'Path', 'Preferred') - for el in export_locations: - for key in expected_keys: - self.assertIn(key, el) - self.assertTrue(uuidutils.is_uuid_like(el['ID'])) - self.assertIn(el['Preferred'], ('True', 'False')) - - @ddt.data('admin', 'user') - def test_list_share_export_locations_with_columns(self, role): - self.skip_if_microversion_not_supported('2.9') - - client = self.admin_client if role == 'admin' else self.user_client - export_locations = client.list_share_export_locations( - self.share['id'], columns='id,path' - ) - - self.assertGreater(len(export_locations), 0) - expected_keys = ('Id', 'Path') - unexpected_keys = ('Updated At', 'Created At') - for el in export_locations: - for key in expected_keys: - self.assertIn(key, el) - for key in unexpected_keys: - self.assertNotIn(key, el) - self.assertTrue(uuidutils.is_uuid_like(el['Id'])) - - @ddt.data('admin', 'user') - def test_get_share_export_location(self, role): - self.skip_if_microversion_not_supported('2.14') - - client = self.admin_client if role == 'admin' else self.user_client - export_locations = client.list_share_export_locations(self.share['id']) - - el = client.get_share_export_location( - self.share['id'], export_locations[0]['ID'] - ) - - expected_keys = ['path', 'updated_at', 'created_at', 'id', 'preferred'] - if role == 'admin': - expected_keys.extend(['is_admin_only', 'share_instance_id']) - for key in expected_keys: - self.assertIn(key, el) - if role == 'admin': - self.assertTrue(uuidutils.is_uuid_like(el['share_instance_id'])) - self.assertIn(el['is_admin_only'], ('True', 'False')) - self.assertTrue(uuidutils.is_uuid_like(el['id'])) - self.assertIn(el['preferred'], ('True', 'False')) - for list_k, get_k in ( - ('ID', 'id'), - ('Path', 'path'), - ('Preferred', 'preferred'), - ): - self.assertEqual(export_locations[0][list_k], el[get_k]) - - def test_list_share_instance_export_locations(self): - self.skip_if_microversion_not_supported('2.14') - - client = self.admin_client - share_instances = client.list_share_instances(self.share['id']) - self.assertGreater(len(share_instances), 0) - self.assertIn('ID', share_instances[0]) - self.assertTrue(uuidutils.is_uuid_like(share_instances[0]['ID'])) - share_instance_id = share_instances[0]['ID'] - - export_locations = client.list_share_instance_export_locations( - share_instance_id - ) - - self.assertGreater(len(export_locations), 0) - expected_keys = ('ID', 'Path', 'Is Admin only', 'Preferred') - for el in export_locations: - for key in expected_keys: - self.assertIn(key, el) - self.assertTrue(uuidutils.is_uuid_like(el['ID'])) - - def test_list_share_instance_export_locations_with_columns(self): - self.skip_if_microversion_not_supported('2.9') - - client = self.admin_client - share_instances = client.list_share_instances(self.share['id']) - self.assertGreater(len(share_instances), 0) - self.assertIn('ID', share_instances[0]) - self.assertTrue(uuidutils.is_uuid_like(share_instances[0]['ID'])) - share_instance_id = share_instances[0]['ID'] - - export_locations = client.list_share_instance_export_locations( - share_instance_id, columns='id,path' - ) - - self.assertGreater(len(export_locations), 0) - expected_keys = ('Id', 'Path') - unexpected_keys = ('Updated At', 'Created At', 'Is Admin only') - for el in export_locations: - for key in expected_keys: - self.assertIn(key, el) - for key in unexpected_keys: - self.assertNotIn(key, el) - self.assertTrue(uuidutils.is_uuid_like(el['Id'])) - - def test_get_share_instance_export_location(self): - self.skip_if_microversion_not_supported('2.14') - - client = self.admin_client - share_instances = client.list_share_instances(self.share['id']) - self.assertGreater(len(share_instances), 0) - self.assertIn('ID', share_instances[0]) - self.assertTrue(uuidutils.is_uuid_like(share_instances[0]['ID'])) - share_instance_id = share_instances[0]['ID'] - - export_locations = client.list_share_instance_export_locations( - share_instance_id - ) - - el = client.get_share_instance_export_location( - share_instance_id, export_locations[0]['ID'] - ) - - expected_keys = ( - 'path', - 'updated_at', - 'created_at', - 'id', - 'preferred', - 'is_admin_only', - 'share_instance_id', - ) - for key in expected_keys: - self.assertIn(key, el) - self.assertIn(el['is_admin_only'], ('True', 'False')) - self.assertIn(el['preferred'], ('True', 'False')) - self.assertTrue(uuidutils.is_uuid_like(el['id'])) - for list_k, get_k in ( - ('ID', 'id'), - ('Path', 'path'), - ('Preferred', 'preferred'), - ('Is Admin only', 'is_admin_only'), - ): - self.assertEqual(export_locations[0][list_k], el[get_k]) diff --git a/manilaclient/tests/functional/test_limits.py b/manilaclient/tests/functional/test_limits.py deleted file mode 100644 index 8d79cb6b..00000000 --- a/manilaclient/tests/functional/test_limits.py +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright 2015 Mirantis Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import ddt - -from manilaclient.tests.functional import base - - -@ddt.ddt -class ManilaClientTestLimitsReadOnly(base.BaseTestCase): - @ddt.data('admin', 'user') - def test_rate_limits(self, role): - self.clients[role].manila('rate-limits') - - @ddt.data('admin', 'user') - def test_absolute_limits(self, role): - self.clients[role].manila('absolute-limits') diff --git a/manilaclient/tests/functional/test_messages.py b/manilaclient/tests/functional/test_messages.py deleted file mode 100644 index dd06c524..00000000 --- a/manilaclient/tests/functional/test_messages.py +++ /dev/null @@ -1,80 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import ddt - -from manilaclient.tests.functional import base - - -@ddt.ddt -class MessagesReadOnlyTest(base.BaseTestCase): - @ddt.data( - ("admin", "2.37"), - ("user", "2.37"), - ) - @ddt.unpack - def test_message_list(self, role, microversion): - self.skip_if_microversion_not_supported(microversion) - self.clients[role].manila("message-list", microversion=microversion) - - -@ddt.ddt -class MessagesReadWriteTest(base.BaseTestCase): - def setUp(self): - super().setUp() - self.message = self.create_message() - - def test_list_messages(self): - self.skip_if_microversion_not_supported('2.37') - messages = self.admin_client.list_messages() - self.assertTrue(any(m['ID'] is not None for m in messages)) - self.assertTrue(any(m['User Message'] is not None for m in messages)) - self.assertTrue(any(m['Resource ID'] is not None for m in messages)) - self.assertTrue(any(m['Action ID'] is not None for m in messages)) - self.assertTrue(any(m['Detail ID'] is not None for m in messages)) - self.assertTrue(any(m['Resource Type'] is not None for m in messages)) - - @ddt.data( - 'id', - 'action_id', - 'resource_id', - 'action_id', - 'detail_id', - 'resource_type', - 'created_at', - 'action_id,detail_id,resource_id', - ) - def test_list_share_type_select_column(self, columns): - self.skip_if_microversion_not_supported('2.37') - self.admin_client.list_messages(columns=columns) - - def test_get_message(self): - self.skip_if_microversion_not_supported('2.37') - message = self.admin_client.get_message(self.message['ID']) - expected_keys = ( - 'id', - 'action_id', - 'resource_id', - 'action_id', - 'detail_id', - 'resource_type', - 'created_at', - 'created_at', - ) - for key in expected_keys: - self.assertIn(key, message) - - def test_delete_message(self): - self.skip_if_microversion_not_supported('2.37') - message = self.create_message(cleanup_in_class=False) - self.admin_client.delete_message(message['ID']) - self.admin_client.wait_for_message_deletion(message['ID']) diff --git a/manilaclient/tests/functional/test_quotas.py b/manilaclient/tests/functional/test_quotas.py deleted file mode 100644 index ed5663c4..00000000 --- a/manilaclient/tests/functional/test_quotas.py +++ /dev/null @@ -1,395 +0,0 @@ -# Copyright 2015 Mirantis Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from random import randint - -import ddt -from tempest.lib.cli import output_parser -from tempest.lib.common.utils import data_utils -from tempest.lib import exceptions - -from manilaclient import api_versions -from manilaclient.tests.functional import base -from manilaclient.tests.functional import utils - -REPLICA_QUOTAS_MICROVERSION = '2.53' - - -def _get_share_type_quota_values(project_quota_value): - project_quota_value = int(project_quota_value) - if project_quota_value == -1: - return randint(1, 999) - elif project_quota_value == 0: - return 0 - else: - return project_quota_value - 1 - - -@ddt.ddt -@utils.skip_if_microversion_not_supported("2.39") -class QuotasReadWriteTest(base.BaseTestCase): - def setUp(self): - super(self.__class__, self).setUp() - self.microversion = "2.39" - self.project_id = self.admin_client.get_project_id( - self.admin_client.tenant_name - ) - - # Create share type - self.share_type = self.create_share_type( - name=data_utils.rand_name("manilaclient_functional_test"), - driver_handles_share_servers=False, - is_public=True, - microversion=self.microversion, - ) - self.st_id = self.share_type["ID"] - - def _verify_current_st_quotas_equal_to(self, quotas, microversion): - # Read share type quotas - cmd = ( - f'quota-show --tenant-id {self.project_id} ' - f'--share-type {self.st_id}' - ) - st_quotas_raw = self.admin_client.manila( - cmd, microversion=microversion - ) - st_quotas = output_parser.details(st_quotas_raw) - - # Verify that quotas - self.assertGreater(len(st_quotas), 3) - for key, value in st_quotas.items(): - if key not in ( - 'shares', - 'gigabytes', - 'snapshots', - 'snapshot_gigabytes', - ): - continue - self.assertIn(key, quotas) - self.assertEqual(int(quotas[key]), int(value)) - - def _verify_current_quotas_equal_to(self, quotas, microversion): - # Read quotas - cmd = f'quota-show --tenant-id {self.project_id}' - quotas_raw = self.admin_client.manila(cmd, microversion=microversion) - quotas = output_parser.details(quotas_raw) - - # Verify that quotas - self.assertGreater(len(quotas), 3) - for key, value in quotas.items(): - if key not in ( - 'shares', - 'gigabytes', - 'snapshots', - 'snapshot_gigabytes', - 'share_groups', - 'share_group_snapshots', - ): - continue - self.assertIn(key, quotas) - self.assertEqual(int(quotas[key]), int(value)) - - @ddt.data( - *set( - [ - "2.40", - api_versions.MAX_VERSION, - ] - ) - ) - def test_update_quotas_for_share_groups(self, microversion): - if not utils.is_microversion_supported(microversion): - msg = f"Microversion '{microversion}' not supported." - raise self.skipException(msg) - - # Get default quotas - cmd = 'quota-defaults' - quotas_raw = self.admin_client.manila(cmd, microversion=microversion) - default_quotas = output_parser.details(quotas_raw) - - # Get project quotas - cmd = f'quota-show --tenant-id {self.project_id} ' - quotas_raw = self.admin_client.manila(cmd, microversion=microversion) - p_quotas = output_parser.details(quotas_raw) - - # Define custom share group quotas for project - p_custom_quotas = { - 'share_groups': -1 if int(p_quotas['share_groups']) != -1 else 999, - 'share_group_snapshots': -1 - if int(p_quotas['share_group_snapshots']) != -1 - else 999, - } - - # Update share group quotas for project - cmd = ( - 'quota-update {} --share-groups {} --share-group-snapshots {}' - ).format( - self.project_id, - p_custom_quotas['share_groups'], - p_custom_quotas['share_group_snapshots'], - ) - self.admin_client.manila(cmd, microversion=microversion) - - # Verify quotas - self._verify_current_quotas_equal_to(p_custom_quotas, microversion) - - # Reset quotas - cmd = ( - f'quota-delete --tenant-id {self.project_id} ' - f'--share-type {self.st_id}' - ) - self.admin_client.manila(cmd, microversion=microversion) - - # Verify quotas after reset - self._verify_current_quotas_equal_to(default_quotas, microversion) - - # Return project quotas back - cmd = ( - 'quota-update {} --share-groups {} --share-group-snapshots {}' - ).format( - self.project_id, - p_quotas['share_groups'], - p_quotas['share_group_snapshots'], - ) - self.admin_client.manila(cmd, microversion=microversion) - - # Verify quotas after reset - self._verify_current_quotas_equal_to(p_quotas, microversion) - - @ddt.data('--share-groups', '--share-group-snapshots') - @utils.skip_if_microversion_not_supported("2.39") - def test_update_quotas_for_share_groups_using_too_old_microversion( - self, arg - ): - cmd = f'quota-update {self.project_id} {arg} 13' - self.assertRaises( - exceptions.CommandFailed, - self.admin_client.manila, - cmd, - microversion='2.39', - ) - - @ddt.data('--share-replicas', '--replica-gigabytes') - @utils.skip_if_microversion_not_supported("2.52") - def test_update_quotas_for_share_replicas_using_too_old_microversion( - self, arg - ): - cmd = f'quota-update {self.project_id} {arg} 10' - self.assertRaises( - exceptions.CommandFailed, - self.admin_client.manila, - cmd, - microversion='2.52', - ) - - @ddt.data('--share-groups', '--share-group-snapshots') - @utils.skip_if_microversion_not_supported("2.40") - def test_update_share_type_quotas_for_share_groups(self, arg): - cmd = ( - f'quota-update {self.project_id} --share-type {self.st_id} ' - f'{arg} 13' - ) - self.assertRaises( - exceptions.CommandFailed, - self.admin_client.manila, - cmd, - microversion='2.40', - ) - - @ddt.data( - *set( - [ - "2.39", - "2.40", - REPLICA_QUOTAS_MICROVERSION, - api_versions.MAX_VERSION, - ] - ) - ) - def test_update_share_type_quotas_positive(self, microversion): - if not utils.is_microversion_supported(microversion): - msg = f"Microversion '{microversion}' not supported." - raise self.skipException(msg) - - # Get project quotas - cmd = f'quota-show --tenant-id {self.project_id} ' - quotas_raw = self.admin_client.manila(cmd, microversion=microversion) - p_quotas = output_parser.details(quotas_raw) - - # Define share type quotas - st_custom_quotas = { - 'shares': _get_share_type_quota_values(p_quotas['shares']), - 'snapshots': _get_share_type_quota_values(p_quotas['snapshots']), - 'gigabytes': _get_share_type_quota_values(p_quotas['gigabytes']), - 'snapshot_gigabytes': _get_share_type_quota_values( - p_quotas['snapshot_gigabytes'] - ), - } - supports_share_replica_quotas = api_versions.APIVersion( - microversion - ) >= api_versions.APIVersion(REPLICA_QUOTAS_MICROVERSION) - - if supports_share_replica_quotas: - st_custom_quotas['share_replicas'] = _get_share_type_quota_values( - p_quotas['share_replicas'] - ) - st_custom_quotas['replica_gigabytes'] = ( - _get_share_type_quota_values(p_quotas['replica_gigabytes']) - ) - replica_params = ( - ' --share-replicas {} --replica-gigabytes {}' - ).format( - st_custom_quotas['share_replicas'], - st_custom_quotas['replica_gigabytes'], - ) - - # Update quotas for share type - cmd = ( - 'quota-update {} --share-type {} ' - '--shares {} --gigabytes {} --snapshots {} ' - '--snapshot-gigabytes {}' - ).format( - self.project_id, - self.st_id, - st_custom_quotas['shares'], - st_custom_quotas['gigabytes'], - st_custom_quotas['snapshots'], - st_custom_quotas['snapshot_gigabytes'], - ) - - if supports_share_replica_quotas: - cmd += replica_params - self.admin_client.manila(cmd, microversion=microversion) - - # Verify share type quotas - self._verify_current_st_quotas_equal_to(st_custom_quotas, microversion) - - # Reset share type quotas - cmd = ( - f'quota-delete --tenant-id {self.project_id} ' - f'--share-type {self.st_id}' - ) - self.admin_client.manila(cmd, microversion=microversion) - - # Verify share type quotas after reset - self._verify_current_st_quotas_equal_to(p_quotas, microversion) - - @utils.skip_if_microversion_not_supported("2.38") - def test_read_share_type_quotas_with_too_old_microversion(self): - cmd = ( - f'quota-show --tenant-id {self.project_id} ' - f'--share-type {self.st_id}' - ) - self.assertRaises( - exceptions.CommandFailed, - self.admin_client.manila, - cmd, - microversion='2.38', - ) - - @utils.skip_if_microversion_not_supported("2.38") - def test_update_share_type_quotas_with_too_old_microversion(self): - cmd = 'quota-update --tenant-id {} --share-type {} --shares {}'.format( - self.project_id, self.st_id, '0' - ) - self.assertRaises( - exceptions.CommandFailed, - self.admin_client.manila, - cmd, - microversion='2.38', - ) - - @utils.skip_if_microversion_not_supported("2.38") - def test_delete_share_type_quotas_with_too_old_microversion(self): - cmd = ( - f'quota-delete --tenant-id {self.project_id} ' - f'--share-type {self.st_id}' - ) - self.assertRaises( - exceptions.CommandFailed, - self.admin_client.manila, - cmd, - microversion='2.38', - ) - - -@ddt.ddt -class ManilaClientTestQuotasReadOnly(base.BaseTestCase): - def test_quota_class_show_by_admin(self): - roles = self.parser.listing( - self.clients['admin'].manila('quota-class-show', params='abc') - ) - self.assertTableStruct(roles, ('Property', 'Value')) - - def test_quota_class_show_by_user(self): - self.assertRaises( - exceptions.CommandFailed, - self.clients['user'].manila, - 'quota-class-show', - params='abc', - ) - - def _get_quotas(self, role, operation, microversion): - roles = self.parser.listing( - self.clients[role].manila( - f'quota-{operation}', microversion=microversion - ) - ) - self.assertTableStruct(roles, ('Property', 'Value')) - - @ddt.data('admin', 'user') - @utils.skip_if_microversion_not_supported("1.0") - def test_quota_defaults_api_1_0(self, role): - self._get_quotas(role, "defaults", "1.0") - - @ddt.data('admin', 'user') - @utils.skip_if_microversion_not_supported("2.0") - def test_quota_defaults_api_2_0(self, role): - self._get_quotas(role, "defaults", "2.0") - - @ddt.data('admin', 'user') - @utils.skip_if_microversion_not_supported("2.6") - def test_quota_defaults_api_2_6(self, role): - self._get_quotas(role, "defaults", "2.6") - - @ddt.data('admin', 'user') - @utils.skip_if_microversion_not_supported("2.7") - def test_quota_defaults_api_2_7(self, role): - self._get_quotas(role, "defaults", "2.7") - - @ddt.data('admin', 'user') - @utils.skip_if_microversion_not_supported("1.0") - def test_quota_show_api_1_0(self, role): - self._get_quotas(role, "show", "1.0") - - @ddt.data('admin', 'user') - @utils.skip_if_microversion_not_supported("2.0") - def test_quota_show_api_2_0(self, role): - self._get_quotas(role, "show", "2.0") - - @ddt.data('admin', 'user') - @utils.skip_if_microversion_not_supported("2.6") - def test_quota_show_api_2_6(self, role): - self._get_quotas(role, "show", "2.6") - - @ddt.data('admin', 'user') - @utils.skip_if_microversion_not_supported("2.7") - def test_quota_show_api_2_7(self, role): - self._get_quotas(role, "show", "2.7") - - @ddt.data('admin', 'user') - @utils.skip_if_microversion_not_supported("2.25") - def test_quota_show_api_2_25(self, role): - self._get_quotas(role, "show --detail", "2.25") diff --git a/manilaclient/tests/functional/test_scheduler_stats.py b/manilaclient/tests/functional/test_scheduler_stats.py deleted file mode 100644 index 117795db..00000000 --- a/manilaclient/tests/functional/test_scheduler_stats.py +++ /dev/null @@ -1,49 +0,0 @@ -# Copyright (c) 2015 Clinton Knight. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from tempest.lib.common.utils import data_utils -from tempest.lib import exceptions - -from manilaclient.tests.functional import base - - -class ManilaClientTestSchedulerStatsReadOnly(base.BaseTestCase): - def test_pools_list(self): - self.clients['admin'].manila('pool-list') - - def test_pools_list_with_debug_flag(self): - self.clients['admin'].manila('pool-list', flags='--debug') - - def test_pools_list_with_detail(self): - self.clients['admin'].manila('pool-list', params='--detail') - - def test_pools_list_with_share_type_filter(self): - share_type = self.create_share_type( - name=data_utils.rand_name('manilaclient_functional_test'), - snapshot_support=True, - ) - self.clients['admin'].manila( - 'pool-list', params='--share_type ' + share_type['ID'] - ) - - def test_pools_list_with_filters(self): - self.clients['admin'].manila( - 'pool-list', - params='--host myhost --backend mybackend --pool mypool', - ) - - def test_pools_list_by_user(self): - self.assertRaises( - exceptions.CommandFailed, self.clients['user'].manila, 'pool-list' - ) diff --git a/manilaclient/tests/functional/test_security_services.py b/manilaclient/tests/functional/test_security_services.py deleted file mode 100644 index e8a819b3..00000000 --- a/manilaclient/tests/functional/test_security_services.py +++ /dev/null @@ -1,80 +0,0 @@ -# Copyright 2015 Mirantis Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import ddt -from tempest.lib.common.utils import data_utils - -from manilaclient.tests.functional import base - - -@ddt.ddt -class SecurityServiceReadWriteTest(base.BaseTestCase): - def setUp(self): - super().setUp() - self.name = data_utils.rand_name('autotest') - self.description = 'fake_description' - self.user = 'fake_user' - self.password = 'fake_password' - self.server = 'fake_server' - self.domain = 'fake_domain' - self.dns_ip = '1.2.3.4' - self.ou = 'fake_ou' - self.default_ad_site = 'fake_default_ad_site' - - @ddt.data( - {'name': 'test_name'}, - {'description': 'test_description'}, - {'user': 'test_username'}, - {'password': 'test_password'}, - {'server': 'test_server'}, - {'default_ad_site': 'test_default_ad_site'}, - {'domain': 'test_domain'}, - {'dns_ip': 'test_dns_ip'}, - {'ou': 'test_ou'}, - {'name': '""'}, - {'description': '""'}, - {'user': '""'}, - {'password': '""'}, - {'server': '""'}, - {'default_ad_site': '""'}, - {'domain': '""'}, - {'dns_ip': '""'}, - {'ou': '""'}, - ) - def test_create_update_security_service(self, ss_data): - expected_data = { - 'name': self.name, - 'description': self.description, - 'user': self.user, - 'password': self.password, - 'server': self.server, - 'domain': self.domain, - 'dns_ip': self.dns_ip, - 'ou': self.ou, - } - - if 'default_ad_site' in ss_data: - expected_data.pop('server') - expected_data['default_ad_site'] = self.default_ad_site - - ss = self.create_security_service(**expected_data) - update = self.admin_client.update_security_service(ss['id'], **ss_data) - expected_data.update(ss_data) - - for k, v in expected_data.items(): - if v == '""': - self.assertEqual('None', update[k]) - else: - self.assertEqual(v, update[k]) diff --git a/manilaclient/tests/functional/test_services.py b/manilaclient/tests/functional/test_services.py deleted file mode 100644 index bdf424db..00000000 --- a/manilaclient/tests/functional/test_services.py +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright 2015 Mirantis Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import ddt - -from manilaclient.tests.functional import base - - -@ddt.ddt -class ManilaClientTestServicesReadOnly(base.BaseTestCase): - @ddt.data("1.0", "2.0", "2.6", "2.7") - def test_services_list(self, microversion): - self.skip_if_microversion_not_supported(microversion) - self.admin_client.manila('service-list', microversion=microversion) - - def test_list_with_debug_flag(self): - self.clients['admin'].manila('service-list', flags='--debug') - - def test_shares_list_filter_by_host(self): - self.clients['admin'].manila('service-list', params='--host host') - - def test_shares_list_filter_by_binary(self): - self.clients['admin'].manila('service-list', params='--binary binary') - - def test_shares_list_filter_by_zone(self): - self.clients['admin'].manila('service-list', params='--zone zone') - - def test_shares_list_filter_by_status(self): - self.clients['admin'].manila('service-list', params='--status status') - - def test_shares_list_filter_by_state(self): - self.clients['admin'].manila('service-list', params='--state state') diff --git a/manilaclient/tests/functional/test_share_access.py b/manilaclient/tests/functional/test_share_access.py deleted file mode 100644 index be268293..00000000 --- a/manilaclient/tests/functional/test_share_access.py +++ /dev/null @@ -1,384 +0,0 @@ -# Copyright 2015 Mirantis Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import ast - -import ddt -from tempest.lib import exceptions as tempest_lib_exc - -from manilaclient import api_versions -from manilaclient import config -from manilaclient.tests.functional import base - -CONF = config.CONF - - -@ddt.ddt -class ShareAccessReadWriteBase(base.BaseTestCase): - protocol = None - access_level = None - - def setUp(self): - super().setUp() - if self.protocol not in CONF.enable_protocols: - message = f"{self.protocol} tests are disabled." - raise self.skipException(message) - if self.access_level not in CONF.access_levels_mapping.get( - self.protocol, '' - ).split(' '): - raise self.skipException( - f"{self.access_level} tests for {self.protocol} share " - "access are disabled." - ) - self.access_types = CONF.access_types_mapping.get( - self.protocol, '' - ).split(' ') - if not self.access_types: - raise self.skipException( - f"No access levels were provided for {self.protocol} " - "share access tests." - ) - - self.share = self.create_share( - share_protocol=self.protocol, public=True - ) - self.share_id = self.share['id'] - - # NOTE(vponomaryov): increase following int range when significant - # amount of new tests is added. - int_range = range(20, 50) - self.access_to = { - # NOTE(vponomaryov): list of unique values is required for ability - # to create lots of access rules for one share using different - # API microversions. - 'ip': [f'99.88.77.{i}' for i in int_range], - # NOTE(vponomaryov): following users are fakes and access rules - # that use it are expected to fail, but they are used only for - # API testing. - 'user': [f'foo_user_{i}' for i in int_range], - 'cert': [f'tenant_{i}.example.com' for i in int_range], - 'ipv6': [f'2001:db8::{i}' for i in int_range], - } - - def _test_create_list_access_rule_for_share( - self, microversion, metadata=None - ): - access_type = self.access_types[0] - - access = self.user_client.access_allow( - self.share['id'], - access_type, - self.access_to[access_type].pop(), - self.access_level, - metadata=metadata, - microversion=microversion, - ) - - return access - - @ddt.data( - *set( - [ - "1.0", - "2.0", - "2.6", - "2.7", - "2.21", - "2.33", - "2.44", - "2.45", - api_versions.MAX_VERSION, - ] - ) - ) - def test_create_list_access_rule_for_share(self, microversion): - self.skip_if_microversion_not_supported(microversion) - access = self._test_create_list_access_rule_for_share( - microversion=microversion - ) - access_list = self.user_client.list_access( - self.share['id'], microversion=microversion - ) - self.assertTrue( - any([item for item in access_list if access['id'] == item['id']]) - ) - self.assertTrue(any(a['access_type'] is not None for a in access_list)) - self.assertTrue(any(a['access_to'] is not None for a in access_list)) - self.assertTrue( - any(a['access_level'] is not None for a in access_list) - ) - if api_versions.APIVersion(microversion) >= api_versions.APIVersion( - "2.33" - ): - self.assertTrue( - all( - all( - key in access - for key in ('access_key', 'created_at', 'updated_at') - ) - for access in access_list - ) - ) - elif api_versions.APIVersion(microversion) >= api_versions.APIVersion( - "2.21" - ): - self.assertTrue(all('access_key' in a for a in access_list)) - else: - self.assertTrue(all('access_key' not in a for a in access_list)) - - @ddt.data("1.0", "2.0", "2.6", "2.7") - def test_create_list_access_rule_for_share_select_column( - self, microversion - ): - self.skip_if_microversion_not_supported(microversion) - self._test_create_list_access_rule_for_share(microversion=microversion) - access_list = self.user_client.list_access( - self.share['id'], - columns="access_type,access_to", - microversion=microversion, - ) - self.assertTrue(any(a['Access_Type'] is not None for a in access_list)) - self.assertTrue(any(a['Access_To'] is not None for a in access_list)) - self.assertTrue(all('Access_Level' not in a for a in access_list)) - self.assertTrue(all('access_level' not in a for a in access_list)) - - def _create_delete_access_rule( - self, share_id, access_type, access_to, microversion=None - ): - self.skip_if_microversion_not_supported(microversion) - if access_type not in self.access_types: - raise self.skipException( - f"'{access_type}' access rules is disabled for protocol " - f"'{self.protocol}'." - ) - - access = self.user_client.access_allow( - share_id, - access_type, - access_to, - self.access_level, - microversion=microversion, - ) - - self.assertEqual(share_id, access.get('share_id')) - self.assertEqual(access_type, access.get('access_type')) - self.assertEqual( - access_to.replace('\\\\', '\\'), access.get('access_to') - ) - self.assertEqual(self.access_level, access.get('access_level')) - if api_versions.APIVersion(microversion) >= api_versions.APIVersion( - "2.33" - ): - self.assertIn('access_key', access) - self.assertIn('created_at', access) - self.assertIn('updated_at', access) - elif api_versions.APIVersion(microversion) >= api_versions.APIVersion( - "2.21" - ): - self.assertIn('access_key', access) - else: - self.assertNotIn('access_key', access) - - self.user_client.wait_for_access_rule_status(share_id, access['id']) - self.user_client.access_deny(share_id, access['id']) - self.user_client.wait_for_access_rule_deletion(share_id, access['id']) - - self.assertRaises( - tempest_lib_exc.NotFound, - self.user_client.get_access, - share_id, - access['id'], - ) - - @ddt.data(*set(["2.45", api_versions.MAX_VERSION])) - def test_create_list_access_rule_with_metadata(self, microversion): - self.skip_if_microversion_not_supported(microversion) - - md1 = {"key1": "value1", "key2": "value2"} - md2 = {"key3": "value3", "key4": "value4"} - self._test_create_list_access_rule_for_share( - metadata=md1, microversion=microversion - ) - access = self._test_create_list_access_rule_for_share( - metadata=md2, microversion=microversion - ) - access_list = self.user_client.list_access( - self.share['id'], - metadata={"key4": "value4"}, - microversion=microversion, - ) - self.assertEqual(1, len(access_list)) - # Verify share metadata - get_access = self.user_client.access_show( - access_list[0]['id'], microversion=microversion - ) - metadata = ast.literal_eval(get_access['metadata']) - self.assertEqual(2, len(metadata)) - self.assertIn('key3', metadata) - self.assertIn('key4', metadata) - self.assertEqual(md2['key3'], metadata['key3']) - self.assertEqual(md2['key4'], metadata['key4']) - self.assertEqual(access['id'], access_list[0]['id']) - - self.user_client.access_deny(access['share_id'], access['id']) - self.user_client.wait_for_access_rule_deletion( - access['share_id'], access['id'] - ) - - @ddt.data(*set(["2.45", api_versions.MAX_VERSION])) - def test_create_update_show_access_rule_with_metadata(self, microversion): - self.skip_if_microversion_not_supported(microversion) - - md1 = {"key1": "value1", "key2": "value2"} - md2 = {"key3": "value3", "key2": "value4"} - # create a access rule with metadata - access = self._test_create_list_access_rule_for_share( - metadata=md1, microversion=microversion - ) - # get the access rule - get_access = self.user_client.access_show( - access['id'], microversion=microversion - ) - # verify access rule - self.assertEqual(access['id'], get_access['id']) - self.assertEqual(md1, ast.literal_eval(get_access['metadata'])) - - # update access rule metadata - self.user_client.access_set_metadata( - access['id'], metadata=md2, microversion=microversion - ) - get_access = self.user_client.access_show( - access['id'], microversion=microversion - ) - - # verify access rule after update access rule metadata - self.assertEqual( - {"key1": "value1", "key2": "value4", "key3": "value3"}, - ast.literal_eval(get_access['metadata']), - ) - self.assertEqual(access['id'], get_access['id']) - - @ddt.data(*set(["2.45", api_versions.MAX_VERSION])) - def test_delete_access_rule_metadata(self, microversion): - self.skip_if_microversion_not_supported(microversion) - - md = {"key1": "value1", "key2": "value2"} - # create a access rule with metadata - access = self._test_create_list_access_rule_for_share( - metadata=md, microversion=microversion - ) - # get the access rule - get_access = self.user_client.access_show( - access['id'], microversion=microversion - ) - - # verify access rule - self.assertEqual(access['id'], get_access['id']) - self.assertEqual(md, ast.literal_eval(get_access['metadata'])) - - # delete access rule metadata - self.user_client.access_unset_metadata( - access['id'], keys=["key1", "key2"], microversion=microversion - ) - get_access = self.user_client.access_show( - access['id'], microversion=microversion - ) - - # verify access rule after delete access rule metadata - self.assertEqual({}, ast.literal_eval(get_access['metadata'])) - self.assertEqual(access['id'], get_access['id']) - - @ddt.data("1.0", "2.0", "2.6", "2.7", "2.21", "2.33") - def test_create_delete_ip_access_rule(self, microversion): - self._create_delete_access_rule( - self.share_id, 'ip', self.access_to['ip'].pop(), microversion - ) - - @ddt.data("1.0", "2.0", "2.6", "2.7", "2.21", "2.33") - def test_create_delete_user_access_rule(self, microversion): - self._create_delete_access_rule( - self.share_id, 'user', CONF.username_for_user_rules, microversion - ) - - @ddt.data("1.0", "2.0", "2.6", "2.7", "2.21", "2.33") - def test_create_delete_cert_access_rule(self, microversion): - self._create_delete_access_rule( - self.share_id, 'cert', self.access_to['cert'].pop(), microversion - ) - - @ddt.data("2.38", api_versions.MAX_VERSION) - def test_create_delete_ipv6_access_rule(self, microversion): - self._create_delete_access_rule( - self.share_id, 'ip', self.access_to['ipv6'].pop(), microversion - ) - - -class NFSShareRWAccessReadWriteTest(ShareAccessReadWriteBase): - protocol = 'nfs' - access_level = 'rw' - - -class NFSShareROAccessReadWriteTest(ShareAccessReadWriteBase): - protocol = 'nfs' - access_level = 'ro' - - -class CIFSShareRWAccessReadWriteTest(ShareAccessReadWriteBase): - protocol = 'cifs' - access_level = 'rw' - - -class CIFSShareROAccessReadWriteTest(ShareAccessReadWriteBase): - protocol = 'cifs' - access_level = 'ro' - - -class GlusterFSShareRWAccessReadWriteTest(ShareAccessReadWriteBase): - protocol = 'glusterfs' - access_level = 'rw' - - -class GlusterFSShareROAccessReadWriteTest(ShareAccessReadWriteBase): - protocol = 'glusterfs' - access_level = 'ro' - - -class HDFSShareRWAccessReadWriteTest(ShareAccessReadWriteBase): - protocol = 'hdfs' - access_level = 'rw' - - -class HDFSShareROAccessReadWriteTest(ShareAccessReadWriteBase): - protocol = 'hdfs' - access_level = 'ro' - - -class MAPRFSShareRWAccessReadWriteTest(ShareAccessReadWriteBase): - protocol = 'maprfs' - access_level = 'rw' - - -class MAPRFSShareROAccessReadWriteTest(ShareAccessReadWriteBase): - protocol = 'maprfs' - access_level = 'ro' - - -def load_tests(loader, tests, _): - result = [] - for test_case in tests: - if type(test_case._tests[0]) is ShareAccessReadWriteBase: - continue - result.append(test_case) - return loader.suiteClass(result) diff --git a/manilaclient/tests/functional/test_share_network_subnets.py b/manilaclient/tests/functional/test_share_network_subnets.py deleted file mode 100644 index 26c43330..00000000 --- a/manilaclient/tests/functional/test_share_network_subnets.py +++ /dev/null @@ -1,129 +0,0 @@ -# Copyright 2019 NetApp -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import ddt -from manilaclient.tests.functional import base -from manilaclient.tests.functional import utils -from tempest.lib.common.utils import data_utils -from tempest.lib import exceptions - - -@ddt.ddt -@utils.skip_if_microversion_not_supported('2.51') -class ShareNetworkSubnetsReadWriteTest(base.BaseTestCase): - def setUp(self): - super().setUp() - self.name = data_utils.rand_name('autotest') - self.description = 'fake_description' - self.neutron_net_id = 'fake_neutron_net_id' - self.neutron_subnet_id = 'fake_neutron_subnet_id' - - self.sn = self.create_share_network( - name=self.name, - description=self.description, - neutron_net_id=self.neutron_net_id, - neutron_subnet_id=self.neutron_subnet_id, - ) - - def test_get_share_network_subnet(self): - default_subnet = utils.get_default_subnet( - self.user_client, self.sn['id'] - ) - - subnet = self.user_client.get_share_network_subnet( - self.sn['id'], default_subnet['id'] - ) - - self.assertEqual(self.neutron_net_id, subnet['neutron_net_id']) - self.assertEqual(self.neutron_subnet_id, subnet['neutron_subnet_id']) - - def test_get_invalid_share_network_subnet(self): - self.assertRaises( - exceptions.CommandFailed, - self.user_client.get_share_network_subnet, - self.sn['id'], - 'invalid_subnet_id', - ) - - def _get_availability_zone(self): - availability_zones = self.user_client.list_availability_zones() - return availability_zones[0]['Name'] - - def test_add_share_network_subnet_to_share_network(self): - neutron_net_id = 'new_neutron_net_id' - neutron_subnet_id = 'new_neutron_subnet_id' - availability_zone = self._get_availability_zone() - - subnet = self.add_share_network_subnet( - self.sn['id'], - neutron_net_id, - neutron_subnet_id, - availability_zone, - cleanup_in_class=False, - ) - - self.assertEqual(neutron_net_id, subnet['neutron_net_id']) - self.assertEqual(neutron_subnet_id, subnet['neutron_subnet_id']) - self.assertEqual(availability_zone, subnet['availability_zone']) - - @ddt.data( - {'neutron_net_id': None, 'neutron_subnet_id': 'fake_subnet_id'}, - {'neutron_net_id': 'fake_net_id', 'neutron_subnet_id': None}, - {'availability_zone': 'invalid_availability_zone'}, - ) - def test_add_invalid_share_network_subnet_to_share_network(self, params): - self.assertRaises( - exceptions.CommandFailed, - self.add_share_network_subnet, - self.sn['id'], - **params, - ) - - def test_add_share_network_subnet_to_invalid_share_network(self): - self.assertRaises( - exceptions.CommandFailed, - self.add_share_network_subnet, - 'invalid_share_network', - self.neutron_net_id, - self.neutron_subnet_id, - ) - - def test_add_delete_share_network_subnet_from_share_network(self): - neutron_net_id = 'new_neutron_net_id' - neutron_subnet_id = 'new_neutron_subnet_id' - availability_zone = self._get_availability_zone() - - subnet = self.add_share_network_subnet( - self.sn['id'], - neutron_net_id, - neutron_subnet_id, - availability_zone, - cleanup_in_class=False, - ) - self.user_client.delete_share_network_subnet( - share_network_subnet=subnet['id'], share_network=self.sn['id'] - ) - - self.user_client.wait_for_share_network_subnet_deletion( - share_network_subnet=subnet['id'], share_network=self.sn['id'] - ) - - def test_delete_invalid_share_network_subnet(self): - self.assertRaises( - exceptions.NotFound, - self.user_client.delete_share_network_subnet, - share_network_subnet='invalid_subnet_id', - share_network=self.sn['id'], - ) diff --git a/manilaclient/tests/functional/test_share_networks.py b/manilaclient/tests/functional/test_share_networks.py deleted file mode 100644 index 3a3dacb8..00000000 --- a/manilaclient/tests/functional/test_share_networks.py +++ /dev/null @@ -1,695 +0,0 @@ -# Copyright 2015 Mirantis Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import ast -import ddt -from tempest.lib.common.utils import data_utils -from tempest.lib import exceptions as tempest_lib_exc -import time - -from manilaclient import config -from manilaclient import exceptions -from manilaclient.tests.functional import base -from manilaclient.tests.functional import utils - -SECURITY_SERVICE_UPDATE_VERSION = '2.63' -CONF = config.CONF - - -@ddt.ddt -class ShareNetworksReadWriteTest(base.BaseTestCase): - def setUp(self): - super().setUp() - self.name = data_utils.rand_name('autotest') - self.description = 'fake_description' - self.neutron_net_id = 'fake_neutron_net_id' - self.neutron_subnet_id = 'fake_neutron_subnet_id' - - self.sn = self.create_share_network( - name=self.name, - description=self.description, - neutron_net_id=self.neutron_net_id, - neutron_subnet_id=self.neutron_subnet_id, - ) - - @ddt.data( - {'name': data_utils.rand_name('autotest_share_network_name')}, - {'description': 'fake_description'}, - { - 'neutron_net_id': 'fake_neutron_net_id', - 'neutron_subnet_id': 'fake_neutron_subnet_id', - }, - ) - def test_create_delete_share_network(self, net_data): - share_subnet_support = utils.share_network_subnets_are_supported() - share_subnet_fields = ( - ['neutron_net_id', 'neutron_subnet_id', 'availability_zone'] - if share_subnet_support - else [] - ) - sn = self.create_share_network(cleanup_in_class=False, **net_data) - default_subnet = ( - utils.get_default_subnet(self.user_client, sn['id']) - if share_subnet_support - else None - ) - - expected_data = { - 'name': 'None', - 'description': 'None', - 'neutron_net_id': 'None', - 'neutron_subnet_id': 'None', - } - expected_data.update(net_data) - share_network_expected_data = [ - (k, v) - for k, v in expected_data.items() - if k not in share_subnet_fields - ] - share_subnet_expected_data = [ - (k, v) - for k, v in expected_data.items() - if k in share_subnet_fields - ] - - for k, v in share_network_expected_data: - self.assertEqual(v, sn[k]) - for k, v in share_subnet_expected_data: - self.assertEqual(v, default_subnet[k]) - - self.admin_client.delete_share_network(sn['id']) - self.admin_client.wait_for_share_network_deletion(sn['id']) - - @utils.skip_if_microversion_not_supported('2.51') - def test_create_delete_share_network_with_az(self): - share_subnet_fields = [ - 'neutron_net_id', - 'neutron_subnet_id', - 'availability_zone', - ] - az = self.user_client.list_availability_zones()[0] - net_data = { - 'neutron_net_id': 'fake_neutron_net_id', - 'neutron_subnet_id': 'fake_neutron_subnet_id', - 'availability_zone': az['Name'], - } - sn = self.create_share_network(cleanup_in_class=False, **net_data) - default_subnet = utils.get_subnet_by_availability_zone_name( - self.user_client, sn['id'], az['Name'] - ) - - expected_data = { - 'name': 'None', - 'description': 'None', - 'neutron_net_id': 'None', - 'neutron_subnet_id': 'None', - 'availability_zone': 'None', - } - expected_data.update(net_data) - share_network_expected_data = [ - (k, v) - for k, v in expected_data.items() - if k not in share_subnet_fields - ] - share_subnet_expected_data = [ - (k, v) - for k, v in expected_data.items() - if k in share_subnet_fields - ] - - for k, v in share_network_expected_data: - self.assertEqual(v, sn[k]) - for k, v in share_subnet_expected_data: - self.assertEqual(v, default_subnet[k]) - - self.admin_client.delete_share_network(sn['id']) - self.admin_client.wait_for_share_network_deletion(sn['id']) - - def test_get_share_network_with_neutron_data(self): - get = self.admin_client.get_share_network(self.sn['id']) - - self.assertEqual(self.name, get['name']) - self.assertEqual(self.description, get['description']) - if not utils.share_network_subnets_are_supported(): - self.assertEqual(self.neutron_net_id, get['neutron_net_id']) - self.assertEqual(self.neutron_subnet_id, get['neutron_subnet_id']) - - def _get_expected_update_data(self, net_data, net_creation_data): - # NOTE(dviroel): When subnets are supported, the outputs are converted - # from string to literal structures in order to process the content of - # 'share_network_subnets' field. - default_return_value = ( - None if utils.share_network_subnets_are_supported() else 'None' - ) - - expected_nn_id = ( - default_return_value - if net_data.get('neutron_net_id') - else net_creation_data.get('neutron_net_id', default_return_value) - ) - expected_nsn_id = ( - default_return_value - if net_data.get('neutron_subnet_id') - else net_creation_data.get( - 'neutron_subnet_id', default_return_value - ) - ) - return expected_nn_id, expected_nsn_id - - @ddt.data( - ({'name': data_utils.rand_name('autotest_share_network_name')}, {}), - ({'description': 'fake_description'}, {}), - ( - { - 'neutron_net_id': 'fake_neutron_net_id', - 'neutron_subnet_id': 'fake_neutron_subnet_id', - }, - {}, - ), - ({'name': '""'}, {}), - ({'description': '""'}, {}), - ( - {'neutron_net_id': '""'}, - { - 'neutron_net_id': 'fake_nn_id', - 'neutron_subnet_id': 'fake_nsn_id', - }, - ), - ( - {'neutron_subnet_id': '""'}, - { - 'neutron_net_id': 'fake_nn_id', - 'neutron_subnet_id': 'fake_nsn_id', - }, - ), - ) - @ddt.unpack - def test_create_update_share_network(self, net_data, net_creation_data): - sn = self.create_share_network( - cleanup_in_class=False, **net_creation_data - ) - - update = self.admin_client.update_share_network(sn['id'], **net_data) - - expected_nn_id, expected_nsn_id = self._get_expected_update_data( - net_data, net_creation_data - ) - - expected_data = { - 'name': 'None', - 'description': 'None', - 'neutron_net_id': expected_nn_id, - 'neutron_subnet_id': expected_nsn_id, - } - subnet_keys = [] - if utils.share_network_subnets_are_supported(): - subnet_keys = ['neutron_net_id', 'neutron_subnet_id'] - subnet = ast.literal_eval(update['share_network_subnets']) - - update_values = dict( - [(k, v) for k, v in net_data.items() if v != '""'] - ) - expected_data.update(update_values) - - for k, v in expected_data.items(): - if k in subnet_keys: - self.assertEqual(v, subnet[0][k]) - else: - self.assertEqual(v, update[k]) - - self.admin_client.delete_share_network(sn['id']) - self.admin_client.wait_for_share_network_deletion(sn['id']) - - @ddt.data(True, False) - def test_list_share_networks(self, all_tenants): - share_networks = self.admin_client.list_share_networks(all_tenants) - - self.assertTrue( - any(self.sn['id'] == sn['id'] for sn in share_networks) - ) - for sn in share_networks: - self.assertEqual(2, len(sn)) - self.assertIn('id', sn) - self.assertIn('name', sn) - - def test_list_share_networks_select_column(self): - share_networks = self.admin_client.list_share_networks(columns="id") - self.assertTrue(any(s['Id'] is not None for s in share_networks)) - self.assertTrue(all('Name' not in s for s in share_networks)) - self.assertTrue(all('name' not in s for s in share_networks)) - - def _list_share_networks_with_filters(self, filters): - assert_subnet_fields = utils.share_network_subnets_are_supported() - share_subnet_fields = ( - ['neutron_subnet_id', 'neutron_net_id'] - if assert_subnet_fields - else [] - ) - share_network_filters = [ - (k, v) for k, v in filters.items() if k not in share_subnet_fields - ] - share_network_subnet_filters = [ - (k, v) for k, v in filters.items() if k in share_subnet_fields - ] - share_networks = self.admin_client.list_share_networks(filters=filters) - - self.assertGreater(len(share_networks), 0) - self.assertTrue( - any(self.sn['id'] == sn['id'] for sn in share_networks) - ) - for sn in share_networks: - try: - share_network = self.admin_client.get_share_network(sn['id']) - default_subnet = ( - utils.get_default_subnet(self.user_client, sn['id']) - if assert_subnet_fields - else None - ) - except tempest_lib_exc.NotFound: - # NOTE(vponomaryov): Case when some share network was deleted - # between our 'list' and 'get' requests. Skip such case. - continue - for k, v in share_network_filters: - self.assertIn(k, share_network) - self.assertEqual(v, share_network[k]) - for k, v in share_network_subnet_filters: - self.assertIn(k, default_subnet) - self.assertEqual(v, default_subnet[k]) - - def test_list_share_networks_filter_by_project_id(self): - project_id = self.admin_client.get_project_id( - self.admin_client.tenant_name - ) - filters = {'project_id': project_id} - self._list_share_networks_with_filters(filters) - - def test_list_share_networks_filter_by_name(self): - filters = {'name': self.name} - self._list_share_networks_with_filters(filters) - - def test_list_share_networks_filter_by_description(self): - filters = {'description': self.description} - self._list_share_networks_with_filters(filters) - - def test_list_share_networks_filter_by_neutron_net_id(self): - filters = {'neutron_net_id': self.neutron_net_id} - self._list_share_networks_with_filters(filters) - - def test_list_share_networks_filter_by_neutron_subnet_id(self): - filters = {'neutron_subnet_id': self.neutron_subnet_id} - self._list_share_networks_with_filters(filters) - - @ddt.data('name', 'description') - def test_list_share_networks_filter_by_inexact(self, option): - self.create_share_network( - name=data_utils.rand_name('autotest_inexact'), - description='fake_description_inexact', - neutron_net_id='fake_neutron_net_id', - neutron_subnet_id='fake_neutron_subnet_id', - ) - - filters = {option + '~': 'inexact'} - share_networks = self.admin_client.list_share_networks(filters=filters) - - self.assertGreater(len(share_networks), 0) - - def test_list_share_networks_by_inexact_unicode_option(self): - self.create_share_network( - name='网络名称', - description='网络描述', - neutron_net_id='fake_neutron_net_id', - neutron_subnet_id='fake_neutron_subnet_id', - ) - - filters = {'name~': '名称'} - share_networks = self.admin_client.list_share_networks(filters=filters) - - self.assertGreater(len(share_networks), 0) - - filters = {'description~': '描述'} - share_networks = self.admin_client.list_share_networks(filters=filters) - - self.assertGreater(len(share_networks), 0) - - def test_share_network_reset_status(self): - share_network = self.create_share_network( - client=self.user_client, - name='cool_net_name', - description='fakedescription', - neutron_net_id='fake_neutron_net_id', - neutron_subnet_id='fake_neutron_subnet_id', - ) - - # Admin operation - self.admin_client.share_network_reset_state( - share_network['id'], - 'error', - microversion=SECURITY_SERVICE_UPDATE_VERSION, - ) - - self.user_client.wait_for_resource_status( - share_network['id'], - 'error', - microversion=SECURITY_SERVICE_UPDATE_VERSION, - resource_type="share_network", - ) - - def test_share_network_security_service_add(self): - share_network = self.create_share_network( - client=self.user_client, - name='cool_net_name', - description='fakedescription', - neutron_net_id='fake_neutron_net_id', - neutron_subnet_id='fake_neutron_subnet_id', - ) - new_security_service = self.create_security_service( - client=self.user_client - ) - - check_result = ( - self.user_client.share_network_security_service_add_check( - share_network['id'], - security_service_id=new_security_service['id'], - ) - ) - - self.assertEqual(check_result['compatible'], 'True') - - self.user_client.share_network_security_service_add( - share_network['id'], new_security_service['id'] - ) - - network_services = ( - self.user_client.share_network_security_service_list( - share_network['id'] - ) - ) - - self.assertEqual(len(network_services), 1) - self.assertEqual(network_services[0]['id'], new_security_service['id']) - - def test_share_network_security_service_update(self): - share_network = self.create_share_network( - client=self.user_client, - name='cool_net_name', - description='fakedescription', - neutron_net_id='fake_neutron_net_id', - neutron_subnet_id='fake_neutron_subnet_id', - ) - current_name = 'current' - new_name = 'new' - current_security_service = self.create_security_service( - client=self.user_client, name=current_name - ) - new_security_service = self.create_security_service( - client=self.user_client, name=new_name - ) - - check_result = ( - self.user_client.share_network_security_service_add_check( - share_network['id'], current_security_service['id'] - ) - ) - - self.assertEqual(check_result['compatible'], 'True') - - self.user_client.share_network_security_service_add( - share_network['id'], current_security_service['id'] - ) - - network_services = ( - self.user_client.share_network_security_service_list( - share_network['id'] - ) - ) - - self.assertEqual(len(network_services), 1) - self.assertEqual(network_services[0]['name'], current_name) - - check_result = ( - self.user_client.share_network_security_service_update_check( - share_network['id'], - current_security_service['id'], - new_security_service['id'], - ) - ) - - self.assertEqual(check_result['compatible'], 'True') - - self.user_client.share_network_security_service_update( - share_network['id'], - current_security_service['id'], - new_security_service['id'], - ) - - network_services = ( - self.user_client.share_network_security_service_list( - share_network['id'] - ) - ) - - self.assertEqual(len(network_services), 1) - self.assertEqual(network_services[0]['name'], new_name) - - def test_share_network_subnet_create_check(self): - share_network = self.create_share_network( - client=self.user_client, - description='fakedescription', - ) - - check_result = self.user_client.share_network_subnet_create_check( - share_network['id'], - neutron_net_id='fake_neutron_net_id', - neutron_subnet_id='fake_neutron_subnet_id', - ) - - self.assertEqual(check_result['compatible'], 'True') - - @ddt.data( - {'neutron_net_id': None, 'neutron_subnet_id': 'fake_subnet_id'}, - {'neutron_net_id': 'fake_net_id', 'neutron_subnet_id': None}, - {'availability_zone': 'invalid_availability_zone'}, - ) - def test_check_add_share_network_subnet_with_invalid_params(self, params): - self.assertRaises( - tempest_lib_exc.CommandFailed, - self.user_client.share_network_subnet_create_check, - self.sn['id'], - **params, - ) - - def test_check_add_share_network_subnet_to_invalid_share_network(self): - self.assertRaises( - tempest_lib_exc.CommandFailed, - self.user_client.share_network_subnet_create_check, - 'invalid_share_network', - self.neutron_net_id, - self.neutron_subnet_id, - ) - - -class ShareNetworkSecurityServiceCheckReadWriteTests(base.BaseTestCase): - protocol = None - - def setUp(self): - super().setUp() - if self.protocol not in CONF.enable_protocols: - message = f"{self.protocol} tests are disabled." - raise self.skipException(message) - self.client = self.get_user_client() - if not self.client.share_network: - message = "Can run only with DHSS=True mode" - raise self.skipException(message) - - def _wait_for_update_security_service_compatible_result( - self, - share_network, - current_security_service, - new_security_service=None, - ): - compatible_expected_result = 'True' - check_is_compatible = 'None' - tentatives = 0 - - # There might be a delay from the time the check is requested until - # the backend has performed all checks - while check_is_compatible != compatible_expected_result: - tentatives += 1 - if not new_security_service: - check_is_compatible = ( - self.user_client.share_network_security_service_add_check( - share_network['id'], current_security_service['id'] - ) - )['compatible'] - else: - check_is_compatible = ( - self.user_client.share_network_security_service_update_check( - share_network['id'], - current_security_service['id'], - new_security_service['id'], - ) - )['compatible'] - if tentatives > 3: - timeout_message = ( - "Share network security service add/update check did not " - "reach 'compatible=True' within 15 seconds." - ) - raise exceptions.TimeoutException(message=timeout_message) - time.sleep(5) - - def test_check_if_security_service_can_be_added_to_share_network_in_use( - self, - ): - share_network = self.create_share_network( - client=self.user_client, - description='fakedescription', - neutron_net_id='fake_neutron_net_id', - neutron_subnet_id='fake_neutron_subnet_id', - ) - # Create a share so we can be sure that a share server will exist and - # the check will be performed in the backends - self.create_share( - self.protocol, - client=self.user_client, - share_network=share_network['id'], - ) - - current_security_service = self.create_security_service( - client=self.user_client - ) - - check_result = ( - self.user_client.share_network_security_service_add_check( - share_network['id'], current_security_service['id'] - ) - ) - - self.assertEqual(check_result['compatible'], 'None') - - self._wait_for_update_security_service_compatible_result( - share_network, current_security_service - ) - - def test_add_and_update_security_service_when_share_network_is_in_use( - self, - ): - share_network = self.create_share_network( - client=self.user_client, - name='cool_net_name', - description='fakedescription', - neutron_net_id='fake_neutron_net_id', - neutron_subnet_id='fake_neutron_subnet_id', - ) - - # Create a share so we can be sure that a share server will exist and - # the check will be performed in the backends - self.create_share( - self.protocol, - name='fake_share_name', - share_network=share_network['id'], - client=self.user_client, - ) - - current_security_service = self.create_security_service( - client=self.user_client, name='current_security_service' - ) - new_security_service = self.create_security_service( - client=self.user_client, name='new_security_service' - ) - - check_result = ( - self.user_client.share_network_security_service_add_check( - share_network['id'], current_security_service['id'] - ) - ) - - self.assertEqual(check_result['compatible'], 'None') - - self._wait_for_update_security_service_compatible_result( - share_network, current_security_service - ) - - self.user_client.share_network_security_service_add( - share_network['id'], current_security_service['id'] - ) - - network_services = ( - self.user_client.share_network_security_service_list( - share_network['id'] - ) - ) - - self.assertEqual(len(network_services), 1) - self.assertEqual( - network_services[0]['name'], current_security_service['name'] - ) - - self.user_client.wait_for_resource_status( - share_network['id'], - 'active', - microversion=SECURITY_SERVICE_UPDATE_VERSION, - resource_type="share_network", - ) - - check_result = ( - self.user_client.share_network_security_service_update_check( - share_network['id'], - current_security_service['id'], - new_security_service['id'], - ) - ) - - self.assertEqual(check_result['compatible'], 'None') - - self._wait_for_update_security_service_compatible_result( - share_network, - current_security_service, - new_security_service=new_security_service, - ) - - self.user_client.share_network_security_service_update( - share_network['id'], - current_security_service['id'], - new_security_service['id'], - ) - - network_services = ( - self.user_client.share_network_security_service_list( - share_network['id'] - ) - ) - - self.assertEqual(len(network_services), 1) - self.assertEqual( - network_services[0]['name'], new_security_service['name'] - ) - - self.user_client.wait_for_resource_status( - share_network['id'], - 'active', - microversion=SECURITY_SERVICE_UPDATE_VERSION, - resource_type="share_network", - ) - - -base_security_service_check = ShareNetworkSecurityServiceCheckReadWriteTests - - -class ShareNetworkSecServiceCheckRWNFSTest(base_security_service_check): - protocol = 'nfs' - - -class ShareNetworkSecServiceCheckRWTestsCIFSTest(base_security_service_check): - protocol = 'cifs' diff --git a/manilaclient/tests/functional/test_share_replica_export_locations.py b/manilaclient/tests/functional/test_share_replica_export_locations.py deleted file mode 100644 index 219a9200..00000000 --- a/manilaclient/tests/functional/test_share_replica_export_locations.py +++ /dev/null @@ -1,122 +0,0 @@ -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import ddt -from oslo_utils import uuidutils -import testtools - -from manilaclient import config -from manilaclient.tests.functional import base -from manilaclient.tests.functional import utils - -CONF = config.CONF - - -@ddt.ddt -@testtools.skipUnless( - CONF.run_replication_tests, "Replication tests are disabled." -) -@utils.skip_if_microversion_not_supported('2.47') -class ShareReplicaExportLocationsTest(base.BaseTestCase): - def _create_share_and_replica(self): - replication_type = CONF.replication_type - share_type = self.create_share_type( - driver_handles_share_servers=False, - extra_specs={'replication_type': replication_type}, - ) - share = self.create_share( - share_type=share_type['ID'], client=self.get_user_client() - ) - share_replica = self.create_share_replica(share['id']) - return share, share_replica - - @ddt.data('admin', 'user') - def test_list_share_export_locations(self, role): - share, share_replica = self._create_share_and_replica() - client = self.admin_client if role == 'admin' else self.user_client - export_locations = client.list_share_replica_export_locations( - share_replica['id'] - ) - - self.assertGreater(len(export_locations), 0) - expected_keys = [ - 'ID', - 'Path', - 'Preferred', - 'Replica State', - 'Availability Zone', - ] - - for el in export_locations: - for key in expected_keys: - self.assertIn(key, el) - self.assertTrue(uuidutils.is_uuid_like(el['ID'])) - self.assertIn(el['Preferred'], ('True', 'False')) - - @ddt.data('admin', 'user') - def test_list_share_export_locations_with_columns(self, role): - share, share_replica = self._create_share_and_replica() - client = self.admin_client if role == 'admin' else self.user_client - export_locations = client.list_share_replica_export_locations( - share_replica['id'], columns='id,path' - ) - - self.assertGreater(len(export_locations), 0) - expected_keys = ('Id', 'Path') - unexpected_keys = ('Updated At', 'Created At') - for el in export_locations: - for key in expected_keys: - self.assertIn(key, el) - for key in unexpected_keys: - self.assertNotIn(key, el) - self.assertTrue(uuidutils.is_uuid_like(el['Id'])) - - @ddt.data('admin', 'user') - def test_get_share_replica_export_location(self, role): - share, share_replica = self._create_share_and_replica() - client = self.admin_client if role == 'admin' else self.user_client - export_locations = client.list_share_replica_export_locations( - share_replica['id'] - ) - - el = client.get_share_replica_export_location( - share_replica['id'], export_locations[0]['ID'] - ) - - expected_keys = [ - 'path', - 'updated_at', - 'created_at', - 'id', - 'preferred', - 'replica_state', - 'availability_zone', - ] - if role == 'admin': - expected_keys.extend(['is_admin_only', 'share_instance_id']) - for key in expected_keys: - self.assertIn(key, el) - if role == 'admin': - self.assertTrue(uuidutils.is_uuid_like(el['share_instance_id'])) - self.assertIn(el['is_admin_only'], ('True', 'False')) - self.assertTrue(uuidutils.is_uuid_like(el['id'])) - self.assertIn(el['preferred'], ('True', 'False')) - for list_k, get_k in ( - ('ID', 'id'), - ('Path', 'path'), - ('Preferred', 'preferred'), - ('Replica State', 'replica_state'), - ('Availability Zone', 'availability_zone'), - ): - self.assertEqual(export_locations[0][list_k], el[get_k]) diff --git a/manilaclient/tests/functional/test_share_replicas.py b/manilaclient/tests/functional/test_share_replicas.py deleted file mode 100644 index f7465688..00000000 --- a/manilaclient/tests/functional/test_share_replicas.py +++ /dev/null @@ -1,51 +0,0 @@ -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from manilaclient import config -from manilaclient.tests.functional import base -from manilaclient.tests.functional import utils - -CONF = config.CONF - - -@utils.skip_if_microversion_not_supported('2.72') -class ShareReplicasTest(base.BaseTestCase): - def _create_share_and_replica(self): - replication_type = CONF.replication_type - share_type = self.create_share_type( - driver_handles_share_servers=True, - extra_specs={'replication_type': replication_type}, - ) - share_network = self.create_share_network() - share = self.create_share( - share_type=share_type['ID'], - share_network=share_network['id'], - client=self.get_user_client(), - ) - share_replica = self.create_share_replica( - share['id'], - share_network=share_network['id'], - wait_for_creation=True, - client=self.get_user_client(), - ) - return share, share_replica - - def test_share_replica_create(self): - share, share_replica = self._create_share_and_replica() - self.assertEqual(share['id'], share_replica['share_id']) - - def test_share_replica_delete(self): - share, share_replica = self._create_share_and_replica() - self.user_client.delete_share_replica(share_replica['id']) - self.user_client.wait_for_share_replica_deletion(share_replica['id']) diff --git a/manilaclient/tests/functional/test_share_servers.py b/manilaclient/tests/functional/test_share_servers.py deleted file mode 100644 index 63e4c19c..00000000 --- a/manilaclient/tests/functional/test_share_servers.py +++ /dev/null @@ -1,405 +0,0 @@ -# Copyright 2015 Mirantis Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import ast -import ddt -import testtools - -from tempest.lib.common.utils import data_utils -from tempest.lib import exceptions - -from manilaclient.common import constants -from manilaclient import config -from manilaclient.tests.functional import base -from manilaclient.tests.functional import utils - -CONF = config.CONF - - -@ddt.ddt -class ShareServersReadOnlyTest(base.BaseTestCase): - def setUp(self): - super().setUp() - self.client = self.get_admin_client() - - def test_share_server_list(self): - self.client.list_share_servers() - - def test_share_server_list_with_host_param(self): - self.client.list_share_servers(filters={'host': 'fake_host'}) - - def test_share_server_list_with_status_param(self): - self.client.list_share_servers(filters={'status': 'fake_status'}) - - def test_share_server_list_with_share_network_param(self): - self.client.list_share_servers(filters={'share_network': 'fake_sn'}) - - def test_share_server_list_with_project_id_param(self): - self.client.list_share_servers( - filters={'project_id': 'fake_project_id'} - ) - - @ddt.data( - 'host', - 'status', - 'project_id', - 'share_network', - 'host,status,project_id,share_network', - ) - def test_share_server_list_with_specified_columns(self, columns): - self.client.list_share_servers(columns=columns) - - def test_share_server_list_by_user(self): - self.assertRaises( - exceptions.CommandFailed, self.user_client.list_share_servers - ) - - -@ddt.ddt -class ShareServersReadWriteBase(base.BaseTestCase): - protocol = None - - def setUp(self): - super().setUp() - if not CONF.run_share_servers_tests: - message = "share-server tests are disabled." - raise self.skipException(message) - if self.protocol not in CONF.enable_protocols: - message = f"{self.protocol} tests are disabled." - raise self.skipException(message) - self.client = self.get_admin_client() - if not self.client.share_network: - message = "Can run only with DHSS=True mode" - raise self.skipException(message) - - def _create_share_and_share_network(self): - name = data_utils.rand_name('autotest_share_name') - description = data_utils.rand_name('autotest_share_description') - - common_share_network = self.client.get_share_network( - self.client.share_network - ) - share_net_info = ( - utils.get_default_subnet( - self.user_client, common_share_network['id'] - ) - if utils.share_network_subnets_are_supported() - else common_share_network - ) - neutron_net_id = ( - share_net_info['neutron_net_id'] - if 'none' not in share_net_info['neutron_net_id'].lower() - else None - ) - neutron_subnet_id = ( - share_net_info['neutron_subnet_id'] - if 'none' not in share_net_info['neutron_subnet_id'].lower() - else None - ) - share_network = self.client.create_share_network( - neutron_net_id=neutron_net_id, - neutron_subnet_id=neutron_subnet_id, - ) - - self.share = self.create_share( - share_protocol=self.protocol, - size=1, - name=name, - description=description, - share_network=share_network['id'], - client=self.client, - wait_for_creation=True, - ) - self.share = self.client.get_share(self.share['id']) - return self.share, share_network - - def _delete_share_and_share_server(self, share_id, share_server_id): - # Delete share - self.client.delete_share(share_id) - self.client.wait_for_share_deletion(share_id) - - # Delete share server - self.client.delete_share_server(share_server_id) - self.client.wait_for_share_server_deletion(share_server_id) - - def test_get_and_delete_share_server(self): - self.share, share_network = self._create_share_and_share_network() - share_server_id = self.client.get_share(self.share['id'])[ - 'share_server_id' - ] - - # Get share server - server = self.client.get_share_server(share_server_id) - expected_keys = ( - 'id', - 'host', - 'status', - 'created_at', - 'updated_at', - 'share_network_id', - 'share_network_name', - 'project_id', - ) - - if utils.is_microversion_supported('2.49'): - expected_keys += ('identifier', 'is_auto_deletable') - - for key in expected_keys: - self.assertIn(key, server) - - self._delete_share_and_share_server(self.share['id'], share_server_id) - self.client.delete_share_network(share_network['id']) - - @testtools.skipUnless( - CONF.run_manage_tests, 'Share Manage/Unmanage tests are disabled.' - ) - @utils.skip_if_microversion_not_supported('2.49') - def test_manage_and_unmanage_share_server(self): - share, share_network = self._create_share_and_share_network() - share_server_id = self.client.get_share(self.share['id'])[ - 'share_server_id' - ] - server = self.client.get_share_server(share_server_id) - server_host = server['host'] - export_location = self.client.list_share_export_locations( - self.share['id'] - )[0]['Path'] - share_host = share['host'] - identifier = server['identifier'] - - self.assertEqual('True', server['is_auto_deletable']) - - # Unmanages share - self.client.unmanage_share(share['id']) - self.client.wait_for_share_deletion(share['id']) - - server = self.client.get_share_server(share_server_id) - self.assertEqual('False', server['is_auto_deletable']) - - # Unmanages share server - self.client.unmanage_server(share_server_id) - self.client.wait_for_share_server_deletion(share_server_id) - - # Manage share server - managed_share_server_id = self.client.share_server_manage( - server_host, share_network['id'], identifier - ) - self.client.wait_for_resource_status( - managed_share_server_id, - constants.STATUS_ACTIVE, - resource_type='share_server', - ) - - managed_server = self.client.get_share_server(managed_share_server_id) - self.assertEqual('False', managed_server['is_auto_deletable']) - - # Manage share - managed_share_id = self.client.manage_share( - share_host, self.protocol, export_location, managed_share_server_id - ) - self.client.wait_for_resource_status( - managed_share_id, constants.STATUS_AVAILABLE - ) - - self._delete_share_and_share_server( - managed_share_id, managed_share_server_id - ) - self.client.delete_share_network(share_network['id']) - - -class ShareServersReadWriteNFSTest(ShareServersReadWriteBase): - protocol = 'nfs' - - -class ShareServersReadWriteCIFSTest(ShareServersReadWriteBase): - protocol = 'cifs' - - -@ddt.ddt -@utils.skip_if_microversion_not_supported('2.57') -class ShareServersMigrationBase(base.BaseTestCase): - protocol = None - - def setUp(self): - super().setUp() - if not CONF.run_share_servers_tests: - message = "Share-server tests are disabled." - raise self.skipException(message) - if self.protocol not in CONF.enable_protocols: - message = f"{self.protocol} tests are disabled." - raise self.skipException(message) - self.client = self.get_admin_client() - if not self.client.share_network: - message = "Can run only with DHSS=True mode" - raise self.skipException(message) - if not CONF.run_share_servers_migration_tests: - message = "Share server migration tests are disabled." - raise self.skipException(message) - - def _create_share_and_share_network(self): - name = data_utils.rand_name('autotest_share_name') - description = data_utils.rand_name('autotest_share_description') - - common_share_network = self.client.get_share_network( - self.client.share_network - ) - share_net_info = utils.get_default_subnet( - self.client, common_share_network['id'] - ) - - neutron_net_id = ( - share_net_info['neutron_net_id'] - if 'none' not in share_net_info['neutron_net_id'].lower() - else None - ) - neutron_subnet_id = ( - share_net_info['neutron_subnet_id'] - if 'none' not in share_net_info['neutron_subnet_id'].lower() - else None - ) - share_network = self.client.create_share_network( - neutron_net_id=neutron_net_id, - neutron_subnet_id=neutron_subnet_id, - ) - share_type = self.create_share_type( - data_utils.rand_name('test_share_type'), - driver_handles_share_servers=True, - ) - - share = self.create_share( - share_protocol=self.protocol, - size=1, - name=name, - description=description, - share_type=share_type['ID'], - share_network=share_network['id'], - client=self.client, - wait_for_creation=True, - ) - share = self.client.get_share(share['id']) - return share, share_network - - @ddt.data('cancel', 'complete') - def test_share_server_migration(self, operation): - # Create a share and share network to be used in the tests. - share, share_network = self._create_share_and_share_network() - share_server_id = share['share_server_id'] - src_host = share['host'].split('#')[0] - pools = self.admin_client.pool_list(detail=True) - - host_list = list() - # Filter the backends DHSS True and different - # than the source host. - for hosts in pools: - host_name = hosts['Name'].split('#')[0] - if ( - ast.literal_eval(hosts['Capabilities']).get( - 'driver_handles_share_servers' - ) - and host_name != src_host - ): - host_list.append(host_name) - - host_list = list(set(host_list)) - # If not found any host we need skip the test. - if len(host_list) == 0: - raise self.skipException( - "No hosts available for share server migration." - ) - - dest_backend = None - # If found at least one host, we still need to verify the - # share server migration compatibility with the destination host. - for host in host_list: - compatibility = self.admin_client.share_server_migration_check( - server_id=share_server_id, - dest_host=host, - writable=False, - nondisruptive=False, - preserve_snapshots=False, - new_share_network=None, - ) - # If found at least one compatible host, we will use it. - if compatibility['compatible']: - dest_host = host - # If not found, we need skip the test. - if dest_backend is not None: - raise self.skipException( - "No hosts compatible to perform a share server migration." - ) - - # Start the share server migration - self.admin_client.share_server_migration_start( - share_server_id, dest_host - ) - - server = self.admin_client.get_share_server(share_server_id) - share = self.admin_client.get_share(share['id']) - self.assertEqual(constants.STATUS_SERVER_MIGRATING, share['status']) - - # Wait for the share server migration driver phase 1 done. - task_state = constants.TASK_STATE_MIGRATION_DRIVER_PHASE1_DONE - server = self.admin_client.wait_for_server_migration_task_state( - share_server_id, dest_host, task_state - ) - migration_progress = ( - self.admin_client.share_server_migration_get_progress( - share_server_id - ) - ) - dest_share_server_id = migration_progress.get( - 'destination_share_server_id' - ) - - # Call share server migration complete or cancel operations - # according the ddt. - if operation == 'complete': - task_state = constants.TASK_STATE_MIGRATION_SUCCESS - self.admin_client.share_server_migration_complete(share_server_id) - server = self.admin_client.wait_for_server_migration_task_state( - dest_share_server_id, dest_host, task_state - ) - - self.admin_client.wait_for_share_server_deletion(share_server_id) - else: - self.admin_client.share_server_migration_cancel(server['id']) - task_state = constants.TASK_STATE_MIGRATION_CANCELLED - # Wait for the respectives task state for each operation above. - server = self.admin_client.wait_for_server_migration_task_state( - server['id'], dest_host, task_state - ) - - # Check if the share is available again. - share = self.admin_client.get_share(share['id']) - self.assertEqual('available', share['status']) - - -class ShareServersMigrationNFSTest(ShareServersMigrationBase): - protocol = 'nfs' - - -class ShareServersMigrationCIFSTest(ShareServersMigrationBase): - protocol = 'cifs' - - -def load_tests(loader, tests, _): - result = [] - for test_case in tests: - if type(test_case._tests[0]) is ShareServersReadWriteBase: - continue - if type(test_case._tests[0]) is ShareServersMigrationBase: - continue - result.append(test_case) - return loader.suiteClass(result) diff --git a/manilaclient/tests/functional/test_share_transfers.py b/manilaclient/tests/functional/test_share_transfers.py deleted file mode 100644 index 75ca4420..00000000 --- a/manilaclient/tests/functional/test_share_transfers.py +++ /dev/null @@ -1,100 +0,0 @@ -# Copyright (c) 2022 China Telecom Digital Intelligence. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from tempest.lib.common.utils import data_utils - -from manilaclient.tests.functional import base - - -class ShareTransferTests(base.BaseTestCase): - """Check of base share transfers command""" - - def setUp(self): - super().setUp() - self.share_type = self.create_share_type( - name=data_utils.rand_name('test_share_type'), - driver_handles_share_servers=False, - ) - - def test_transfer_create_list_show_delete(self): - """Create, list, show and delete a share transfer""" - self.skip_if_microversion_not_supported('2.77') - share = self.create_share( - share_protocol='nfs', - size=1, - name=data_utils.rand_name('autotest_share_name'), - client=self.user_client, - share_type=self.share_type['ID'], - use_wait_option=True, - ) - self.assertEqual("available", share['status']) - # create share transfer - transfer = self.create_share_transfer( - share['id'], name='test_share_transfer' - ) - self.assertIn('auth_key', transfer) - - # list share transfers - transfers = self.list_share_transfer() - # We must have at least one transfer - self.assertTrue(len(transfers) > 0) - - # show the share transfer - transfer_show = self.get_share_transfer(transfer['id']) - self.assertEqual(transfer_show['name'], transfer['name']) - self.assertNotIn('auth_key', transfer_show) - - # delete share transfer - self.delete_share_transfer(transfer['id']) - self.user_client.wait_for_transfer_deletion(transfer['id']) - share = self.user_client.get_share(share['id']) - self.assertEqual("available", share['status']) - # finally delete the share - self.user_client.delete_share(share['id']) - self.user_client.wait_for_share_deletion(share['id']) - - def test_transfer_accept(self): - """Show share transfer accept""" - self.skip_if_microversion_not_supported('2.77') - share = self.create_share( - share_protocol='nfs', - size=1, - name=data_utils.rand_name('autotest_share_name'), - client=self.user_client, - share_type=self.share_type['ID'], - use_wait_option=True, - ) - self.assertEqual("available", share['status']) - # create share transfer - transfer = self.create_share_transfer( - share['id'], name='test_share_transfer' - ) - share = self.user_client.get_share(share['id']) - transfer_id = transfer['id'] - auth_key = transfer['auth_key'] - self.assertEqual("share", transfer['resource_type']) - self.assertEqual('test_share_transfer', transfer['name']) - self.assertEqual("awaiting_transfer", share['status']) - - # accept the share transfer - self.accept_share_transfer(transfer_id, auth_key) - # after accept complete, the transfer will be deleted. - self.user_client.wait_for_transfer_deletion(transfer_id) - share = self.user_client.get_share(share['id']) - # check share status roll back to available - self.assertEqual("available", share['status']) - # finally delete the share - self.user_client.delete_share(share['id']) - self.user_client.wait_for_share_deletion(share['id']) diff --git a/manilaclient/tests/functional/test_share_types.py b/manilaclient/tests/functional/test_share_types.py deleted file mode 100644 index eaa9f668..00000000 --- a/manilaclient/tests/functional/test_share_types.py +++ /dev/null @@ -1,627 +0,0 @@ -# Copyright 2015 Mirantis Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import ddt -from tempest.lib.common.utils import data_utils - -from manilaclient import api_versions -from manilaclient.tests.functional import base -from manilaclient.tests.unit.v2 import test_types as unit_test_types - - -@ddt.ddt -class ShareTypesReadOnlyTest(base.BaseTestCase): - @ddt.data( - ("admin", "1.0"), - ("admin", "2.0"), - ("admin", "2.6"), - ("admin", "2.7"), - ("user", "1.0"), - ("user", "2.0"), - ("user", "2.6"), - ("user", "2.7"), - ) - @ddt.unpack - def test_share_type_list(self, role, microversion): - self.skip_if_microversion_not_supported(microversion) - self.clients[role].manila("type-list", microversion=microversion) - - @ddt.data("1.0", "2.0", "2.6", "2.7") - def test_extra_specs_list(self, microversion): - self.skip_if_microversion_not_supported(microversion) - self.admin_client.manila("extra-specs-list", microversion=microversion) - - -@ddt.ddt -class ShareTypesReadWriteTest(base.BaseTestCase): - create_keys = ( - 'ID', - 'Name', - 'Visibility', - 'is_default', - 'required_extra_specs', - 'optional_extra_specs', - ) - - def _share_type_listed_by( - self, share_type_id, by_admin=False, list_all=False, microversion=None - ): - client = self.admin_client if by_admin else self.user_client - share_types = client.list_share_types( - list_all=list_all, microversion=microversion - ) - return any(share_type_id == st['ID'] for st in share_types) - - def _verify_access(self, share_type_id, is_public, microversion=None): - if is_public: - # Verify that it is listed with common 'type-list' operation. - share_types = self.admin_client.list_share_types( - list_all=False, microversion=microversion - ) - self.assertTrue( - any(share_type_id == st['ID'] for st in share_types) - ) - else: - # Verify that it is not listed for user - self.assertFalse( - self._share_type_listed_by( - share_type_id=share_type_id, - by_admin=False, - list_all=True, - microversion=microversion, - ) - ) - - # Verify it is listed for admin - self.assertTrue( - self._share_type_listed_by( - share_type_id=share_type_id, - by_admin=True, - list_all=True, - microversion=microversion, - ) - ) - - # Verify it is not listed by default - self.assertFalse( - self._share_type_listed_by( - share_type_id=share_type_id, - by_admin=True, - list_all=False, - microversion=microversion, - ) - ) - - @ddt.data(*unit_test_types.get_valid_type_create_data_2_0()) - @ddt.unpack - def test_create_delete_share_type( - self, is_public, dhss, spec_snapshot_support, extra_specs - ): - self.skip_if_microversion_not_supported('2.0') - self._test_create_delete_share_type( - '2.0', - is_public, - dhss, - spec_snapshot_support, - None, - None, - None, - extra_specs, - ) - - @ddt.data(*unit_test_types.get_valid_type_create_data_2_24()) - @ddt.unpack - def test_create_delete_share_type_2_24( - self, - is_public, - dhss, - spec_snapshot_support, - spec_create_share_from_snapshot, - extra_specs, - ): - self.skip_if_microversion_not_supported('2.24') - self._test_create_delete_share_type( - '2.24', - is_public, - dhss, - spec_snapshot_support, - spec_create_share_from_snapshot, - None, - None, - extra_specs, - ) - - @ddt.data(*unit_test_types.get_valid_type_create_data_2_27()) - @ddt.unpack - def test_create_delete_share_type_2_27( - self, - is_public, - dhss, - spec_snapshot_support, - spec_create_share_from_snapshot, - spec_revert_to_snapshot_support, - extra_specs, - ): - self.skip_if_microversion_not_supported('2.27') - self._test_create_delete_share_type( - '2.27', - is_public, - dhss, - spec_snapshot_support, - spec_create_share_from_snapshot, - spec_revert_to_snapshot_support, - None, - extra_specs, - ) - - def test_create_delete_share_type_with_description(self): - self.skip_if_microversion_not_supported('2.41') - self._test_create_delete_share_type( - '2.41', - True, - False, - None, - None, - None, - None, - None, - description=data_utils.rand_name('test_share_type_description'), - ) - - @ddt.data( - ('name_updated_1', 'description_updated', True), - ('name_updated_2', 'description_updated', False), - ('name_updated_3', None, None), - (None, 'description_updated', None), - (None, None, True), - (None, None, False), - ) - @ddt.unpack - def test_create_update_delete_share_type_2_50( - self, new_name, new_description, new_is_public - ): - self.skip_if_microversion_not_supported('2.50') - microversion = '2.50' - share_type_name = data_utils.rand_name('share_type_update_test') - - # Create share type - share_type = self.create_share_type( - name=share_type_name, - driver_handles_share_servers=False, - snapshot_support=None, - create_share_from_snapshot=None, - revert_to_snapshot=None, - mount_snapshot=None, - is_public=True, - microversion=microversion, - extra_specs={}, - description="share_type_description", - ) - - st_id = share_type['ID'] - - # Update share type - st_updated = self.update_share_type( - st_id, - name=new_name, - description=new_description, - is_public=new_is_public, - microversion=microversion, - ) - # Verify type name - if new_name: - self.assertEqual(new_name, st_updated['Name']) - - # Verify type description - if new_description: - self.assertEqual(new_description, st_updated['Description']) - - # Verify public - if new_is_public is not None: - self.assertEqual( - 'public' if new_is_public else 'private', - st_updated['Visibility'].lower(), - ) - - # Delete share type - self.admin_client.delete_share_type(st_id, microversion=microversion) - - # Wait for share type deletion - self.admin_client.wait_for_share_type_deletion( - st_id, microversion=microversion - ) - - # Verify that it is not listed with common 'type-list' operation. - share_types = self.admin_client.list_share_types( - list_all=False, microversion=microversion - ) - self.assertFalse(any(st_id == st['ID'] for st in share_types)) - - def test_unset_share_type_description_2_50(self): - self.skip_if_microversion_not_supported('2.50') - microversion = '2.50' - share_type_name = data_utils.rand_name('share_type_update_test') - - # Create share type - share_type = self.create_share_type( - name=share_type_name, - driver_handles_share_servers=False, - snapshot_support=None, - create_share_from_snapshot=None, - revert_to_snapshot=None, - mount_snapshot=None, - is_public=True, - microversion=microversion, - extra_specs={}, - description="share_type_description", - ) - - st_id = share_type['ID'] - - # Update share type - new_description = "" - st_updated = self.update_share_type( - st_id, description=new_description, microversion=microversion - ) - - # Verify type description - self.assertEqual('None', st_updated['Description']) - - # Delete share type - self.admin_client.delete_share_type(st_id, microversion=microversion) - - # Wait for share type deletion - self.admin_client.wait_for_share_type_deletion( - st_id, microversion=microversion - ) - - # Verify that it is not listed with common 'type-list' operation. - share_types = self.admin_client.list_share_types( - list_all=False, microversion=microversion - ) - self.assertFalse(any(st_id == st['ID'] for st in share_types)) - - def _test_create_delete_share_type( - self, - microversion, - is_public, - dhss, - spec_snapshot_support, - spec_create_share_from_snapshot, - spec_revert_to_snapshot_support, - spec_mount_snapshot_support, - extra_specs, - description=None, - ): - share_type_name = data_utils.rand_name('manilaclient_functional_test') - - if extra_specs is None: - extra_specs = {} - - # Create share type - share_type = self.create_share_type( - name=share_type_name, - driver_handles_share_servers=dhss, - snapshot_support=spec_snapshot_support, - create_share_from_snapshot=spec_create_share_from_snapshot, - revert_to_snapshot=spec_revert_to_snapshot_support, - mount_snapshot=spec_mount_snapshot_support, - is_public=is_public, - microversion=microversion, - extra_specs=extra_specs, - description=description, - ) - - # Verify response body - for key in self.create_keys: - self.assertIn(key, share_type) - - # Verify type name - self.assertEqual(share_type_name, share_type['Name']) - - # Verify type description - if api_versions.APIVersion(microversion) >= api_versions.APIVersion( - '2.41' - ): - self.assertEqual(description, share_type['Description']) - else: - self.assertNotIn('description', share_type) - - # Verify required DHSS extra spec - dhss_expected = f'driver_handles_share_servers : {dhss}' - self.assertEqual(dhss_expected, share_type['required_extra_specs']) - - # Determine expected extra specs. Note that prior to 2.24, - # the standard 'snapshot_support' extra spec was required. - expected_extra_specs = [] - for key, val in extra_specs.items(): - expected_extra_specs.append((f'{key} : {val}').strip()) - - if api_versions.APIVersion(microversion) < api_versions.APIVersion( - '2.24' - ): - if 'snapshot_support' not in extra_specs: - if spec_snapshot_support is None: - expected_extra_specs.append( - ('{} : {}'.format('snapshot_support', True)).strip() - ) - else: - expected_extra_specs.append( - ( - '{} : {}'.format( - 'snapshot_support', spec_snapshot_support - ) - ).strip() - ) - else: - if spec_snapshot_support is not None: - expected_extra_specs.append( - ( - '{} : {}'.format( - 'snapshot_support', spec_snapshot_support - ) - ).strip() - ) - - if spec_create_share_from_snapshot is not None: - expected_extra_specs.append( - ( - '{} : {}'.format( - 'create_share_from_snapshot_support', - spec_create_share_from_snapshot, - ) - ).strip() - ) - if spec_revert_to_snapshot_support is not None: - expected_extra_specs.append( - ( - '{} : {}'.format( - 'revert_to_snapshot_support', - spec_revert_to_snapshot_support, - ) - ).strip() - ) - if spec_mount_snapshot_support is not None: - expected_extra_specs.append( - ( - '{} : {}'.format( - 'mount_snapshot_support', spec_mount_snapshot_support - ) - ).strip() - ) - - # Verify optional extra specs - optional_extra_specs = share_type['optional_extra_specs'] - if optional_extra_specs == '': - optional_extra_specs = [] - elif not isinstance(optional_extra_specs, list): - optional_extra_specs = [optional_extra_specs] - - self.assertEqual(len(expected_extra_specs), len(optional_extra_specs)) - for e in optional_extra_specs: - self.assertIn(e.strip(), expected_extra_specs) - - # Verify public & default attributes - self.assertEqual( - 'public' if is_public else 'private', - share_type['Visibility'].lower(), - ) - self.assertEqual('-', share_type['is_default']) - - # Verify its access - st_id = share_type['ID'] - self._verify_access( - share_type_id=st_id, is_public=is_public, microversion=microversion - ) - - # Delete share type - self.admin_client.delete_share_type(st_id, microversion=microversion) - - # Wait for share type deletion - self.admin_client.wait_for_share_type_deletion( - st_id, microversion=microversion - ) - - # Verify that it is not listed with common 'type-list' operation. - share_types = self.admin_client.list_share_types( - list_all=False, microversion=microversion - ) - self.assertFalse(any(st_id == st['ID'] for st in share_types)) - - @ddt.data("2.6", "2.7") - def test_add_remove_access_to_private_share_type(self, microversion): - self.skip_if_microversion_not_supported(microversion) - - share_type_name = data_utils.rand_name('manilaclient_functional_test') - is_public = False - - # Create share type - share_type = self.create_share_type( - name=share_type_name, - driver_handles_share_servers='False', - is_public=is_public, - microversion=microversion, - ) - - st_id = share_type['ID'] - user_project_id = self.admin_client.get_project_id( - self.user_client.tenant_name - ) - - self._verify_access( - share_type_id=st_id, - is_public=is_public, - microversion=microversion, - ) - - # Project ID is in access list - false - st_access_list = self.admin_client.list_share_type_access( - st_id, microversion=microversion - ) - self.assertNotIn(user_project_id, st_access_list) - - # Add access for project of user - self.admin_client.add_share_type_access( - st_id, user_project_id, microversion=microversion - ) - - # Verify it is listed for user as well as for admin - self.assertTrue( - self._share_type_listed_by( - share_type_id=st_id, by_admin=False, list_all=True - ) - ) - self.assertTrue( - self._share_type_listed_by( - share_type_id=st_id, by_admin=True, list_all=True - ) - ) - - # Project ID is in access list - true - st_access_list = self.admin_client.list_share_type_access( - st_id, microversion=microversion - ) - self.assertIn(user_project_id, st_access_list) - - # Remove access - self.admin_client.remove_share_type_access( - st_id, user_project_id, microversion=microversion - ) - - self._verify_access( - share_type_id=st_id, - is_public=is_public, - microversion=microversion, - ) - - # Project ID is in access list - false - st_access_list = self.admin_client.list_share_type_access( - st_id, microversion=microversion - ) - self.assertNotIn(user_project_id, st_access_list) - - @ddt.data("2.6", "2.7") - def test_list_share_type(self, microversion): - share_type_name = data_utils.rand_name('manilaclient_functional_test') - - # Create share type - self.create_share_type( - name=share_type_name, driver_handles_share_servers='False' - ) - share_types = self.admin_client.list_share_types( - list_all=True, microversion=microversion - ) - self.assertTrue(any(s['ID'] is not None for s in share_types)) - self.assertTrue(any(s['Name'] is not None for s in share_types)) - self.assertTrue(any(s['visibility'] is not None for s in share_types)) - - @ddt.data("2.6", "2.7") - def test_list_share_type_select_column(self, microversion): - share_type_name = data_utils.rand_name('manilaclient_functional_test') - - # Create share type - self.create_share_type( - name=share_type_name, driver_handles_share_servers='False' - ) - share_types = self.admin_client.list_share_types( - list_all=True, columns="id,name", microversion=microversion - ) - self.assertTrue(any(s['id'] is not None for s in share_types)) - self.assertTrue(any(s['name'] is not None for s in share_types)) - self.assertTrue(all('visibility' not in s for s in share_types)) - self.assertTrue(all('Visibility' not in s for s in share_types)) - - def test_list_share_type_filter_search(self): - # Fake extra spec and type name - extra_specs = {'aaaa': 'bbbb'} - # Create share type - name1 = data_utils.rand_name('manilaclient_functional_test1') - self.create_share_type( - name=name1, driver_handles_share_servers='False' - ) - # Create share type - name2 = data_utils.rand_name('manilaclient_functional_test2') - self.create_share_type( - name=name2, - extra_specs=extra_specs, - driver_handles_share_servers='True', - ) - - # List type by extra_specs - list_all = False - search_opts = {'extra_specs': extra_specs} - share_types = self.admin_client.list_share_types( - list_all=list_all, search_opts=search_opts, microversion='2.43' - ) - self.assertTrue(share_types is not None) - - expect = 'aaaa : bbbb' - self.assertTrue(len(share_types) == 1) - self.assertTrue(all('optional_extra_specs' in s for s in share_types)) - self.assertTrue(all(s['Name'] == name2 for s in share_types)) - self.assertTrue( - all(s['optional_extra_specs'] == expect for s in share_types) - ) - - -@ddt.ddt -class ShareTypeExtraSpecsReadWriteTest(base.BaseTestCase): - @ddt.data( - (True, False), - (True, True), - (False, True), - (False, False), - (False, False, "2.6"), - (False, False, "2.7"), - ) - @ddt.unpack - def test_share_type_extra_specs_life_cycle( - self, is_public, dhss, microversion=None - ): - if microversion: - self.skip_if_microversion_not_supported(microversion) - - # Create share type - st = self.create_share_type( - driver_handles_share_servers=dhss, - is_public=is_public, - microversion=microversion, - ) - - # Add extra specs to share type - st_extra_specs = dict(foo_key='foo_value', bar_key='bar_value') - self.admin_client.set_share_type_extra_specs( - st['ID'], st_extra_specs, microversion=microversion - ) - - # View list of extra specs - extra_specs = self.admin_client.list_share_type_extra_specs( - st['ID'], microversion=microversion - ) - for k, v in st_extra_specs.items(): - self.assertIn(f'{k} : {v}', extra_specs) - - # Remove one extra spec - self.admin_client.unset_share_type_extra_specs( - st['ID'], ('foo_key',), microversion=microversion - ) - - # Verify that removed extra spec is absent - extra_specs = self.admin_client.list_share_type_extra_specs( - st['ID'], microversion=microversion - ) - self.assertNotIn('foo_key : foo_value', extra_specs) - self.assertIn('bar_key : bar_value', extra_specs) - self.assertIn(f'driver_handles_share_servers : {dhss}', extra_specs) diff --git a/manilaclient/tests/functional/test_shares.py b/manilaclient/tests/functional/test_shares.py deleted file mode 100644 index 7b589612..00000000 --- a/manilaclient/tests/functional/test_shares.py +++ /dev/null @@ -1,339 +0,0 @@ -# Copyright 2015 Mirantis Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import ddt -import testtools - -from tempest.lib.common.utils import data_utils -from tempest.lib import exceptions - -from manilaclient.common import constants -from manilaclient import config -from manilaclient.tests.functional import base -from manilaclient.tests.functional import utils - -CONF = config.CONF - - -@ddt.ddt -class SharesReadWriteBase(base.BaseTestCase): - protocol = None - - def setUp(self): - super().setUp() - if self.protocol not in CONF.enable_protocols: - message = f"{self.protocol} tests are disabled" - raise self.skipException(message) - self.name = data_utils.rand_name('autotest_share_name') - self.description = data_utils.rand_name('autotest_share_description') - - # NOTE(vponomaryov): following share is used only in one test - # until tests for snapshots appear. - self.share = self.create_share( - share_protocol=self.protocol, - size=1, - name=self.name, - description=self.description, - client=self.get_user_client(), - ) - - def test_create_delete_share(self): - name = data_utils.rand_name('autotest_share_name') - - create = self.create_share( - self.protocol, name=name, client=self.user_client - ) - - self.assertEqual("creating", create['status']) - self.assertEqual(name, create['name']) - self.assertEqual('1', create['size']) - self.assertEqual(self.protocol.upper(), create['share_proto']) - - self.user_client.delete_share(create['id']) - - self.user_client.wait_for_share_deletion(create['id']) - - def test_create_update_share(self): - name = data_utils.rand_name('autotest_share_name') - new_name = 'new_' + name - description = data_utils.rand_name('autotest_share_description') - new_description = 'new_' + description - - create = self.create_share( - self.protocol, - name=name, - description=description, - client=self.user_client, - ) - - self.assertEqual(name, create['name']) - self.assertEqual(description, create['description']) - self.assertEqual('False', create['is_public']) - - self.user_client.update_share( - create['id'], name=new_name, description=new_description - ) - get = self.user_client.get_share(create['id']) - - self.assertEqual(new_name, get['name']) - self.assertEqual(new_description, get['description']) - self.assertEqual('False', get['is_public']) - - # only admins operating at system scope can set a share to be public - self.admin_client.update_share(create['id'], is_public=True) - get = self.user_client.get_share(create['id']) - - self.assertEqual(new_name, get['name']) - self.assertEqual(new_description, get['description']) - self.assertEqual('True', get['is_public']) - - def test_get_share(self): - get = self.user_client.get_share(self.share['id']) - - self.assertEqual(self.name, get['name']) - self.assertEqual(self.description, get['description']) - self.assertEqual('1', get['size']) - self.assertEqual(self.protocol.upper(), get['share_proto']) - - def test_create_delete_with_wait(self): - name = data_utils.rand_name('share-with-wait-%s') - description = data_utils.rand_name('we-wait-until-share-is-ready') - - share_1, share_2 = ( - self.create_share( - self.protocol, - name=(name % num), - description=description, - use_wait_option=True, - client=self.user_client, - ) - for num in range(0, 2) - ) - - self.assertEqual("available", share_1['status']) - self.assertEqual("available", share_2['status']) - - self.delete_share( - [share_1['id'], share_2['id']], wait=True, client=self.user_client - ) - - for share in (share_1, share_2): - self.assertRaises( - exceptions.NotFound, self.user_client.get_share, share['id'] - ) - - def test_create_soft_delete_and_restore_share(self): - self.skip_if_microversion_not_supported('2.69') - microversion = '2.69' - description = data_utils.rand_name('we-wait-until-share-is-ready') - - share = self.create_share( - self.protocol, - name='share_name', - description=description, - use_wait_option=True, - client=self.user_client, - ) - - self.assertEqual("available", share['status']) - - # soft delete the share to recycle bin - self.soft_delete_share( - [share['id']], client=self.user_client, microversion=microversion - ) - self.user_client.wait_for_share_soft_deletion(share['id']) - - # get shares list in recycle bin - result = self.user_client.list_shares( - is_soft_deleted=True, microversion=microversion - ) - share_ids = [sh['ID'] for sh in result] - # check share is in recycle bin - self.assertIn(share['id'], share_ids) - - # restore the share from recycle bin - self.restore_share( - [share['id']], client=self.user_client, microversion=microversion - ) - self.user_client.wait_for_share_restore(share['id']) - - result1 = self.user_client.list_shares( - is_soft_deleted=True, microversion=microversion - ) - share_ids1 = [sh['ID'] for sh in result1] - # check share not in recycle bin - self.assertNotIn(share['id'], share_ids1) - - -@ddt.ddt -class SharesTestMigration(base.BaseTestCase): - def setUp(self): - super().setUp() - - self.old_type = self.create_share_type( - data_utils.rand_name('test_share_type'), - driver_handles_share_servers=True, - ) - self.new_type = self.create_share_type( - data_utils.rand_name('test_share_type'), - driver_handles_share_servers=True, - ) - self.error_type = self.create_share_type( - data_utils.rand_name('test_share_type'), - driver_handles_share_servers=True, - extra_specs={'cause_error': 'no_valid_host'}, - ) - - self.old_share_net = self.get_user_client().get_share_network( - self.get_user_client().share_network - ) - share_net_info = ( - utils.get_default_subnet( - self.get_user_client(), self.old_share_net['id'] - ) - if utils.share_network_subnets_are_supported() - else self.old_share_net - ) - self.new_share_net = self.create_share_network( - neutron_net_id=share_net_info['neutron_net_id'], - neutron_subnet_id=share_net_info['neutron_subnet_id'], - ) - - @utils.skip_if_microversion_not_supported('2.22') - @ddt.data('migration_error', 'migration_success', 'None') - def test_reset_task_state(self, state): - share = self.create_share( - share_protocol='nfs', - size=1, - name=data_utils.rand_name('autotest_share_name'), - client=self.get_user_client(), - share_type=self.old_type['ID'], - share_network=self.old_share_net['id'], - wait_for_creation=True, - ) - share = self.user_client.get_share(share['id']) - - self.admin_client.reset_task_state(share['id'], state) - share = self.user_client.get_share(share['id']) - self.assertEqual(state, share['task_state']) - - @utils.skip_if_microversion_not_supported('2.29') - @testtools.skipUnless( - CONF.run_migration_tests, 'Share migration tests are disabled.' - ) - @ddt.data('cancel', 'success', 'error') - def test_full_migration(self, test_type): - # We are testing with DHSS=True only because it allows us to specify - # new_share_network. - - share = self.create_share( - share_protocol='nfs', - size=1, - name=data_utils.rand_name('autotest_share_name'), - client=self.get_user_client(), - share_type=self.old_type['ID'], - share_network=self.old_share_net['id'], - wait_for_creation=True, - ) - share = self.admin_client.get_share(share['id']) - - pools = self.admin_client.pool_list(detail=True) - - dest_pool = utils.choose_matching_backend(share, pools, self.new_type) - - self.assertIsNotNone(dest_pool) - - source_pool = share['host'] - - new_type = self.new_type - if test_type == 'error': - statuses = constants.TASK_STATE_MIGRATION_ERROR - new_type = self.error_type - else: - statuses = ( - constants.TASK_STATE_MIGRATION_DRIVER_PHASE1_DONE, - constants.TASK_STATE_DATA_COPYING_COMPLETED, - ) - - self.admin_client.migration_start( - share['id'], - dest_pool, - writable=True, - nondisruptive=False, - preserve_metadata=True, - preserve_snapshots=True, - force_host_assisted_migration=False, - new_share_network=self.new_share_net['id'], - new_share_type=new_type['ID'], - ) - - share = self.admin_client.wait_for_migration_task_state( - share['id'], dest_pool, statuses - ) - - progress = self.admin_client.migration_get_progress(share['id']) - self.assertEqual('100', progress['total_progress']) - - self.assertEqual(source_pool, share['host']) - self.assertEqual(self.old_type['ID'], share['share_type']) - self.assertEqual(self.old_share_net['id'], share['share_network_id']) - - if test_type == 'error': - self.assertEqual(statuses, progress['task_state']) - else: - if test_type == 'success': - self.admin_client.migration_complete(share['id']) - statuses = constants.TASK_STATE_MIGRATION_SUCCESS - elif test_type == 'cancel': - self.admin_client.migration_cancel(share['id']) - statuses = constants.TASK_STATE_MIGRATION_CANCELLED - - share = self.admin_client.wait_for_migration_task_state( - share['id'], dest_pool, statuses - ) - progress = self.admin_client.migration_get_progress(share['id']) - self.assertEqual(statuses, progress['task_state']) - if test_type == 'success': - self.assertEqual(dest_pool, share['host']) - self.assertEqual(new_type['ID'], share['share_type']) - self.assertEqual( - self.new_share_net['id'], share['share_network_id'] - ) - else: - self.assertEqual(source_pool, share['host']) - self.assertEqual(self.old_type['ID'], share['share_type']) - self.assertEqual( - self.old_share_net['id'], share['share_network_id'] - ) - - -class NFSSharesReadWriteTest(SharesReadWriteBase): - protocol = 'nfs' - - -class CIFSSharesReadWriteTest(SharesReadWriteBase): - protocol = 'cifs' - - -class GlusterFSSharesReadWriteTest(SharesReadWriteBase): - protocol = 'glusterfs' - - -class HDFSSharesReadWriteTest(SharesReadWriteBase): - protocol = 'hdfs' - - -class MAPRFSSharesReadWriteTest(SharesReadWriteBase): - protocol = 'maprfs' diff --git a/manilaclient/tests/functional/test_shares_listing.py b/manilaclient/tests/functional/test_shares_listing.py deleted file mode 100644 index 12f97313..00000000 --- a/manilaclient/tests/functional/test_shares_listing.py +++ /dev/null @@ -1,414 +0,0 @@ -# Copyright 2015 Mirantis Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import ddt -from tempest.lib.common.utils import data_utils -from tempest.lib import exceptions -import testtools - -from manilaclient.common import constants -from manilaclient import config -from manilaclient.tests.functional import base - -CONF = config.CONF - - -@ddt.ddt -class SharesListReadOnlyTest(base.BaseTestCase): - @ddt.data('admin', 'user') - def test_shares_list(self, role): - self.clients[role].manila('list') - - @ddt.data('admin', 'user') - def test_list_with_debug_flag(self, role): - self.clients[role].manila('list', flags='--debug') - - @ddt.data('admin', 'user') - def test_shares_list_all_tenants(self, role): - self.clients[role].manila('list', params='--all-tenants') - - @ddt.data('admin', 'user') - def test_shares_list_filter_by_name(self, role): - self.clients[role].manila('list', params='--name name') - - @ddt.data('admin', 'user') - def test_shares_list_filter_by_export_location(self, role): - self.clients[role].manila('list', params='--export_location fake') - - @ddt.data('admin', 'user') - def test_shares_list_filter_by_inexact_name(self, role): - self.clients[role].manila('list', params='--name~ na') - - @ddt.data('admin', 'user') - def test_shares_list_filter_by_inexact_description(self, role): - self.clients[role].manila('list', params='--description~ des') - - @ddt.data('admin', 'user') - def test_shares_list_filter_by_status(self, role): - self.clients[role].manila('list', params='--status status') - - def test_shares_list_filter_by_share_server_as_admin(self): - self.clients['admin'].manila('list', params='--share-server fake') - - def test_shares_list_filter_by_share_server_as_user(self): - self.assertRaises( - exceptions.CommandFailed, - self.clients['user'].manila, - 'list', - params='--share-server fake', - ) - - @ddt.data('admin', 'user') - def test_shares_list_filter_by_project_id(self, role): - self.clients[role].manila('list', params='--project-id fake') - - def test_shares_list_filter_by_host(self): - self.clients['admin'].manila('list', params='--host fake') - - @ddt.data('admin', 'user') - def test_shares_list_with_limit_and_offset(self, role): - self.clients[role].manila('list', params='--limit 1 --offset 1') - - @ddt.data( - {'role': 'admin', 'direction': 'asc'}, - {'role': 'admin', 'direction': 'desc'}, - {'role': 'user', 'direction': 'asc'}, - {'role': 'user', 'direction': 'desc'}, - ) - @ddt.unpack - def test_shares_list_with_sorting(self, role, direction): - self.clients[role].manila( - 'list', params='--sort-key host --sort-dir ' + direction - ) - - @ddt.data('admin', 'user') - def test_snapshot_list(self, role): - self.clients[role].manila('snapshot-list') - - @ddt.data('admin', 'user') - def test_snapshot_list_all_tenants(self, role): - self.clients[role].manila('snapshot-list', params='--all-tenants') - - @ddt.data('admin', 'user') - def test_snapshot_list_filter_by_name(self, role): - self.clients[role].manila('snapshot-list', params='--name name') - - @ddt.data('admin', 'user') - def test_snapshot_list_filter_by_status(self, role): - self.clients[role].manila('snapshot-list', params='--status status') - - -@ddt.ddt -class SharesListReadWriteTest(base.BaseTestCase): - def setUp(self): - super().setUp() - self.private_name = data_utils.rand_name('autotest_share_name') - self.private_description = data_utils.rand_name( - 'autotest_share_description' - ) - self.public_name = data_utils.rand_name('autotest_public_share_name') - self.public_description = data_utils.rand_name( - 'autotest_public_share_description' - ) - - self.admin_private_name = data_utils.rand_name( - 'autotest_admin_private_share_name' - ) - self.admin_private_description = data_utils.rand_name( - 'autotest_admin_private_share_description' - ) - - self.soft_name = data_utils.rand_name('soft_delete_share_name') - - self.admin_private_share = self.create_share( - name=self.admin_private_name, - description=self.admin_private_description, - public=False, - client=None, - wait_for_creation=False, - ) - - self.private_share = self.create_share( - name=self.private_name, - description=self.private_description, - public=False, - client=self.get_user_client(), - wait_for_creation=False, - ) - - self.public_share = self.create_share( - name=self.public_name, - description=self.public_description, - public=True, - client=self.admin_client, - ) - - self.wait_soft_delete_share = self.create_share( - name=self.soft_name, - public=False, - client=self.get_user_client(), - wait_for_creation=False, - ) - - self.shares_created = ( - self.private_share['id'], - self.public_share['id'], - self.admin_private_share['id'], - self.wait_soft_delete_share['id'], - ) - - for share_id in self.shares_created: - self.admin_client.wait_for_resource_status( - share_id, constants.STATUS_AVAILABLE - ) - - self.soft_delete_share( - [self.wait_soft_delete_share['id']], - client=self.get_user_client(), - microversion='2.69', - ) - - def _list_shares(self, filters=None): - filters = filters or dict() - shares = self.user_client.list_shares(filters=filters) - - self.assertGreater(len(shares), 0) - if filters: - for share in shares: - try: - share_get = self.user_client.get_share(share['ID']) - except exceptions.NotFound: - # NOTE(vponomaryov): Case when some share was deleted - # between our 'list' and 'get' requests. Skip such case. - # It occurs with concurrently running tests. - continue - if 'migrating' in share_get['status']: - # all bets are off, a fair chance share migration - # started between the 'list' and 'get' requests. No need - # to verify these shares. - continue - for filter_key, expected_value in filters.items(): - if filter_key in ('share_network', 'share-network'): - filter_key = 'share_network_id' - if share_get[filter_key] != expected_value: - # Possibly a mismatch because the share was - # migrated to a new network in the time that - # elapsed between the 'list' and 'get' requests. - # If this isn't one of the shares created in - # this class, don't worry about such mismatches - self.assertNotIn( - share_get['id'], self.shares_created - ) - continue - - if ( - expected_value != 'deleting' - and share_get[filter_key] == 'deleting' - ): - continue - self.assertEqual(expected_value, share_get[filter_key]) - - def test_list_shares(self): - self._list_shares() - - @ddt.data(1, 0) - def test_list_shares_for_all_tenants(self, all_tenants): - shares = self.admin_client.list_shares(all_tenants=all_tenants) - self.assertLessEqual(1, len(shares)) - - if all_tenants: - self.assertTrue(all('Project ID' in s for s in shares)) - for s_id in ( - self.private_share['id'], - self.public_share['id'], - self.admin_private_share['id'], - ): - self.assertTrue(any(s_id == s['ID'] for s in shares)) - else: - self.assertTrue(all('Project ID' not in s for s in shares)) - self.assertTrue( - any(self.admin_private_share['id'] == s['ID'] for s in shares) - ) - if ( - self.private_share['project_id'] - != (self.admin_private_share['project_id']) - ): - for s_id in ( - self.private_share['id'], - self.public_share['id'], - ): - self.assertFalse(any(s_id == s['ID'] for s in shares)) - - @ddt.data(True, False) - def test_list_shares_with_public(self, public): - shares = self.user_client.list_shares(is_public=public) - self.assertGreater(len(shares), 1) - if public: - self.assertTrue(all('Project ID' in s for s in shares)) - else: - self.assertTrue(all('Project ID' not in s for s in shares)) - - def test_list_shares_by_name(self): - shares = self.user_client.list_shares( - filters={'name': self.private_name} - ) - - self.assertEqual(1, len(shares)) - self.assertTrue( - any(self.private_share['id'] == s['ID'] for s in shares) - ) - for share in shares: - get = self.user_client.get_share(share['ID']) - self.assertEqual(self.private_name, get['name']) - - def test_list_shares_by_share_type(self): - share_type_id = self.user_client.get_share_type( - self.private_share['share_type'] - )['ID'] - # NOTE(vponomaryov): this is API 2.6+ specific - self._list_shares({'share_type': share_type_id}) - - def test_list_shares_by_status(self): - self._list_shares({'status': 'available'}) - - def test_list_shares_by_project_id(self): - project_id = self.user_client.get_project_id( - self.user_client.tenant_name - ) - self._list_shares({'project_id': project_id}) - - @testtools.skipUnless( - CONF.share_network, "Usage of Share networks is disabled" - ) - def test_list_shares_by_share_network(self): - share_network_id = self.user_client.get_share_network( - CONF.share_network - )['id'] - self._list_shares({'share_network': share_network_id}) - - @ddt.data( - {'limit': 1}, - {'limit': 2}, - {'limit': 1, 'offset': 1}, - {'limit': 2, 'offset': 0}, - ) - def test_list_shares_with_limit(self, filters): - shares = self.user_client.list_shares(filters=filters) - self.assertEqual(filters['limit'], len(shares)) - - def test_list_share_select_column(self): - shares = self.user_client.list_shares(columns="Name,Size") - self.assertTrue(any(s['Name'] is not None for s in shares)) - self.assertTrue(any(s['Size'] is not None for s in shares)) - self.assertTrue(all('Description' not in s for s in shares)) - - @ddt.data('ID', 'Path') - def test_list_shares_by_export_location(self, option): - export_locations = self.admin_client.list_share_export_locations( - self.public_share['id'] - ) - shares = self.admin_client.list_shares( - filters={'export_location': export_locations[0][option]} - ) - - self.assertEqual(1, len(shares)) - self.assertTrue( - any(self.public_share['id'] == s['ID'] for s in shares) - ) - for share in shares: - get = self.admin_client.get_share(share['ID']) - self.assertEqual(self.public_name, get['name']) - - @ddt.data('ID', 'Path') - def test_list_share_instances_by_export_location(self, option): - export_locations = self.admin_client.list_share_export_locations( - self.public_share['id'] - ) - share_instances = self.admin_client.list_share_instances( - filters={'export_location': export_locations[0][option]} - ) - - self.assertEqual(1, len(share_instances)) - - share_instance_id = share_instances[0]['ID'] - except_export_locations = ( - self.admin_client.list_share_instance_export_locations( - share_instance_id - ) - ) - self.assertGreater(len(except_export_locations), 0) - self.assertTrue( - any( - export_locations[0][option] == e[option] - for e in except_export_locations - ) - ) - - def test_list_share_by_export_location_with_invalid_version(self): - self.assertRaises( - exceptions.CommandFailed, - self.admin_client.list_shares, - filters={'export_location': 'fake'}, - microversion='2.34', - ) - - def test_list_share_instance_by_export_location_invalid_version(self): - self.assertRaises( - exceptions.CommandFailed, - self.admin_client.list_share_instances, - filters={'export_location': 'fake'}, - microversion='2.34', - ) - - @ddt.data('name', 'description') - def test_list_shares_by_inexact_option(self, option): - shares = self.user_client.list_shares(filters={option + '~': option}) - - # We know we have to have atleast three shares. - # Due to test concurrency, there can be - # more than three shares (some created by other tests). - self.assertGreaterEqual(len(shares), 3) - self.assertTrue( - any(self.private_share['id'] == s['ID'] for s in shares) - ) - - def test_list_shares_by_inexact_unicode_option(self): - self.create_share( - name='共享名称', description='共享描述', client=self.user_client - ) - filters = {'name~': '名称'} - shares = self.user_client.list_shares(filters=filters) - self.assertGreater(len(shares), 0) - - filters = {'description~': '描述'} - shares = self.user_client.list_shares(filters=filters) - self.assertGreater(len(shares), 0) - - def test_list_shares_by_description(self): - shares = self.user_client.list_shares( - filters={'description': self.private_description} - ) - - self.assertEqual(1, len(shares)) - self.assertTrue( - any(self.private_share['id'] == s['ID'] for s in shares) - ) - - def test_list_shares_in_recycle_bin(self): - shares = self.user_client.list_shares(is_soft_deleted=True) - - self.assertTrue( - any(self.wait_soft_delete_share['id'] == s['ID'] for s in shares) - ) diff --git a/manilaclient/tests/functional/test_shares_metadata.py b/manilaclient/tests/functional/test_shares_metadata.py deleted file mode 100644 index 5d642d0a..00000000 --- a/manilaclient/tests/functional/test_shares_metadata.py +++ /dev/null @@ -1,155 +0,0 @@ -# Copyright 2015 Mirantis Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import ddt - -from manilaclient.tests.functional import base - - -@ddt.ddt -class SharesMetadataReadWriteTest(base.BaseTestCase): - def setUp(self): - super().setUp() - self.share = self.create_share(client=self.get_user_client()) - - def test_set_metadata_in_share_creation(self): - md = {"key1": "value1", "key2": "value2"} - - # Create share with metadata - share = self.create_share(metadata=md, client=self.get_user_client()) - - # Read share metadata - metadata = self.user_client.get_share_metadata(share["id"]) - - # Verify share metadata - self.assertEqual(2, len(metadata)) - self.assertIn('key1', metadata) - self.assertIn('key2', metadata) - self.assertEqual(md['key1'], metadata['key1']) - self.assertEqual(md['key2'], metadata['key2']) - - def test_set_and_get_metadata(self): - # Create share - share = self.create_share( - cleanup_in_class=False, client=self.get_user_client() - ) - - # Set share metadata - md = {"key3": "value3", "key4": "value4"} - self.user_client.set_share_metadata(share["id"], md) - - # Read share metadata - metadata = self.user_client.get_share_metadata(share["id"]) - - # Verify share metadata - self.assertEqual(2, len(metadata)) - self.assertIn('key3', metadata) - self.assertIn('key4', metadata) - self.assertEqual(md['key3'], metadata['key3']) - self.assertEqual(md['key4'], metadata['key4']) - - def test_set_and_delete_metadata(self): - # Create share - share = self.create_share( - cleanup_in_class=False, client=self.get_user_client() - ) - - # Set share metadata - md = {"key3": "value3", "key4": "value4"} - self.user_client.set_share_metadata(share["id"], md) - - # Unset share metadata - self.user_client.unset_share_metadata(share["id"], list(md.keys())) - - # Verify deletion of share metadata - metadata = self.user_client.get_share_metadata(share["id"]) - self.assertEqual({}, metadata) - - def test_set_and_add_metadata(self): - md = {'key5': 'value5'} - - # Create share with metadata - share = self.create_share( - metadata=md, cleanup_in_class=False, client=self.get_user_client() - ) - - # Set share metadata - self.user_client.set_share_metadata(share["id"], {'key6': 'value6'}) - self.user_client.set_share_metadata(share["id"], {'key7': 'value7'}) - - # Read share metadata - metadata = self.user_client.get_share_metadata(share["id"]) - - # Verify share metadata - self.assertEqual(3, len(metadata)) - for i in (5, 6, 7): - key = f'key{i}' - self.assertIn(key, metadata) - self.assertEqual(f'value{i}', metadata[key]) - - def test_set_and_replace_metadata(self): - md = {'key8': 'value8'} - - # Create share with metadata - share = self.create_share( - metadata=md, cleanup_in_class=False, client=self.get_user_client() - ) - - # Set share metadata - self.user_client.set_share_metadata(share["id"], {'key9': 'value9'}) - - # Replace all existing share metadata - self.user_client.update_all_share_metadata( - share["id"], {'key10': 'value10'} - ) - - # Read share metadata - metadata = self.user_client.get_share_metadata(share["id"]) - - # Verify share metadata - self.assertEqual(1, len(metadata)) - self.assertIn('key10', metadata) - self.assertEqual('value10', metadata['key10']) - - @ddt.data( - {"k": "value"}, {"k" * 255: "value"}, {"key": "v"}, {"key": "v" * 1023} - ) - def test_set_metadata_min_max_sizes_of_keys_and_values(self, metadata): - # Set share metadata - self.user_client.set_share_metadata(self.share["id"], metadata) - - # Read share metadata - get = self.user_client.get_share_metadata(self.share["id"]) - - # Verify share metadata - key = list(metadata.keys())[0] - self.assertIn(key, get) - self.assertEqual(metadata[key], get[key]) - - @ddt.data( - {"k": "value"}, {"k" * 255: "value"}, {"key": "v"}, {"key": "v" * 1023} - ) - def test_update_metadata_min_max_sizes_of_keys_and_values(self, metadata): - # Update share metadata - self.user_client.update_all_share_metadata(self.share["id"], metadata) - - # Read share metadata - get = self.user_client.get_share_metadata(self.share["id"]) - - # Verify share metadata - self.assertEqual(len(metadata), len(get)) - for key in metadata: - self.assertIn(key, get) - self.assertEqual(metadata[key], get[key]) diff --git a/manilaclient/tests/functional/test_snapshot_access.py b/manilaclient/tests/functional/test_snapshot_access.py deleted file mode 100644 index 817d0088..00000000 --- a/manilaclient/tests/functional/test_snapshot_access.py +++ /dev/null @@ -1,221 +0,0 @@ -# Copyright (c) 2017 Hitachi Data Systems -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -from tempest.lib import exceptions as tempest_lib_exc -import testtools - -from manilaclient import config -from manilaclient.tests.functional import base -from manilaclient.tests.functional import utils - -CONF = config.CONF - - -@utils.skip_if_microversion_not_supported('2.32') -class SnapshotAccessReadBase(base.BaseTestCase): - protocol = None - - def setUp(self): - super().setUp() - if self.protocol not in CONF.enable_protocols: - message = f"{self.protocol} tests are disabled." - raise self.skipException(message) - self.access_types = CONF.access_types_mapping.get( - self.protocol, '' - ).split(' ') - if not self.access_types: - raise self.skipException( - f"No access types were provided for {self.protocol} " - "snapshot access tests." - ) - - self.share = self.create_share( - share_protocol=self.protocol, client=self.get_user_client() - ) - int_range = range(0, 10) - - self.access_to = { - 'ip': [f'99.88.77.{i}' for i in int_range], - 'user': [f'foo_user_{i}' for i in int_range], - 'cert': [f'tenant_{i}.example.com' for i in int_range], - } - - def _test_create_list_access_rule_for_snapshot(self, snapshot_id): - access = [] - access_type = self.access_types[0] - - for i in range(5): - access_ = self.user_client.snapshot_access_allow( - snapshot_id, access_type, self.access_to[access_type][i] - ) - access.append(access_) - - return access - - def test_create_list_access_rule_for_snapshot(self): - snapshot = self.create_snapshot( - share=self.share['id'], - client=self.get_user_client(), - cleanup_in_class=False, - ) - - access = self._test_create_list_access_rule_for_snapshot( - snapshot['id'] - ) - - access_list = self.user_client.list_access( - snapshot['id'], is_snapshot=True - ) - - for i in range(5): - self.assertIn( - access[i]['id'], [access_list[j]['id'] for j in range(5)] - ) - self.assertIn( - access[i]['access_type'], - [access_list[j]['access_type'] for j in range(5)], - ) - self.assertIn( - access[i]['access_to'], - [access_list[j]['access_to'] for j in range(5)], - ) - self.assertIsNotNone(access_list[i]['access_type']) - self.assertIsNotNone(access_list[i]['access_to']) - - def test_create_list_access_rule_for_snapshot_select_column(self): - snapshot = self.create_snapshot( - share=self.share['id'], - client=self.get_user_client(), - cleanup_in_class=False, - ) - - self._test_create_list_access_rule_for_snapshot(snapshot['id']) - - access_list = self.user_client.list_access( - snapshot['id'], columns="access_type,access_to", is_snapshot=True - ) - - self.assertTrue(any(x['Access_Type'] is not None for x in access_list)) - self.assertTrue(any(x['Access_To'] is not None for x in access_list)) - - def _create_delete_access_rule(self, snapshot_id, access_type, access_to): - if access_type not in self.access_types: - raise self.skipException( - f"'{access_type}' access rules is disabled for protocol " - f"'{self.protocol}'." - ) - - access = self.user_client.snapshot_access_allow( - snapshot_id, access_type, access_to - ) - - self.assertEqual(access_type, access.get('access_type')) - self.assertEqual( - access_to.replace('\\\\', '\\'), access.get('access_to') - ) - - self.user_client.wait_for_access_rule_status( - snapshot_id, access['id'], is_snapshot=True - ) - self.user_client.snapshot_access_deny(snapshot_id, access['id']) - self.user_client.wait_for_access_rule_deletion( - snapshot_id, access['id'], is_snapshot=True - ) - - self.assertRaises( - tempest_lib_exc.NotFound, - self.user_client.get_access, - snapshot_id, - access['id'], - is_snapshot=True, - ) - - def test_create_delete_snapshot_ip_access_rule(self): - snapshot = self.create_snapshot( - share=self.share['id'], - client=self.get_user_client(), - cleanup_in_class=False, - ) - self._create_delete_access_rule( - snapshot['id'], 'ip', self.access_to['ip'][0] - ) - - def test_create_delete_snapshot_user_access_rule(self): - snapshot = self.create_snapshot( - share=self.share['id'], - client=self.get_user_client(), - cleanup_in_class=False, - ) - self._create_delete_access_rule( - snapshot['id'], 'user', CONF.username_for_user_rules - ) - - def test_create_delete_snapshot_cert_access_rule(self): - snapshot = self.create_snapshot( - share=self.share['id'], - client=self.get_user_client(), - cleanup_in_class=False, - ) - self._create_delete_access_rule( - snapshot['id'], 'cert', self.access_to['cert'][0] - ) - - -@testtools.skipUnless( - CONF.run_snapshot_tests and CONF.run_mount_snapshot_tests, - "Snapshots or mountable snapshots tests are disabled.", -) -class NFSSnapshotAccessTest(SnapshotAccessReadBase): - protocol = 'nfs' - - -@testtools.skipUnless( - CONF.run_snapshot_tests and CONF.run_mount_snapshot_tests, - "Snapshots or mountable snapshots tests are disabled.", -) -class CIFSSnapshotAccessTest(SnapshotAccessReadBase): - protocol = 'cifs' - - -@testtools.skipUnless( - CONF.run_snapshot_tests and CONF.run_mount_snapshot_tests, - "Snapshots or mountable snapshots tests are disabled.", -) -class GlusterFSSnapshotAccessTest(SnapshotAccessReadBase): - protocol = 'glusterfs' - - -@testtools.skipUnless( - CONF.run_snapshot_tests and CONF.run_mount_snapshot_tests, - "Snapshots or mountable snapshots tests are disabled.", -) -class HDFSSnapshotAccessTest(SnapshotAccessReadBase): - protocol = 'hdfs' - - -@testtools.skipUnless( - CONF.run_snapshot_tests and CONF.run_mount_snapshot_tests, - "Snapshots or mountable snapshots tests are disabled.", -) -class MAPRFSSnapshotAccessTest(SnapshotAccessReadBase): - protocol = 'maprfs' - - -def load_tests(loader, tests, _): - result = [] - for test_case in tests: - if type(test_case._tests[0]) is SnapshotAccessReadBase: - continue - result.append(test_case) - return loader.suiteClass(result) diff --git a/manilaclient/tests/functional/test_snapshot_instances.py b/manilaclient/tests/functional/test_snapshot_instances.py deleted file mode 100644 index d0ee9b60..00000000 --- a/manilaclient/tests/functional/test_snapshot_instances.py +++ /dev/null @@ -1,140 +0,0 @@ -# Copyright 2016 Huawei inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import ddt -from oslo_utils import uuidutils -import testtools - -from manilaclient import config -from manilaclient.tests.functional import base -from manilaclient.tests.functional import utils - -CONF = config.CONF - - -@ddt.ddt -@testtools.skipUnless(CONF.run_snapshot_tests, 'Snapshot tests disabled.') -@utils.skip_if_microversion_not_supported('2.19') -class SnapshotInstancesTest(base.BaseTestCase): - def setUp(self): - super().setUp() - self.share = self.create_share(client=self.get_user_client()) - self.snapshot = self.create_snapshot( - share=self.share['id'], client=self.get_user_client() - ) - - def test_list_all_snapshot_instances(self): - snapshot_instances = self.admin_client.list_snapshot_instances() - - self.assertGreater(len(snapshot_instances), 0) - expected_keys = ('ID', 'Snapshot ID', 'Status') - for si in snapshot_instances: - for key in expected_keys: - self.assertIn(key, si) - self.assertTrue(uuidutils.is_uuid_like(si['ID'])) - self.assertTrue(uuidutils.is_uuid_like(si['Snapshot ID'])) - - def test_list_all_snapshot_instances_details(self): - snapshot_instances = self.admin_client.list_snapshot_instances( - detailed=True - ) - - self.assertGreater(len(snapshot_instances), 0) - expected_keys = ( - 'ID', - 'Snapshot ID', - 'Status', - 'Created_at', - 'Updated_at', - 'Share_id', - 'Share_instance_id', - 'Progress', - 'Provider_location', - ) - for si in snapshot_instances: - for key in expected_keys: - self.assertIn(key, si) - for key in ('ID', 'Snapshot ID', 'Share_id', 'Share_instance_id'): - self.assertTrue(uuidutils.is_uuid_like(si[key])) - - def test_list_snapshot_instance_with_snapshot(self): - snapshot_instances = self.admin_client.list_snapshot_instances( - snapshot_id=self.snapshot['id'] - ) - - self.assertEqual(1, len(snapshot_instances)) - expected_keys = ('ID', 'Snapshot ID', 'Status') - for si in snapshot_instances: - for key in expected_keys: - self.assertIn(key, si) - self.assertTrue(uuidutils.is_uuid_like(si['ID'])) - self.assertTrue(uuidutils.is_uuid_like(si['Snapshot ID'])) - - def test_list_snapshot_instance_with_columns(self): - snapshot_instances = self.admin_client.list_snapshot_instances( - self.snapshot['id'], columns='id,status' - ) - - self.assertGreater(len(snapshot_instances), 0) - expected_keys = ('Id', 'Status') - unexpected_keys = ('Snapshot ID',) - for si in snapshot_instances: - for key in expected_keys: - self.assertIn(key, si) - for key in unexpected_keys: - self.assertNotIn(key, si) - self.assertTrue(uuidutils.is_uuid_like(si['Id'])) - - def test_get_snapshot_instance(self): - snapshot_instances = self.admin_client.list_snapshot_instances( - self.snapshot['id'] - ) - - snapshot_instance = self.admin_client.get_snapshot_instance( - snapshot_instances[0]['ID'] - ) - self.assertGreater(len(snapshot_instance), 0) - expected_keys = ( - 'id', - 'snapshot_id', - 'status', - 'created_at', - 'updated_at', - 'share_id', - 'share_instance_id', - 'progress', - 'provider_location', - ) - - for key in expected_keys: - self.assertIn(key, snapshot_instance) - for key in ('id', 'snapshot_id', 'share_id', 'share_instance_id'): - self.assertTrue(uuidutils.is_uuid_like(snapshot_instance[key])) - - def test_snapshot_instance_reset_state(self): - snapshot_instances = self.admin_client.list_snapshot_instances( - self.snapshot['id'] - ) - self.admin_client.reset_snapshot_instance( - snapshot_instances[0]['ID'], 'error' - ) - snapshot_instance = self.admin_client.get_snapshot_instance( - snapshot_instances[0]['ID'] - ) - - self.assertEqual('error', snapshot_instance['status']) - self.admin_client.reset_snapshot_instance( - snapshot_instance['id'], 'available' - ) diff --git a/manilaclient/tests/functional/test_snapshot_instances_export_locations.py b/manilaclient/tests/functional/test_snapshot_instances_export_locations.py deleted file mode 100644 index 92931f2d..00000000 --- a/manilaclient/tests/functional/test_snapshot_instances_export_locations.py +++ /dev/null @@ -1,131 +0,0 @@ -# Copyright (c) 2017 Hitachi Data Systems -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import ddt -from oslo_utils import uuidutils -import testtools - -from manilaclient import config -from manilaclient.tests.functional import base -from manilaclient.tests.functional import utils - -CONF = config.CONF - - -@ddt.ddt -@testtools.skipUnless( - CONF.run_snapshot_tests and CONF.run_mount_snapshot_tests, - "Snapshots or mountable snapshots tests are disabled.", -) -@utils.skip_if_microversion_not_supported('2.32') -class SnapshotInstanceExportLocationReadWriteTest(base.BaseTestCase): - def setUp(self): - super().setUp() - self.share = self.create_share(client=self.get_user_client()) - self.snapshot = self.create_snapshot( - share=self.share['id'], client=self.get_user_client() - ) - - def test_get_snapshot_instance_export_location(self): - client = self.admin_client - snapshot_instances = client.list_snapshot_instances( - self.snapshot['id'] - ) - - self.assertGreater(len(snapshot_instances), 0) - self.assertIn('ID', snapshot_instances[0]) - self.assertTrue(uuidutils.is_uuid_like(snapshot_instances[0]['ID'])) - - snapshot_instance_id = snapshot_instances[0]['ID'] - - export_locations = client.list_snapshot_instance_export_locations( - snapshot_instance_id - ) - - el = client.get_snapshot_instance_export_location( - snapshot_instance_id, export_locations[0]['ID'] - ) - expected_keys = [ - 'path', - 'id', - 'is_admin_only', - 'share_snapshot_instance_id', - 'updated_at', - 'created_at', - ] - - for key in expected_keys: - self.assertIn(key, el) - for key, key_el in ( - ('ID', 'id'), - ('Path', 'path'), - ('Is Admin only', 'is_admin_only'), - ): - self.assertEqual(export_locations[0][key], el[key_el]) - self.assertTrue( - uuidutils.is_uuid_like(el['share_snapshot_instance_id']) - ) - self.assertTrue(uuidutils.is_uuid_like(el['id'])) - self.assertIn(el['is_admin_only'], ('True', 'False')) - - def test_list_snapshot_instance_export_locations(self): - client = self.admin_client - snapshot_instances = client.list_snapshot_instances( - self.snapshot['id'] - ) - - self.assertGreater(len(snapshot_instances), 0) - self.assertIn('ID', snapshot_instances[0]) - self.assertTrue(uuidutils.is_uuid_like(snapshot_instances[0]['ID'])) - - snapshot_instance_id = snapshot_instances[0]['ID'] - - export_locations = client.list_snapshot_instance_export_locations( - snapshot_instance_id - ) - - self.assertGreater(len(export_locations), 0) - - expected_keys = ('ID', 'Path', 'Is Admin only') - for el in export_locations: - for key in expected_keys: - self.assertIn(key, el) - self.assertTrue(uuidutils.is_uuid_like(el['ID'])) - - def test_list_snapshot_instance_export_locations_with_columns(self): - client = self.admin_client - snapshot_instances = client.list_snapshot_instances( - self.snapshot['id'] - ) - - self.assertGreater(len(snapshot_instances), 0) - self.assertIn('ID', snapshot_instances[0]) - self.assertTrue(uuidutils.is_uuid_like(snapshot_instances[0]['ID'])) - snapshot_instance_id = snapshot_instances[0]['ID'] - - export_locations = client.list_snapshot_instance_export_locations( - snapshot_instance_id, columns='id,path' - ) - - self.assertGreater(len(export_locations), 0) - expected_keys = ('Id', 'Path') - unexpected_keys = ('Updated At', 'Created At', 'Is Admin only') - - for el in export_locations: - for key in expected_keys: - self.assertIn(key, el) - for key in unexpected_keys: - self.assertNotIn(key, el) - self.assertTrue(uuidutils.is_uuid_like(el['Id'])) diff --git a/manilaclient/tests/functional/test_snapshots_export_locations.py b/manilaclient/tests/functional/test_snapshots_export_locations.py deleted file mode 100644 index 3059467c..00000000 --- a/manilaclient/tests/functional/test_snapshots_export_locations.py +++ /dev/null @@ -1,96 +0,0 @@ -# Copyright (c) 2017 Hitachi Data Systems -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import ddt -from oslo_utils import uuidutils -import testtools - -from manilaclient import config -from manilaclient.tests.functional import base -from manilaclient.tests.functional import utils - -CONF = config.CONF - - -@ddt.ddt -@testtools.skipUnless( - CONF.run_snapshot_tests and CONF.run_mount_snapshot_tests, - "Snapshots or mountable snapshots tests are disabled.", -) -@utils.skip_if_microversion_not_supported('2.32') -class SnapshotExportLocationReadWriteTest(base.BaseTestCase): - def setUp(self): - super().setUp() - self.share = self.create_share(client=self.get_user_client()) - self.snapshot = self.create_snapshot( - share=self.share['id'], client=self.get_user_client() - ) - - @ddt.data('admin', 'user') - def test_get_snapshot_export_location(self, role): - client = self.admin_client if role == 'admin' else self.user_client - - export_locations = client.list_snapshot_export_locations( - self.snapshot['id'] - ) - - el = client.get_snapshot_export_location( - self.snapshot['id'], export_locations[0]['ID'] - ) - - expected_keys = ['path', 'id', 'updated_at', 'created_at'] - if role == 'admin': - expected_keys.extend( - ['is_admin_only', 'share_snapshot_instance_id'] - ) - self.assertTrue( - uuidutils.is_uuid_like(el['share_snapshot_instance_id']) - ) - self.assertIn(el['is_admin_only'], ('True', 'False')) - self.assertTrue(uuidutils.is_uuid_like(el['id'])) - for key in expected_keys: - self.assertIn(key, el) - - @ddt.data('admin', 'user') - def test_list_snapshot_export_locations(self, role): - client = self.admin_client if role == 'admin' else self.user_client - export_locations = client.list_snapshot_export_locations( - self.snapshot['id'] - ) - - self.assertGreater(len(export_locations), 0) - expected_keys = ('ID', 'Path') - - for el in export_locations: - for key in expected_keys: - self.assertIn(key, el) - self.assertTrue(uuidutils.is_uuid_like(el['ID'])) - - @ddt.data('admin', 'user') - def test_list_snapshot_export_locations_with_columns(self, role): - client = self.admin_client if role == 'admin' else self.user_client - export_locations = client.list_snapshot_export_locations( - self.snapshot['id'], columns='id,path' - ) - - self.assertGreater(len(export_locations), 0) - expected_keys = ('Id', 'Path') - unexpected_keys = ('Updated At', 'Created At') - for el in export_locations: - for key in expected_keys: - self.assertIn(key, el) - for key in unexpected_keys: - self.assertNotIn(key, el) - self.assertTrue(uuidutils.is_uuid_like(el['Id'])) diff --git a/manilaclient/tests/unit/test_shell.py b/manilaclient/tests/unit/test_shell.py deleted file mode 100644 index 478ffd85..00000000 --- a/manilaclient/tests/unit/test_shell.py +++ /dev/null @@ -1,556 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import io -import re -import sys -from unittest import mock - -import ddt -import fixtures -from tempest.lib.cli import output_parser -from testtools import matchers - -import manilaclient -from manilaclient.common import cliutils -from manilaclient.common import constants -from manilaclient import exceptions -from manilaclient import shell -from manilaclient.tests.unit import utils -from manilaclient.tests.unit.v2 import fakes - - -@ddt.ddt -class OpenstackManilaShellTest(utils.TestCase): - FAKE_ENV = { - 'OS_USERNAME': 'username', - 'OS_PASSWORD': 'password', - 'OS_TENANT_NAME': 'tenant_name', - 'OS_AUTH_URL': 'http://no.where', - } - - # Patch os.environ to avoid required auth info. - def set_env_vars(self, env_vars): - for k, v in env_vars.items(): - self.useFixture(fixtures.EnvironmentVariable(k, v)) - - def shell_discover_client( - self, - current_client, - os_api_version, - os_endpoint_type, - os_service_type, - client_args, - ): - return current_client, manilaclient.API_MAX_VERSION - - def shell(self, argstr): - orig = sys.stdout - try: - sys.stdout = io.StringIO() - _shell = shell.OpenStackManilaShell() - _shell._discover_client = self.shell_discover_client - _shell.main(argstr.split()) - except SystemExit: - exc_type, exc_value, exc_traceback = sys.exc_info() - self.assertEqual(exc_value.code, 0) - finally: - out = sys.stdout.getvalue() - sys.stdout.close() - sys.stdout = orig - - return out - - @ddt.data( - {}, - {'OS_AUTH_URL': 'http://foo.bar'}, - {'OS_AUTH_URL': 'http://foo.bar', 'OS_USERNAME': 'foo'}, - { - 'OS_AUTH_URL': 'http://foo.bar', - 'OS_USERNAME': 'foo_user', - 'OS_PASSWORD': 'foo_password', - }, - { - 'OS_TENANT_NAME': 'foo_tenant', - 'OS_USERNAME': 'foo_user', - 'OS_PASSWORD': 'foo_password', - }, - {'OS_TOKEN': 'foo_token'}, - {'OS_MANILA_BYPASS_URL': 'http://foo.foo'}, - ) - def test_main_failure(self, env_vars): - self.set_env_vars(env_vars) - with mock.patch.object(shell, 'client') as mock_client: - self.assertRaises(exceptions.CommandError, self.shell, 'list') - self.assertFalse(mock_client.Client.called) - - @ddt.data(None, 'foo_key') - def test_main_success(self, os_key): - env_vars = { - 'OS_AUTH_URL': 'http://foo.bar', - 'OS_USERNAME': 'foo_username', - 'OS_USER_ID': 'foo_user_id', - 'OS_PASSWORD': 'foo_password', - 'OS_TENANT_NAME': 'foo_tenant', - 'OS_TENANT_ID': 'foo_tenant_id', - 'OS_PROJECT_NAME': 'foo_project', - 'OS_PROJECT_ID': 'foo_project_id', - 'OS_PROJECT_DOMAIN_ID': 'foo_project_domain_id', - 'OS_PROJECT_DOMAIN_NAME': 'foo_project_domain_name', - 'OS_USER_DOMAIN_NAME': 'foo_user_domain_name', - 'OS_USER_DOMAIN_ID': 'foo_user_domain_id', - 'OS_CERT': 'foo_cert', - 'OS_KEY': os_key, - } - self.set_env_vars(env_vars) - cert = env_vars['OS_CERT'] - if os_key: - cert = (cert, env_vars['OS_KEY']) - - with mock.patch.object(shell, 'client') as mock_client: - self.shell('list') - - mock_client.Client.assert_called_with( - manilaclient.API_MAX_VERSION, - username=env_vars['OS_USERNAME'], - password=env_vars['OS_PASSWORD'], - project_name=env_vars['OS_PROJECT_NAME'], - auth_url=env_vars['OS_AUTH_URL'], - insecure=False, - region_name='', - tenant_id=env_vars['OS_PROJECT_ID'], - endpoint_type='publicURL', - extensions=mock.ANY, - service_type=constants.V2_SERVICE_TYPE, - service_name='', - retries=0, - http_log_debug=False, - cacert=None, - use_keyring=False, - force_new_token=False, - user_id=env_vars['OS_USER_ID'], - user_domain_id=env_vars['OS_USER_DOMAIN_ID'], - user_domain_name=env_vars['OS_USER_DOMAIN_NAME'], - project_domain_id=env_vars['OS_PROJECT_DOMAIN_ID'], - project_domain_name=env_vars['OS_PROJECT_DOMAIN_NAME'], - cert=cert, - input_auth_token='', - service_catalog_url='', - ) - - @ddt.data( - { - "env_vars": { - "OS_MANILA_BYPASS_URL": "http://foo.url", - "OS_TOKEN": "foo_token", - }, - "kwargs": { - "--os-token": "bar_token", - "--bypass-url": "http://bar.url", - }, - "expected": { - "input_auth_token": "bar_token", - "service_catalog_url": "http://bar.url", - }, - }, - { - "env_vars": { - "OS_MANILA_BYPASS_URL": "http://foo.url", - "OS_TOKEN": "foo_token", - }, - "kwargs": {}, - "expected": { - "input_auth_token": "foo_token", - "service_catalog_url": "http://foo.url", - }, - }, - { - "env_vars": {}, - "kwargs": { - "--os-token": "bar_token", - "--bypass-url": "http://bar.url", - }, - "expected": { - "input_auth_token": "bar_token", - "service_catalog_url": "http://bar.url", - }, - }, - { - "env_vars": { - "MANILACLIENT_BYPASS_URL": "http://foo.url", - "OS_TOKEN": "foo_token", - }, - "kwargs": {}, - "expected": { - "input_auth_token": "foo_token", - "service_catalog_url": "http://foo.url", - }, - }, - { - "env_vars": {"OS_TOKEN": "foo_token"}, - "kwargs": {"--bypass-url": "http://bar.url"}, - "expected": { - "input_auth_token": "foo_token", - "service_catalog_url": "http://bar.url", - }, - }, - { - "env_vars": { - "MANILACLIENT_BYPASS_URL": "http://foo.url", - "OS_MANILA_BYPASS_URL": "http://bar.url", - "OS_TOKEN": "foo_token", - }, - "kwargs": {"--os-token": "bar_token"}, - "expected": { - "input_auth_token": "bar_token", - "service_catalog_url": "http://bar.url", - }, - }, - ) - @ddt.unpack - def test_main_success_with_token(self, env_vars, kwargs, expected): - self.set_env_vars(env_vars) - with mock.patch.object(shell, "client") as mock_client: - cmd = "" - for k, v in kwargs.items(): - cmd += f"{k}={v} " - cmd += "list" - - self.shell(cmd) - - mock_client.Client.assert_called_with( - manilaclient.API_MAX_VERSION, - username="", - password="", - project_name="", - auth_url="", - insecure=False, - region_name="", - tenant_id="", - endpoint_type="publicURL", - extensions=mock.ANY, - service_type=constants.V2_SERVICE_TYPE, - service_name="", - retries=0, - http_log_debug=False, - cacert=None, - use_keyring=False, - force_new_token=False, - user_id="", - user_domain_id="", - user_domain_name="", - project_domain_id="", - project_domain_name="", - cert=None, - input_auth_token=expected["input_auth_token"], - service_catalog_url=expected["service_catalog_url"], - ) - - @ddt.data( - # default without any env var or kwargs - { - "env_vars": { - "OS_TOKEN": "foo_token", - "OS_MANILA_BYPASS_URL": "http://bar.url", - }, - "kwargs": {}, - "expected": { - "input_auth_token": "foo_token", - "service_catalog_url": "http://bar.url", - "os_endpoint_type": "publicURL", - }, - }, - # only env var - { - "env_vars": { - "OS_TOKEN": "foo_token", - "OS_MANILA_BYPASS_URL": "http://bar.url", - "OS_MANILA_ENDPOINT_TYPE": "custom-endpoint-type", - }, - "kwargs": {}, - "expected": { - "input_auth_token": "foo_token", - "service_catalog_url": "http://bar.url", - "os_endpoint_type": "custom-endpoint-type", - }, - }, - # only kwargs - { - "env_vars": { - "OS_TOKEN": "foo_token", - "OS_MANILA_BYPASS_URL": "http://bar.url", - }, - "kwargs": {"--endpoint-type": "custom-kwargs-endpoint-type"}, - "expected": { - "input_auth_token": "foo_token", - "service_catalog_url": "http://bar.url", - "os_endpoint_type": "custom-kwargs-endpoint-type", - }, - }, - # env var *and* kwargs (kwargs should win) - { - "env_vars": { - "OS_TOKEN": "foo_token", - "OS_MANILA_BYPASS_URL": "http://bar.url", - "os_endpoint_type": "custom-env-endpoint-type", - }, - "kwargs": {"--endpoint-type": "custom-kwargs-endpoint-type"}, - "expected": { - "input_auth_token": "foo_token", - "service_catalog_url": "http://bar.url", - "os_endpoint_type": "custom-kwargs-endpoint-type", - }, - }, - ) - @ddt.unpack - def test_main_success_with_os_endpoint(self, env_vars, kwargs, expected): - self.set_env_vars(env_vars) - with mock.patch.object(shell, "client") as mock_client: - cmd = "" - for k, v in kwargs.items(): - cmd += f"{k}={v} " - cmd += "list" - - self.shell(cmd) - - mock_client.Client.assert_called_with( - manilaclient.API_MAX_VERSION, - username="", - password="", - project_name="", - auth_url="", - insecure=False, - region_name="", - tenant_id="", - endpoint_type=expected["os_endpoint_type"], - extensions=mock.ANY, - service_type=constants.V2_SERVICE_TYPE, - service_name="", - retries=0, - http_log_debug=False, - cacert=None, - use_keyring=False, - force_new_token=False, - user_id="", - user_domain_id="", - user_domain_name="", - project_domain_id="", - project_domain_name="", - cert=None, - input_auth_token=expected["input_auth_token"], - service_catalog_url=expected["service_catalog_url"], - ) - - def test_help_unknown_command(self): - self.assertRaises(exceptions.CommandError, self.shell, 'help foofoo') - - @ddt.data('list --help', '--help list', 'help list') - def test_help_on_subcommand(self, cmd): - required = [ - '.*?^usage: manila list', - '.*?^List NAS shares with filters.', - ] - help_text = self.shell(cmd) - for r in required: - self.assertThat( - help_text, matchers.MatchesRegex(r, re.DOTALL | re.MULTILINE) - ) - - def test_common_args_in_help_message(self): - expected_args = ( - '--version', - '', - '--debug', - '--os-cache', - '--os-reset-cache', - '--os-user-id', - '--os-username', - '--os-password', - '--os-tenant-name', - '--os-project-name', - '--os-tenant-id', - '--os-project-id', - '--os-user-domain-id', - '--os-user-domain-name', - '--os-project-domain-id', - '--os-project-domain-name', - '--os-auth-url', - '--os-region-name', - '--service-type', - '--service-name', - '--share-service-name', - '--endpoint-type', - '--os-share-api-version', - '--os-cacert', - '--retries', - '--os-cert', - '--os-key', - ) - - help_text = self.shell('help') - - for expected_arg in expected_args: - self.assertIn(expected_arg, help_text) - - -class CustomOpenStackManilaShell(shell.OpenStackManilaShell): - @staticmethod - @cliutils.arg( - '--default-is-none', - '--default_is_none', - type=str, - metavar='', - action='single_alias', - help='Default value is None and metavar set.', - default=None, - ) - def do_foo(cs, args): - cliutils.print_dict({'key': args.default_is_none}) - - @staticmethod - @cliutils.arg( - '--default-is-not-none', - '--default_is_not_none', - type=str, - action='single_alias', - help='Default value is not None and metavar not set.', - default='bar', - ) - def do_bar(cs, args): - cliutils.print_dict({'key': args.default_is_not_none}) - - @staticmethod - @cliutils.arg( - '--list-like', - '--list_like', - nargs='*', - action='single_alias', - help='Default value is None, metavar not set and result is list.', - default=None, - ) - def do_quuz(cs, args): - cliutils.print_dict({'key': args.list_like}) - - -@ddt.ddt -class AllowOnlyOneAliasAtATimeActionTest(utils.TestCase): - FAKE_ENV = { - 'OS_USERNAME': 'username', - 'OS_PASSWORD': 'password', - 'OS_TENANT_NAME': 'tenant_name', - 'OS_AUTH_URL': 'http://no.where', - } - - def setUp(self): - super(self.__class__, self).setUp() - for k, v in self.FAKE_ENV.items(): - self.useFixture(fixtures.EnvironmentVariable(k, v)) - self.mock_object( - shell.client, - 'get_client_class', - mock.Mock(return_value=fakes.FakeClient), - ) - - def shell_discover_client( - self, - current_client, - os_api_version, - os_endpoint_type, - os_service_type, - client_args, - ): - return current_client, manilaclient.API_MAX_VERSION - - def shell(self, argstr): - orig = sys.stdout - try: - sys.stdout = io.StringIO() - _shell = CustomOpenStackManilaShell() - _shell._discover_client = self.shell_discover_client - _shell.main(argstr.split()) - except SystemExit: - exc_type, exc_value, exc_traceback = sys.exc_info() - self.assertEqual(exc_value.code, 0) - finally: - out = sys.stdout.getvalue() - sys.stdout.close() - sys.stdout = orig - - return out - - @ddt.data( - ('--default-is-none foo', 'foo'), - ('--default-is-none foo --default-is-none foo', 'foo'), - ('--default-is-none foo --default_is_none foo', 'foo'), - ('--default_is_none None', 'None'), - ) - @ddt.unpack - def test_foo_success(self, options_str, expected_result): - output = self.shell(f'foo {options_str}') - parsed_output = output_parser.details(output) - self.assertEqual({'key': expected_result}, parsed_output) - - @ddt.data( - '--default-is-none foo --default-is-none bar', - '--default-is-none foo --default_is_none bar', - '--default-is-none foo --default_is_none FOO', - ) - def test_foo_error(self, options_str): - self.assertRaises( - matchers.MismatchError, self.shell, f'foo {options_str}' - ) - - @ddt.data( - ('--default-is-not-none bar', 'bar'), - ('--default_is_not_none bar --default-is-not-none bar', 'bar'), - ('--default_is_not_none bar --default_is_not_none bar', 'bar'), - ('--default-is-not-none not_bar', 'not_bar'), - ('--default_is_not_none None', 'None'), - ) - @ddt.unpack - def test_bar_success(self, options_str, expected_result): - output = self.shell(f'bar {options_str}') - parsed_output = output_parser.details(output) - self.assertEqual({'key': expected_result}, parsed_output) - - @ddt.data( - '--default-is-not-none foo --default-is-not-none bar', - '--default-is-not-none foo --default_is_not_none bar', - '--default-is-not-none bar --default_is_not_none BAR', - ) - def test_bar_error(self, options_str): - self.assertRaises( - matchers.MismatchError, self.shell, f'bar {options_str}' - ) - - @ddt.data( - ('--list-like q=w', "['q=w']"), - ('--list-like q=w --list_like q=w', "['q=w']"), - ( - '--list-like q=w e=r t=y --list_like e=r t=y q=w', - "['e=r', 'q=w', 't=y']", - ), - ('--list_like q=w e=r t=y', "['e=r', 'q=w', 't=y']"), - ) - @ddt.unpack - def test_quuz_success(self, options_str, expected_result): - output = self.shell(f'quuz {options_str}') - parsed_output = output_parser.details(output) - self.assertEqual({'key': expected_result}, parsed_output) - - @ddt.data( - '--list-like q=w --list_like e=r t=y', - ) - def test_quuz_error(self, options_str): - self.assertRaises( - matchers.MismatchError, self.shell, f'quuz {options_str}' - ) diff --git a/manilaclient/tests/unit/v2/test_shell.py b/manilaclient/tests/unit/v2/test_shell.py deleted file mode 100644 index 82148499..00000000 --- a/manilaclient/tests/unit/v2/test_shell.py +++ /dev/null @@ -1,4859 +0,0 @@ -# Copyright 2013 OpenStack Foundation -# Copyright 2014 Mirantis, Inc. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import itertools -from unittest import mock - -import ddt -import fixtures -from oslo_utils import strutils - -from manilaclient import api_versions -from manilaclient import client -from manilaclient.common.apiclient import utils as apiclient_utils -from manilaclient.common import cliutils -from manilaclient.common import constants -from manilaclient import exceptions -from manilaclient import shell -from manilaclient.tests.unit import utils as test_utils -from manilaclient.tests.unit.v2 import fakes -from manilaclient import utils -from manilaclient.v2 import messages -from manilaclient.v2 import security_services -from manilaclient.v2 import share_access_rules -from manilaclient.v2 import share_group_types -from manilaclient.v2 import share_groups -from manilaclient.v2 import share_instances -from manilaclient.v2 import share_network_subnets -from manilaclient.v2 import share_networks -from manilaclient.v2 import share_servers -from manilaclient.v2 import share_snapshots -from manilaclient.v2 import share_types -from manilaclient.v2 import shares -from manilaclient.v2 import shell as shell_v2 - - -@ddt.ddt -class ShellTest(test_utils.TestCase): - FAKE_ENV = { - 'MANILA_USERNAME': 'username', - 'MANILA_PASSWORD': 'password', - 'MANILA_PROJECT_ID': 'project_id', - 'MANILA_URL': 'http://no.where', - } - - # Patch os.environ to avoid required auth info. - def setUp(self): - """Run before each test.""" - super().setUp() - for var in self.FAKE_ENV: - self.useFixture( - fixtures.EnvironmentVariable(var, self.FAKE_ENV[var]) - ) - self.mock_completion() - - self.shell = shell.OpenStackManilaShell() - - # HACK(bcwaldon): replace this when we start using stubs - self.old_get_client_class = client.get_client_class - client.get_client_class = lambda *_: fakes.FakeClient - - # Following shows available separators for optional params - # and its values - self.separators = [' ', '='] - self.create_share_body = { - "share": { - "share_type": None, - "name": None, - "snapshot_id": None, - "description": None, - "metadata": {}, - "share_proto": "nfs", - "share_network_id": None, - "size": 1, - "is_public": False, - "availability_zone": None, - "scheduler_hints": {}, - } - } - - def tearDown(self): - # For some method like test_image_meta_bad_action we are - # testing a SystemExit to be thrown and object self.shell has - # no time to get instantatiated which is OK in this case, so - # we make sure the method is there before launching it. - if hasattr(self.shell, 'cs') and hasattr( - self.shell.cs, 'clear_callstack' - ): - self.shell.cs.clear_callstack() - - # HACK(bcwaldon): replace this when we start using stubs - client.get_client_class = self.old_get_client_class - super().tearDown() - - def run_command(self, cmd, version=None): - if version: - args = ['--os-share-api-version', version] + cmd.split() - else: - args = cmd.split() - self.shell.main(args) - - def assert_called(self, method, url, body=None, **kwargs): - return self.shell.cs.assert_called(method, url, body, **kwargs) - - def assert_called_anytime( - self, method, url, body=None, clear_callstack=True - ): - return self.shell.cs.assert_called_anytime( - method, url, body, clear_callstack=clear_callstack - ) - - def test_availability_zone_list(self): - self.run_command('availability-zone-list') - self.assert_called('GET', '/availability-zones') - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_availability_zone_list_select_column(self): - self.run_command('availability-zone-list --columns id,name') - self.assert_called('GET', '/availability-zones') - cliutils.print_list.assert_called_once_with( - mock.ANY, fields=['Id', 'Name'] - ) - - def test_service_list(self): - self.run_command('service-list') - self.assert_called('GET', '/services') - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_service_list_select_column(self): - self.run_command('service-list --columns id,host') - self.assert_called('GET', '/services') - cliutils.print_list.assert_called_once_with( - mock.ANY, fields=['Id', 'Host'] - ) - - def test_service_enable(self): - self.run_command('service-enable foo_host@bar_backend manila-share') - self.assert_called( - 'PUT', - '/services/enable', - {'host': 'foo_host@bar_backend', 'binary': 'manila-share'}, - ) - - def test_service_disable(self): - self.run_command('service-disable foo_host@bar_backend manila-share') - self.assert_called( - 'PUT', - '/services/disable', - {'host': 'foo_host@bar_backend', 'binary': 'manila-share'}, - ) - - def test_list(self): - self.run_command('list') - # NOTE(jdg): we default to detail currently - self.assert_called('GET', '/shares/detail') - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_list_select_column(self): - self.run_command('list --column id,name') - self.assert_called('GET', '/shares/detail') - cliutils.print_list.assert_called_once_with( - mock.ANY, ['Id', 'Name'], sortby_index=None - ) - - def test_list_sort_by_name(self): - self.run_command('list --sort_key name') - self.assert_called('GET', '/shares/detail?sort_key=name') - - def test_list_filter_status(self): - for separator in self.separators: - self.run_command('list --status' + separator + 'available') - self.assert_called('GET', '/shares/detail?status=available') - - def test_list_filter_name(self): - for separator in self.separators: - self.run_command('list --name' + separator + '1234') - self.assert_called('GET', '/shares/detail?name=1234') - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_list_all_tenants_only_key(self): - self.run_command('list --all-tenants') - self.assert_called('GET', '/shares/detail?all_tenants=1') - cliutils.print_list.assert_called_once_with( - mock.ANY, - [ - 'ID', - 'Name', - 'Size', - 'Share Proto', - 'Status', - 'Is Public', - 'Share Type Name', - 'Host', - 'Availability Zone', - 'Project ID', - ], - sortby_index=None, - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_list_select_column_and_all_tenants(self): - self.run_command('list --columns ID,Name --all-tenants') - self.assert_called('GET', '/shares/detail?all_tenants=1') - cliutils.print_list.assert_called_once_with( - mock.ANY, ['Id', 'Name'], sortby_index=None - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_list_select_column_and_public(self): - self.run_command('list --columns ID,Name --public') - self.assert_called('GET', '/shares/detail?is_public=True') - cliutils.print_list.assert_called_once_with( - mock.ANY, ['Id', 'Name'], sortby_index=None - ) - - def test_list_all_tenants_key_and_value_1(self): - for separator in self.separators: - self.run_command('list --all-tenants' + separator + '1') - self.assert_called('GET', '/shares/detail?all_tenants=1') - - def test_list_all_tenants_key_and_value_0(self): - for separator in self.separators: - self.run_command('list --all-tenants' + separator + '0') - self.assert_called('GET', '/shares/detail') - - def test_list_filter_by_share_server_and_its_aliases(self): - aliases = [ - '--share-server-id', - '--share-server_id', - '--share_server-id', - '--share_server_id', - ] - for alias in aliases: - for separator in self.separators: - self.run_command('list ' + alias + separator + '1234') - self.assert_called( - 'GET', '/shares/detail?share_server_id=1234' - ) - - def test_list_filter_by_metadata(self): - self.run_command('list --metadata key=value') - # /shares/detail?metadata={'key': 'value'} - self.assert_called( - 'GET', '/shares/detail?metadata=%7B%27key%27%3A+%27value%27%7D' - ) - - def test_list_filter_by_metadata_with_multiple_key_values(self): - self.run_command('list --metadata key1=value1 key2=value2 key3=value3') - # /shares/detail?metadata={'key1': 'value1', - # 'key2': 'value2', 'key3': 'value3'} - self.assert_called( - 'GET', - '/shares/detail?metadata=' - '%7B%27key1%27%3A+%27value1%27%2C+%27key2%27%3A+' - '%27value2%27%2C+%27key3%27%3A+%27value3%27%7D', - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_list_filter_by_metadata_with_empty_metadata(self): - self.run_command('list --metadata \'\'') - - self.assert_called('GET', '/shares/detail') - cliutils.print_list.assert_called() - args, _ = cliutils.print_list.call_args - shares = args[0] - # All 4 shares irrespective of metadata values printed - self.assertEqual(len(shares), 4) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_list_filter_by_metadata_set_to_None(self): - self.run_command('list --metadata None') - - self.assert_called('GET', '/shares/detail') - cliutils.print_list.assert_called() - args, _ = cliutils.print_list.call_args - shares = args[0] - # Check that the size of shares is 2(shares with metadata={}) - self.assertEqual(len(shares), 2) - for share in shares: - self.assertEqual(share.metadata, {}) - - def test_list_filter_by_metadata_with_one_empty_of_many_metadata(self): - self.run_command('list --metadata key=value \'\'') - # /shares/detail?metadata={'key': 'value'} - self.assert_called( - 'GET', '/shares/detail?metadata=%7B%27key%27%3A+%27value%27%7D' - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_list_filter_by_metadata_with_no_metadata(self): - self.run_command('list --metadata') - # /shares/detail - self.assert_called('GET', '/shares/detail') - cliutils.print_list.assert_called() - args, _ = cliutils.print_list.call_args - shares = args[0] - # All 4 shares printed - self.assertEqual(len(shares), 4) - - def test_list_filter_by_extra_specs_and_its_aliases(self): - aliases = [ - '--extra-specs', - '--extra_specs', - ] - for alias in aliases: - self.run_command('list ' + alias + ' key=value') - self.assert_called( - 'GET', - '/shares/detail?extra_specs=%7B%27key%27%3A+%27value%27%7D', - ) - - def test_list_filter_by_share_type_and_its_aliases(self): - fake_st = type('Empty', (object,), {'id': 'fake_st'}) - aliases = [ - '--share-type', - '--share_type', - '--share-type-id', - '--share-type_id', - '--share_type-id', - '--share_type_id', - ] - for alias in aliases: - for separator in self.separators: - with mock.patch.object( - apiclient_utils, - 'find_resource', - mock.Mock(return_value=fake_st), - ): - self.run_command('list ' + alias + separator + fake_st.id) - self.assert_called( - 'GET', '/shares/detail?share_type_id=' + fake_st.id - ) - - def test_list_filter_by_inexact_name(self): - for separator in self.separators: - self.run_command('list --name~' + separator + 'fake_name') - self.assert_called('GET', '/shares/detail?name~=fake_name') - - def test_list_filter_by_inexact_description(self): - for separator in self.separators: - self.run_command( - 'list --description~' + separator + 'fake_description' - ) - self.assert_called( - 'GET', '/shares/detail?description~=fake_description' - ) - - def test_list_filter_by_inexact_unicode_name(self): - for separator in self.separators: - self.run_command('list --name~' + separator + 'ффф') - self.assert_called( - 'GET', '/shares/detail?name~=%D1%84%D1%84%D1%84' - ) - - def test_list_filter_by_inexact_unicode_description(self): - for separator in self.separators: - self.run_command('list --description~' + separator + 'ффф') - self.assert_called( - 'GET', '/shares/detail?description~=%D1%84%D1%84%D1%84' - ) - - def test_list_filter_by_share_type_not_found(self): - for separator in self.separators: - self.assertRaises( - exceptions.CommandError, - self.run_command, - 'list --share-type' + separator + 'not_found_expected', - ) - self.assert_called('GET', '/types?all_tenants=1&is_public=all') - - def test_list_with_limit(self): - for separator in self.separators: - self.run_command('list --limit' + separator + '50') - self.assert_called('GET', '/shares/detail?limit=50') - - def test_list_with_offset(self): - for separator in self.separators: - self.run_command('list --offset' + separator + '50') - self.assert_called('GET', '/shares/detail?offset=50') - - def test_list_with_sort_dir_verify_keys(self): - # Verify allowed aliases and keys - aliases = ['--sort_dir', '--sort-dir'] - for alias in aliases: - for key in constants.SORT_DIR_VALUES: - for separator in self.separators: - self.run_command('list ' + alias + separator + key) - self.assert_called('GET', '/shares/detail?sort_dir=' + key) - - def test_list_with_fake_sort_dir(self): - self.assertRaises( - ValueError, - self.run_command, - 'list --sort-dir fake_sort_dir', - ) - - def test_list_with_sort_key_verify_keys(self): - # Verify allowed aliases and keys - aliases = ['--sort_key', '--sort-key'] - for alias in aliases: - for key in constants.SHARE_SORT_KEY_VALUES: - for separator in self.separators: - self.run_command('list ' + alias + separator + key) - key = 'share_network_id' if key == 'share_network' else key - key = 'snapshot_id' if key == 'snapshot' else key - key = 'share_type_id' if key == 'share_type' else key - key = ( - 'availability_zone_id' - if key == 'availability_zone' - else key - ) - self.assert_called('GET', '/shares/detail?sort_key=' + key) - - def test_list_with_fake_sort_key(self): - self.assertRaises( - ValueError, - self.run_command, - 'list --sort-key fake_sort_key', - ) - - def test_list_filter_by_snapshot(self): - fake_s = type('Empty', (object,), {'id': 'fake_snapshot_id'}) - for separator in self.separators: - with mock.patch.object( - apiclient_utils, - 'find_resource', - mock.Mock(return_value=fake_s), - ): - self.run_command('list --snapshot' + separator + fake_s.id) - self.assert_called( - 'GET', '/shares/detail?snapshot_id=' + fake_s.id - ) - - def test_list_filter_by_snapshot_not_found(self): - self.assertRaises( - exceptions.CommandError, - self.run_command, - 'list --snapshot not_found_expected', - ) - self.assert_called('GET', '/snapshots/detail?all_tenants=1') - - def test_list_filter_by_host(self): - for separator in self.separators: - self.run_command('list --host' + separator + 'fake_host') - self.assert_called('GET', '/shares/detail?host=fake_host') - - @ddt.data( - ('id', 'b4991315-eb7d-43ec-979e-5715d4399827'), ('path', 'fake_path') - ) - @ddt.unpack - def test_share_list_filter_by_export_location(self, filter_type, value): - for separator in self.separators: - self.run_command('list --export_location' + separator + value) - self.assert_called( - 'GET', - '/shares/detail?export_location_' + filter_type + '=' + value, - ) - - @ddt.data('list', 'share-instance-list') - def test_share_or_instance_list_filter_by_export_location_version_invalid( - self, cmd - ): - self.assertRaises( - exceptions.CommandError, - self.run_command, - cmd + ' --export_location=fake', - '2.34', - ) - - def test_list_filter_by_share_network(self): - aliases = [ - '--share-network', - '--share_network', - ] - fake_sn = type('Empty', (object,), {'id': 'fake_share_network_id'}) - for alias in aliases: - for separator in self.separators: - with mock.patch.object( - apiclient_utils, - 'find_resource', - mock.Mock(return_value=fake_sn), - ): - self.run_command('list ' + alias + separator + fake_sn.id) - self.assert_called( - 'GET', '/shares/detail?share_network_id=' + fake_sn.id - ) - - def test_list_filter_by_share_network_not_found(self): - self.assertRaises( - exceptions.CommandError, - self.run_command, - 'list --share-network not_found_expected', - ) - self.assert_called('GET', '/share-networks/detail?all_tenants=1') - - @ddt.data('True', 'False') - def test_list_filter_with_count(self, value): - except_url = '/shares/detail?with_count=' + value - if value == 'False': - except_url = '/shares/detail' - - for separator in self.separators: - self.run_command('list --count' + separator + value) - self.assert_called('GET', except_url) - - @ddt.data('True', 'False') - def test_list_filter_with_count_invalid_version(self, value): - self.assertRaises( - exceptions.CommandError, - self.run_command, - 'list --count ' + value, - version='2.41', - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_share_instance_list(self): - self.run_command('share-instance-list') - - self.assert_called('GET', '/share_instances') - cliutils.print_list.assert_called_once_with( - mock.ANY, - [ - 'ID', - 'Share ID', - 'Host', - 'Status', - 'Availability Zone', - 'Share Network ID', - 'Share Server ID', - 'Share Type ID', - ], - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_share_instance_list_select_column(self): - self.run_command('share-instance-list --column id,host,status') - - self.assert_called('GET', '/share_instances') - cliutils.print_list.assert_called_once_with( - mock.ANY, ['Id', 'Host', 'Status'] - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - @ddt.data( - ('id', 'b4991315-eb7d-43ec-979e-5715d4399827'), ('path', 'fake_path') - ) - @ddt.unpack - def test_share_instance_list_filter_by_export_location( - self, filter_type, value - ): - for separator in self.separators: - self.run_command( - 'share-instance-list --export_location' + separator + value - ) - self.assert_called( - 'GET', - ( - '/share_instances?export_location_' - + filter_type - + '=' - + value - ), - ) - - @mock.patch.object( - apiclient_utils, 'find_resource', mock.Mock(return_value='fake') - ) - def test_share_instance_list_with_share(self): - self.run_command('share-instance-list --share-id=fake') - self.assert_called('GET', '/shares/fake/instances') - - def test_share_instance_list_invalid_share(self): - self.assertRaises( - exceptions.CommandError, - self.run_command, - 'share-instance-list --share-id=not-found-id', - ) - - def test_share_instance_show(self): - self.run_command('share-instance-show 1234') - self.assert_called_anytime('GET', '/share_instances/1234') - - def test_share_instance_export_location_list(self): - self.run_command('share-instance-export-location-list 1234') - - self.assert_called_anytime( - 'GET', '/share_instances/1234/export_locations' - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_share_instance_export_location_list_with_columns(self): - self.run_command( - 'share-instance-export-location-list 1234 --columns uuid,path' - ) - - self.assert_called_anytime( - 'GET', '/share_instances/1234/export_locations' - ) - cliutils.print_list.assert_called_once_with(mock.ANY, ['Uuid', 'Path']) - - def test_share_instance_export_location_show(self): - self.run_command( - 'share-instance-export-location-show 1234 fake_el_uuid' - ) - self.assert_called_anytime( - 'GET', '/share_instances/1234/export_locations/fake_el_uuid' - ) - - def test_share_instance_reset_state(self): - self.run_command('share-instance-reset-state 1234') - expected = {'reset_status': {'status': 'available'}} - self.assert_called( - 'POST', '/share_instances/1234/action', body=expected - ) - - def test_share_instance_force_delete(self): - manager_mock = mock.Mock() - share_instance = share_instances.ShareInstance( - manager_mock, {'id': 'fake'}, True - ) - - with mock.patch.object( - shell_v2, - '_find_share_instance', - mock.Mock(return_value=share_instance), - ): - self.run_command('share-instance-force-delete 1234') - manager_mock.force_delete.assert_called_once_with(share_instance) - - @ddt.data( - ('share_instance_xyz',), ('share_instance_abc', 'share_instance_xyz') - ) - def test_share_instance_force_delete_wait(self, instances_to_delete): - fake_manager = mock.Mock() - fake_instances = [ - share_instances.ShareInstance(fake_manager, {'id': '1234'}) - for instance in instances_to_delete - ] - instance_not_found_error = ( - "Delete for instance %s failed: No " - "instance with a name or " - "ID of '%s' exists." - ) - instances_are_not_found_errors = [ - exceptions.CommandError( - instance_not_found_error % (instance, instance) - ) - for instance in instances_to_delete - ] - self.mock_object( - shell_v2, - '_find_share_instance', - mock.Mock( - side_effect=(fake_instances + instances_are_not_found_errors) - ), - ) - self.run_command( - 'share-instance-force-delete {} --wait'.format( - ' '.join(instances_to_delete) - ) - ) - shell_v2._find_share_instance.assert_has_calls( - [ - mock.call(self.shell.cs, instance) - for instance in instances_to_delete - ] - ) - fake_manager.force_delete.assert_has_calls( - [mock.call(instance) for instance in fake_instances] - ) - self.assertEqual( - len(instances_to_delete), fake_manager.force_delete.call_count - ) - - def test_type_show_details(self): - self.run_command('type-show 1234') - self.assert_called_anytime('GET', '/types/1234') - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - @ddt.data( - *itertools.product( - ( - 'type-list --columns id,is_default', - 'type-list --columns id,name', - 'type-list --columns is_default', - 'type-list', - ), - {'2.45', '2.46', api_versions.MAX_VERSION}, - ) - ) - @ddt.unpack - def test_type_list(self, command, version): - self.run_command(command, version=version) - - columns_requested = [ - 'ID', - 'Name', - 'visibility', - 'is_default', - 'required_extra_specs', - 'optional_extra_specs', - 'Description', - ] - if 'columns' in command: - columns_requested = command.split('--columns ')[1].split(',') - - is_default_in_api = api_versions.APIVersion( - version - ) >= api_versions.APIVersion('2.46') - - if not is_default_in_api and 'is_default' in columns_requested: - self.assert_called('GET', '/types/default') - self.assert_called_anytime('GET', '/types') - else: - self.assert_called('GET', '/types') - - cliutils.print_list.assert_called_with( - mock.ANY, columns_requested, mock.ANY - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_type_list_select_column(self): - self.run_command('type-list --columns id,name') - - self.assert_called('GET', '/types') - cliutils.print_list.assert_called_once_with( - mock.ANY, ['id', 'name'], mock.ANY - ) - - def test_type_list_all(self): - self.run_command('type-list --all') - self.assert_called_anytime('GET', '/types?is_public=all') - - @ddt.data(True, False) - def test_type_create_with_access(self, public): - expected = { - 'share_type': { - 'name': 'test-type-3', - 'extra_specs': { - 'driver_handles_share_servers': False, - }, - 'share_type_access:is_public': public, - } - } - self.run_command( - f'type-create test-type-3 false --is-public {str(public)}' - ) - self.assert_called('POST', '/types', body=expected) - - def test_type_access_list(self): - self.run_command('type-access-list 3') - self.assert_called('GET', '/types/3/share_type_access') - - def test_type_access_add_project(self): - expected = {'addProjectAccess': {'project': '101'}} - self.run_command('type-access-add 3 101') - self.assert_called('POST', '/types/3/action', body=expected) - - def test_type_access_remove_project(self): - expected = {'removeProjectAccess': {'project': '101'}} - self.run_command('type-access-remove 3 101') - self.assert_called('POST', '/types/3/action', body=expected) - - def test_list_filter_by_project_id(self): - aliases = ['--project-id', '--project_id'] - for alias in aliases: - for separator in self.separators: - self.run_command('list ' + alias + separator + 'fake_id') - self.assert_called('GET', '/shares/detail?project_id=fake_id') - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_list_with_public_shares(self): - listed_fields = [ - 'ID', - 'Name', - 'Size', - 'Share Proto', - 'Status', - 'Is Public', - 'Share Type Name', - 'Host', - 'Availability Zone', - 'Project ID', - ] - self.run_command('list --public') - self.assert_called('GET', '/shares/detail?is_public=True') - cliutils.print_list.assert_called_with( - mock.ANY, listed_fields, sortby_index=None - ) - - def test_show(self): - self.run_command('show 1234') - self.assert_called_anytime('GET', '/shares/1234') - - def test_share_export_location_list(self): - self.run_command('share-export-location-list 1234') - self.assert_called_anytime('GET', '/shares/1234/export_locations') - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_share_export_location_list_with_columns(self): - self.run_command('share-export-location-list 1234 --columns uuid,path') - - self.assert_called_anytime('GET', '/shares/1234/export_locations') - cliutils.print_list.assert_called_once_with(mock.ANY, ['Uuid', 'Path']) - - def test_share_export_location_show(self): - self.run_command('share-export-location-show 1234 fake_el_uuid') - self.assert_called_anytime( - 'GET', '/shares/1234/export_locations/fake_el_uuid' - ) - - @ddt.data( - { - 'cmd_args': '--driver_options opt1=opt1 opt2=opt2' - ' --share_type fake_share_type', - 'valid_params': { - 'driver_options': {'opt1': 'opt1', 'opt2': 'opt2'}, - 'share_type': 'fake_share_type', - 'share_server_id': None, - }, - }, - { - 'cmd_args': '--share_type fake_share_type', - 'valid_params': { - 'driver_options': {}, - 'share_type': 'fake_share_type', - 'share_server_id': None, - }, - }, - { - 'cmd_args': '', - 'valid_params': { - 'driver_options': {}, - 'share_type': None, - 'share_server_id': None, - }, - }, - { - 'cmd_args': '--public --wait', - 'valid_params': { - 'driver_options': {}, - 'share_type': None, - 'share_server_id': None, - }, - 'is_public': True, - 'version': '--os-share-api-version 2.8', - }, - { - 'cmd_args': '', - 'valid_params': { - 'driver_options': {}, - 'share_type': None, - 'share_server_id': None, - }, - 'is_public': False, - 'version': '--os-share-api-version 2.8', - }, - { - 'cmd_args': '--driver_options opt1=opt1 opt2=opt2' - ' --share_type fake_share_type' - ' --wait', - 'valid_params': { - 'driver_options': {'opt1': 'opt1', 'opt2': 'opt2'}, - 'share_type': 'fake_share_type', - 'share_server_id': None, - }, - 'version': '--os-share-api-version 2.49', - }, - { - 'cmd_args': '--driver_options opt1=opt1 opt2=opt2' - ' --share_type fake_share_type' - ' --share_server_id fake_server', - 'valid_params': { - 'driver_options': {'opt1': 'opt1', 'opt2': 'opt2'}, - 'share_type': 'fake_share_type', - 'share_server_id': 'fake_server', - }, - 'version': '--os-share-api-version 2.49', - }, - { - 'cmd_args': '--driver_options opt1=opt1 opt2=opt2' - ' --share_type fake_share_type' - ' --share_server_id fake_server' - ' --wait', - 'valid_params': { - 'driver_options': {'opt1': 'opt1', 'opt2': 'opt2'}, - 'share_type': 'fake_share_type', - 'share_server_id': 'fake_server', - }, - }, - ) - @ddt.unpack - def test_manage( - self, cmd_args, valid_params, is_public=False, version=None - ): - share_to_be_managed = shares.Share('fake_share', {'id': 'fake'}) - self.mock_object( - shell_v2, - '_wait_for_resource_status', - mock.Mock(return_value=share_to_be_managed), - ) - - if version is not None: - self.run_command( - version - + ' manage fake_service fake_protocol ' - + ' fake_export_path ' - + cmd_args - ) - else: - self.run_command( - ' manage fake_service fake_protocol ' - + ' fake_export_path ' - + cmd_args - ) - expected = { - 'share': { - 'service_host': 'fake_service', - 'protocol': 'fake_protocol', - 'export_path': 'fake_export_path', - 'name': None, - 'description': None, - 'is_public': is_public, - 'share_server_id': valid_params['share_server_id'], - } - } - expected['share'].update(valid_params) - - self.assert_called('POST', '/shares/manage', body=expected) - - if '--wait' in cmd_args: - shell_v2._wait_for_resource_status.assert_called_once_with( - self.shell.cs, - share_to_be_managed, - resource_type='share', - expected_status='available', - ) - else: - shell_v2._wait_for_resource_status.assert_not_called() - - def test_manage_invalid_param_share_server_id(self): - self.assertRaises( - exceptions.CommandError, - self.run_command, - '--os-share-api-version 2.48' - + ' manage fake_service fake_protocol ' - + ' fake_export_path ' - + ' --driver_options opt1=opt1 opt2=opt2' - + ' --share_type fake_share_type' - + ' --share_server_id fake_server', - ) - - def test_share_server_manage_unsupported_version(self): - self.assertRaises( - exceptions.UnsupportedVersion, - self.run_command, - '--os-share-api-version 2.48 ' - + 'share-server-manage fake_host fake_share_net_id fake_id', - ) - - def test_share_server_manage_invalid_param_subnet_id(self): - self.assertRaises( - exceptions.CommandError, - self.run_command, - '--os-share-api-version 2.49 ' - + 'share-server-manage fake_host fake_share_net_id fake_id ' - + '--share-network-subnet fake_subnet_id', - ) - - @ddt.data( - { - 'driver_args': '--driver_options opt1=opt1 opt2=opt2', - 'valid_params': { - 'driver_options': {'opt1': 'opt1', 'opt2': 'opt2'}, - }, - }, - { - 'driver_args': '--driver_options opt1=opt1 opt2=opt2', - 'subnet_id': 'fake_subnet_1', - 'valid_params': { - 'driver_options': {'opt1': 'opt1', 'opt2': 'opt2'}, - }, - }, - { - 'driver_args': '--driver_options opt1=opt1 opt2=opt2', - 'valid_params': { - 'driver_options': {'opt1': 'opt1', 'opt2': 'opt2'}, - }, - 'version': '2.51', - }, - { - 'driver_args': '--driver_options opt1=opt1 opt2=opt2', - 'subnet_id': 'fake_subnet_1', - 'valid_params': { - 'driver_options': {'opt1': 'opt1', 'opt2': 'opt2'}, - }, - 'version': '2.51', - }, - { - 'driver_args': "", - 'valid_params': {'driver_options': {}}, - 'version': '2.51', - }, - { - 'driver_args': '--driver_options opt1=opt1 opt2=opt2', - 'valid_params': { - 'driver_options': {'opt1': 'opt1', 'opt2': 'opt2'}, - }, - 'version': '2.49', - }, - { - 'driver_args': '', - 'valid_params': { - 'driver_options': {}, - }, - 'network_id': 'fake_network_id', - 'version': '2.49', - }, - { - 'driver_args': "", - 'valid_params': {'driver_options': {}}, - 'version': '2.49', - }, - ) - @ddt.unpack - def test_share_server_manage_wait( - self, - driver_args, - valid_params, - version=None, - network_id=None, - subnet_id=None, - ): - fake_manager = mock.Mock() - subnet_support = version is None or api_versions.APIVersion( - version - ) >= api_versions.APIVersion('2.51') - - network_id = '3456' if network_id is None else network_id - fake_share_network = share_networks.ShareNetwork( - fake_manager, {'id': network_id, 'uuid': network_id} - ) - self.mock_object( - shell_v2, - '_find_share_network', - mock.Mock(return_value=fake_share_network), - ) - fake_share_server = share_servers.ShareServer( - fake_manager, {'id': 'fake'} - ) - self.mock_object( - shell_v2, - '_find_share_server', - mock.Mock(return_value=fake_share_server), - ) - - self.mock_object(shell_v2, '_wait_for_resource_status', mock.Mock()) - command = ( - 'share-server-manage ' - '{host} ' - '{share_network_id} ' - '{identifier} ' - '{driver_args} '.format( - host='fake_host', - share_network_id=fake_share_network.id, - identifier='88-as-23-f3-45', - driver_args=driver_args, - ) - ) - command += f'--share-network-subnet {subnet_id}' if subnet_id else '' - - self.run_command(command, version=version) - - expected = { - 'share_server': { - 'host': 'fake_host', - 'share_network_id': fake_share_network.id, - 'identifier': '88-as-23-f3-45', - 'driver_options': driver_args, - } - } - if subnet_support: - expected['share_server']['share_network_subnet_id'] = subnet_id - expected['share_server'].update(valid_params) - - self.assert_called('POST', '/share-servers/manage', body=expected) - - shell_v2._wait_for_resource_status.assert_has_calls( - [ - mock.call( - self.shell.cs, - fake_share_server, - resource_type='share_server', - expected_status='active', - ) - ] - ) - - @ddt.data( - constants.STATUS_ERROR, - constants.STATUS_ACTIVE, - constants.STATUS_MANAGE_ERROR, - constants.STATUS_UNMANAGE_ERROR, - constants.STATUS_DELETING, - constants.STATUS_CREATING, - ) - def test_share_server_reset_state(self, status): - self.run_command(f'share-server-reset-state 1234 --state {status} ') - expected = {'reset_status': {'status': status}} - self.assert_called('POST', '/share-servers/1234/action', body=expected) - - @ddt.data('--wait', '') - def test_unmanage(self, wait_option): - version = api_versions.APIVersion('2.46') - api = mock.Mock(api_version=version) - manager = shares.ShareManager(api=api) - fake_share = shares.Share( - manager, - { - 'id': 'xyzzyspoon', - 'api_version': version, - 'status': 'available', - }, - ) - share_not_found_error = ( - "ERROR: No share with a name or ID of '%s' exists." - ) - share_not_found_error = exceptions.CommandError( - share_not_found_error % (fake_share.id) - ) - self.mock_object( - shell_v2, - '_find_share', - mock.Mock( - side_effect=( - [fake_share, fake_share, fake_share, share_not_found_error] - ) - ), - ) - self.mock_object( - shares.ShareManager, 'get', mock.Mock(return_value=fake_share) - ) - - self.run_command(f'unmanage {wait_option} xyzzyspoon') - - expected_get_share_calls = 4 if wait_option else 1 - shell_v2._find_share.assert_has_calls( - [mock.call(self.shell.cs, fake_share.id)] - * expected_get_share_calls - ) - uri = f'/shares/{fake_share.id}/action' - api.client.post.assert_called_once_with(uri, body={'unmanage': None}) - - def test_share_server_unmanage(self): - self.run_command('share-server-unmanage 1234') - self.assert_called( - 'POST', - '/share-servers/1234/action', - body={'unmanage': {'force': False}}, - ) - - def test_share_server_unmanage_force(self): - self.run_command('share-server-unmanage 1234 --force') - self.assert_called( - 'POST', - '/share-servers/1234/action', - body={'unmanage': {'force': True}}, - ) - - @mock.patch.object(shell_v2, '_wait_for_resource_status', mock.Mock()) - def test_share_server_unmanage_wait(self): - self.run_command('share-server-unmanage 1234 --wait') - - self.assert_called( - 'POST', - '/share-servers/1234/action', - body={'unmanage': {'force': False}}, - pos=-2, - ) - expected_share_server = shell_v2._find_share_server( - self.shell.cs, '1234' - ) - shell_v2._wait_for_resource_status.assert_called_once_with( - self.shell.cs, - expected_share_server, - resource_type='share_server', - expected_status='unmanaged', - ) - - @mock.patch.object(shell_v2, '_wait_for_resource_status', mock.Mock()) - def test_share_server_unmanage_wait_with_force(self): - self.run_command('share-server-unmanage 1234 --force --wait') - - self.assert_called( - 'POST', - '/share-servers/1234/action', - body={'unmanage': {'force': True}}, - pos=-2, - ) - expected_share_server = shell_v2._find_share_server( - self.shell.cs, '1234' - ) - shell_v2._wait_for_resource_status.assert_called_once_with( - self.shell.cs, - expected_share_server, - resource_type='share_server', - expected_status='unmanaged', - ) - - @ddt.data( - { - 'cmd_args': '--driver_options opt1=opt1 opt2=opt2', - 'valid_params': { - 'driver_options': {'opt1': 'opt1', 'opt2': 'opt2'}, - }, - }, - { - 'cmd_args': '', - 'valid_params': { - 'driver_options': {}, - }, - }, - ) - @ddt.unpack - @mock.patch.object(shell_v2, '_find_share', mock.Mock()) - @mock.patch.object(shell_v2, '_wait_for_resource_status', mock.Mock()) - def test_snapshot_manage(self, cmd_args, valid_params): - share_containing_snapshot = shares.Share('fake_share', {'id': '1234'}) - shell_v2._find_share.return_value = share_containing_snapshot - self.run_command( - 'snapshot-manage fake_share fake_provider_location ' + cmd_args - ) - expected = { - 'snapshot': { - 'share_id': '1234', - 'provider_location': 'fake_provider_location', - 'name': None, - 'description': None, - } - } - expected['snapshot'].update(valid_params) - self.assert_called('POST', '/snapshots/manage', body=expected) - # _wait_for_resource_status should not be triggered - self.assertEqual(0, shell_v2._wait_for_resource_status.call_count) - - @mock.patch.object(shell_v2, '_find_share', mock.Mock()) - @mock.patch.object(shell_v2, '_wait_for_resource_status', mock.Mock()) - def test_snapshot_manage_with_wait(self): - share_containing_snapshot = shares.Share('fake_share', {'id': '1234'}) - shell_v2._find_share.return_value = share_containing_snapshot - cmd_args = '--wait --driver_options opt1=opt1 opt2=opt2' - self.run_command( - 'snapshot-manage fake_share fake_provider_location ' + cmd_args - ) - expected = { - 'snapshot': { - 'share_id': '1234', - 'provider_location': 'fake_provider_location', - 'name': None, - 'description': None, - } - } - valid_params = {'driver_options': {'opt1': 'opt1', 'opt2': 'opt2'}} - expected['snapshot'].update(valid_params) - self.assert_called('POST', '/snapshots/manage', body=expected) - - shell_v2._find_share.assert_has_calls( - [mock.call(self.shell.cs, 'fake_share')] - ) - self.assertEqual(1, shell_v2._find_share.call_count) - # _wait_for_resource_status should be triggered once - shell_v2._wait_for_resource_status.assert_called_once_with( - self.shell.cs, mock.ANY, 'available', resource_type='snapshot' - ) - - @mock.patch.object(shell_v2, '_find_share', mock.Mock()) - @mock.patch.object(shell_v2, '_wait_for_resource_status', mock.Mock()) - def test_snapshot_unmanage(self): - share_containing_snapshot = shares.Share('fake_share', {'id': '1234'}) - shell_v2._find_share.return_value = share_containing_snapshot - self.run_command('snapshot-unmanage 1234') - - self.assert_called( - 'POST', '/snapshots/1234/action', body={'unmanage': None} - ) - self.assertEqual(0, shell_v2._wait_for_resource_status.call_count) - - @mock.patch.object(shell_v2, '_find_share', mock.Mock()) - @mock.patch.object(shell_v2, '_wait_for_resource_status', mock.Mock()) - def test_snapshot_unmanage_with_wait(self): - share_containing_snapshot = shares.Share('fake_share', {'id': '1234'}) - shell_v2._find_share.return_value = share_containing_snapshot - self.run_command('snapshot-unmanage 1234 --wait') - - self.assert_called( - 'POST', '/snapshots/1234/action', body={'unmanage': None} - ) - expected_snapshot = shell_v2._find_share_snapshot( - self.shell.cs, '1234' - ) - # _wait_for_resource_status should be trigerred once - shell_v2._wait_for_resource_status.assert_called_once_with( - self.shell.cs, - expected_snapshot, - 'deleted', - resource_type='snapshot', - ) - - @mock.patch.object(shell_v2, '_wait_for_share_status', mock.Mock()) - def test_revert_to_snapshot(self): - fake_share_snapshot = type( - 'FakeShareSnapshot', (object,), {'id': '5678', 'share_id': '1234'} - ) - self.mock_object( - shell_v2, - '_find_share_snapshot', - mock.Mock(return_value=fake_share_snapshot), - ) - - self.run_command('revert-to-snapshot 5678') - - self.assert_called( - 'POST', - '/shares/1234/action', - body={'revert': {'snapshot_id': '5678'}}, - ) - # _wait_for_share_status should not be trigerred - self.assertEqual(0, shell_v2._wait_for_share_status.call_count) - - @mock.patch.object(shell_v2, '_wait_for_share_status', mock.Mock()) - def test_revert_to_snapshot_with_wait(self): - fake_share_snapshot = type( - 'FakeShareSnapshot', (object,), {'id': '5678', 'share_id': '1234'} - ) - self.mock_object( - shell_v2, - '_find_share_snapshot', - mock.Mock(return_value=fake_share_snapshot), - ) - - self.run_command('revert-to-snapshot 5678 --wait') - - self.assert_called( - 'POST', - '/shares/1234/action', - body={'revert': {'snapshot_id': '5678'}}, - ) - # _wait_for_share_status should be trigerred once - shell_v2._wait_for_share_status.assert_called_once_with( - self.shell.cs, mock.ANY - ) - - def test_delete(self): - self.run_command('delete 1234') - self.assert_called('DELETE', '/shares/1234') - - @ddt.data('--group sg1313', '--share-group sg1313', '--share_group sg1313') - @mock.patch.object(shell_v2, '_find_share_group', mock.Mock()) - def test_delete_with_share_group(self, sg_cmd): - fake_sg = type('FakeShareGroup', (object,), {'id': sg_cmd.split()[-1]}) - shell_v2._find_share_group.return_value = fake_sg - - self.run_command(f'delete 1234 {sg_cmd}') - - self.assert_called('DELETE', '/shares/1234?share_group_id=sg1313') - self.assertTrue(shell_v2._find_share_group.called) - - def test_delete_not_found(self): - self.assertRaises( - exceptions.CommandError, self.run_command, 'delete fake-not-found' - ) - - @ddt.data(('share_xyz',), ('share_abc', 'share_xyz')) - def test_delete_wait(self, shares_to_delete): - fake_shares = [ - shares.Share('fake', {'id': share}) for share in shares_to_delete - ] - share_not_found_error = ( - "Delete for share %s failed: No share with " - "a name or ID of '%s' exists." - ) - shares_are_not_found_errors = [ - exceptions.CommandError(share_not_found_error % (share, share)) - for share in shares_to_delete - ] - self.mock_object( - shell_v2, - '_find_share', - mock.Mock(side_effect=(fake_shares + shares_are_not_found_errors)), - ) - - self.run_command('delete {} --wait'.format(' '.join(shares_to_delete))) - - shell_v2._find_share.assert_has_calls( - [mock.call(self.shell.cs, share) for share in shares_to_delete] - ) - for share in fake_shares: - uri = f'/shares/{share.id}' - self.assert_called_anytime('DELETE', uri, clear_callstack=False) - - @ddt.data(('share_xyz',), ('share_abc', 'share_xyz')) - def test_force_delete_wait(self, shares_to_delete): - fake_manager = mock.Mock() - fake_shares = [ - shares.Share(fake_manager, {'id': '1234'}) - for share in shares_to_delete - ] - share_not_found_error = ( - "Delete for share %s failed: No share with " - "a name or ID of '%s' exists." - ) - shares_are_not_found_errors = [ - exceptions.CommandError(share_not_found_error % (share, share)) - for share in shares_to_delete - ] - self.mock_object( - shell_v2, - '_find_share', - mock.Mock(side_effect=(fake_shares + shares_are_not_found_errors)), - ) - self.run_command( - 'force-delete {} --wait'.format(' '.join(shares_to_delete)) - ) - shell_v2._find_share.assert_has_calls( - [mock.call(self.shell.cs, share) for share in shares_to_delete] - ) - fake_manager.force_delete.assert_has_calls( - [mock.call(share) for share in fake_shares] - ) - self.assertEqual( - len(shares_to_delete), fake_manager.force_delete.call_count - ) - - def test_soft_delete(self): - self.run_command('soft-delete 1234') - expected = {'soft_delete': None} - self.assert_called('POST', '/shares/1234/action', body=expected) - - def test_restore(self): - self.run_command('restore 1234') - expected = {'restore': None} - self.assert_called('POST', '/shares/1234/action', body=expected) - - def test_list_snapshots(self): - self.run_command('snapshot-list') - self.assert_called('GET', '/snapshots/detail') - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_snapshot_list_select_column(self): - self.run_command('snapshot-list --columns id,name') - self.assert_called('GET', '/snapshots/detail') - cliutils.print_list.assert_called_once_with( - mock.ANY, ['Id', 'Name'], sortby_index=None - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_list_snapshots_all_tenants_only_key(self): - self.run_command('snapshot-list --all-tenants') - self.assert_called('GET', '/snapshots/detail?all_tenants=1') - cliutils.print_list.assert_called_once_with( - mock.ANY, - ['ID', 'Share ID', 'Status', 'Name', 'Share Size', 'Project ID'], - sortby_index=None, - ) - - def test_list_snapshots_all_tenants_key_and_value_1(self): - for separator in self.separators: - self.run_command('snapshot-list --all-tenants' + separator + '1') - self.assert_called('GET', '/snapshots/detail?all_tenants=1') - - def test_list_snapshots_all_tenants_key_and_value_0(self): - for separator in self.separators: - self.run_command('snapshot-list --all-tenants' + separator + '0') - self.assert_called('GET', '/snapshots/detail') - - def test_list_snapshots_filter_by_name(self): - for separator in self.separators: - self.run_command('snapshot-list --name' + separator + '1234') - self.assert_called('GET', '/snapshots/detail?name=1234') - - def test_list_snapshots_filter_by_status(self): - for separator in self.separators: - self.run_command('snapshot-list --status' + separator + '1234') - self.assert_called('GET', '/snapshots/detail?status=1234') - - def test_list_snapshots_filter_by_share_id(self): - aliases = ['--share_id', '--share-id'] - for alias in aliases: - for separator in self.separators: - self.run_command('snapshot-list ' + alias + separator + '1234') - self.assert_called('GET', '/snapshots/detail?share_id=1234') - - def test_list_snapshots_only_used(self): - for separator in self.separators: - self.run_command('snapshot-list --usage' + separator + 'used') - self.assert_called('GET', '/snapshots/detail?usage=used') - - def test_list_snapshots_only_unused(self): - for separator in self.separators: - self.run_command('snapshot-list --usage' + separator + 'unused') - self.assert_called('GET', '/snapshots/detail?usage=unused') - - def test_list_snapshots_any(self): - for separator in self.separators: - self.run_command('snapshot-list --usage' + separator + 'any') - self.assert_called('GET', '/snapshots/detail?usage=any') - - def test_list_snapshots_with_limit(self): - for separator in self.separators: - self.run_command('snapshot-list --limit' + separator + '50') - self.assert_called('GET', '/snapshots/detail?limit=50') - - def test_list_snapshots_with_offset(self): - for separator in self.separators: - self.run_command('snapshot-list --offset' + separator + '50') - self.assert_called('GET', '/snapshots/detail?offset=50') - - def test_list_snapshots_filter_by_inexact_name(self): - for separator in self.separators: - self.run_command('snapshot-list --name~' + separator + 'fake_name') - self.assert_called('GET', '/snapshots/detail?name~=fake_name') - - def test_list_snapshots_filter_by_inexact_description(self): - for separator in self.separators: - self.run_command( - 'snapshot-list --description~' + separator + 'fake_description' - ) - self.assert_called( - 'GET', '/snapshots/detail?description~=fake_description' - ) - - def test_list_snapshots_filter_by_inexact_unicode_name(self): - for separator in self.separators: - self.run_command('snapshot-list --name~' + separator + 'ффф') - self.assert_called( - 'GET', '/snapshots/detail?name~=%D1%84%D1%84%D1%84' - ) - - def test_list_snapshots_filter_by_inexact_unicode_description(self): - for separator in self.separators: - self.run_command( - 'snapshot-list --description~' + separator + 'ффф' - ) - self.assert_called( - 'GET', '/snapshots/detail?description~=%D1%84%D1%84%D1%84' - ) - - def test_list_snapshots_with_sort_dir_verify_keys(self): - aliases = ['--sort_dir', '--sort-dir'] - for alias in aliases: - for key in constants.SORT_DIR_VALUES: - for separator in self.separators: - self.run_command( - 'snapshot-list ' + alias + separator + key - ) - self.assert_called( - 'GET', '/snapshots/detail?sort_dir=' + key - ) - - def test_list_snapshots_with_fake_sort_dir(self): - self.assertRaises( - ValueError, - self.run_command, - 'snapshot-list --sort-dir fake_sort_dir', - ) - - def test_list_snapshots_with_sort_key_verify_keys(self): - aliases = ['--sort_key', '--sort-key'] - for alias in aliases: - for key in constants.SNAPSHOT_SORT_KEY_VALUES: - for separator in self.separators: - self.run_command( - 'snapshot-list ' + alias + separator + key - ) - self.assert_called( - 'GET', '/snapshots/detail?sort_key=' + key - ) - - def test_list_snapshots_with_fake_sort_key(self): - self.assertRaises( - ValueError, - self.run_command, - 'snapshot-list --sort-key fake_sort_key', - ) - - @ddt.data('True', 'False') - def test_list_snapshots_filter_with_count(self, value): - except_url = '/snapshots/detail?with_count=' + value - if value == 'False': - except_url = '/snapshots/detail' - - for separator in self.separators: - self.run_command('snapshot-list --count' + separator + value) - self.assert_called('GET', except_url) - - @ddt.data('True', 'False') - def test_list_snapshots_filter_with_count_invalid_version(self, value): - self.assertRaises( - exceptions.CommandError, - self.run_command, - 'snapshot-list --count ' + value, - version='2.78', - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_extra_specs_list(self): - self.run_command('extra-specs-list') - - self.assert_called('GET', '/types?is_public=all') - cliutils.print_list.assert_called_once_with( - mock.ANY, ['ID', 'Name', 'all_extra_specs'], mock.ANY - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_extra_specs_list_select_column(self): - self.run_command('extra-specs-list --columns id,name') - - self.assert_called('GET', '/types?is_public=all') - cliutils.print_list.assert_called_once_with( - mock.ANY, ['id', 'name'], mock.ANY - ) - - @ddt.data('fake', 'FFFalse', 'trueee') - def test_type_create_invalid_dhss_value(self, value): - self.assertRaises( - exceptions.CommandError, - self.run_command, - 'type-create test ' + value, - ) - - @ddt.data('True', 'False') - def test_type_create_duplicate_dhss(self, value): - self.assertRaises( - exceptions.CommandError, - self.run_command, - 'type-create test ' - + value - + ' --extra-specs driver_handles_share_servers=' - + value, - ) - - @ddt.data( - *itertools.product( - ['snapshot_support', 'create_share_from_snapshot_support'], - ['True', 'False'], - ) - ) - @ddt.unpack - def test_type_create_duplicate_switch_and_extra_spec(self, key, value): - cmd = ( - f'type-create test True --{key} {value} --extra-specs ' - f'{key}={value}' - ) - - self.assertRaises(exceptions.CommandError, self.run_command, cmd) - - def test_type_create_duplicate_extra_spec_key(self): - self.assertRaises( - exceptions.CommandError, - self.run_command, - 'type-create test True --extra-specs a=foo1 a=foo2', - ) - - @ddt.unpack - @ddt.data( - {'expected_bool': True, 'text': 'true'}, - {'expected_bool': True, 'text': '1'}, - {'expected_bool': False, 'text': 'false'}, - {'expected_bool': False, 'text': '0'}, - ) - def test_type_create(self, expected_bool, text): - expected = { - "share_type": { - "name": "test", - "share_type_access:is_public": True, - "extra_specs": { - "driver_handles_share_servers": expected_bool, - }, - } - } - - self.run_command('type-create test ' + text) - - self.assert_called('POST', '/types', body=expected) - - def test_type_create_with_description(self): - expected = { - "share_type": { - "name": "test", - "description": "test_description", - "share_type_access:is_public": True, - "extra_specs": { - "driver_handles_share_servers": False, - }, - } - } - self.run_command( - 'type-create test false --description test_description', - version='2.41', - ) - - self.assert_called('POST', '/types', body=expected) - - @ddt.data('2.26', '2.40') - def test_type_create_invalid_description_version(self, version): - self.assertRaises( - exceptions.CommandError, - self.run_command, - 'type-create test false --description test_description', - version=version, - ) - - @ddt.unpack - @ddt.data( - *( - [ - {'expected_bool': True, 'text': v} - for v in ('true', 'True', '1', 'TRUE', 'tRuE') - ] - + [ - {'expected_bool': False, 'text': v} - for v in ('false', 'False', '0', 'FALSE', 'fAlSe') - ] - ) - ) - def test_type_create_with_snapshot_support(self, expected_bool, text): - expected = { - "share_type": { - "name": "test", - "share_type_access:is_public": True, - "extra_specs": { - "snapshot_support": expected_bool, - "driver_handles_share_servers": False, - }, - } - } - self.run_command('type-create test false --snapshot-support ' + text) - - self.assert_called('POST', '/types', body=expected) - - @ddt.unpack - @ddt.data( - { - 'expected_bool': True, - 'snapshot_text': 'true', - 'replication_type': 'readable', - }, - { - 'expected_bool': False, - 'snapshot_text': 'false', - 'replication_type': 'writable', - }, - ) - def test_create_with_extra_specs( - self, expected_bool, snapshot_text, replication_type - ): - expected = { - "share_type": { - "name": "test", - "share_type_access:is_public": True, - "extra_specs": { - "driver_handles_share_servers": False, - "snapshot_support": expected_bool, - "replication_type": replication_type, - }, - } - } - - self.run_command( - 'type-create test false --extra-specs' - ' snapshot_support=' - + snapshot_text - + ' replication_type=' - + replication_type - ) - - self.assert_called('POST', '/types', body=expected) - - @ddt.unpack - @ddt.data( - *( - [ - {'expected_bool': True, 'text': v} - for v in ('true', 'True', '1', 'TRUE', 'tRuE') - ] - + [ - {'expected_bool': False, 'text': v} - for v in ('false', 'False', '0', 'FALSE', 'fAlSe') - ] - ) - ) - def test_type_create_with_create_share_from_snapshot_support( - self, expected_bool, text - ): - expected = { - "share_type": { - "name": "test", - "share_type_access:is_public": True, - "extra_specs": { - "driver_handles_share_servers": False, - "snapshot_support": True, - "create_share_from_snapshot_support": expected_bool, - }, - } - } - - self.run_command( - 'type-create test false --snapshot-support true ' - '--create-share-from-snapshot-support ' + text - ) - - self.assert_called('POST', '/types', body=expected) - - @ddt.data('snapshot_support', 'create_share_from_snapshot_support') - def test_type_create_invalid_switch_value(self, value): - self.assertRaises( - exceptions.CommandError, - self.run_command, - f'type-create test false --{value} fake', - ) - - @ddt.data('snapshot_support', 'create_share_from_snapshot_support') - def test_type_create_invalid_extra_spec_value(self, value): - self.assertRaises( - exceptions.CommandError, - self.run_command, - f'type-create test false --extra-specs {value}=fake', - ) - - @ddt.unpack - @ddt.data( - *( - [ - {'expected_bool': True, 'text': v} - for v in ('true', 'True', '1', 'TRUE', 'tRuE') - ] - + [ - {'expected_bool': False, 'text': v} - for v in ('false', 'False', '0', 'FALSE', 'fAlSe') - ] - ) - ) - def test_type_create_with_revert_to_snapshot_support( - self, expected_bool, text - ): - expected = { - "share_type": { - "name": "test", - "share_type_access:is_public": True, - "extra_specs": { - "driver_handles_share_servers": False, - "snapshot_support": True, - "revert_to_snapshot_support": expected_bool, - }, - } - } - - self.run_command( - 'type-create test false --snapshot-support true ' - '--revert-to-snapshot-support ' + text - ) - - self.assert_called('POST', '/types', body=expected) - - @ddt.data('fake', 'FFFalse', 'trueee') - def test_type_create_invalid_revert_to_snapshot_support_value(self, value): - self.assertRaises( - exceptions.CommandError, - self.run_command, - 'type-create test false --revert-to-snapshot-support ' + value, - ) - - @ddt.unpack - @ddt.data( - *( - [ - {'expected_bool': True, 'text': v} - for v in ('true', 'True', '1', 'TRUE', 'tRuE') - ] - + [ - {'expected_bool': False, 'text': v} - for v in ('false', 'False', '0', 'FALSE', 'fAlSe') - ] - ) - ) - def test_type_create_with_mount_snapshot_support( - self, expected_bool, text - ): - expected = { - "share_type": { - "name": "test", - "share_type_access:is_public": True, - "extra_specs": { - "driver_handles_share_servers": False, - "snapshot_support": True, - "revert_to_snapshot_support": False, - "mount_snapshot_support": expected_bool, - }, - } - } - - self.run_command( - 'type-create test false --snapshot-support true ' - '--revert-to-snapshot-support false ' - '--mount-snapshot-support ' + text - ) - - self.assert_called('POST', '/types', body=expected) - - @ddt.data('fake', 'FFFalse', 'trueee') - def test_type_create_invalid_mount_snapshot_support_value(self, value): - self.assertRaises( - exceptions.CommandError, - self.run_command, - 'type-create test false --mount-snapshot-support ' + value, - ) - - @ddt.data('--is-public', '--is_public') - def test_update(self, alias): - # basic rename with positional arguments - self.run_command('update 1234 --name new-name') - expected = {'share': {'display_name': 'new-name'}} - self.assert_called('PUT', '/shares/1234', body=expected) - # change description only - self.run_command('update 1234 --description=new-description') - expected = {'share': {'display_description': 'new-description'}} - self.assert_called('PUT', '/shares/1234', body=expected) - # update is_public attr - valid_is_public_values = strutils.TRUE_STRINGS + strutils.FALSE_STRINGS - for is_public in valid_is_public_values: - self.run_command(f'update 1234 {alias} {is_public}') - expected = { - 'share': { - 'is_public': strutils.bool_from_string( - is_public, strict=True - ), - }, - } - self.assert_called('PUT', '/shares/1234', body=expected) - for invalid_val in ['truebar', 'bartrue']: - self.assertRaises( - ValueError, - self.run_command, - f'update 1234 {alias} {invalid_val}', - ) - # update all attributes - self.run_command( - 'update 1234 --name new-name ' - '--description=new-description ' - f'{alias} True' - ) - expected = { - 'share': { - 'display_name': 'new-name', - 'display_description': 'new-description', - 'is_public': True, - } - } - self.assert_called('PUT', '/shares/1234', body=expected) - self.assertRaises( - exceptions.CommandError, self.run_command, 'update 1234' - ) - - def test_rename_snapshot(self): - # basic rename with positional arguments - self.run_command('snapshot-rename 1234 new-name') - expected = {'snapshot': {'display_name': 'new-name'}} - self.assert_called('PUT', '/snapshots/1234', body=expected) - # change description only - self.run_command('snapshot-rename 1234 --description=new-description') - expected = {'snapshot': {'display_description': 'new-description'}} - - self.assert_called('PUT', '/snapshots/1234', body=expected) - # snapshot-rename and change description - self.run_command( - 'snapshot-rename 1234 new-name --description=new-description' - ) - expected = { - 'snapshot': { - 'display_name': 'new-name', - 'display_description': 'new-description', - } - } - self.assert_called('PUT', '/snapshots/1234', body=expected) - # noop, the only all will be the lookup - self.assertRaises( - exceptions.CommandError, self.run_command, 'snapshot-rename 1234' - ) - - def test_set_metadata_set(self): - self.run_command('metadata 1234 set key1=val1 key2=val2') - self.assert_called( - 'POST', - '/shares/1234/metadata', - {'metadata': {'key1': 'val1', 'key2': 'val2'}}, - ) - - def test_set_metadata_delete_dict(self): - self.run_command('metadata 1234 unset key1=val1 key2=val2') - self.assert_called('DELETE', '/shares/1234/metadata/key1') - self.assert_called('DELETE', '/shares/1234/metadata/key2', pos=-2) - - def test_set_metadata_delete_keys(self): - self.run_command('metadata 1234 unset key1 key2') - self.assert_called('DELETE', '/shares/1234/metadata/key1') - self.assert_called('DELETE', '/shares/1234/metadata/key2', pos=-2) - - def test_share_metadata_update_all(self): - self.run_command('metadata-update-all 1234 key1=val1 key2=val2') - self.assert_called( - 'PUT', - '/shares/1234/metadata', - {'metadata': {'key1': 'val1', 'key2': 'val2'}}, - ) - - def test_extract_metadata(self): - # mimic the result of argparse's parse_args() method - class Arguments: - def __init__(self, metadata=None): - if metadata is None: - metadata = [] - self.metadata = metadata - - inputs = [ - ([], {}), - (["key=value"], {"key": "value"}), - (["key"], {"key": None}), - (["k1=v1", "k2=v2"], {"k1": "v1", "k2": "v2"}), - (["k1=v1", "k2"], {"k1": "v1", "k2": None}), - (["k1", "k2=v2"], {"k1": None, "k2": "v2"}), - ] - - for input in inputs: - args = Arguments(metadata=input[0]) - self.assertEqual(shell_v2._extract_metadata(args), input[1]) - - @ddt.data('--wait', '') - def test_extend_with_wait_option(self, wait_option): - available_share = shares.Share( - 'fake', {'id': '1234', 'status': 'available'} - ) - share_to_extend = shares.Share( - 'fake', {'id': '1234', 'status': 'extending'} - ) - fake_shares = [ - available_share, - share_to_extend, - share_to_extend, - available_share, - ] - self.mock_object( - shell_v2, '_find_share', mock.Mock(side_effect=fake_shares) - ) - expected_extend_body = {'extend': {'new_size': 77}} - self.run_command(f'extend 1234 77 {wait_option}') - self.assert_called_anytime( - 'POST', - '/shares/1234/action', - body=expected_extend_body, - clear_callstack=False, - ) - if wait_option: - shell_v2._find_share.assert_has_calls( - [mock.call(self.shell.cs, '1234')] * 4 - ) - self.assertEqual(4, shell_v2._find_share.call_count) - else: - shell_v2._find_share.assert_called_with(self.shell.cs, '1234') - self.assertEqual(2, shell_v2._find_share.call_count) - - def test_reset_state(self): - self.run_command('reset-state 1234') - expected = {'reset_status': {'status': 'available'}} - self.assert_called('POST', '/shares/1234/action', body=expected) - - @ddt.data('--wait', '') - def test_shrink_with_wait_option(self, wait_option): - available_share = shares.Share( - 'fake', {'id': '1234', 'status': 'available'} - ) - share_to_shrink = shares.Share( - 'fake', {'id': '1234', 'status': 'shrinking'} - ) - fake_shares = [ - available_share, - share_to_shrink, - share_to_shrink, - available_share, - ] - self.mock_object( - shell_v2, '_find_share', mock.Mock(side_effect=fake_shares) - ) - expected_shrink_body = {'shrink': {'new_size': 77}} - self.run_command(f'shrink 1234 77 {wait_option}') - self.assert_called_anytime( - 'POST', - '/shares/1234/action', - body=expected_shrink_body, - clear_callstack=False, - ) - if wait_option: - shell_v2._find_share.assert_has_calls( - [mock.call(self.shell.cs, '1234')] * 4 - ) - self.assertEqual(4, shell_v2._find_share.call_count) - else: - shell_v2._find_share.assert_called_with(self.shell.cs, '1234') - self.assertEqual(2, shell_v2._find_share.call_count) - - def test_reset_state_with_flag(self): - self.run_command('reset-state --state error 1234') - expected = {'reset_status': {'status': 'error'}} - self.assert_called('POST', '/shares/1234/action', body=expected) - - def test_snapshot_reset_state(self): - self.run_command('snapshot-reset-state 1234') - expected = {'reset_status': {'status': 'available'}} - self.assert_called('POST', '/snapshots/1234/action', body=expected) - - def test_snapshot_reset_state_with_flag(self): - self.run_command('snapshot-reset-state --state error 1234') - expected = {'reset_status': {'status': 'error'}} - self.assert_called('POST', '/snapshots/1234/action', body=expected) - - @ddt.data( - {}, - {'--name': 'fake_name'}, - {'--description': 'fake_description'}, - {'--neutron_net_id': 'fake_neutron_net_id'}, - {'--neutron_subnet_id': 'fake_neutron_subnet_id'}, - { - '--description': 'fake_description', - '--name': 'fake_name', - '--neutron_net_id': 'fake_neutron_net_id', - '--neutron_subnet_id': 'fake_neutron_subnet_id', - }, - ) - def test_share_network_create(self, data): - cmd = 'share-network-create' - for k, v in data.items(): - cmd += ' ' + k + ' ' + v - self.run_command(cmd) - - self.assert_called('POST', '/share-networks') - - @ddt.unpack - @ddt.data( - {'data': {'--name': 'fake_name'}}, - {'data': {'--description': 'fake_description'}}, - { - 'data': {'--neutron_net_id': 'fake_neutron_net_id'}, - 'version': '2.49', - }, - { - 'data': {'--neutron_subnet_id': 'fake_neutron_subnet_id'}, - 'version': '2.49', - }, - { - 'data': { - '--description': 'fake_description', - '--name': 'fake_name', - '--neutron_net_id': 'fake_neutron_net_id', - '--neutron_subnet_id': 'fake_neutron_subnet_id', - }, - 'version': '2.49', - }, - {'data': {'--name': '""'}}, - {'data': {'--description': '""'}}, - { - 'data': {'--neutron_net_id': '""'}, - 'version': '2.49', - }, - { - 'data': {'--neutron_subnet_id': '""'}, - 'version': '2.49', - }, - { - 'data': { - '--description': '""', - '--name': '""', - '--neutron_net_id': '""', - '--neutron_subnet_id': '""', - }, - 'version': '2.49', - }, - ) - def test_share_network_update(self, data, version=None): - cmd = 'share-network-update 1111' - expected = dict() - for k, v in data.items(): - cmd += ' ' + k + ' ' + v - expected[k[2:]] = v - expected = dict(share_network=expected) - - self.run_command(cmd, version=version) - - self.assert_called('PUT', '/share-networks/1111', body=expected) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_share_network_list(self): - self.run_command('share-network-list') - self.assert_called( - 'GET', - '/share-networks/detail', - ) - cliutils.print_list.assert_called_once_with( - mock.ANY, fields=['id', 'name'] - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_share_network_list_select_column(self): - self.run_command('share-network-list --columns id') - self.assert_called( - 'GET', - '/share-networks/detail', - ) - cliutils.print_list.assert_called_once_with(mock.ANY, fields=['Id']) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_share_network_list_all_tenants(self): - self.run_command('share-network-list --all-tenants') - self.assert_called( - 'GET', - '/share-networks/detail?all_tenants=1', - ) - cliutils.print_list.assert_called_once_with( - mock.ANY, fields=['id', 'name'] - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - @mock.patch.object(shell_v2, '_find_security_service', mock.Mock()) - def test_share_network_list_filter_by_security_service(self): - ss = type('FakeSecurityService', (object,), {'id': 'fake-ss-id'}) - shell_v2._find_security_service.return_value = ss - for command in ['--security_service', '--security-service']: - self.run_command(f'share-network-list {command} {ss.id}') - self.assert_called( - 'GET', - f'/share-networks/detail?security_service_id={ss.id}', - ) - shell_v2._find_security_service.assert_called_with(mock.ANY, ss.id) - cliutils.print_list.assert_called_with( - mock.ANY, fields=['id', 'name'] - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_share_network_list_project_id_aliases(self): - for command in ['--project-id', '--project_id']: - self.run_command(f'share-network-list {command} 1234') - self.assert_called( - 'GET', - '/share-networks/detail?project_id=1234', - ) - cliutils.print_list.assert_called_with( - mock.ANY, fields=['id', 'name'] - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_share_network_list_created_before_aliases(self): - for command in ['--created-before', '--created_before']: - self.run_command(f'share-network-list {command} 2001-01-01') - self.assert_called( - 'GET', - '/share-networks/detail?created_before=2001-01-01', - ) - cliutils.print_list.assert_called_with( - mock.ANY, fields=['id', 'name'] - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_share_network_list_created_since_aliases(self): - for command in ['--created-since', '--created_since']: - self.run_command(f'share-network-list {command} 2001-01-01') - self.assert_called( - 'GET', - '/share-networks/detail?created_since=2001-01-01', - ) - cliutils.print_list.assert_called_with( - mock.ANY, fields=['id', 'name'] - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_share_network_list_neutron_net_id_aliases(self): - for command in [ - '--neutron-net-id', - '--neutron-net_id', - '--neutron_net-id', - '--neutron_net_id', - ]: - self.run_command(f'share-network-list {command} fake-id') - self.assert_called( - 'GET', - '/share-networks/detail?neutron_net_id=fake-id', - ) - cliutils.print_list.assert_called_with( - mock.ANY, fields=['id', 'name'] - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_share_network_list_neutron_subnet_id_aliases(self): - for command in [ - '--neutron-subnet-id', - '--neutron-subnet_id', - '--neutron_subnet-id', - '--neutron_subnet_id', - ]: - self.run_command(f'share-network-list {command} fake-id') - self.assert_called( - 'GET', - '/share-networks/detail?neutron_subnet_id=fake-id', - ) - cliutils.print_list.assert_called_with( - mock.ANY, fields=['id', 'name'] - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_share_network_list_network_type_aliases(self): - for command in ['--network_type', '--network-type']: - self.run_command(f'share-network-list {command} local') - self.assert_called( - 'GET', - '/share-networks/detail?network_type=local', - ) - cliutils.print_list.assert_called_with( - mock.ANY, fields=['id', 'name'] - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_share_network_list_segmentation_id_aliases(self): - for command in ['--segmentation-id', '--segmentation_id']: - self.run_command(f'share-network-list {command} 1234') - self.assert_called( - 'GET', - '/share-networks/detail?segmentation_id=1234', - ) - cliutils.print_list.assert_called_with( - mock.ANY, fields=['id', 'name'] - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_share_network_list_ip_version_aliases(self): - for command in ['--ip-version', '--ip_version']: - self.run_command(f'share-network-list {command} 4') - self.assert_called( - 'GET', - '/share-networks/detail?ip_version=4', - ) - cliutils.print_list.assert_called_with( - mock.ANY, fields=['id', 'name'] - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_share_network_list_all_filters(self): - filters = { - 'name': 'fake-name', - 'project-id': '1234', - 'created-since': '2001-01-01', - 'created-before': '2002-02-02', - 'neutron-net-id': 'fake-net', - 'neutron-subnet-id': 'fake-subnet', - 'network-type': 'local', - 'segmentation-id': '5678', - 'cidr': 'fake-cidr', - 'ip-version': '4', - 'offset': 10, - 'limit': 20, - } - command_str = 'share-network-list' - for key, value in filters.items(): - command_str += f' --{key}={value}' - self.run_command(command_str) - query = utils.safe_urlencode( - sorted([(k.replace('-', '_'), v) for (k, v) in filters.items()]) - ) - self.assert_called( - 'GET', - f'/share-networks/detail?{query}', - ) - cliutils.print_list.assert_called_once_with( - mock.ANY, fields=['id', 'name'] - ) - - def test_share_network_list_filter_by_inexact_name(self): - for separator in self.separators: - self.run_command( - 'share-network-list --name~' + separator + 'fake_name' - ) - self.assert_called('GET', '/share-networks/detail?name~=fake_name') - - def test_share_network_list_filter_by_inexact_description(self): - for separator in self.separators: - self.run_command( - 'share-network-list --description~' - + separator - + 'fake_description' - ) - self.assert_called( - 'GET', '/share-networks/detail?description~=fake_description' - ) - - def test_share_network_list_filter_by_inexact_unicode_name(self): - for separator in self.separators: - self.run_command('share-network-list --name~' + separator + 'ффф') - self.assert_called( - 'GET', '/share-networks/detail?name~=%D1%84%D1%84%D1%84' - ) - - def test_share_network_list_filter_by_inexact_unicode_description(self): - for separator in self.separators: - self.run_command( - 'share-network-list --description~' + separator + 'ффф' - ) - self.assert_called( - 'GET', '/share-networks/detail?description~=%D1%84%D1%84%D1%84' - ) - - def test_share_network_security_service_add(self): - self.run_command( - 'share-network-security-service-add fake_share_nw ' - 'fake_security_service' - ) - self.assert_called( - 'POST', - '/share-networks/1234/action', - ) - - def test_share_network_security_service_remove(self): - self.run_command( - 'share-network-security-service-remove fake_share_nw ' - 'fake_security_service' - ) - self.assert_called( - 'POST', - '/share-networks/1234/action', - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_share_network_security_service_list_select_column(self): - self.run_command( - 'share-network-security-service-list ' - 'fake_share_nw --column id,name' - ) - self.assert_called( - 'GET', - '/security-services/detail?share_network_id=1234', - ) - cliutils.print_list.assert_called_once_with( - mock.ANY, fields=['Id', 'Name'] - ) - - def test_share_network_security_service_list_by_name(self): - self.run_command('share-network-security-service-list fake_share_nw') - self.assert_called( - 'GET', - '/security-services/detail?share_network_id=1234', - ) - - def test_share_network_security_service_list_by_name_not_found(self): - self.assertRaises( - exceptions.CommandError, - self.run_command, - 'share-network-security-service-list inexistent_share_nw', - ) - - def test_share_network_security_service_list_by_name_multiple(self): - self.assertRaises( - exceptions.CommandError, - self.run_command, - 'share-network-security-service-list duplicated_name', - ) - - def test_share_network_security_service_list_by_id(self): - self.run_command('share-network-security-service-list 1111') - self.assert_called( - 'GET', - '/security-services/detail?share_network_id=1111', - ) - - @ddt.data( - {}, - { - '--neutron_net_id': 'fake_neutron_net_id', - '--neutron_subnet_id': 'fake_neutron_subnet_id', - }, - {'--availability-zone': 'fake_availability_zone_id'}, - { - '--neutron_net_id': 'fake_neutron_net_id', - '--neutron_subnet_id': 'fake_neutron_subnet_id', - '--availability-zone': 'fake_availability_zone_id', - }, - ) - def test_share_network_subnet_add(self, data): - fake_share_network = type( - 'FakeShareNetwork', (object,), {'id': '1234'} - ) - self.mock_object( - shell_v2, - '_find_share_network', - mock.Mock(return_value=fake_share_network), - ) - - cmd = 'share-network-subnet-create' - for k, v in data.items(): - cmd += ' ' + k + ' ' + v - cmd += ' ' + fake_share_network.id - self.run_command(cmd) - - shell_v2._find_share_network.assert_called_once_with( - mock.ANY, fake_share_network.id - ) - self.assert_called('POST', '/share-networks/1234/subnets') - - @ddt.data( - {'--neutron_net_id': 'fake_neutron_net_id'}, - {'--neutron_subnet_id': 'fake_neutron_subnet_id'}, - { - '--neutron_net_id': 'fake_neutron_net_id', - '--availability-zone': 'fake_availability_zone_id', - }, - { - '--neutron_subnet_id': 'fake_neutron_subnet_id', - '--availability-zone': 'fake_availability_zone_id', - }, - ) - def test_share_network_subnet_add_invalid_param(self, data): - cmd = 'share-network-subnet-create' - for k, v in data.items(): - cmd += ' ' + k + ' ' + v - cmd += ' fake_network_id' - - self.assertRaises(exceptions.CommandError, self.run_command, cmd) - - def test_share_network_subnet_add_invalid_share_network(self): - cmd = 'share-network-subnet-create not-found-id' - - self.assertRaises(exceptions.CommandError, self.run_command, cmd) - - @ddt.data(('fake_subnet1',), ('fake_subnet1', 'fake_subnet2')) - def test_share_network_subnet_delete(self, subnet_ids): - fake_share_network = type( - 'FakeShareNetwork', (object,), {'id': '1234'} - ) - self.mock_object( - shell_v2, - '_find_share_network', - mock.Mock(return_value=fake_share_network), - ) - fake_share_network_subnets = [ - share_network_subnets.ShareNetworkSubnet( - 'fake', {'id': subnet_id}, True - ) - for subnet_id in subnet_ids - ] - - self.run_command( - 'share-network-subnet-delete {network_id} {subnet_ids}'.format( - network_id=fake_share_network.id, - subnet_ids=' '.join(subnet_ids), - ) - ) - - shell_v2._find_share_network.assert_called_once_with( - mock.ANY, fake_share_network.id - ) - for subnet in fake_share_network_subnets: - self.assert_called_anytime( - 'DELETE', - f'/share-networks/1234/subnets/{subnet.id}', - clear_callstack=False, - ) - - def test_share_network_subnet_delete_invalid_share_network(self): - command = 'share-network-subnet-delete {net_id} {subnet_id}'.format( - net_id='not-found-id', - subnet_id='1234', - ) - - self.assertRaises(exceptions.CommandError, self.run_command, command) - - def test_share_network_subnet_delete_invalid_share_network_subnet(self): - fake_share_network = type( - 'FakeShareNetwork', (object,), {'id': '1234'} - ) - self.mock_object( - shell_v2, - '_find_share_network', - mock.Mock(return_value=fake_share_network), - ) - command = 'share-network-subnet-delete {net_id} {subnet_id}'.format( - net_id=fake_share_network.id, - subnet_id='not-found-id', - ) - - self.assertRaises(exceptions.CommandError, self.run_command, command) - - @mock.patch.object(cliutils, 'print_dict', mock.Mock()) - def test_share_network_subnet_show(self): - fake_share_network = type( - 'FakeShareNetwork', (object,), {'id': '1234'} - ) - self.mock_object( - shell_v2, - '_find_share_network', - mock.Mock(return_value=fake_share_network), - ) - args = { - 'share_net_id': fake_share_network.id, - 'subnet_id': 'fake_subnet_id', - } - - self.run_command( - 'share-network-subnet-show {share_net_id} {subnet_id}'.format( - **args - ) - ) - - self.assert_called( - 'GET', - '/share-networks/{share_net_id}/subnets/{subnet_id}'.format( - **args - ), - ) - cliutils.print_dict.assert_called_once_with(mock.ANY) - - def test_share_network_subnet_show_invalid_share_network(self): - command = 'share-network-subnet-show {net_id} {subnet_id}'.format( - net_id='not-found-id', - subnet_id=1234, - ) - - self.assertRaises(exceptions.CommandError, self.run_command, command) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_share_server_list_select_column(self): - self.run_command('share-server-list --columns id,host,status') - self.assert_called('GET', '/share-servers') - cliutils.print_list.assert_called_once_with( - mock.ANY, fields=['Id', 'Host', 'Status'] - ) - - def test_create_share(self): - # Use only required fields - expected = self.create_share_body.copy() - expected['share']['share_type'] = 'test_type' - self.run_command("create nfs 1 --share-type test_type") - self.assert_called("POST", "/shares", body=expected) - - def test_create_public_share(self): - expected = self.create_share_body.copy() - expected['share']['is_public'] = True - expected['share']['share_type'] = 'test_type' - self.run_command("create --public nfs 1 --share-type test_type") - self.assert_called("POST", "/shares", body=expected) - - def test_create_with_share_network(self): - # Except required fields added share network - sn = "fake-share-network" - with mock.patch.object( - shell_v2, "_find_share_network", mock.Mock(return_value=sn) - ): - self.run_command( - f"create nfs 1 --share-type test_type --share-network {sn}" - ) - expected = self.create_share_body.copy() - expected['share']['share_network_id'] = sn - expected['share']['share_type'] = 'test_type' - self.assert_called("POST", "/shares", body=expected) - shell_v2._find_share_network.assert_called_once_with(mock.ANY, sn) - - def test_create_with_metadata(self): - # Except required fields added metadata - self.run_command( - "create nfs 1 --metadata key1=value1 key2=value2 " - "--share-type test_type" - ) - expected = self.create_share_body.copy() - expected['share']['metadata'] = {"key1": "value1", "key2": "value2"} - expected['share']['share_type'] = 'test_type' - self.assert_called("POST", "/shares", body=expected) - - def test_create_with_wait(self): - self.run_command("create nfs 1 --wait --share-type test_type") - expected = self.create_share_body.copy() - expected['share']['share_type'] = 'test_type' - self.assert_called_anytime( - "POST", "/shares", body=expected, clear_callstack=False - ) - self.assert_called("GET", "/shares/1234") - - def test_create_share_with_no_existing_share_type(self): - self.assertRaises( - exceptions.CommandError, self.run_command, "create nfs 1" - ) - - @ddt.data('None', 'NONE', 'none') - def test_create_share_with_the_name_none(self, name): - self.assertRaises( - exceptions.CommandError, - self.run_command, - f"create nfs 1 --name {name} --share-type test_type", - ) - - def test_allow_access_cert(self): - self.run_command("access-allow 1234 cert client.example.com") - - expected = { - "allow_access": { - "access_type": "cert", - "access_to": "client.example.com", - } - } - self.assert_called("POST", "/shares/1234/action", body=expected) - - def test_allow_access_cert_error_gt64(self): - common_name = 'x' * 65 - self.assertRaises( - exceptions.CommandError, - self.run_command, - (f"access-allow 1234 cert {common_name}"), - ) - - def test_allow_access_cert_error_zero(self): - cmd = mock.Mock() - cmd.split = mock.Mock( - side_effect=lambda: ['access-allow', '1234', 'cert', ''] - ) - - self.assertRaises(exceptions.CommandError, self.run_command, cmd) - - cmd.split.assert_called_once_with() - - def test_allow_access_cert_error_whitespace(self): - cmd = mock.Mock() - cmd.split = mock.Mock( - side_effect=lambda: ['access-allow', '1234', 'cert', ' '] - ) - - self.assertRaises(exceptions.CommandError, self.run_command, cmd) - - cmd.split.assert_called_once_with() - - def test_allow_access_with_access_level(self): - aliases = ['--access_level', '--access-level'] - expected = { - "allow_access": { - "access_type": "ip", - "access_to": "10.0.0.6", - "access_level": "ro", - } - } - - for alias in aliases: - for s in self.separators: - self.run_command( - "access-allow " + alias + s + "ro 1111 ip 10.0.0.6" - ) - self.assert_called( - "POST", "/shares/1111/action", body=expected - ) - - def test_allow_access_with_valid_access_levels(self): - expected = { - "allow_access": { - "access_type": "ip", - "access_to": "10.0.0.6", - } - } - - for level in ['rw', 'ro']: - expected["allow_access"]['access_level'] = level - self.run_command( - "access-allow --access-level " + level + " 1111 ip 10.0.0.6" - ) - self.assert_called("POST", "/shares/1111/action", body=expected) - - def test_allow_access_with_invalid_access_level(self): - self.assertRaises( - SystemExit, - self.run_command, - "access-allow --access-level fake 1111 ip 10.0.0.6", - ) - - def test_allow_access_with_metadata(self): - expected = { - "allow_access": { - "access_type": "ip", - "access_to": "10.0.0.6", - "metadata": {"key1": "v1", "key2": "v2"}, - } - } - - self.run_command( - "access-allow 2222 ip 10.0.0.6 --metadata key1=v1 key2=v2", - version="2.45", - ) - self.assert_called("POST", "/shares/2222/action", body=expected) - - def test_set_access_metadata(self): - expected = { - "metadata": { - "key1": "v1", - "key2": "v2", - } - } - self.run_command( - "access-metadata 9999 set key1=v1 key2=v2", version="2.45" - ) - self.assert_called( - "PUT", "/share-access-rules/9999/metadata", body=expected - ) - - def test_unset_access_metadata(self): - self.run_command("access-metadata 9999 unset key1", version="2.45") - self.assert_called("DELETE", "/share-access-rules/9999/metadata/key1") - - @ddt.data("1.0", "2.0", "2.44") - def test_allow_access_with_metadata_not_support_version(self, version): - self.assertRaises( - exceptions.CommandError, - self.run_command, - "access-allow 2222 ip 10.0.0.6 --metadata key1=v1", - version=version, - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - @ddt.data(*set(["2.44", "2.45", api_versions.MAX_VERSION])) - def test_access_list(self, version): - self.run_command("access-list 1111", version=version) - version = api_versions.APIVersion(version) - cliutils.print_list.assert_called_with( - mock.ANY, - [ - 'id', - 'access_type', - 'access_to', - 'access_level', - 'state', - 'access_key', - 'created_at', - 'updated_at', - ], - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - @ddt.data(*set(["2.44", "2.45", api_versions.MAX_VERSION])) - def test_access_list_select_column(self, version): - self.run_command( - "access-list 1111 --columns id,access_type", version=version - ) - cliutils.print_list.assert_called_with(mock.ANY, ['Id', 'Access_Type']) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_snapshot_access_list(self): - self.run_command("snapshot-access-list 1234") - - self.assert_called('GET', '/snapshots/1234/access-list') - cliutils.print_list.assert_called_with( - mock.ANY, ['id', 'access_type', 'access_to', 'state'] - ) - - @mock.patch.object(cliutils, 'print_dict', mock.Mock()) - def test_snapshot_access_allow(self): - self.run_command("snapshot-access-allow 1234 ip 1.1.1.1") - - self.assert_called('POST', '/snapshots/1234/action') - cliutils.print_dict.assert_called_with( - {'access_type': 'ip', 'access_to': '1.1.1.1'} - ) - - @ddt.data(*set(["2.45", api_versions.MAX_VERSION])) - def test_allow_access_wait(self, version): - fake_access_rule = {'id': 'fake_id'} - fake_access = mock.Mock() - fake_access._info = fake_access_rule - fake_share = mock.Mock() - fake_share.name = 'fake_share' - fake_share.allow = mock.Mock(return_value=fake_access_rule) - self.mock_object( - shell_v2, - '_wait_for_resource_status', - mock.Mock(return_value=fake_access), - ) - self.mock_object( - share_access_rules.ShareAccessRuleManager, - 'get', - mock.Mock(return_value=fake_access_rule), - ) - with mock.patch.object( - apiclient_utils, - 'find_resource', - mock.Mock(return_value=fake_share), - ): - is_default_in_api = api_versions.APIVersion( - version - ) >= api_versions.APIVersion('2.45') - if is_default_in_api: - self.run_command( - "access-allow fake_share ip 10.0.0.1 --wait", - version=version, - ) - shell_v2._wait_for_resource_status.assert_has_calls( - [ - mock.call( - self.shell.cs, - fake_access_rule, - resource_type='share_access_rule', - expected_status='active', - status_attr='state', - ) - ] - ) - - def test_snapshot_access_deny(self): - self.run_command("snapshot-access-deny 1234 fake_id") - - self.assert_called('POST', '/snapshots/1234/action') - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_snapshot_export_location_list(self): - self.run_command('snapshot-export-location-list 1234') - - self.assert_called('GET', '/snapshots/1234/export-locations') - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_snapshot_instance_export_location_list(self): - self.run_command('snapshot-instance-export-location-list 1234') - - self.assert_called('GET', '/snapshot-instances/1234/export-locations') - - @mock.patch.object(cliutils, 'print_dict', mock.Mock()) - def test_snapshot_instance_export_location_show(self): - self.run_command( - 'snapshot-instance-export-location-show 1234 fake_el_id' - ) - - self.assert_called( - 'GET', '/snapshot-instances/1234/export-locations/fake_el_id' - ) - cliutils.print_dict.assert_called_once_with( - {'path': '/fake_path', 'id': 'fake_id'} - ) - - @mock.patch.object(cliutils, 'print_dict', mock.Mock()) - def test_snapshot_export_location_show(self): - self.run_command('snapshot-export-location-show 1234 fake_el_id') - - self.assert_called( - 'GET', '/snapshots/1234/export-locations/fake_el_id' - ) - cliutils.print_dict.assert_called_once_with( - {'path': '/fake_path', 'id': 'fake_id'} - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_security_service_list(self): - self.run_command('security-service-list') - self.assert_called( - 'GET', - '/security-services', - ) - cliutils.print_list.assert_called_once_with( - mock.ANY, fields=['id', 'name', 'status', 'type'] - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_security_service_list_select_column(self): - self.run_command('security-service-list --columns name,type') - self.assert_called( - 'GET', - '/security-services', - ) - cliutils.print_list.assert_called_once_with( - mock.ANY, fields=['Name', 'Type'] - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - @mock.patch.object(shell_v2, '_find_share_network', mock.Mock()) - def test_security_service_list_filter_share_network(self): - class FakeShareNetwork: - id = 'fake-sn-id' - - sn = FakeShareNetwork() - shell_v2._find_share_network.return_value = sn - for command in ['--share-network', '--share_network']: - self.run_command(f'security-service-list {command} {sn.id}') - self.assert_called( - 'GET', - f'/security-services?share_network_id={sn.id}', - ) - shell_v2._find_share_network.assert_called_with(mock.ANY, sn.id) - cliutils.print_list.assert_called_with( - mock.ANY, fields=['id', 'name', 'status', 'type'] - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_security_service_list_detailed(self): - self.run_command('security-service-list --detailed') - self.assert_called( - 'GET', - '/security-services/detail', - ) - cliutils.print_list.assert_called_once_with( - mock.ANY, fields=['id', 'name', 'status', 'type', 'share_networks'] - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_security_service_list_all_tenants(self): - self.run_command('security-service-list --all-tenants') - self.assert_called( - 'GET', - '/security-services?all_tenants=1', - ) - cliutils.print_list.assert_called_once_with( - mock.ANY, fields=['id', 'name', 'status', 'type'] - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_security_service_list_all_filters(self): - filters = { - 'status': 'new', - 'name': 'fake-name', - 'type': 'ldap', - 'user': 'fake-user', - 'dns-ip': '1.1.1.1', - 'ou': 'fake-ou', - 'server': 'fake-server', - 'domain': 'fake-domain', - 'offset': 10, - 'limit': 20, - } - command_str = 'security-service-list' - for key, value in filters.items(): - command_str += f' --{key}={value}' - self.run_command(command_str) - self.assert_called( - 'GET', - '/security-services?dns_ip=1.1.1.1&domain=fake-domain&limit=20' - '&name=fake-name&offset=10&ou=fake-ou&server=fake-server' - '&status=new&type=ldap&user=fake-user', - ) - cliutils.print_list.assert_called_once_with( - mock.ANY, fields=['id', 'name', 'status', 'type'] - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_security_service_list_filter_by_dns_ip_alias(self): - self.run_command('security-service-list --dns_ip 1.1.1.1') - self.assert_called( - 'GET', - '/security-services?dns_ip=1.1.1.1', - ) - cliutils.print_list.assert_called_once_with( - mock.ANY, fields=['id', 'name', 'status', 'type'] - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_security_service_list_filter_by_ou_alias(self): - self.run_command('security-service-list --ou fake-ou') - self.assert_called( - 'GET', - '/security-services?ou=fake-ou', - ) - cliutils.print_list.assert_called_once_with( - mock.ANY, fields=['id', 'name', 'status', 'type'] - ) - - @ddt.data( - {'--name': 'fake_name'}, - {'--description': 'fake_description'}, - {'--dns-ip': 'fake_dns_ip'}, - {'--ou': 'fake_ou'}, - {'--domain': 'fake_domain'}, - {'--server': 'fake_server'}, - {'--user': 'fake_user'}, - {'--password': 'fake_password'}, - { - '--name': 'fake_name', - '--description': 'fake_description', - '--dns-ip': 'fake_dns_ip', - '--ou': 'fake_ou', - '--domain': 'fake_domain', - '--server': 'fake_server', - '--user': 'fake_user', - '--password': 'fake_password', - }, - {'--name': '""'}, - {'--description': '""'}, - {'--dns-ip': '""'}, - {'--ou': '""'}, - {'--domain': '""'}, - {'--server': '""'}, - {'--user': '""'}, - {'--password': '""'}, - { - '--name': '""', - '--description': '""', - '--dns-ip': '""', - '--ou': '""', - '--domain': '""', - '--server': '""', - '--user': '""', - '--password': '""', - }, - ) - def test_security_service_update(self, data): - cmd = 'security-service-update 1111' - expected = dict() - for k, v in data.items(): - cmd += ' ' + k + ' ' + v - expected[k[2:].replace('-', '_')] = v - expected = dict(security_service=expected) - - self.run_command(cmd) - - self.assert_called('PUT', '/security-services/1111', body=expected) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_pool_list(self): - self.run_command('pool-list') - self.assert_called( - 'GET', - '/scheduler-stats/pools?backend=.%2A&host=.%2A&pool=.%2A', - ) - cliutils.print_list.assert_called_with( - mock.ANY, fields=["Name", "Host", "Backend", "Pool"] - ) - - @mock.patch.object(cliutils, 'print_dict', mock.Mock()) - def test_quota_show(self): - self.run_command('quota-show --tenant 1234') - self.assert_called( - 'GET', - '/quota-sets/1234', - ) - cliutils.print_dict.assert_called_once_with(mock.ANY) - - @mock.patch.object(cliutils, 'print_dict', mock.Mock()) - def test_quota_show_with_detail(self): - self.run_command('quota-show --tenant 1234 --detail') - self.assert_called( - 'GET', - '/quota-sets/1234/detail', - ) - cliutils.print_dict.assert_called_once_with(mock.ANY) - - @mock.patch.object(cliutils, 'print_dict', mock.Mock()) - def test_quota_show_with_user_id(self): - self.run_command('quota-show --tenant 1234 --user 1111') - self.assert_called( - 'GET', - '/quota-sets/1234?user_id=1111', - ) - cliutils.print_dict.assert_called_once_with(mock.ANY) - - @ddt.data('1111', '0') - @mock.patch('manilaclient.common.cliutils.print_dict') - def test_quota_show_with_share_type(self, share_type_id, mock_print_dict): - self.run_command( - f'quota-show --tenant 1234 --share_type {share_type_id}' - ) - - self.assert_called( - 'GET', - f'/quota-sets/1234?share_type={share_type_id}', - ) - mock_print_dict.assert_called_once_with(mock.ANY) - - @ddt.data( - ('--shares 13', {'shares': 13}), - ('--gigabytes 14', {'gigabytes': 14}), - ('--snapshots 15', {'snapshots': 15}), - ('--snapshot-gigabytes 13', {'snapshot_gigabytes': 13}), - ('--share-networks 13', {'share_networks': 13}), - ('--share-groups 13', {'share_groups': 13}), - ('--share-groups 0', {'share_groups': 0}), - ('--share-group-snapshots 13', {'share_group_snapshots': 13}), - ('--share-group-snapshots 0', {'share_group_snapshots': 0}), - ('--share-replicas 15', {'share_replicas': 15}), - ('--replica_gigabytes 100', {'replica_gigabytes': 100}), - ('--per_share_gigabytes 101', {'per_share_gigabytes': 101}), - ) - @ddt.unpack - def test_quota_update(self, cmd, expected_body): - self.run_command(f'quota-update 1234 {cmd}') - - expected = {'quota_set': dict(expected_body, tenant_id='1234')} - self.assert_called('PUT', '/quota-sets/1234', body=expected) - - @ddt.data( - "quota-update 1234 --share-groups 13 --share-type foo", - "quota-update 1234 --share-group-snapshots 14 --share-type bar", - ( - "quota-update 1234 --share-groups 13 --share-type foo " - "--share-group-snapshots 14" - ), - "--os-share-api-version 2.39 quota-update 1234 --share-groups 13", - ( - "--os-share-api-version 2.39 quota-update 1234 " - "--share-group-snapshots 13" - ), - ( - "--os-share-api-version 2.38 quota-update 1234 --shares 5 " - "--share-type foo" - ), - ) - def test_quota_update_with_wrong_combinations(self, cmd): - self.assertRaises(exceptions.CommandError, self.run_command, cmd) - - @mock.patch.object(cliutils, 'print_dict', mock.Mock()) - def test_pool_list_with_detail(self): - self.run_command('pool-list --detail') - self.assert_called( - 'GET', - '/scheduler-stats/pools/detail?backend=.%2A&host=.%2A&pool=.%2A', - ) - cliutils.print_dict.assert_called_with( - {'name': 'host1@backend1#pool2', 'qos': False} - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_pool_list_select_column(self): - self.run_command('pool-list --columns name,host') - self.assert_called( - 'GET', - '/scheduler-stats/pools/detail?backend=.%2A&host=.%2A&pool=.%2A', - ) - cliutils.print_list.assert_called_with( - mock.ANY, fields=["Name", "Host"] - ) - - @ddt.data( - ( - {"key1": "value1", "key2": "value2"}, - {"key1": "value1", "key2": "value2"}, - ), - ( - { - "key1": {"key11": "value11", "key12": "value12"}, - "key2": {"key21": "value21"}, - }, - { - "key1": "key11 = value11\nkey12 = value12", - "key2": "key21 = value21", - }, - ), - ({}, {}), - ) - @ddt.unpack - @mock.patch.object(cliutils, 'print_dict', mock.Mock()) - def test_quota_set_pretty_show(self, value, expected): - fake_quota_set = fakes.FakeQuotaSet(value) - - shell_v2._quota_set_pretty_show(fake_quota_set) - cliutils.print_dict.assert_called_with(expected) - - @ddt.data( - '--share-type test_type', - '--share_type test_type', - '--share-type-id 0123456789', - '--share_type_id 0123456789', - ) - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_pool_list_with_filters(self, param): - cmd = ( - 'pool-list --host host1 --backend backend1 --pool pool1' - + ' ' - + param - ) - self.run_command(cmd) - self.assert_called( - 'GET', - '/scheduler-stats/pools?backend=backend1&host=host1&' - f'pool=pool1&share_type={param.split()[-1]}', - ) - cliutils.print_list.assert_called_with( - mock.ANY, fields=["Name", "Host", "Backend", "Pool"] - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_api_version(self): - self.run_command('api-version') - self.assert_called('GET', '') - cliutils.print_list.assert_called_with( - mock.ANY, - ['ID', 'Status', 'Version', 'Min_version'], - field_labels=['ID', 'Status', 'Version', 'Minimum Version'], - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_share_group_list(self): - self.run_command('share-group-list') - - self.assert_called('GET', '/share-groups/detail') - cliutils.print_list.assert_called_once_with( - mock.ANY, - fields=('ID', 'Name', 'Status', 'Description'), - sortby_index=None, - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_share_group_list_select_column(self): - self.run_command('share-group-list --columns id,name,description') - - self.assert_called('GET', '/share-groups/detail') - cliutils.print_list.assert_called_once_with( - mock.ANY, fields=['Id', 'Name', 'Description'], sortby_index=None - ) - - def test_share_group_list_filter_by_inexact_name(self): - for separator in self.separators: - self.run_command( - 'share-group-list --name~' + separator + 'fake_name' - ) - self.assert_called('GET', '/share-groups/detail?name~=fake_name') - - def test_share_group_list_filter_by_inexact_description(self): - for separator in self.separators: - self.run_command( - 'share-group-list --description~' - + separator - + 'fake_description' - ) - self.assert_called( - 'GET', '/share-groups/detail?description~=fake_description' - ) - - def test_share_group_list_filter_by_inexact_unicode_name(self): - for separator in self.separators: - self.run_command('share-group-list --name~' + separator + 'ффф') - self.assert_called( - 'GET', '/share-groups/detail?name~=%D1%84%D1%84%D1%84' - ) - - def test_share_group_list_filter_by_inexact_unicode_description(self): - for separator in self.separators: - self.run_command( - 'share-group-list --description~' + separator + 'ффф' - ) - self.assert_called( - 'GET', '/share-groups/detail?description~=%D1%84%D1%84%D1%84' - ) - - def test_share_group_show(self): - fake_manager = mock.Mock() - fake_share_group = share_groups.ShareGroup( - fake_manager, {'id': '1234'} - ) - self.mock_object( - shell_v2, - '_find_share_group', - mock.Mock(side_effect=[fake_share_group]), - ) - - self.run_command('share-group-show 1234') - - shell_v2._find_share_group.assert_has_calls( - [mock.call(self.shell.cs, "1234")] - ) - - def test_share_group_create_wait(self): - fake_manager = mock.Mock() - fake_share_type1 = share_types.ShareType( - fake_manager, {'name': '1234', 'uuid': '1234'} - ) - fake_share_type2 = share_types.ShareType( - fake_manager, {'name': '5678', 'uuid': '5678'} - ) - fake_share_group_type = share_group_types.ShareGroupType( - fake_manager, {'name': 'fake_sg', 'uuid': '2345'} - ) - fake_share_network = share_networks.ShareNetwork( - fake_manager, {'id': '3456', 'uuid': '3456'} - ) - fake_share_group = share_groups.ShareGroup( - fake_manager, {'id': 'fake-sg-id', 'name': 'fake_sg'} - ) - - self.mock_object( - shell_v2, - '_find_share_type', - mock.Mock(side_effect=[fake_share_type1, fake_share_type2]), - ) - self.mock_object( - shell_v2, - '_find_share_group_type', - mock.Mock(side_effect=[fake_share_group_type]), - ) - self.mock_object( - shell_v2, - '_find_share_network', - mock.Mock(side_effect=[fake_share_network]), - ) - self.mock_object( - shell_v2, - '_wait_for_resource_status', - mock.Mock(side_effect=[fake_share_group]), - ) - - self.run_command( - 'share-group-create --name fake_sg --description my_group ' - '--share-types 1234,5678 ' - '--share-group-type fake_sg ' - '--share-network 3456 ' - '--availability-zone fake_az --wait' - ) - - shell_v2._find_share_type.assert_has_calls( - [ - mock.call(self.shell.cs, '1234'), - mock.call(self.shell.cs, '5678'), - ] - ) - - shell_v2._find_share_group_type.assert_has_calls( - [mock.call(self.shell.cs, 'fake_sg')] - ) - - shell_v2._find_share_network.assert_has_calls( - [mock.call(self.shell.cs, '3456')] - ) - - expected = { - 'share_group': { - 'name': 'fake_sg', - 'description': 'my_group', - 'availability_zone': 'fake_az', - 'share_group_type_id': '2345', - 'share_network_id': '3456', - 'share_types': ['1234', '5678'], - }, - } - self.assert_called('POST', '/share-groups', body=expected) - - shell_v2._wait_for_resource_status.assert_has_calls( - [ - mock.call( - self.shell.cs, - fake_share_group, - resource_type='share_group', - expected_status='available', - ) - ] - ) - - @ddt.data( - '--name fake_name --availability-zone fake_az', - '--description my_fake_description --name fake_name', - '--availability-zone fake_az', - ) - def test_share_group_create_no_share_types(self, data): - cmd = 'share-group-create' + ' ' + data - - self.run_command(cmd) - - self.assert_called('POST', '/share-groups') - - def test_share_group_create_invalid_args(self): - fake_share_type_1 = type('FakeShareType1', (object,), {'id': '1234'}) - fake_share_type_2 = type('FakeShareType2', (object,), {'id': '5678'}) - self.mock_object( - shell_v2, - '_find_share_type', - mock.Mock(side_effect=[fake_share_type_1, fake_share_type_2]), - ) - fake_share_group_type = type( - 'FakeShareGroupType', (object,), {'id': '2345'} - ) - self.mock_object( - shell_v2, - '_find_share_group_type', - mock.Mock(return_value=fake_share_group_type), - ) - fake_share_group_snapshot = type( - 'FakeShareGroupSnapshot', (object,), {'id': '3456'} - ) - self.mock_object( - shell_v2, - '_find_share_group_snapshot', - mock.Mock(return_value=fake_share_group_snapshot), - ) - - self.assertRaises( - ValueError, - self.run_command, - 'share-group-create --name fake_sg ' - '--description my_group --share-types 1234,5678 ' - '--share-group-type fake_sg_type ' - '--source-share-group-snapshot fake_share_group_snapshot ' - '--availability-zone fake_az', - ) - - @ddt.data( - ('--name new-name', {'name': 'new-name'}), - ('--description new-description', {'description': 'new-description'}), - ( - '--name new-name --description new-description', - {'name': 'new-name', 'description': 'new-description'}, - ), - ) - @ddt.unpack - def test_share_group_update(self, cmd, expected_body): - fake_manager = mock.Mock() - fake_share_group = share_groups.ShareGroup( - fake_manager, {'uuid': '1234', 'id': '1234'} - ) - self.mock_object( - shell_v2, - '_find_share_group', - mock.Mock(side_effect=[fake_share_group]), - ) - - self.run_command(f'share-group-update 1234 {cmd}') - - shell_v2._find_share_group.assert_has_calls( - [mock.call(self.shell.cs, '1234')] - ) - expected = {'share_group': expected_body} - self.assert_called('PUT', '/share-groups/1234', body=expected) - - def test_try_update_share_group_without_data(self): - self.assertRaises( - exceptions.CommandError, - self.run_command, - 'share-group-update 1234', - ) - - @ddt.data(('share_group_xyz',), ('share_group_abc', 'share_group_xyz')) - def test_share_group_delete_wait(self, share_group_to_delete): - fake_manager = mock.Mock() - fake_share_group = [ - share_groups.ShareGroup(fake_manager, {'id': share_group}) - for share_group in share_group_to_delete - ] - share_group_not_found_error = ( - "Delete for share group %s " - "failed: No group with a " - "name or ID of '%s' exists." - ) - share_group_are_not_found_errors = [ - exceptions.CommandError( - share_group_not_found_error % (share_group, share_group) - ) - for share_group in share_group_to_delete - ] - self.mock_object( - shell_v2, - '_find_share_group', - mock.Mock( - side_effect=( - fake_share_group + share_group_are_not_found_errors - ) - ), - ) - self.mock_object(shell_v2, '_wait_for_resource_status', mock.Mock()) - self.run_command( - 'share-group-delete {} --wait'.format( - ' '.join(share_group_to_delete) - ) - ) - shell_v2._find_share_group.assert_has_calls( - [ - mock.call(self.shell.cs, share_group) - for share_group in share_group_to_delete - ] - ) - fake_manager.delete.assert_has_calls( - [ - mock.call(share_group, force=False) - for share_group in fake_share_group - ] - ) - shell_v2._wait_for_resource_status.assert_has_calls( - [ - mock.call( - self.shell.cs, - share_group, - resource_type='share_group', - expected_status='deleted', - ) - for share_group in fake_share_group - ] - ) - - def test_share_group_delete_force(self): - fake_manager = mock.Mock() - fake_share_group = share_groups.ShareGroup( - fake_manager, {'id': 'fake-group'} - ) - self.mock_object( - shell_v2, - '_find_share_group', - mock.Mock(side_effect=[fake_share_group]), - ) - self.run_command('share-group-delete --force fake-group') - shell_v2._find_share_group.assert_has_calls( - [mock.call(self.shell.cs, "fake-group")] - ) - fake_manager.delete.assert_has_calls( - [mock.call(fake_share_group, force=True)] - ) - self.assertEqual(1, fake_manager.delete.call_count) - - @mock.patch.object(shell_v2, '_find_share_group', mock.Mock()) - def test_share_group_delete_all_fail(self): - shell_v2._find_share_group.side_effect = Exception - - self.assertRaises( - exceptions.CommandError, - self.run_command, - 'share-group-delete fake-group', - ) - - @mock.patch.object(shell_v2, '_find_share_group', mock.Mock()) - def test_share_group_reset_state_with_flag(self): - fake_group = type('FakeShareGroup', (object,), {'id': '1234'}) - shell_v2._find_share_group.return_value = fake_group - - self.run_command('share-group-reset-state --state error 1234') - - self.assert_called( - 'POST', - '/share-groups/1234/action', - {'reset_status': {'status': 'error'}}, - ) - - @ddt.data( - 'fake-sg-id', - '--name fake_name fake-sg-id', - '--description my_fake_description --name fake_name fake-sg-id', - ) - @mock.patch.object(shell_v2, '_find_share_group', mock.Mock()) - @mock.patch.object(shell_v2, '_wait_for_resource_status', mock.Mock()) - def test_share_group_snapshot_create(self, data): - fake_sg = type('FakeShareGroup', (object,), {'id': '1234'}) - shell_v2._find_share_group.return_value = fake_sg - - self.run_command('share-group-snapshot-create ' + data) - - shell_v2._find_share_group.assert_called_with(mock.ANY, 'fake-sg-id') - self.assert_called('POST', '/share-group-snapshots') - self.assertEqual(0, shell_v2._wait_for_resource_status.call_count) - - @mock.patch.object(shell_v2, '_find_share_group', mock.Mock()) - @mock.patch.object(shell_v2, '_wait_for_resource_status', mock.Mock()) - def test_share_group_snapshot_create_with_wait(self): - fake_sg = type('FakeShareGroup', (object,), {'id': '1234'}) - shell_v2._find_share_group.return_value = fake_sg - self.run_command('share-group-snapshot-create fake-sg-id --wait') - - shell_v2._find_share_group.assert_called_with(mock.ANY, 'fake-sg-id') - self.assert_called('POST', '/share-group-snapshots') - # _wait_for_resource_status should be triggered once - shell_v2._wait_for_resource_status.assert_called_once_with( - self.shell.cs, - mock.ANY, - resource_type='share_group_snapshot', - expected_status='available', - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_share_group_snapshot_list(self): - self.run_command('share-group-snapshot-list') - - self.assert_called('GET', '/share-group-snapshots/detail') - cliutils.print_list.assert_called_once_with( - mock.ANY, - fields=('id', 'name', 'status', 'description'), - sortby_index=None, - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_share_group_snapshot_list_select_column(self): - self.run_command('share-group-snapshot-list --columns id,name') - - self.assert_called('GET', '/share-group-snapshots/detail') - cliutils.print_list.assert_called_once_with( - mock.ANY, fields=['Id', 'Name'], sortby_index=None - ) - - def test_share_group_snapshot_list_all_tenants_only_key(self): - self.run_command('share-group-snapshot-list --all-tenants') - - self.assert_called( - 'GET', '/share-group-snapshots/detail?all_tenants=1' - ) - - def test_share_group_snapshot_list_all_tenants_key_and_value_1(self): - for separator in self.separators: - self.run_command( - 'share-group-snapshot-list --all-tenants' + separator + '1' - ) - - self.assert_called( - 'GET', '/share-group-snapshots/detail?all_tenants=1' - ) - - def test_share_group_snapshot_list_with_filters(self): - self.run_command('share-group-snapshot-list --limit 10 --offset 0') - - self.assert_called( - 'GET', '/share-group-snapshots/detail?limit=10&offset=0' - ) - - def test_share_group_snapshot_show(self): - self.run_command('share-group-snapshot-show 1234') - - self.assert_called('GET', '/share-group-snapshots/1234') - - def test_share_group_snapshot_list_members(self): - self.run_command('share-group-snapshot-list-members 1234') - - self.assert_called('GET', '/share-group-snapshots/1234') - - def test_share_group_snapshot_list_members_select_column(self): - self.mock_object(cliutils, 'print_list') - - self.run_command( - 'share-group-snapshot-list-members 1234 --columns id,size' - ) - - self.assert_called('GET', '/share-group-snapshots/1234') - cliutils.print_list.assert_called_once_with( - mock.ANY, fields=['Id', 'Size'] - ) - - @mock.patch.object(shell_v2, '_find_share_group_snapshot', mock.Mock()) - def test_share_group_snapshot_reset_state(self): - fake_sg_snapshot = type( - 'FakeShareGroupSnapshot', (object,), {'id': '1234'} - ) - shell_v2._find_share_group_snapshot.return_value = fake_sg_snapshot - - self.run_command('share-group-snapshot-reset-state 1234') - - self.assert_called( - 'POST', - '/share-group-snapshots/1234/action', - {'reset_status': {'status': 'available'}}, - ) - - @mock.patch.object(shell_v2, '_find_share_group_snapshot', mock.Mock()) - def test_share_group_snapshot_reset_state_with_flag(self): - fake_sg_snapshot = type('FakeSGSnapshot', (object,), {'id': '1234'}) - shell_v2._find_share_group_snapshot.return_value = fake_sg_snapshot - - self.run_command( - 'share-group-snapshot-reset-state --state creating 1234' - ) - - self.assert_called( - 'POST', - '/share-group-snapshots/1234/action', - {'reset_status': {'status': 'creating'}}, - ) - - @ddt.data( - ('--name new-name', {'name': 'new-name'}), - ('--description new-description', {'description': 'new-description'}), - ( - '--name new-name --description new-description', - {'name': 'new-name', 'description': 'new-description'}, - ), - ) - @ddt.unpack - def test_share_group_snapshot_update(self, cmd, expected_body): - self.run_command(f'share-group-snapshot-update 1234 {cmd}') - - expected = {'share_group_snapshot': expected_body} - self.assert_called('PUT', '/share-group-snapshots/1234', body=expected) - - def test_try_update_share_group_snapshot_without_data(self): - self.assertRaises( - exceptions.CommandError, - self.run_command, - 'share-group-snapshot-update 1234', - ) - - @mock.patch.object(shell_v2, '_find_share_group_snapshot', mock.Mock()) - @mock.patch.object(shell_v2, '_wait_for_resource_status', mock.Mock()) - def test_share_group_snapshot_delete(self): - fake_sg_snapshot = type('FakeSGSnapshot', (object,), {'id': '1234'}) - shell_v2._find_share_group_snapshot.return_value = fake_sg_snapshot - - self.run_command('share-group-snapshot-delete fake-group-snapshot') - - self.assert_called('DELETE', '/share-group-snapshots/1234') - self.assertEqual(0, shell_v2._wait_for_resource_status.call_count) - - @mock.patch.object(shell_v2, '_find_share_group_snapshot', mock.Mock()) - @mock.patch.object(shell_v2, '_wait_for_resource_status', mock.Mock()) - def test_share_group_snapshot_delete_with_wait(self): - fake_sg_snapshot = type('FakeSGSnapshot', (object,), {'id': '1234'}) - shell_v2._find_share_group_snapshot.return_value = fake_sg_snapshot - - self.run_command( - 'share-group-snapshot-delete fake-group-snapshot --wait' - ) - - self.assert_called('DELETE', '/share-group-snapshots/1234') - # _wait_for_resource_status should be triggered once - shell_v2._wait_for_resource_status.assert_called_once_with( - self.shell.cs, - mock.ANY, - resource_type='share_group_snapshot', - expected_status='deleted', - ) - - @mock.patch.object(shell_v2, '_find_share_group_snapshot', mock.Mock()) - def test_share_group_snapshot_delete_force(self): - fake_sg_snapshot = type('FakeSGSnapshot', (object,), {'id': '1234'}) - shell_v2._find_share_group_snapshot.return_value = fake_sg_snapshot - - self.run_command( - 'share-group-snapshot-delete --force fake-sg-snapshot' - ) - - self.assert_called( - 'POST', - '/share-group-snapshots/1234/action', - {'force_delete': None}, - ) - - def test_share_group_snapshot_delete_all_fail(self): - self.mock_object( - shell_v2, - '_find_share_group_snapshot', - mock.Mock(side_effect=Exception), - ) - - self.assertRaises( - exceptions.CommandError, - self.run_command, - 'share-group-snapshot-delete fake-sg-snapshot', - ) - - @ddt.data( - *itertools.product( - ( - '--columns id,is_default', - '--columns id,name', - '--columns is_default', - '', - ), - {'2.45', '2.46', api_versions.MAX_VERSION}, - ) - ) - @ddt.unpack - def test_share_group_type_list(self, command_args, version): - self.mock_object(shell_v2, '_print_share_group_type_list') - command = 'share-group-type-list ' + command_args - columns_requested = command_args.split('--columns ')[-1] or None - is_default_in_api = api_versions.APIVersion( - version - ) >= api_versions.APIVersion('2.46') - - self.run_command(command, version=version) - - if not is_default_in_api and ( - not columns_requested or 'is_default' in columns_requested - ): - self.assert_called('GET', '/share-group-types/default') - self.assert_called_anytime('GET', '/share-group-types') - else: - self.assert_called('GET', '/share-group-types') - - shell_v2._print_share_group_type_list.assert_called_once_with( - mock.ANY, - default_share_group_type=mock.ANY, - columns=columns_requested, - ) - - def test_share_group_type_list_select_column(self): - self.mock_object(shell_v2, '_print_share_group_type_list') - - self.run_command('share-group-type-list --columns id,name') - - self.assert_called('GET', '/share-group-types') - shell_v2._print_share_group_type_list.assert_called_once_with( - mock.ANY, default_share_group_type=mock.ANY, columns='id,name' - ) - - def test_share_group_type_list_all(self): - self.run_command('share-group-type-list --all') - - self.assert_called_anytime('GET', '/share-group-types?is_public=all') - - @ddt.data(('', mock.ANY), (' --columns id,name', 'id,name')) - @ddt.unpack - def test_share_group_specs_list(self, args_cmd, expected_columns): - self.mock_object(shell_v2, '_print_type_and_extra_specs_list') - - self.run_command('share-group-type-specs-list') - - self.assert_called('GET', '/share-group-types?is_public=all') - shell_v2._print_type_and_extra_specs_list.assert_called_once_with( - mock.ANY, columns=mock.ANY - ) - - @ddt.data(True, False) - def test_share_group_type_create_with_access_and_group_specs(self, public): - fake_share_type_1 = type('FakeShareType', (object,), {'id': '1234'}) - fake_share_type_2 = type('FakeShareType', (object,), {'id': '5678'}) - self.mock_object( - shell_v2, - '_find_share_type', - mock.Mock(side_effect=[fake_share_type_1, fake_share_type_2]), - ) - expected = { - 'share_group_type': { - 'name': 'test-group-type-1', - 'share_types': ['1234', '5678'], - 'group_specs': {'spec1': 'value1'}, - 'is_public': public, - } - } - - self.run_command( - 'share-group-type-create test-group-type-1 ' - f'type1,type2 --is-public {str(public)} --group-specs ' - 'spec1=value1' - ) - - self.assert_called_anytime('POST', '/share-group-types', body=expected) - - def test_share_group_type_delete(self): - fake_share_group_type = type( - 'FakeShareGroupType', (object,), {'id': '1234'} - ) - self.mock_object( - shell_v2, - '_find_share_group_type', - mock.Mock(return_value=fake_share_group_type), - ) - - self.run_command('share-group-type-delete test-group-type-1') - - self.assert_called('DELETE', '/share-group-types/1234') - - def test_share_group_type_key_set(self): - fake_share_group_type = type( - 'FakeShareGroupType', - (object,), - { - 'id': '1234', - 'is_public': False, - 'set_keys': mock.Mock(), - 'unset_keys': mock.Mock(), - }, - ) - self.mock_object( - shell_v2, - '_find_share_group_type', - mock.Mock(return_value=fake_share_group_type), - ) - - self.run_command('share-group-type-key fake_sg_type set key1=value1') - - fake_share_group_type.set_keys.assert_called_with({'key1': 'value1'}) - - def test_share_group_type_key_unset(self): - fake_share_group_type = type( - 'FakeShareGroupType', - (object,), - { - 'id': '1234', - 'is_public': False, - 'set_keys': mock.Mock(), - 'unset_keys': mock.Mock(), - }, - ) - self.mock_object( - shell_v2, - '_find_share_group_type', - mock.Mock(return_value=fake_share_group_type), - ) - - self.run_command('share-group-type-key fake_group_type unset key1') - - fake_share_group_type.unset_keys.assert_called_with(['key1']) - - def test_share_group_type_access_list(self): - fake_share_group_type = type( - 'FakeShareGroupType', (object,), {'id': '1234', 'is_public': False} - ) - self.mock_object( - shell_v2, - '_find_share_group_type', - mock.Mock(return_value=fake_share_group_type), - ) - - self.run_command('share-group-type-access-list 1234') - - self.assert_called('GET', '/share-group-types/1234/access') - - def test_share_group_type_access_list_public(self): - fake_share_group_type = type( - 'FakeShareGroupType', (object,), {'id': '1234', 'is_public': True} - ) - self.mock_object( - shell_v2, - '_find_share_group_type', - mock.Mock(return_value=fake_share_group_type), - ) - - self.assertRaises( - exceptions.CommandError, - self.run_command, - 'share-group-type-access-list 1234', - ) - - def test_share_group_type_access_add_project(self): - fake_share_group_type = type( - 'FakeShareGroupType', (object,), {'id': '1234', 'is_public': False} - ) - self.mock_object( - shell_v2, - '_find_share_group_type', - mock.Mock(return_value=fake_share_group_type), - ) - expected = {'addProjectAccess': {'project': '101'}} - - self.run_command('share-group-type-access-add 1234 101') - - self.assert_called( - 'POST', '/share-group-types/1234/action', body=expected - ) - - def test_share_group_type_access_remove_project(self): - fake_share_group_type = type( - 'FakeShareGroupType', (object,), {'id': '1234', 'is_public': False} - ) - self.mock_object( - shell_v2, - '_find_share_group_type', - mock.Mock(return_value=fake_share_group_type), - ) - expected = {'removeProjectAccess': {'project': '101'}} - - self.run_command('share-group-type-access-remove 1234 101') - - self.assert_called( - 'POST', '/share-group-types/1234/action', body=expected - ) - - @ddt.data( - {'--shares': 5}, - {'--snapshots': 5}, - {'--gigabytes': 5}, - {'--snapshot-gigabytes': 5}, - {'--snapshot_gigabytes': 5}, - {'--share-networks': 5}, - {'--share_networks': 5}, - { - '--shares': 5, - '--snapshots': 5, - '--gigabytes': 5, - '--snapshot-gigabytes': 5, - '--share-networks': 5, - }, - { - '--shares': 5, - '--snapshots': 5, - '--gigabytes': 5, - '--snapshot-gigabytes': 5, - '--share-networks': 5, - '--share-groups': 5, - '--share-group-snapshots': 5, - }, - ) - def test_quota_class_update(self, data): - cmd = 'quota-class-update test' - expected = dict() - for k, v in data.items(): - cmd += f' {k} {v}' - expected[k[2:].replace('-', '_')] = v - expected['class_name'] = 'test' - expected = dict(quota_class_set=expected) - - self.run_command(cmd) - self.assert_called('PUT', '/quota-class-sets/test', body=expected) - - @ddt.data(True, False) - @mock.patch.object(shell_v2, '_find_share_replica', mock.Mock()) - @mock.patch.object(shell_v2, '_wait_for_resource_status', mock.Mock()) - def test_share_replica_delete_force(self, force): - fake_replica = type('FakeShareReplica', (object,), {'id': '1234'}) - shell_v2._find_share_replica.return_value = fake_replica - - force = '--force' if force else '' - self.run_command('share-replica-delete fake-replica ' + force) - - if force: - self.assert_called( - 'POST', - '/share-replicas/1234/action', - body={'force_delete': None}, - ) - else: - self.assert_called('DELETE', '/share-replicas/1234') - self.assertEqual(0, shell_v2._wait_for_resource_status.call_count) - - @mock.patch.object(shell_v2, '_find_share_replica', mock.Mock()) - @mock.patch.object(shell_v2, '_wait_for_resource_status', mock.Mock()) - def test_share_replica_delete_with_wait(self): - fake_replica = type('FakeShareReplica', (object,), {'id': '1234'}) - shell_v2._find_share_replica.return_value = fake_replica - - self.run_command('share-replica-delete fake-replica --wait') - - self.assert_called('DELETE', '/share-replicas/1234') - - # _wait_for_resource_status should be triggered once - shell_v2._wait_for_resource_status.assert_called_once_with( - self.shell.cs, - mock.ANY, - resource_type='share_replica', - expected_status='deleted', - ) - - @ddt.data([1, 0], [1, 1], [2, 0], [2, 1], [2, 2]) - @ddt.unpack - @mock.patch.object(shell_v2, '_find_share_replica', mock.Mock()) - def test_share_replica_delete_errors(self, replica_count, replica_errors): - class StubbedReplicaFindError(Exception): - """Error in find share replica stub""" - - pass - - class StubbedFindWithErrors: - def __init__(self, existing_replicas): - self.existing_replicas = existing_replicas - - def __call__(self, cs, replica): - if replica not in self.existing_replicas: - raise StubbedReplicaFindError - return type('FakeShareReplica', (object,), {'id': replica}) - - all_replicas = [] - existing_replicas = [] - for counter in range(replica_count): - replica = f'fake-replica-{counter}' - if counter >= replica_errors: - existing_replicas.append(replica) - all_replicas.append(replica) - - shell_v2._find_share_replica.side_effect = StubbedFindWithErrors( - existing_replicas - ) - cmd = 'share-replica-delete {}'.format(' '.join(all_replicas)) - - if replica_count == replica_errors: - self.assertRaises(exceptions.CommandError, self.run_command, cmd) - else: - self.run_command(cmd) - for replica in existing_replicas: - self.assert_called_anytime( - 'DELETE', - '/share-replicas/' + replica, - clear_callstack=False, - ) - - def test_share_replica_list_all(self): - self.run_command('share-replica-list') - - self.assert_called('GET', '/share-replicas/detail') - - @mock.patch.object(shell_v2, '_find_share', mock.Mock()) - def test_share_replica_list_for_share(self): - fshare = type('FakeShare', (object,), {'id': 'fake-share-id'}) - shell_v2._find_share.return_value = fshare - cmd = 'share-replica-list --share-id %s' - self.run_command(cmd % fshare.id) - - self.assert_called( - 'GET', '/share-replicas/detail?share_id=fake-share-id' - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_share_replica_list_select_column(self): - self.run_command('share-replica-list --columns id,status') - - self.assert_called('GET', '/share-replicas/detail') - - cliutils.print_list.assert_called_once_with(mock.ANY, ['Id', 'Status']) - - @ddt.data( - 'fake-share-id --az fake-az', - 'fake-share-id --availability-zone fake-az', - ) - @mock.patch.object(shell_v2, '_find_share', mock.Mock()) - @mock.patch.object(shell_v2, '_wait_for_resource_status', mock.Mock()) - def test_share_replica_create(self, data): - fshare = type('FakeShare', (object,), {'id': 'fake-share-id'}) - shell_v2._find_share.return_value = fshare - - cmd = 'share-replica-create' + ' ' + data - - self.run_command(cmd) - - shell_v2._find_share.assert_called_with(mock.ANY, fshare.id) - self.assert_called('POST', '/share-replicas') - self.assertEqual(0, shell_v2._wait_for_resource_status.call_count) - - @mock.patch.object(shell_v2, '_find_share', mock.Mock()) - @mock.patch.object(shell_v2, '_wait_for_resource_status', mock.Mock()) - def test_share_replica_create_with_wait(self): - fshare = type('FakeShare', (object,), {'id': 'fake-share-id'}) - shell_v2._find_share.return_value = fshare - - cmd = ( - 'share-replica-create fake-share-id ' - '--availability-zone fake-az --wait' - ) - - self.run_command(cmd) - - shell_v2._find_share.assert_called_with(mock.ANY, fshare.id) - self.assert_called('POST', '/share-replicas') - # _wait_for_resource_status should be triggered once - shell_v2._wait_for_resource_status.assert_called_once_with( - self.shell.cs, - mock.ANY, - resource_type='share_replica', - expected_status='available', - ) - - def test_share_replica_show(self): - self.run_command('share-replica-show 5678') - - self.assert_called_anytime('GET', '/share-replicas/5678') - - @mock.patch.object(shell_v2, '_find_share_replica', mock.Mock()) - @mock.patch.object(shell_v2, '_wait_for_resource_status', mock.Mock()) - def test_share_replica_promote_quiesce_wait_time(self): - fake_replica = type('FakeShareReplica', (object,), {'id': '1234'}) - shell_v2._find_share_replica.return_value = fake_replica - cmd = ( - 'share-replica-promote ' - + fake_replica.id - + ' --quiesce-wait-time 5' - ) - self.run_command(cmd) - self.assert_called( - 'POST', - '/share-replicas/1234/action', - body={'promote': {'quiesce_wait_time': '5'}}, - ) - self.assertEqual(0, shell_v2._wait_for_resource_status.call_count) - - @mock.patch.object(shell_v2, '_find_share_replica', mock.Mock()) - @mock.patch.object(shell_v2, '_wait_for_resource_status', mock.Mock()) - def test_share_replica_promote_with_wait_(self): - fake_replica = type('FakeShareReplica', (object,), {'id': '1234'}) - shell_v2._find_share_replica.return_value = fake_replica - cmd = 'share-replica-promote ' + fake_replica.id + ' --wait' - self.run_command(cmd) - self.assert_called('POST', '/share-replicas/1234/action') - # _wait_for_resource_status should be triggered once - shell_v2._wait_for_resource_status.assert_called_once_with( - self.shell.cs, - mock.ANY, - resource_type='share_replica', - expected_status='active', - status_attr='replica_state', - ) - - @ddt.data('promote', 'resync') - @mock.patch.object(shell_v2, '_find_share_replica', mock.Mock()) - def test_share_replica_actions(self, action): - fake_replica = type('FakeShareReplica', (object,), {'id': '1234'}) - shell_v2._find_share_replica.return_value = fake_replica - cmd = 'share-replica-' + action + ' ' + fake_replica.id - - self.run_command(cmd) - - self.assert_called( - 'POST', - '/share-replicas/1234/action', - body={action.replace('-', '_'): None}, - ) - - @mock.patch.object(shell_v2, '_find_share_replica', mock.Mock()) - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - @ddt.data(None, "replica_state,path") - def test_share_replica_export_location_list(self, columns): - fake_replica = type('FakeShareReplica', (object,), {'id': '1234'}) - shell_v2._find_share_replica.return_value = fake_replica - cmd = 'share-replica-export-location-list ' + fake_replica.id - if columns is not None: - cmd = cmd + f' --columns={columns}' - expected_columns = list( - map(lambda x: x.strip().title(), columns.split(",")) - ) - else: - expected_columns = [ - 'ID', - 'Availability Zone', - 'Replica State', - 'Preferred', - 'Path', - ] - - self.run_command(cmd) - - self.assert_called('GET', '/share-replicas/1234/export-locations') - cliutils.print_list.assert_called_with(mock.ANY, expected_columns) - - @mock.patch.object(shell_v2, '_find_share_replica', mock.Mock()) - def test_share_replica_export_location_show(self): - fake_replica = type('FakeShareReplica', (object,), {'id': '1234'}) - shell_v2._find_share_replica.return_value = fake_replica - self.run_command( - 'share-replica-export-location-show 1234 fake-el-uuid' - ) - self.assert_called( - 'GET', '/share-replicas/1234/export-locations/fake-el-uuid' - ) - - @ddt.data('reset-state', 'reset-replica-state') - @mock.patch.object(shell_v2, '_find_share_replica', mock.Mock()) - def test_share_replica_reset_state_cmds(self, action): - if action == 'reset-state': - attr = 'status' - action_name = 'reset_status' - else: - attr = 'replica_state' - action_name = action.replace('-', '_') - fake_replica = type('FakeShareReplica', (object,), {'id': '1234'}) - shell_v2._find_share_replica.return_value = fake_replica - cmd = 'share-replica-%(action)s %(resource)s --state %(state)s' - - self.run_command( - cmd % {'action': action, 'resource': 1234, 'state': 'xyzzyspoon!'} - ) - - self.assert_called( - 'POST', - '/share-replicas/1234/action', - body={action_name: {attr: 'xyzzyspoon!'}}, - ) - - def test_snapshot_instance_list_all(self): - self.run_command('snapshot-instance-list') - self.assert_called('GET', '/snapshot-instances') - - def test_snapshot_instance_list_all_detail(self): - self.run_command('snapshot-instance-list --detail True') - self.assert_called('GET', '/snapshot-instances/detail') - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_snapshot_instance_list_select_column(self): - self.run_command('snapshot-instance-list --columns id,status') - self.assert_called('GET', '/snapshot-instances') - cliutils.print_list.assert_called_once_with(mock.ANY, ['Id', 'Status']) - - @mock.patch.object(shell_v2, '_find_share_snapshot', mock.Mock()) - def test_snapshot_instance_list_for_snapshot(self): - fsnapshot = type('FakeSnapshot', (object,), {'id': 'fake-snapshot-id'}) - shell_v2._find_share_snapshot.return_value = fsnapshot - cmd = 'snapshot-instance-list --snapshot %s' - self.run_command(cmd % fsnapshot.id) - - self.assert_called( - 'GET', '/snapshot-instances?snapshot_id=fake-snapshot-id' - ) - - def test_snapshot_instance_show(self): - self.run_command('snapshot-instance-show 1234') - self.assert_called_anytime( - 'GET', '/snapshot-instances/1234', clear_callstack=False - ) - self.assert_called_anytime( - 'GET', '/snapshot-instances/1234/export-locations' - ) - - def test_snapshot_instance_reset_state(self): - self.run_command('snapshot-instance-reset-state 1234') - expected = {'reset_status': {'status': 'available'}} - self.assert_called( - 'POST', '/snapshot-instances/1234/action', body=expected - ) - - def test_migration_start(self): - command = ( - "migration-start --force-host-assisted-migration True " - "--new-share-network 1111 --new-share-type 1 1234 " - "host@backend#pool --writable False --nondisruptive True " - "--preserve-metadata False --preserve-snapshots True" - ) - self.run_command(command) - expected = { - 'migration_start': { - 'host': 'host@backend#pool', - 'force_host_assisted_migration': 'True', - 'preserve_metadata': 'False', - 'writable': 'False', - 'nondisruptive': 'True', - 'preserve_snapshots': 'True', - 'new_share_network_id': 1111, - 'new_share_type_id': 1, - } - } - self.assert_called('POST', '/shares/1234/action', body=expected) - - @ddt.data( - 'migration-complete', 'migration-get-progress', 'migration-cancel' - ) - def test_migration_others(self, method): - command = ' '.join((method, '1234')) - self.run_command(command) - expected = {method.replace('-', '_'): None} - self.assert_called('POST', '/shares/1234/action', body=expected) - - @ddt.data('migration_error', 'migration_success', None) - def test_reset_task_state(self, param): - command = ' '.join(('reset-task-state --state', str(param), '1234')) - self.run_command(command) - expected = {'reset_task_state': {'task_state': param}} - self.assert_called('POST', '/shares/1234/action', body=expected) - - @ddt.data( - ('fake_security_service1',), - ('fake_security_service1', 'fake_security_service2'), - ) - def test_security_service_delete(self, ss_ids): - fake_security_services = [ - security_services.SecurityService('fake', {'id': ss_id}, True) - for ss_id in ss_ids - ] - self.mock_object( - shell_v2, - '_find_security_service', - mock.Mock(side_effect=fake_security_services), - ) - - self.run_command('security-service-delete {}'.format(' '.join(ss_ids))) - - shell_v2._find_security_service.assert_has_calls( - [mock.call(self.shell.cs, ss_id) for ss_id in ss_ids] - ) - for ss in fake_security_services: - self.assert_called_anytime( - 'DELETE', - f'/security-services/{ss.id}', - clear_callstack=False, - ) - - @ddt.data( - ('fake_share_network1',), - ('fake_share_network1', 'fake_share_network1'), - ) - def test_share_network_delete(self, sn_ids): - fake_share_networks = [ - share_networks.ShareNetwork('fake', {'id': sn_id}, True) - for sn_id in sn_ids - ] - self.mock_object( - shell_v2, - '_find_share_network', - mock.Mock(side_effect=fake_share_networks), - ) - - self.run_command('share-network-delete {}'.format(' '.join(sn_ids))) - - shell_v2._find_share_network.assert_has_calls( - [mock.call(self.shell.cs, sn_id) for sn_id in sn_ids] - ) - for sn in fake_share_networks: - self.assert_called_anytime( - 'DELETE', f'/share-networks/{sn.id}', clear_callstack=False - ) - - @mock.patch.object(shell_v2, '_find_share', mock.Mock()) - @mock.patch.object(shell_v2, '_wait_for_snapshot_status', mock.Mock()) - def test_snapshot_create(self): - share_to_create_snapshot = shares.Share('fake_share', {'id': '1234'}) - shell_v2._find_share.return_value = share_to_create_snapshot - - self.run_command( - 'snapshot-create fake_share --name testshare1snapshot' - ) - - shell_v2._find_share.assert_has_calls( - [mock.call(self.shell.cs, 'fake_share')] - ) - self.assert_called_anytime('POST', '/snapshots', clear_callstack=False) - # _wait_for_snapshot_status should not be trigerred - self.assertEqual(0, shell_v2._wait_for_snapshot_status.call_count) - - @mock.patch.object(shell_v2, '_find_share', mock.Mock()) - @mock.patch.object(shell_v2, '_wait_for_snapshot_status', mock.Mock()) - def test_snapshot_create_with_wait(self): - share_to_create_snapshot = shares.Share('fake_share', {'id': '1234'}) - shell_v2._find_share.return_value = share_to_create_snapshot - - self.run_command( - 'snapshot-create fake_share --name testshare1snapshot --wait' - ) - - shell_v2._find_share.assert_has_calls( - [mock.call(self.shell.cs, 'fake_share')] - ) - self.assert_called_anytime('POST', '/snapshots', clear_callstack=False) - # _wait_for_snapshot_status should be trigerred once - shell_v2._wait_for_snapshot_status.assert_called_once_with( - self.shell.cs, mock.ANY, expected_status='available' - ) - - @ddt.data(('fake_snapshot1',), ('fake_snapshot1', 'fake_snapshot2')) - def test_snapshot_delete(self, snapshot_ids): - fake_snapshots = [ - share_snapshots.ShareSnapshot('fake', {'id': snapshot_id}, True) - for snapshot_id in snapshot_ids - ] - self.mock_object( - shell_v2, - '_find_share_snapshot', - mock.Mock(side_effect=fake_snapshots), - ) - - self.run_command('snapshot-delete {}'.format(' '.join(snapshot_ids))) - - shell_v2._find_share_snapshot.assert_has_calls( - [mock.call(self.shell.cs, s_id) for s_id in snapshot_ids] - ) - for snapshot in fake_snapshots: - self.assert_called_anytime( - 'DELETE', f'/snapshots/{snapshot.id}', clear_callstack=False - ) - - @mock.patch.object(shell_v2, '_find_share_snapshot', mock.Mock()) - @mock.patch.object(shell_v2, '_wait_for_snapshot_status', mock.Mock()) - def test_snapshot_delete_with_wait(self): - fake_snapshot = share_snapshots.ShareSnapshot( - 'fake', {'id': 'fake_snapshot1'}, True - ) - shell_v2._find_share_snapshot.return_value = fake_snapshot - - self.run_command('snapshot-delete fake_snapshot1 --wait') - - shell_v2._find_share_snapshot.assert_has_calls( - [mock.call(self.shell.cs, 'fake_snapshot1')] - ) - self.assert_called_anytime( - 'DELETE', '/snapshots/fake_snapshot1', clear_callstack=False - ) - # _wait_for_resource_status should be trigerred once - shell_v2._wait_for_snapshot_status.assert_called_once_with( - self.shell.cs, 'fake_snapshot1', expected_status='deleted' - ) - - @ddt.data(('snapshot_xyz',), ('snapshot_abc', 'snapshot_xyz')) - def test_snapshot_force_delete_wait(self, snapshots_to_delete): - fake_manager = mock.Mock() - fake_snapshots = [ - share_snapshots.ShareSnapshot(fake_manager, {'id': '1234'}) - for snapshot in snapshots_to_delete - ] - snapshot_not_found_error = ( - "Delete for snapshot %s failed: No " - "snapshot with a name or " - "ID of '%s' exists." - ) - snapshots_are_not_found_errors = [ - exceptions.CommandError( - snapshot_not_found_error % (snapshot, snapshot) - ) - for snapshot in snapshots_to_delete - ] - self.mock_object( - shell_v2, - '_find_share_snapshot', - mock.Mock( - side_effect=(fake_snapshots + snapshots_are_not_found_errors) - ), - ) - self.run_command( - 'snapshot-force-delete {} --wait'.format( - ' '.join(snapshots_to_delete) - ) - ) - shell_v2._find_share_snapshot.assert_has_calls( - [ - mock.call(self.shell.cs, snapshot) - for snapshot in snapshots_to_delete - ] - ) - fake_manager.force_delete.assert_has_calls( - [mock.call(snapshot) for snapshot in fake_snapshots] - ) - self.assertEqual( - len(snapshots_to_delete), fake_manager.force_delete.call_count - ) - - @ddt.data(('fake_type1',), ('fake_type1', 'fake_type2')) - def test_share_type_delete(self, type_ids): - fake_share_types = [ - share_types.ShareType('fake', {'id': type_id}, True) - for type_id in type_ids - ] - self.mock_object( - shell_v2, - '_find_share_type', - mock.Mock(side_effect=fake_share_types), - ) - - self.run_command('type-delete {}'.format(' '.join(type_ids))) - - shell_v2._find_share_type.assert_has_calls( - [mock.call(self.shell.cs, t_id) for t_id in type_ids] - ) - for fake_share_type in fake_share_types: - self.assert_called_anytime( - 'DELETE', - f'/types/{fake_share_type.id}', - clear_callstack=False, - ) - - @ddt.data(('share_server_xyz',), ('share_server_abc', 'share_server_xyz')) - def test_share_server_delete_wait(self, share_servers_to_delete): - fake_manager = mock.Mock() - fake_share_servers = [ - share_servers.ShareServer(fake_manager, {'id': '1234'}) - for share_server in share_servers_to_delete - ] - share_server_not_found_error = ( - "Delete for share server %s " - "failed: No server with a " - "name or ID of '%s' exists." - ) - share_servers_are_not_found_errors = [ - exceptions.CommandError( - share_server_not_found_error % (share_server, share_server) - ) - for share_server in share_servers_to_delete - ] - self.mock_object( - shell_v2, - '_find_share_server', - mock.Mock( - side_effect=( - fake_share_servers + share_servers_are_not_found_errors - ) - ), - ) - - self.mock_object(shell_v2, '_wait_for_resource_status', mock.Mock()) - - self.run_command( - 'share-server-delete {} --wait'.format( - ' '.join(share_servers_to_delete) - ) - ) - - shell_v2._find_share_server.assert_has_calls( - [ - mock.call(self.shell.cs, share_server) - for share_server in share_servers_to_delete - ] - ) - fake_manager.delete.assert_has_calls( - [mock.call(share_server) for share_server in fake_share_servers] - ) - shell_v2._wait_for_resource_status.assert_has_calls( - [ - mock.call( - self.shell.cs, - share_server, - resource_type='share_server', - expected_status='deleted', - ) - for share_server in fake_share_servers - ] - ) - self.assertEqual( - len(share_servers_to_delete), fake_manager.delete.call_count - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_message_list(self): - self.run_command('message-list') - - self.assert_called('GET', '/messages') - cliutils.print_list.assert_called_once_with( - mock.ANY, - fields=[ - 'ID', - 'Resource Type', - 'Resource ID', - 'Action ID', - 'User Message', - 'Detail ID', - 'Created At', - ], - sortby_index=None, - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_share_message_list_created_before_aliases(self): - self.run_command('message-list --before 2001-01-01') - self.assert_called( - 'GET', - '/messages?created_before=2001-01-01', - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_share_message_list_created_since_aliases(self): - self.run_command('message-list --since 2001-01-01') - self.assert_called( - 'GET', - '/messages?created_since=2001-01-01', - ) - - @mock.patch.object(cliutils, 'print_list', mock.Mock()) - def test_message_list_select_column(self): - self.run_command('message-list --columns id,resource_type') - - self.assert_called('GET', '/messages') - cliutils.print_list.assert_called_once_with( - mock.ANY, fields=['Id', 'Resource_Type'], sortby_index=None - ) - - def test_message_list_with_filters(self): - self.run_command('message-list --limit 10 --offset 0') - - self.assert_called('GET', '/messages?limit=10&offset=0') - - def test_message_show(self): - self.run_command('message-show 1234') - - self.assert_called('GET', '/messages/1234') - - @ddt.data( - ('1234',), - ('1234_error',), - ('1234_error', '5678'), - ('1234', '5678_error'), - ('1234', '5678'), - ) - def test_message_delete(self, ids): - fake_messages = dict() - for mid in ids: - if mid.endswith('_error'): - continue - fake_messages[mid] = messages.Message('fake', {'id': mid}, True) - - def _find_message_with_errors(cs, mid): - if mid.endswith('_error'): - raise Exception - return fake_messages[mid] - - self.mock_object( - shell_v2, - '_find_message', - mock.Mock(side_effect=_find_message_with_errors), - ) - - cmd = 'message-delete {}'.format(' '.join(ids)) - - if len(fake_messages) == 0: - self.assertRaises(exceptions.CommandError, self.run_command, cmd) - else: - self.run_command(cmd) - - shell_v2._find_message.assert_has_calls( - [mock.call(self.shell.cs, mid) for mid in ids] - ) - for fake_message in fake_messages.values(): - self.assert_called_anytime( - 'DELETE', - f'/messages/{fake_message.id}', - clear_callstack=False, - ) - - @ddt.data( - ('share-network-list', ' --description~', '/share-networks/', '2.35'), - ('share-network-list', ' --name~', '/share-networks/', '2.35'), - ('share-group-list', ' --description~', '/share-groups/', '2.35'), - ('share-group-list', ' --name~', '/share-groups/', '2.35'), - ('list', ' --description~', '/shares/', '2.35'), - ('list', ' --name~', '/shares/', '2.35'), - ('snapshot-list', ' --description~', '/snapshots/', '2.35'), - ('snapshot-list', ' --name~', '/snapshots/', '2.35'), - ) - @ddt.unpack - def test_list_filter_by_inexact_version_not_support( - self, cmd, option, url, version - ): - for separator in self.separators: - self.assertRaises( - exceptions.CommandError, - self.run_command, - cmd + option + separator + 'fake', - version=version, - ) - - def test_share_server_unmanage_all_fail(self): - # All of 2345, 5678, 9999 throw exception - cmd = '--os-share-api-version 2.49' - cmd += ' share-server-unmanage' - cmd += ' 2345 5678 9999' - self.assertRaises(exceptions.CommandError, self.run_command, cmd) - - def test_share_server_unmanage_some_fail(self): - # 5678 and 9999 throw exception - self.run_command('share-server-unmanage 1234 5678 9999') - expected = {'unmanage': {'force': False}} - self.assert_called('POST', '/share-servers/1234/action', body=expected) - - @ddt.data('migration-start', 'migration-check') - def test_share_server_migration_start_and_check(self, method): - command = ( - f"share-server-{method} " - "1234 host@backend --new-share-network 1111 " - "--writable False --nondisruptive True " - "--preserve-snapshots True" - ) - self.run_command(command) - method = method.replace('-', '_') - expected = { - method: { - 'host': 'host@backend', - 'writable': 'False', - 'nondisruptive': 'True', - 'preserve_snapshots': 'True', - 'new_share_network_id': 1111, - } - } - self.assert_called('POST', '/share-servers/1234/action', body=expected) - - @ddt.data( - 'migration-complete', 'migration-get-progress', 'migration-cancel' - ) - def test_share_server_migration_others(self, method): - command = 'share-server-' + ' '.join((method, '1234')) - self.run_command(command) - expected = {method.replace('-', '_'): None} - self.assert_called('POST', '/share-servers/1234/action', body=expected) - - @ddt.data('migration_error', 'migration_success', None) - def test_share_server_reset_task_state(self, param): - command = ' '.join( - ('share-server-reset-task-state --state', str(param), '1234') - ) - self.run_command(command) - expected = {'reset_task_state': {'task_state': param}} - self.assert_called('POST', '/share-servers/1234/action', body=expected) diff --git a/manilaclient/v2/shell.py b/manilaclient/v2/shell.py deleted file mode 100644 index b2275b64..00000000 --- a/manilaclient/v2/shell.py +++ /dev/null @@ -1,7907 +0,0 @@ -# Copyright 2013 OpenStack Foundation -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - - -from operator import xor -import os -import re -import sys -import time - -from oslo_utils import strutils - -from manilaclient import api_versions -from manilaclient.common.apiclient import utils as apiclient_utils -from manilaclient.common import cliutils -from manilaclient.common import constants -from manilaclient import exceptions -import manilaclient.v2.shares - - -def _wait_for_resource_status( - cs, - resource, - expected_status, - resource_type='share', - status_attr='status', - poll_timeout=900, - poll_interval=2, -): - """Waiter for resource status changes - - :param cs: command shell control - :param expected_status: a string or a list of strings containing expected - states to wait for - :param resource_type: 'share', 'snapshot', 'share_replica', 'share_group', - or 'share_group_snapshot' - :param status_attr: 'status', 'task_state', 'access_rules_status' or any - other status field that is expected to have the "expected_status" - :param poll_timeout: how long to wait for in seconds - :param poll_interval: how often to try in seconds - """ - find_resource = { - 'share': _find_share, - 'snapshot': _find_share_snapshot, - 'share_replica': _find_share_replica, - 'share_group': _find_share_group, - 'share_group_snapshot': _find_share_group_snapshot, - 'share_instance': _find_share_instance, - 'share_server': _find_share_server, - 'share_access_rule': _find_share_access_rule, - } - - print_resource = { - 'share': _print_share, - 'snapshot': _print_share_snapshot, - 'share_replica': _print_share_replica, - 'share_group': _print_share_group, - 'share_group_snapshot': _print_share_group_snapshot, - 'share_instance': _print_share_instance, - 'share_access_rule': _print_share_access_rule, - } - - expected_status = expected_status or ('available',) - if not isinstance(expected_status, (list, tuple, set)): - expected_status = (expected_status,) - - time_elapsed = 0 - timeout_message = ( - "%(resource_type)s %(resource)s did not reach " - "%(expected_states)s within %(seconds)d seconds." - ) - error_message = ( - "%(resource_type)s %(resource)s has reached a failed state." - ) - deleted_message = ( - "%(resource_type)s %(resource)s has been successfully deleted." - ) - unmanaged_message = ( - "%(resource_type)s %(resource)s has been successfully unmanaged." - ) - message_payload = { - 'resource_type': resource_type.capitalize(), - 'resource': resource.id, - } - not_found_regex = "no .* exists" - while True: - if time_elapsed > poll_timeout: - print_resource[resource_type](cs, resource) - message_payload.update( - {'expected_states': expected_status, 'seconds': poll_timeout} - ) - raise exceptions.TimeoutException( - message=timeout_message % message_payload - ) - try: - resource = find_resource[resource_type](cs, resource.id) - except exceptions.CommandError as e: - if re.search(not_found_regex, str(e), flags=re.IGNORECASE): - if 'deleted' in expected_status: - print(deleted_message % message_payload) - break - if 'unmanaged' in expected_status: - print(unmanaged_message % message_payload) - break - else: - raise e - - if getattr(resource, status_attr) in expected_status: - break - elif 'error' in getattr(resource, status_attr): - print_resource[resource_type](cs, resource) - raise exceptions.ResourceInErrorState( - message=error_message % message_payload - ) - time.sleep(poll_interval) - time_elapsed += poll_interval - - return resource - - -def _find_share(cs, share): - """Get a share by ID.""" - return apiclient_utils.find_resource(cs.shares, share) - - -def _find_share_transfer(cs, transfer): - """Get a share transfer by ID.""" - return apiclient_utils.find_resource(cs.transfers, transfer) - - -@api_versions.wraps("1.0", "2.8") -def _print_share(cs, share): - info = share._info.copy() - info.pop('links', None) - - # NOTE(vponomaryov): remove deprecated single field 'export_location' and - # leave only list field 'export_locations'. Also, transform the latter to - # text with new line separators to make it pretty in CLI. - # It will look like following: - # +-------------------+--------------------------------------------+ - # | Property | Value | - # +-------------------+--------------------------------------------+ - # | status | available | - # | export_locations | 1.2.3.4:/f/o/o | - # | | 5.6.7.8:/b/a/r | - # | | 9.10.11.12:/q/u/u/z | - # | id | d778d2ee-b6bb-4c5f-9f5d-6f3057d549b1 | - # | size | 1 | - # | share_proto | NFS | - # +-------------------+--------------------------------------------+ - if info.get('export_locations'): - info.pop('export_location', None) - info['export_locations'] = "\n".join(info['export_locations']) - - # No need to print both volume_type and share_type to CLI - if 'volume_type' in info and 'share_type' in info: - info.pop('volume_type', None) - - cliutils.print_dict(info) - - -@api_versions.wraps("2.9") # noqa -def _print_share(cs, share): # noqa - info = share._info.copy() - info.pop('links', None) - - # NOTE(vponomaryov): remove deprecated single field 'export_location' and - # leave only list field 'export_locations'. Also, transform the latter to - # text with new line separators to make it pretty in CLI. - # It will look like following: - # +-------------------+--------------------------------------------+ - # | Property | Value | - # +-------------------+--------------------------------------------+ - # | status | available | - # | export_locations | | - # | | uuid = FOO-UUID | - # | | path = 5.6.7.8:/foo/export/location/path | - # | | | - # | | uuid = BAR-UUID | - # | | path = 5.6.7.8:/bar/export/location/path | - # | | | - # | id | d778d2ee-b6bb-4c5f-9f5d-6f3057d549b1 | - # | size | 1 | - # | share_proto | NFS | - # +-------------------+--------------------------------------------+ - if info.get('export_locations'): - info['export_locations'] = cliutils.convert_dict_list_to_string( - info['export_locations'], - ignored_keys=[ - 'replica_state', - 'availability_zone', - 'share_replica_id', - ], - ) - - # No need to print both volume_type and share_type to CLI - if 'volume_type' in info and 'share_type' in info: - info.pop('volume_type', None) - - cliutils.print_dict(info) - - -def _wait_for_share_status(cs, share, expected_status='available'): - return _wait_for_resource_status( - cs, share, expected_status, resource_type='share' - ) - - -def _find_share_instance(cs, instance): - """Get a share instance by ID.""" - return apiclient_utils.find_resource(cs.share_instances, instance) - - -def _print_type_show(stype, default_share_type=None): - if hasattr(stype, 'is_default'): - is_default = 'YES' if stype.is_default else 'NO' - elif default_share_type: - is_default = 'YES' if stype.id == default_share_type.id else 'NO' - else: - is_default = 'NO' - - stype_dict = { - 'id': stype.id, - 'name': stype.name, - 'visibility': _is_share_type_public(stype), - 'is_default': is_default, - 'description': stype.description, - 'required_extra_specs': _print_type_required_extra_specs(stype), - 'optional_extra_specs': _print_type_optional_extra_specs(stype), - } - cliutils.print_dict(stype_dict) - - -@api_versions.wraps("1.0", "2.8") -def _print_share_instance(cs, instance): - info = instance._info.copy() - info.pop('links', None) - cliutils.print_dict(info) - - -@api_versions.wraps("2.9") # noqa -def _print_share_instance(cs, instance): # noqa - info = instance._info.copy() - info.pop('links', None) - if info.get('export_locations'): - info['export_locations'] = cliutils.convert_dict_list_to_string( - info['export_locations'], - ignored_keys=[ - 'replica_state', - 'availability_zone', - 'share_replica_id', - ], - ) - - cliutils.print_dict(info) - - -def _find_share_access_rule(cs, access_rule): - """Get share access rule state""" - return apiclient_utils.find_resource(cs.share_access_rules, access_rule) - - -def _print_share_access_rule(cs, access_rule): - info = access_rule._info.copy() - - cliutils.print_dict(info) - - -def _find_share_replica(cs, replica): - """Get a replica by ID.""" - return apiclient_utils.find_resource(cs.share_replicas, replica) - - -@api_versions.wraps("2.11", "2.46") -def _print_share_replica(cs, replica): - info = replica._info.copy() - info.pop('links', None) - cliutils.print_dict(info) - - -@api_versions.wraps("2.47") # noqa -def _print_share_replica(cs, replica): # noqa - info = replica._info.copy() - info.pop('links', None) - if info.get('export_locations'): - info['export_locations'] = cliutils.convert_dict_list_to_string( - info['export_locations'], - ignored_keys=[ - 'replica_state', - 'availability_zone', - 'share_replica_id', - ], - ) - cliutils.print_dict(info) - - -@api_versions.wraps("2.31") -def _find_share_group(cs, share_group): - """Get a share group ID.""" - return apiclient_utils.find_resource(cs.share_groups, share_group) - - -def _print_share_group(cs, share_group): - info = share_group._info.copy() - info.pop('links', None) - - if info.get('share_types'): - info['share_types'] = "\n".join(info['share_types']) - - cliutils.print_dict(info) - - -@api_versions.wraps("2.31") -def _find_share_group_snapshot(cs, share_group_snapshot): - """Get a share group snapshot by name or ID.""" - return apiclient_utils.find_resource( - cs.share_group_snapshots, share_group_snapshot - ) - - -def _print_share_group_snapshot(cs, share_group_snapshot): - info = share_group_snapshot._info.copy() - info.pop('links', None) - info.pop('members', None) - cliutils.print_dict(info) - - -def _print_share_group_snapshot_members(cs, share_group_snapshot): - info = share_group_snapshot._info.copy() - cliutils.print_dict(info.get('members', {})) - - -def _wait_for_snapshot_status(cs, snapshot, expected_status='available'): - return _wait_for_resource_status( - cs, snapshot, expected_status, resource_type='snapshot' - ) - - -def _find_share_snapshot(cs, snapshot): - """Get a snapshot by ID.""" - return apiclient_utils.find_resource(cs.share_snapshots, snapshot) - - -def _print_share_snapshot(cs, snapshot): - info = snapshot._info.copy() - info.pop('links', None) - - if info.get('export_locations'): - info['export_locations'] = cliutils.convert_dict_list_to_string( - info['export_locations'] - ) - - cliutils.print_dict(info) - - -def _quota_set_pretty_show(quotas): - """Convert quotas object to dict and display.""" - - new_quotas = {} - for quota_k, quota_v in sorted(quotas.to_dict().items()): - if isinstance(quota_v, dict): - quota_v = '\n'.join( - [f'{k} = {v}' for k, v in sorted(quota_v.items())] - ) - new_quotas[quota_k] = quota_v - - cliutils.print_dict(new_quotas) - - -def _find_share_snapshot_instance(cs, snapshot_instance): - """Get a share snapshot instance by ID.""" - return apiclient_utils.find_resource( - cs.share_snapshot_instances, snapshot_instance - ) - - -def _find_share_network(cs, share_network): - """Get a share network by ID or name.""" - return apiclient_utils.find_resource(cs.share_networks, share_network) - - -def _find_security_service(cs, security_service): - """Get a security service by ID or name.""" - return apiclient_utils.find_resource( - cs.security_services, security_service - ) - - -def _find_share_server(cs, share_server): - """Get a share server by ID.""" - return apiclient_utils.find_resource(cs.share_servers, share_server) - - -def _find_message(cs, message): - """Get a message by ID.""" - return apiclient_utils.find_resource(cs.messages, message) - - -def _translate_keys(collection, convert): - for item in collection: - keys = item.__dict__ - for from_key, to_key in convert: - if from_key in keys and to_key not in keys: - setattr(item, to_key, item._info[from_key]) - - -def _extract_metadata(args, allow_empty_key=True): - return _extract_key_value_options(args, 'metadata', allow_empty_key) - - -def _extract_extra_specs(args): - return _extract_key_value_options(args, 'extra_specs') - - -def _extract_group_specs(args): - return _extract_key_value_options(args, 'group_specs') - - -def _extract_key_value_options(args, option_name, allow_empty_key=True): - result_dict = {} - duplicate_options = [] - - options = getattr(args, option_name, None) - - if options: - for option in options: - # unset doesn't require a val, so we have the if/else - if '=' in option: - (key, value) = option.split('=', 1) - elif allow_empty_key: - key = option - value = None - else: - # disallow empty key - continue - if key not in result_dict: - result_dict[key] = value - else: - duplicate_options.append(key) - - if len(duplicate_options) > 0: - duplicate_str = ', '.join(duplicate_options) - msg = f"Following options were duplicated: {duplicate_str}" - raise exceptions.CommandError(msg) - return result_dict - - -def _split_columns(columns, title=True): - if title: - list_of_keys = list( - map(lambda x: x.strip().title(), columns.split(",")) - ) - else: - list_of_keys = list( - map(lambda x: x.strip().lower(), columns.split(",")) - ) - return list_of_keys - - -@api_versions.wraps("2.0") -def do_api_version(cs, args): - """Display the API version information.""" - columns = ['ID', 'Status', 'Version', 'Min_version'] - column_labels = ['ID', 'Status', 'Version', 'Minimum Version'] - response = cs.services.server_api_version() - cliutils.print_list(response, columns, field_labels=column_labels) - - -def do_endpoints(cs, args): - """Discover endpoints that get returned from the authenticate services.""" - catalog = cs.keystone_client.service_catalog.catalog - for e in catalog.get('serviceCatalog', catalog.get('catalog')): - cliutils.print_dict(e['endpoints'][0], e['name']) - - -def do_credentials(cs, args): - """Show user credentials returned from auth.""" - catalog = cs.keystone_client.service_catalog.catalog - cliutils.print_dict(catalog['user'], "User Credentials") - if not catalog['version'] == 'v3': - data = catalog['token'] - else: - data = { - 'issued_at': catalog['issued_at'], - 'expires': catalog['expires_at'], - 'id': catalog['auth_token'], - 'audit_ids': catalog['audit_ids'], - 'tenant': catalog['project'], - } - cliutils.print_dict(data, "Token") - - -_quota_resources = [ - 'shares', - 'snapshots', - 'gigabytes', - 'snapshot_gigabytes', - 'share_networks', - 'share_replicas', - 'replica_gigabytes', - 'per_share_gigabytes', - 'share_groups', - 'share_group_snapshots', -] - - -def _quota_class_update(manager, identifier, args): - updates = {} - for resource in _quota_resources: - val = getattr(args, resource, None) - if val is not None: - updates[resource] = val - - if updates: - manager.update(identifier, **updates) - - -@cliutils.arg( - '--tenant-id', - '--tenant', - '--project', - '--project-id', - action='single_alias', - dest='project_id', - metavar='', - default=None, - help='ID of project to list the quotas for.', -) -@cliutils.arg( - '--user-id', - metavar='', - default=None, - help="ID of user to list the quotas for. Optional. " - "Mutually exclusive with '--share-type'.", -) -@cliutils.arg( - '--share-type', - '--share_type', - metavar='', - type=str, - default=None, - action='single_alias', - help="UUID or name of a share type to set the quotas for. Optional. " - "Mutually exclusive with '--user-id'. " - "Available only for microversion >= 2.39", -) -@cliutils.arg( - '--detail', - action='store_true', - help='Optional flag to indicate whether to show quota in detail. ' - 'Default false, available only for microversion >= 2.25.', -) -@api_versions.wraps("1.0") -def do_quota_show(cs, args): - """List the quotas for a project, user or share type.""" - project_id = args.project_id or cs.keystone_client.project_id - kwargs = { - "tenant_id": project_id, - "user_id": args.user_id, - "detail": args.detail, - } - if args.share_type is not None: - if cs.api_version < api_versions.APIVersion("2.39"): - raise exceptions.CommandError( - "'share type' quotas are available only starting with " - "'2.39' API microversion." - ) - kwargs["share_type"] = args.share_type - _quota_set_pretty_show(cs.quotas.get(**kwargs)) - - -@cliutils.arg( - '--tenant-id', - '--tenant', - '--project', - '--project-id', - action='single_alias', - dest='project_id', - metavar='', - default=None, - help='ID of the project to list the default quotas for.', -) -def do_quota_defaults(cs, args): - """List the default quotas for a project.""" - project = args.project_id or cs.keystone_client.project_id - _quota_set_pretty_show(cs.quotas.defaults(project)) - - -@cliutils.arg( - 'project_id', - metavar='', - help='UUID of project to set the quotas for.', -) -@cliutils.arg( - '--user-id', - metavar='', - default=None, - help="ID of a user to set the quotas for. Optional. " - "Mutually exclusive with '--share-type'.", -) -@cliutils.arg( - '--shares', - metavar='', - type=int, - default=None, - help='New value for the "shares" quota.', -) -@cliutils.arg( - '--snapshots', - metavar='', - type=int, - default=None, - help='New value for the "snapshots" quota.', -) -@cliutils.arg( - '--gigabytes', - metavar='', - type=int, - default=None, - help='New value for the "gigabytes" quota.', -) -@cliutils.arg( - '--snapshot-gigabytes', - '--snapshot_gigabytes', # alias - metavar='', - type=int, - default=None, - action='single_alias', - help='New value for the "snapshot_gigabytes" quota.', -) -@cliutils.arg( - '--share-networks', - '--share_networks', - metavar='', - type=int, - default=None, - action='single_alias', - help='New value for the "share_networks" quota.', -) -@cliutils.arg( - '--share-groups', - '--share_groups', - '--groups', - metavar='', - type=int, - default=None, - action='single_alias', - help='New value for the "share_groups" quota.', -) -@cliutils.arg( - '--share-group-snapshots', - '--share_group_snapshots', - '--group-snapshots', - '--group_snapshots', - metavar='', - type=int, - default=None, - action='single_alias', - help='New value for the "share_group_snapshots" quota.', -) -@cliutils.arg( - '--share-type', - '--share_type', - metavar='', - type=str, - default=None, - action='single_alias', - help="UUID or name of a share type to set the quotas for. Optional. " - "Mutually exclusive with '--user-id'. " - "Available only for microversion >= 2.39", -) -@cliutils.arg( - '--share-replicas', - '--share_replicas', - '--replicas', - metavar='', - type=int, - default=None, - help='New value for the "share_replicas" quota. Available only for ' - 'microversion >= 2.53', -) -@cliutils.arg( - '--replica-gigabytes', - '--replica_gigabytes', - metavar='', - type=int, - default=None, - help='New value for the "replica_gigabytes" quota. Available only for ' - 'microversion >= 2.53', -) -@cliutils.arg( - '--per-share-gigabytes', - '--per_share_gigabytes', - metavar='', - type=int, - default=None, - help='New value for the "per_share_gigabytes" quota. Available only for ' - 'microversion >= 2.62', -) -@cliutils.arg( - '--force', - dest='force', - action="store_true", - default=None, - help='Whether force update the quota even if the already used ' - 'and reserved exceeds the new quota.', -) -@api_versions.wraps("1.0") -def do_quota_update(cs, args): - """Update the quotas for a project/user and/or share type (Admin only).""" - kwargs = { - "tenant_id": args.project_id, - "user_id": args.user_id, - "shares": args.shares, - "gigabytes": args.gigabytes, - "snapshots": args.snapshots, - "snapshot_gigabytes": args.snapshot_gigabytes, - "share_networks": args.share_networks, - "force": args.force, - } - if args.share_type is not None: - if cs.api_version < api_versions.APIVersion("2.39"): - raise exceptions.CommandError( - "'share type' quotas are available only starting with " - "'2.39' API microversion." - ) - kwargs["share_type"] = args.share_type - if args.share_groups is not None or args.share_group_snapshots is not None: - if cs.api_version < api_versions.APIVersion("2.40"): - raise exceptions.CommandError( - "'share group' quotas are available only starting with " - "'2.40' API microversion." - ) - elif args.share_type is not None: - raise exceptions.CommandError( - "Share type quotas cannot be used to constrain share groups." - ) - kwargs["share_groups"] = args.share_groups - kwargs["share_group_snapshots"] = args.share_group_snapshots - if args.share_replicas is not None or args.replica_gigabytes is not None: - if cs.api_version < api_versions.APIVersion("2.53"): - raise exceptions.CommandError( - "'share replica' quotas are available only starting with " - "'2.53' API microversion." - ) - kwargs["share_replicas"] = args.share_replicas - kwargs["replica_gigabytes"] = args.replica_gigabytes - if args.per_share_gigabytes is not None: - if cs.api_version < api_versions.APIVersion("2.62"): - raise exceptions.CommandError( - "'per share gigabytes' quotas are available only starting " - "with '2.62' API microversion." - ) - kwargs["per_share_gigabytes"] = args.per_share_gigabytes - - cs.quotas.update(**kwargs) - - -@cliutils.arg( - '--tenant-id', - '--tenant', - '--project', - '--project-id', - action='single_alias', - dest='project_id', - metavar='', - help='ID of the project to delete quota for.', -) -@cliutils.arg( - '--user-id', - metavar='', - help="ID of user to delete quota for. Optional." - "Mutually exclusive with '--share-type'.", -) -@cliutils.arg( - '--share-type', - '--share_type', - metavar='', - type=str, - default=None, - action='single_alias', - help="UUID or name of a share type to set the quotas for. Optional. " - "Mutually exclusive with '--user-id'. " - "Available only for microversion >= 2.39", -) -@api_versions.wraps("1.0") -def do_quota_delete(cs, args): - """Delete quota for a project, or project/user or project/share-type. - - The quota will revert back to default (Admin only). - """ - project_id = args.project_id or cs.keystone_client.project_id - kwargs = { - "tenant_id": project_id, - "user_id": args.user_id, - } - if args.share_type is not None: - if cs.api_version < api_versions.APIVersion("2.39"): - raise exceptions.CommandError( - "'share type' quotas are available only starting with " - "'2.39' API microversion." - ) - kwargs["share_type"] = args.share_type - - cs.quotas.delete(**kwargs) - - -@cliutils.arg( - 'class_name', - metavar='', - help='Name of quota class to list the quotas for.', -) -def do_quota_class_show(cs, args): - """List the quotas for a quota class.""" - - _quota_set_pretty_show(cs.quota_classes.get(args.class_name)) - - -@cliutils.arg( - 'class_name', - metavar='', - help='Name of quota class to set the quotas for.', -) -@cliutils.arg( - '--shares', - metavar='', - type=int, - default=None, - help='New value for the "shares" quota.', -) -@cliutils.arg( - '--snapshots', - metavar='', - type=int, - default=None, - help='New value for the "snapshots" quota.', -) -@cliutils.arg( - '--gigabytes', - metavar='', - type=int, - default=None, - help='New value for the "gigabytes" quota.', -) -@cliutils.arg( - '--snapshot-gigabytes', - '--snapshot_gigabytes', # alias - metavar='', - type=int, - default=None, - action='single_alias', - help='New value for the "snapshot_gigabytes" quota.', -) -@cliutils.arg( - '--share-networks', - '--share_networks', # alias - metavar='', - type=int, - default=None, - action='single_alias', - help='New value for the "share_networks" quota.', -) -@cliutils.arg( - '--share-groups', - '--share_groups', # alias - metavar='', - type=int, - default=None, - action='single_alias', - help='New value for the "share_groups" quota. Available only for ' - 'microversion >= 2.40', -) -@cliutils.arg( - '--share-group-snapshots', - '--share_group_snapshots', - metavar='', - type=int, - default=None, - action='single_alias', - help='New value for the "share_group_snapshots" quota. Available only for ' - 'microversion >= 2.40', -) -@cliutils.arg( - '--share-replicas', - '--share_replicas', # alias - '--replicas', # alias - metavar='', - type=int, - default=None, - action='single_alias', - help='New value for the "share_replicas" quota. Available only for ' - 'microversion >= 2.53', -) -@cliutils.arg( - '--replica-gigabytes', - '--replica_gigabytes', # alias - metavar='', - type=int, - default=None, - action='single_alias', - help='New value for the "replica_gigabytes" quota. Available only for ' - 'microversion >= 2.53', -) -@cliutils.arg( - '--per-share-gigabytes', - '--per_share_gigabytes', # alias - metavar='', - type=int, - default=None, - action='single_alias', - help='New value for the "per_share_gigabytes" quota. Available only for ' - 'microversion >= 2.62', -) -def do_quota_class_update(cs, args): - """Update the quotas for a quota class (Admin only).""" - if args.share_groups is not None or args.share_group_snapshots is not None: - if cs.api_version < api_versions.APIVersion("2.40"): - raise exceptions.CommandError( - "'share groups' quotas are available only starting with " - "'2.40' API microversion." - ) - if args.share_replicas is not None or args.replica_gigabytes is not None: - if cs.api_version < api_versions.APIVersion("2.53"): - raise exceptions.CommandError( - "'share replica' quotas are available only starting with " - "'2.53' API microversion." - ) - if args.per_share_gigabytes is not None: - if cs.api_version < api_versions.APIVersion("2.62"): - raise exceptions.CommandError( - "'per_share_gigabytes' quota is available only starting " - "with '2.62' API microversion." - ) - - _quota_class_update(cs.quota_classes, args.class_name, args) - - -def do_absolute_limits(cs, args): - """Print a list of absolute limits for a user.""" - limits = cs.limits.get().absolute - columns = ['Name', 'Value'] - cliutils.print_list(limits, columns) - - -@cliutils.arg( - '--columns', - metavar='', - type=str, - default=None, - help='Comma separated list of columns to be displayed ' - 'example --columns "verb,uri,value".', -) -def do_rate_limits(cs, args): - """Print a list of rate limits for a user.""" - limits = cs.limits.get().rate - columns = ['Verb', 'URI', 'Value', 'Remain', 'Unit', 'Next_Available'] - - if args.columns is not None: - columns = _split_columns(columns=args.columns) - - cliutils.print_list(limits, columns) - - -@cliutils.arg( - 'share_protocol', - metavar='', - type=str, - help='Share protocol (NFS, CIFS, CephFS, GlusterFS, HDFS or MAPRFS).', -) -@cliutils.arg('size', metavar='', type=int, help='Share size in GiB.') -@cliutils.arg( - '--snapshot-id', - '--snapshot_id', - '--snapshot', - metavar='', - action='single_alias', - help='Optional snapshot ID or name to create the share from.' - ' (Default=None)', - default=None, -) -@cliutils.arg( - '--name', - metavar='', - help='Optional share name. (Default=None)', - default=None, -) -@cliutils.arg( - '--metadata', - type=str, - nargs='*', - metavar='', - help='Metadata key=value pairs (Optional, Default=None).', - default=None, -) -@cliutils.arg( - '--share-network', - '--share_network', - metavar='', - action='single_alias', - help='Optional network info ID or name.', - default=None, -) -@cliutils.arg( - '--description', - metavar='', - help='Optional share description. (Default=None)', - default=None, -) -@cliutils.arg( - '--share-type', - '--share_type', - '--volume-type', - '--volume_type', - metavar='', - default=None, - action='single_alias', - help='Optional share type. Use of optional volume type is deprecated. ' - '(Default=None)', -) -@cliutils.arg( - '--public', - dest='public', - action='store_true', - default=False, - help="Level of visibility for share. Defines whether other projects are " - "able to see it or not. (Default=False)", -) -@cliutils.arg( - '--availability-zone', - '--availability_zone', - '--az', - metavar='', - default=None, - action='single_alias', - help='Availability zone in which share should be created.', -) -@cliutils.arg( - '--share-group', - '--share_group', - '--group', - metavar='', - action='single_alias', - help='Optional share group name or ID in which to create the share ' - '(Default=None).', - default=None, -) -@cliutils.arg('--wait', action='store_true', help='Wait for share creation') -@cliutils.arg( - '--scheduler-hints', - '--scheduler_hints', - '--sh', - metavar='', - nargs='*', - help='Scheduler hints for the share as key=value pairs, ' - 'possible keys are same_host, different_host, ' - 'value must be share_name or share_id.', - default=None, -) -@cliutils.service_type('sharev2') -def do_create(cs, args): - """Creates a new share (NFS, CIFS, CephFS, GlusterFS, HDFS or MAPRFS).""" - - share_metadata = None - if args.metadata is not None: - share_metadata = _extract_metadata(args) - - share_group = None - if args.share_group: - share_group = _find_share_group(cs, args.share_group).id - - share_network = None - if args.share_network: - share_network = _find_share_network(cs, args.share_network) - - snapshot = None - if args.snapshot_id: - snapshot = _find_share_snapshot(cs, args.snapshot_id).id - - if args.name: - if args.name.capitalize() == 'None': - raise exceptions.CommandError( - "Share name cannot be with the value 'None'" - ) - - if not args.share_type: - try: - _find_share_type(cs, "default") - except exceptions.CommandError: - msg = ( - "There is no default share type available. You must pick " - "a valid share type to create a share." - ) - raise exceptions.CommandError(msg) - - scheduler_hints = {} - if args.scheduler_hints: - scheduler_hints = _extract_key_value_options(args, 'scheduler_hints') - same_host_hint_shares = scheduler_hints.get('same_host') - different_host_hint_shares = scheduler_hints.get('different_host') - if same_host_hint_shares: - same_host_hint_shares = [ - _find_share(cs, sh).id - for sh in same_host_hint_shares.split(',') - ] - scheduler_hints['same_host'] = ','.join(same_host_hint_shares) - if different_host_hint_shares: - different_host_hint_shares = [ - _find_share(cs, sh).id - for sh in different_host_hint_shares.split(',') - ] - scheduler_hints['different_host'] = ','.join( - different_host_hint_shares - ) - - share = cs.shares.create( - args.share_protocol, - args.size, - snapshot, - args.name, - args.description, - metadata=share_metadata, - share_network=share_network, - share_type=args.share_type, - is_public=args.public, - availability_zone=args.availability_zone, - share_group_id=share_group, - scheduler_hints=scheduler_hints, - ) - - if args.wait: - share = _wait_for_share_status(cs, share) - - _print_share(cs, share) - - -@api_versions.wraps("2.29") -@cliutils.arg( - 'share', metavar='', help='Name or ID of share to migrate.' -) -@cliutils.arg( - 'host', - metavar='', - help="Destination host where share will be migrated to. Use the " - "format 'host@backend#pool'.", -) -@cliutils.arg( - '--force_host_assisted_migration', - '--force-host-assisted-migration', - metavar='', - choices=['True', 'False'], - action='single_alias', - required=False, - default=False, - help="Enforces the use of the host-assisted migration approach, " - "which bypasses driver optimizations. Default=False.", -) -@cliutils.arg( - '--preserve-metadata', - '--preserve_metadata', - action='single_alias', - metavar='', - choices=['True', 'False'], - required=True, - help="Enforces migration to preserve all file metadata when moving its " - "contents. If set to True, host-assisted migration will not be " - "attempted.", -) -@cliutils.arg( - '--preserve-snapshots', - '--preserve_snapshots', - action='single_alias', - metavar='', - choices=['True', 'False'], - required=True, - help="Enforces migration of the share snapshots to the destination. If " - "set to True, host-assisted migration will not be attempted.", -) -@cliutils.arg( - '--writable', - metavar='', - choices=['True', 'False'], - required=True, - help="Enforces migration to keep the share writable while contents are " - "being moved. If set to True, host-assisted migration will not be " - "attempted.", -) -@cliutils.arg( - '--nondisruptive', - metavar='', - choices=['True', 'False'], - required=True, - help="Enforces migration to be nondisruptive. If set to True, " - "host-assisted migration will not be attempted.", -) -@cliutils.arg( - '--new_share_network', - '--new-share-network', - metavar='', - action='single_alias', - required=False, - help='Specify the new share network for the share. Do not specify this ' - 'parameter if the migrating share has to be retained within its ' - 'current share network.', - default=None, -) -@cliutils.arg( - '--new_share_type', - '--new-share-type', - metavar='', - required=False, - action='single_alias', - help='Specify the new share type for the share. Do not specify this ' - 'parameter if the migrating share has to be retained with its ' - 'current share type.', - default=None, -) -def do_migration_start(cs, args): - """Migrates share to a new host (Admin only, Experimental).""" - share = _find_share(cs, args.share) - new_share_net_id = None - if args.new_share_network: - share_net = _find_share_network(cs, args.new_share_network) - new_share_net_id = share_net.id if share_net else None - new_share_type_id = None - if args.new_share_type: - share_type = _find_share_type(cs, args.new_share_type) - new_share_type_id = share_type.id if share_type else None - share.migration_start( - args.host, - args.force_host_assisted_migration, - args.preserve_metadata, - args.writable, - args.nondisruptive, - args.preserve_snapshots, - new_share_net_id, - new_share_type_id, - ) - - -@cliutils.arg( - 'share', - metavar='', - help='Name or ID of share to complete migration.', -) -@api_versions.wraps("2.22") -def do_migration_complete(cs, args): - """Completes migration for a given share (Admin only, Experimental).""" - share = _find_share(cs, args.share) - share.migration_complete() - - -@cliutils.arg( - 'share', metavar='', help='Name or ID of share to cancel migration.' -) -@api_versions.wraps("2.22") -def do_migration_cancel(cs, args): - """Cancels migration of a given share when copying - - (Admin only, Experimental). - """ - share = _find_share(cs, args.share) - share.migration_cancel() - - -@cliutils.arg( - 'share', metavar='', help='Name or ID of the share to modify.' -) -@cliutils.arg( - '--task-state', - '--task_state', - '--state', - metavar='', - default='None', - action='single_alias', - required=False, - help=( - 'Indicate which task state to assign the share. Options include ' - 'migration_starting, migration_in_progress, migration_completing, ' - 'migration_success, migration_error, migration_cancelled, ' - 'migration_driver_in_progress, migration_driver_phase1_done, ' - 'data_copying_starting, data_copying_in_progress, ' - 'data_copying_completing, data_copying_completed, ' - 'data_copying_cancelled, data_copying_error. If no value is ' - 'provided, None will be used.' - ), -) -@api_versions.wraps("2.22") -def do_reset_task_state(cs, args): - """Explicitly update the task state of a share - - (Admin only, Experimental). - """ - state = args.task_state - if args.task_state == 'None': - state = None - share = _find_share(cs, args.share) - share.reset_task_state(state) - - -@cliutils.arg( - 'share', - metavar='', - help='Name or ID of the share to get share migration progress ' - 'information.', -) -@api_versions.wraps("2.22") -def do_migration_get_progress(cs, args): - """Gets migration progress of a given share when copying - - (Admin only, Experimental). - """ - share = _find_share(cs, args.share) - result = share.migration_get_progress() - # NOTE(ganso): result[0] is response code, result[1] is dict body - cliutils.print_dict(result[1]) - - -@cliutils.arg( - 'share_server_id', - metavar='', - help='ID of the share server to check if the migration is possible.', -) -@cliutils.arg( - 'host', - metavar='', - help="Destination to migrate the share server to. Use the format " - "'@'.", -) -@cliutils.arg( - '--preserve-snapshots', - '--preserve_snapshots', - action='single_alias', - metavar='', - choices=['True', 'False'], - required=True, - help="Set to True if snapshots must be preserved at the migration " - "destination.", -) -@cliutils.arg( - '--writable', - metavar='', - choices=['True', 'False'], - required=True, - help="Set to True if shares associated with the share server must be " - "writable through the first phase of the migration.", -) -@cliutils.arg( - '--nondisruptive', - metavar='', - choices=['True', 'False'], - required=True, - help="Set to True if migration must be non disruptive to clients that are " - "using the shares associated with the share server through both " - "phases of the migration.", -) -@cliutils.arg( - '--new_share_network', - '--new-share-network', - metavar='', - action='single_alias', - required=False, - help="New share network to migrate to. Optional, default=None.", - default=None, -) -@api_versions.wraps("2.57") -@api_versions.experimental_api -def do_share_server_migration_check(cs, args): - """Check migration compatibility for a share server with desired properties - - (Admin only, Experimental). - """ - share_server = _find_share_server(cs, args.share_server_id) - - new_share_net_id = None - if args.new_share_network: - share_net = _find_share_network(cs, args.new_share_network) - new_share_net_id = share_net.id - result = share_server.migration_check( - args.host, - args.writable, - args.nondisruptive, - args.preserve_snapshots, - new_share_net_id, - ) - cliutils.print_dict(result) - - -@cliutils.arg( - 'share_server_id', - metavar='', - help='ID of the share server to migrate.', -) -@cliutils.arg( - 'host', - metavar='', - help="Destination to migrate the share server to. Use the format " - "'@'.", -) -@cliutils.arg( - '--preserve-snapshots', - '--preserve_snapshots', - action='single_alias', - metavar='', - choices=['True', 'False'], - required=True, - help="Set to True if snapshots must be preserved at the migration " - "destination.", -) -@cliutils.arg( - '--writable', - metavar='', - choices=['True', 'False'], - required=True, - help="Enforces migration to keep all its shares writable while contents " - "are being moved.", -) -@cliutils.arg( - '--nondisruptive', - metavar='', - choices=['True', 'False'], - required=True, - help="Enforces migration to be nondisruptive.", -) -@cliutils.arg( - '--new_share_network', - '--new-share-network', - metavar='', - action='single_alias', - required=False, - help='Specify a new share network for the share server. Do not ' - 'specify this parameter if the migrating share server has ' - 'to be retained within its current share network.', - default=None, -) -@api_versions.wraps("2.57") -@api_versions.experimental_api -def do_share_server_migration_start(cs, args): - """Migrates share server to a new host (Admin only, Experimental).""" - share_server = _find_share_server(cs, args.share_server_id) - - new_share_net_id = None - if args.new_share_network: - share_net = _find_share_network(cs, args.new_share_network) - new_share_net_id = share_net.id - share_server.migration_start( - args.host, - args.writable, - args.nondisruptive, - args.preserve_snapshots, - new_share_net_id, - ) - - -@cliutils.arg( - 'share_server_id', - metavar='', - help='ID of share server to complete migration.', -) -@api_versions.wraps("2.57") -@api_versions.experimental_api -def do_share_server_migration_complete(cs, args): - """Completes migration for a given share server - - (Admin only, Experimental). - """ - share_server = _find_share_server(cs, args.share_server_id) - result = share_server.migration_complete() - cliutils.print_dict(result) - - -@cliutils.arg( - 'share_server_id', - metavar='', - help='ID of share server to complete migration.', -) -@api_versions.wraps("2.57") -@api_versions.experimental_api -def do_share_server_migration_cancel(cs, args): - """Cancels migration of a given share server when copying - - (Admin only, Experimental). - """ - share_server = _find_share_server(cs, args.share_server_id) - share_server.migration_cancel() - - -@cliutils.arg( - 'share_server_id', - metavar='', - help='ID of share server to complete migration.', -) -@cliutils.arg( - '--task-state', - '--task_state', - '--state', - metavar='', - default='None', - action='single_alias', - required=False, - help=( - 'Indicate which task state to assign the share server. Options: ' - 'migration_starting, migration_in_progress, migration_completing, ' - 'migration_success, migration_error, migration_cancel_in_progress, ' - 'migration_cancelled, migration_driver_in_progress, ' - 'migration_driver_phase1_done. If no value is provided, None will ' - 'be used.' - ), -) -@api_versions.wraps("2.57") -@api_versions.experimental_api -def do_share_server_reset_task_state(cs, args): - """Explicitly update the task state of a share - - (Admin only, Experimental). - """ - state = args.task_state - if args.task_state == 'None': - state = None - share_server = _find_share_server(cs, args.share_server_id) - share_server.reset_task_state(state) - - -@cliutils.arg( - 'share_server_id', - metavar='', - help='ID of share server to complete migration.', -) -@api_versions.wraps("2.57") -@api_versions.experimental_api -def do_share_server_migration_get_progress(cs, args): - """Gets migration progress of a given share server when copying - - (Admin only, Experimental). - """ - share_server = _find_share_server(cs, args.share_server_id) - result = share_server.migration_get_progress() - cliutils.print_dict(result) - - -@cliutils.arg( - 'share', - metavar='', - help='Name or ID of the share to update metadata on.', -) -@cliutils.arg( - 'action', - metavar='', - choices=['set', 'unset'], - help="Actions: 'set' or 'unset'.", -) -@cliutils.arg( - 'metadata', - metavar='', - nargs='+', - default=[], - help='Metadata to set or unset (only key is necessary to unset).', -) -def do_metadata(cs, args): - """Set or delete metadata on a share.""" - share = _find_share(cs, args.share) - metadata = _extract_metadata(args) - - if args.action == 'set': - share.set_metadata(metadata) - elif args.action == 'unset': - share.delete_metadata(sorted(list(metadata), reverse=True)) - - -@cliutils.arg('share', metavar='', help='Name or ID of the share.') -def do_metadata_show(cs, args): - """Show metadata of given share.""" - share = _find_share(cs, args.share) - metadata = share.get_metadata()._info - cliutils.print_dict(metadata, 'Property') - - -@cliutils.arg( - 'share', - metavar='', - help='Name or ID of the share to update metadata on.', -) -@cliutils.arg( - 'metadata', - metavar='', - nargs='+', - default=[], - help='Metadata entry or entries to update.', -) -def do_metadata_update_all(cs, args): - """Update all metadata of a share.""" - share = _find_share(cs, args.share) - metadata = _extract_metadata(args) - metadata = share.update_all_metadata(metadata)._info['metadata'] - cliutils.print_dict(metadata, 'Property') - - -@api_versions.wraps("2.9") -@cliutils.arg('share', metavar='', help='Name or ID of the share.') -@cliutils.arg( - '--columns', - metavar='', - type=str, - default=None, - help='Comma separated list of columns to be displayed ' - 'example --columns "id,host,status".', -) -def do_share_export_location_list(cs, args): - """List export locations of a given share.""" - if args.columns is not None: - list_of_keys = _split_columns(columns=args.columns) - else: - list_of_keys = [ - 'ID', - 'Path', - 'Preferred', - ] - share = _find_share(cs, args.share) - export_locations = cs.share_export_locations.list(share) - cliutils.print_list(export_locations, list_of_keys) - - -@api_versions.wraps("2.9") -@cliutils.arg('share', metavar='', help='Name or ID of the share.') -@cliutils.arg( - 'export_location', - metavar='', - help='ID of the share export location.', -) -def do_share_export_location_show(cs, args): - """Show export location of the share.""" - share = _find_share(cs, args.share) - export_location = cs.share_export_locations.get( - share, args.export_location - ) - view_data = export_location._info.copy() - cliutils.print_dict(view_data) - - -@cliutils.arg( - 'service_host', - metavar='', - type=str, - help='manage-share service host: some.host@driver#pool.', -) -@cliutils.arg( - 'protocol', - metavar='', - type=str, - help='Protocol of the share to manage, such as NFS or CIFS.', -) -@cliutils.arg( - 'export_path', - metavar='', - type=str, - help='Share export path, NFS share such as: 10.0.0.1:/example_path, ' - 'CIFS share such as: \\\\10.0.0.1\\example_cifs_share.', -) -@cliutils.arg( - '--name', - metavar='', - help='Optional share name. (Default=None)', - default=None, -) -@cliutils.arg( - '--description', - metavar='', - help='Optional share description. (Default=None)', - default=None, -) -@cliutils.arg( - '--share_type', - '--share-type', - metavar='', - default=None, - action='single_alias', - help='Optional share type assigned to share. (Default=None)', -) -@cliutils.arg( - '--driver_options', - '--driver-options', - type=str, - nargs='*', - metavar='', - action='single_alias', - help='Driver option key=value pairs (Optional, Default=None).', - default=None, -) -@cliutils.arg( - '--public', - dest='public', - action='store_true', - default=False, - help="Level of visibility for share. Defines whether other projects are " - "able to see it or not. Available only for microversion >= 2.8. " - "(Default=False)", -) -@cliutils.arg( - '--share_server_id', - '--share-server-id', - metavar='', - default=None, - action='single_alias', - help="Share server associated with share when using a share type with " - "'driver_handles_share_servers' extra_spec set to True. Available " - "only for microversion >= 2.49. (Default=None)", -) -@cliutils.arg('--wait', action='store_true', help='Wait for share management') -def do_manage(cs, args): - """Manage share not handled by Manila (Admin only).""" - driver_options = _extract_key_value_options(args, 'driver_options') - if cs.api_version.matches( - api_versions.APIVersion("2.49"), api_versions.APIVersion() - ): - share = cs.shares.manage( - args.service_host, - args.protocol, - args.export_path, - driver_options=driver_options, - share_type=args.share_type, - name=args.name, - description=args.description, - is_public=args.public, - share_server_id=args.share_server_id, - ) - else: - if args.share_server_id: - raise exceptions.CommandError( - "Invalid parameter " - "--share_server_id specified. This" - " parameter is only supported on" - " microversion 2.49 or newer." - ) - share = cs.shares.manage( - args.service_host, - args.protocol, - args.export_path, - driver_options=driver_options, - share_type=args.share_type, - name=args.name, - description=args.description, - is_public=args.public, - ) - - if args.wait: - share = _wait_for_resource_status( - cs, share, resource_type='share', expected_status='available' - ) - _print_share(cs, share) - - -@api_versions.wraps("2.49") -@cliutils.arg( - 'host', - metavar='', - type=str, - help='Backend name as "@".', -) -@cliutils.arg( - 'share_network', - metavar='', - help="Share network where share server has network allocations in.", -) -@cliutils.arg( - 'identifier', - metavar='', - type=str, - help='A driver-specific share server identifier required by the driver to ' - 'manage the share server.', -) -@cliutils.arg( - '--driver_options', - '--driver-options', - type=str, - nargs='*', - metavar='', - action='single_alias', - help='One or more driver-specific key=value pairs that may be necessary to' - ' manage the share server (Optional, Default=None).', - default=None, -) -@cliutils.arg( - '--share-network-subnet', - '--share_network_subnet', - type=str, - metavar='', - help="Share network subnet where share server has network allocations in. " - "The default subnet will be used if it's not specified. Available " - "for microversion >= 2.51 (Optional, Default=None).", - default=None, -) -@cliutils.arg( - '--wait', - action='store_true', - default='False', - help='Wait for share server to manage', -) -def do_share_server_manage(cs, args): - """Manage share server not handled by Manila (Admin only).""" - driver_options = _extract_key_value_options(args, 'driver_options') - - manage_kwargs = { - 'driver_options': driver_options, - } - if cs.api_version < api_versions.APIVersion("2.51"): - if getattr(args, 'share_network_subnet'): - raise exceptions.CommandError( - "Share network subnet option is only available with manila " - "API version >= 2.51" - ) - else: - manage_kwargs['share_network_subnet_id'] = args.share_network_subnet - - share_server = cs.share_servers.manage( - args.host, args.share_network, args.identifier, **manage_kwargs - ) - - if args.wait: - try: - _wait_for_resource_status( - cs, - share_server, - resource_type='share_server', - expected_status='active', - ) - except exceptions.CommandError as e: - print(e, file=sys.stderr) - - cliutils.print_dict(share_server._info) - - -@cliutils.arg( - 'share_server_id', - metavar='', - help='ID of the share server to modify.', -) -@cliutils.arg( - '--state', - metavar='', - default=constants.STATUS_ACTIVE, - help=( - 'Indicate which state to assign the share server. Options include ' - 'active, error, creating, deleting, managing, unmanaging, ' - 'manage_error and unmanage_error. If no state is provided, active ' - 'will be used.' - ), -) -@api_versions.wraps("2.49") -def do_share_server_reset_state(cs, args): - """Explicitly update the state of a share server (Admin only).""" - cs.share_servers.reset_state(args.share_server_id, args.state) - - -@api_versions.wraps("2.12") -@cliutils.arg( - 'share', metavar='', type=str, help='Name or ID of the share.' -) -@cliutils.arg( - 'provider_location', - metavar='', - type=str, - help='Provider location of the snapshot on the backend.', -) -@cliutils.arg( - '--name', - metavar='', - help='Optional snapshot name (Default=None).', - default=None, -) -@cliutils.arg( - '--description', - metavar='', - help='Optional snapshot description (Default=None).', - default=None, -) -@cliutils.arg( - '--driver_options', - '--driver-options', - type=str, - nargs='*', - metavar='', - action='single_alias', - help='Optional driver options as key=value pairs (Default=None).', - default=None, -) -@cliutils.arg( - '--wait', - action='store_true', - default=False, - help='Wait for share snapshot to be managed', -) -def do_snapshot_manage(cs, args): - """Manage share snapshot not handled by Manila (Admin only).""" - share_ref = _find_share(cs, args.share) - driver_options = _extract_key_value_options(args, 'driver_options') - - share_snapshot = cs.share_snapshots.manage( - share_ref, - args.provider_location, - driver_options=driver_options, - name=args.name, - description=args.description, - ) - - if args.wait: - try: - _wait_for_snapshot_status( - cs, share_snapshot, expected_status='available' - ) - except exceptions.CommandError as e: - print(e, file=sys.stderr) - _print_share_snapshot(cs, share_snapshot) - - -@cliutils.arg('share', metavar='', help='Name or ID of the share(s).') -@cliutils.arg( - '--wait', action='store_true', help='Wait for share unmanagement' -) -def do_unmanage(cs, args): - """Unmanage share (Admin only).""" - share_ref = _find_share(cs, args.share) - share_ref.unmanage() - if args.wait: - _wait_for_share_status(cs, share_ref, expected_status='unmanaged') - - -@api_versions.wraps("2.49") -@cliutils.arg( - 'share_server', - metavar='', - nargs='+', - help='ID of the share server(s).', -) -@cliutils.arg( - '--force', - dest='force', - action="store_true", - required=False, - default=False, - help="Enforces the unmanage share server operation, even if the back-end " - "driver does not support it.", -) -@cliutils.arg( - '--wait', - action='store_true', - default=False, - help='Wait for share server(s) to be unmanaged', -) -def do_share_server_unmanage(cs, args): - """Unmanage share server (Admin only).""" - failure_count = 0 - for server in args.share_server: - try: - cs.share_servers.unmanage(server, args.force) - if args.wait: - share_server_ref = _find_share_server(cs, server) - _wait_for_resource_status( - cs, - share_server_ref, - resource_type='share_server', - expected_status='unmanaged', - ) - except Exception as e: - failure_count += 1 - print( - f"Unmanage for share server {server} failed: {e}", - file=sys.stderr, - ) - - if failure_count == len(args.share_server): - raise exceptions.CommandError( - "Unable to unmanage any of the specified share servers." - ) - - -@api_versions.wraps("2.12") -@cliutils.arg( - 'snapshot', - metavar='', - nargs='+', - help='Name or ID of the snapshot(s).', -) -@cliutils.arg( - '--wait', - action='store_true', - default=False, - help='Wait for share snapshot to be unmanaged', -) -def do_snapshot_unmanage(cs, args): - """Unmanage one or more share snapshots (Admin only).""" - failure_count = 0 - for snapshot in args.snapshot: - try: - snapshot_ref = _find_share_snapshot(cs, snapshot) - snapshot_ref.unmanage_snapshot() - if args.wait: - _wait_for_snapshot_status( - cs, snapshot_ref, expected_status='deleted' - ) - except Exception as e: - failure_count += 1 - print( - f"Unmanage for share snapshot {snapshot} failed: {e}", - file=sys.stderr, - ) - - if failure_count == len(args.snapshot): - raise exceptions.CommandError( - "Unable to unmanage any of the specified snapshots." - ) - - -@api_versions.wraps("2.27") -@cliutils.arg( - 'snapshot', - metavar='', - help='Name or ID of the snapshot to restore. The snapshot must be the ' - 'most recent one known to manila.', -) -@cliutils.arg( - '--wait', - action='store_true', - default=False, - help='Wait for share to be reverted from snapshot.', -) -def do_revert_to_snapshot(cs, args): - """Revert a share to the specified snapshot.""" - snapshot = _find_share_snapshot(cs, args.snapshot) - share = _find_share(cs, snapshot.share_id) - share.revert_to_snapshot(snapshot) - if args.wait: - _wait_for_share_status(cs, share) - - -@cliutils.arg( - 'share', metavar='', nargs='+', help='Name or ID of the share(s).' -) -@cliutils.arg( - '--share-group', - '--share_group', - '--group', - metavar='', - action='single_alias', - help='Optional share group name or ID which contains the share ' - '(Default=None).', - default=None, -) -@cliutils.arg('--wait', action='store_true', help='Wait for share deletion') -@cliutils.service_type('sharev2') -def do_delete(cs, args): - """Remove one or more shares.""" - failure_count = 0 - shares_to_delete = [] - for share in args.share: - try: - share_ref = _find_share(cs, share) - shares_to_delete.append(share_ref) - if args.share_group: - share_group_id = _find_share_group(cs, args.share_group).id - cs.shares.delete(share_ref, share_group_id=share_group_id) - else: - cs.shares.delete(share_ref) - except Exception as e: - failure_count += 1 - print(f"Delete for share {share} failed: {e}", file=sys.stderr) - - if failure_count == len(args.share): - raise exceptions.CommandError( - "Unable to delete any of the specified shares." - ) - - if args.wait: - for share in shares_to_delete: - try: - _wait_for_share_status(cs, share, expected_status='deleted') - except exceptions.CommandError as e: - print(e, file=sys.stderr) - - -@cliutils.arg( - 'share', - metavar='', - nargs='+', - help='Name or ID of the share(s) to force delete.', -) -@cliutils.arg('--wait', action='store_true', help='Wait for share to delete') -@cliutils.service_type('sharev2') -def do_force_delete(cs, args): - """Attempt force-delete of share, regardless of state (Admin only).""" - failure_count = 0 - shares_to_delete = [] - for share in args.share: - try: - share_ref = _find_share(cs, share) - shares_to_delete.append(share_ref) - share_ref.force_delete() - except Exception as e: - failure_count += 1 - print(f"Delete for share {share} failed: {e}", file=sys.stderr) - if failure_count == len(args.share): - raise exceptions.CommandError( - "Unable to force delete any of specified shares." - ) - if args.wait: - for share in shares_to_delete: - try: - _wait_for_share_status(cs, share, expected_status='deleted') - except exceptions.CommandError as e: - print(e, file=sys.stderr) - - -@cliutils.arg( - 'share', metavar='', nargs='+', help='Name or ID of the share(s).' -) -@cliutils.service_type('sharev2') -@api_versions.wraps("2.69") -def do_soft_delete(cs, args): - """Soft delete one or more shares.""" - failure_count = 0 - - for share in args.share: - try: - share_ref = _find_share(cs, share) - cs.shares.soft_delete(share_ref) - except Exception as e: - failure_count += 1 - print( - f"Soft deletion of share {share} failed: {e}", - file=sys.stderr, - ) - - if failure_count == len(args.share): - raise exceptions.CommandError( - "Unable to soft delete any of the specified shares." - ) - - -@cliutils.arg( - 'share', metavar='', nargs='+', help='Name or ID of the share(s).' -) -@cliutils.service_type('sharev2') -@api_versions.wraps("2.69") -def do_restore(cs, args): - """Restore one or more shares from recycle bin.""" - failure_count = 0 - - for share in args.share: - try: - share_ref = _find_share(cs, share) - cs.shares.restore(share_ref) - except Exception as e: - failure_count += 1 - print( - f"Restoration of share {share} failed: {e}", - file=sys.stderr, - ) - - if failure_count == len(args.share): - raise exceptions.CommandError( - "Unable to restore any of the specified shares." - ) - - -@api_versions.wraps("1.0", "2.8") -@cliutils.arg('share', metavar='', help='Name or ID of the NAS share.') -def do_show(cs, args): - """Show details about a NAS share.""" - share = _find_share(cs, args.share) - _print_share(cs, share) - - -@api_versions.wraps("2.9") # noqa -@cliutils.arg('share', metavar='', help='Name or ID of the NAS share.') -def do_show(cs, args): # noqa - """Show details about a NAS share.""" - share = _find_share(cs, args.share) - export_locations = cs.share_export_locations.list(share) - share._info['export_locations'] = export_locations - _print_share(cs, share) - - -@cliutils.arg( - 'share', metavar='', help='Name or ID of the NAS share to modify.' -) -@cliutils.arg( - 'access_type', - metavar='', - help='Access rule type (only "ip", "user"(user or group), "cert" or ' - '"cephx" are supported).', -) -@cliutils.arg( - 'access_to', metavar='', help='Value that defines access.' -) -@cliutils.arg( - '--access-level', - '--access_level', # alias - metavar='', - type=str, - default=None, - choices=['rw', 'ro'], - action='single_alias', - help='Share access level ("rw" and "ro" access levels are supported). ' - 'Defaults to rw.', -) -@cliutils.arg( - '--metadata', - type=str, - nargs='*', - metavar='', - help='Space Separated list of key=value pairs of metadata items. ' - 'OPTIONAL: Default=None. Available only for microversion >= 2.45.', - default=None, -) -@cliutils.arg( - '--wait', - action='store_true', - help='Wait for share access to become active', -) -def do_access_allow(cs, args): - """Allow access to a given share.""" - access_metadata = None - if cs.api_version.matches( - api_versions.APIVersion("2.45"), api_versions.APIVersion() - ): - access_metadata = _extract_metadata(args) - elif getattr(args, 'metadata'): - raise exceptions.CommandError( - "Adding metadata to access rules is supported only beyond " - "API version 2.45" - ) - - share = _find_share(cs, args.share) - access = share.allow( - args.access_type, args.access_to, args.access_level, access_metadata - ) - if args.wait: - try: - if not cs.api_version.matches( - api_versions.APIVersion("2.45"), api_versions.APIVersion() - ): - raise exceptions.CommandError( - "Waiting on the allowing access operation is only " - "available for API versions equal to or greater than 2.45." - ) - access_id = access.get('id') - share_access_rule = cs.share_access_rules.get(access_id) - access = _wait_for_resource_status( - cs, - share_access_rule, - resource_type='share_access_rule', - expected_status='active', - status_attr='state', - )._info - except exceptions.CommandError as e: - print(e, file=sys.stderr) - cliutils.print_dict(access) - - -@api_versions.wraps("2.45") -@cliutils.arg( - 'access_id', metavar='', help='ID of the NAS share access rule.' -) -def do_access_show(cs, args): - """Show details about a NAS share access rule.""" - access = cs.share_access_rules.get(args.access_id) - view_data = access._info.copy() - cliutils.print_dict(view_data) - - -@api_versions.wraps("2.45") -@cliutils.arg( - 'access_id', metavar='', help='ID of the NAS share access rule.' -) -@cliutils.arg( - 'action', - metavar='', - choices=['set', 'unset'], - help="Actions: 'set' or 'unset'.", -) -@cliutils.arg( - 'metadata', - metavar='', - nargs='+', - default=[], - help='Space separated key=value pairs of metadata items to set. ' - 'To unset only keys are required. ', -) -def do_access_metadata(cs, args): - """Set or delete metadata on a share access rule.""" - share_access = cs.share_access_rules.get(args.access_id) - metadata = _extract_metadata(args) - - if args.action == 'set': - cs.share_access_rules.set_metadata(share_access, metadata) - elif args.action == 'unset': - cs.share_access_rules.unset_metadata( - share_access, sorted(list(metadata), reverse=True) - ) - - -@api_versions.wraps("2.32") -@cliutils.arg( - 'snapshot', - metavar='', - help='Name or ID of the share snapshot to allow access to.', -) -@cliutils.arg( - 'access_type', - metavar='', - help='Access rule type (only "ip", "user"(user or group), "cert" or ' - '"cephx" are supported).', -) -@cliutils.arg( - 'access_to', metavar='', help='Value that defines access.' -) -def do_snapshot_access_allow(cs, args): - """Allow read only access to a snapshot.""" - share_snapshot = _find_share_snapshot(cs, args.snapshot) - access = share_snapshot.allow(args.access_type, args.access_to) - cliutils.print_dict(access) - - -@cliutils.arg( - 'share', metavar='', help='Name or ID of the NAS share to modify.' -) -@cliutils.arg( - 'id', metavar='', help='ID of the access rule to be deleted.' -) -def do_access_deny(cs, args): - """Deny access to a share.""" - share = _find_share(cs, args.share) - share.deny(args.id) - - -@api_versions.wraps("2.32") -@cliutils.arg( - 'snapshot', - metavar='', - help='Name or ID of the share snapshot to deny access to.', -) -@cliutils.arg( - 'id', - metavar='', - nargs='+', - help='ID(s) of the access rule(s) to be deleted.', -) -def do_snapshot_access_deny(cs, args): - """Deny access to a snapshot.""" - failure_count = 0 - snapshot = _find_share_snapshot(cs, args.snapshot) - for access_id in args.id: - try: - snapshot.deny(access_id) - except Exception as e: - failure_count += 1 - print( - f"Failed to remove rule {access_id}: {e}.", - file=sys.stderr, - ) - - if failure_count == len(args.id): - raise exceptions.CommandError( - "Unable to delete any of the specified snapshot rules." - ) - - -@api_versions.wraps("1.0", "2.20") -@cliutils.arg('share', metavar='', help='Name or ID of the share.') -@cliutils.arg( - '--columns', - metavar='', - type=str, - default=None, - help='Comma separated list of columns to be displayed ' - 'example --columns "access_type,access_to".', -) -def do_access_list(cs, args): - """Show access list for share.""" - list_of_keys = [ - 'id', - 'access_type', - 'access_to', - 'access_level', - 'state', - ] - - if args.columns is not None: - list_of_keys = _split_columns(columns=args.columns) - - share = _find_share(cs, args.share) - access_list = share.access_list() - cliutils.print_list(access_list, list_of_keys) - - -@api_versions.wraps("2.21") # noqa -@cliutils.arg('share', metavar='', help='Name or ID of the share.') -@cliutils.arg( - '--columns', - metavar='', - type=str, - default=None, - help='Comma separated list of columns to be displayed ' - 'example --columns "access_type,access_to".', -) -def do_access_list(cs, args): # noqa - """Show access list for share.""" - list_of_keys = [ - 'id', - 'access_type', - 'access_to', - 'access_level', - 'state', - 'access_key', - ] - - if args.columns is not None: - list_of_keys = _split_columns(columns=args.columns) - - share = _find_share(cs, args.share) - access_list = share.access_list() - cliutils.print_list(access_list, list_of_keys) - - -@api_versions.wraps("2.33") # noqa -@cliutils.arg('share', metavar='', help='Name or ID of the share.') -@cliutils.arg( - '--columns', - metavar='', - type=str, - default=None, - help='Comma separated list of columns to be displayed ' - 'example --columns "access_type,access_to".', -) -@cliutils.arg( - '--metadata', - type=str, - nargs='*', - metavar='', - help='Filters results by a metadata key and value. OPTIONAL: ' - 'Default=None. Available only for microversion >= 2.45', - default=None, -) -def do_access_list(cs, args): # noqa - """Show access list for share.""" - list_of_keys = [ - 'id', - 'access_type', - 'access_to', - 'access_level', - 'state', - 'access_key', - 'created_at', - 'updated_at', - ] - - share = _find_share(cs, args.share) - if cs.api_version < api_versions.APIVersion("2.45"): - if getattr(args, 'metadata'): - raise exceptions.CommandError( - "Filtering access rules by metadata is supported only beyond " - "API version 2.45" - ) - access_list = share.access_list() - else: - access_list = cs.share_access_rules.access_list( - share, {'metadata': _extract_metadata(args)} - ) - if args.columns is not None: - list_of_keys = _split_columns(columns=args.columns) - cliutils.print_list(access_list, list_of_keys) - - -@api_versions.wraps("2.32") -@cliutils.arg( - 'snapshot', - metavar='', - help='Name or ID of the share snapshot to list access of.', -) -@cliutils.arg( - '--columns', - metavar='', - type=str, - default=None, - help='Comma separated list of columns to be displayed ' - 'example --columns "access_type,access_to".', -) -def do_snapshot_access_list(cs, args): - """Show access list for a snapshot.""" - if args.columns is not None: - list_of_keys = _split_columns(columns=args.columns) - else: - list_of_keys = ['id', 'access_type', 'access_to', 'state'] - - snapshot = _find_share_snapshot(cs, args.snapshot) - access_list = snapshot.access_list() - cliutils.print_list(access_list, list_of_keys) - - -@cliutils.arg( - '--all-tenants', - '--all-projects', - action='single_alias', - dest='all_projects', - metavar='<0|1>', - nargs='?', - type=int, - const=1, - default=0, - help='Display information from all projects (Admin only).', -) -@cliutils.arg( - '--name', - metavar='', - type=str, - default=None, - help='Filter results by name.', -) -@cliutils.arg( - '--description', - metavar='', - type=str, - default=None, - help='Filter results by description. ' - 'Available only for microversion >= 2.36.', -) -@cliutils.arg( - '--name~', - metavar='', - type=str, - default=None, - help='Filter results matching a share name pattern. ' - 'Available only for microversion >= 2.36.', -) -@cliutils.arg( - '--description~', - metavar='', - type=str, - default=None, - help='Filter results matching a share description pattern. ' - 'Available only for microversion >= 2.36.', -) -@cliutils.arg( - '--status', - metavar='', - type=str, - default=None, - help='Filter results by status.', -) -@cliutils.arg( - '--share-server-id', - '--share-server_id', - '--share_server-id', - '--share_server_id', # aliases - metavar='', - type=str, - default=None, - action='single_alias', - help='Filter results by share server ID (Admin only).', -) -@cliutils.arg( - '--metadata', - type=str, - nargs='*', - metavar='', - help='Filters results by a metadata key and value. OPTIONAL: ' - 'Default=None.', - default=None, -) -@cliutils.arg( - '--extra-specs', - '--extra_specs', # alias - type=str, - nargs='*', - metavar='', - action='single_alias', - help='Filters results by a extra specs key and value of share type that ' - 'was used for share creation. OPTIONAL: Default=None.', - default=None, -) -@cliutils.arg( - '--share-type', - '--volume-type', - '--share_type', - '--share-type-id', - '--volume-type-id', # aliases - '--share-type_id', - '--share_type-id', - '--share_type_id', # aliases - '--volume_type', - '--volume_type_id', - metavar='', - type=str, - default=None, - action='single_alias', - help='Filter results by a share type id or name that was used for share ' - 'creation.', -) -@cliutils.arg( - '--limit', - metavar='', - type=int, - default=None, - help='Maximum number of shares to return. OPTIONAL: Default=None.', -) -@cliutils.arg( - '--offset', - metavar='', - type=int, - default=None, - help='Set offset to define start point of share listing. ' - 'OPTIONAL: Default=None.', -) -@cliutils.arg( - '--sort-key', - '--sort_key', # alias - metavar='', - type=str, - default=None, - action='single_alias', - help=( - f'Key to be sorted, available keys are ' - f'{constants.SHARE_SORT_KEY_VALUES}. ' - 'OPTIONAL: Default=None.' - ), -) -@cliutils.arg( - '--sort-dir', - '--sort_dir', # alias - metavar='', - type=str, - default=None, - action='single_alias', - help=f'Sort direction, available values are {constants.SORT_DIR_VALUES}. ' - 'OPTIONAL: Default=None.', -) -@cliutils.arg( - '--snapshot', - metavar='', - type=str, - default=None, - help='Filer results by snapshot name or id, that was used for share.', -) -@cliutils.arg( - '--host', metavar='', default=None, help='Filter results by host.' -) -@cliutils.arg( - '--share-network', - '--share_network', # alias - metavar='', - type=str, - default=None, - action='single_alias', - help='Filter results by share-network name or id.', -) -@cliutils.arg( - '--project-id', - '--project_id', # alias - metavar='', - type=str, - default=None, - action='single_alias', - help="Filter results by project id. Useful with set key '--all-projects'.", -) -@cliutils.arg( - '--public', - dest='public', - action='store_true', - default=False, - help="Add public shares from all projects to result. (Default=False)", -) -@cliutils.arg( - '--share-group', - '--share_group', - '--group', - metavar='', - type=str, - default=None, - action='single_alias', - help='Filter results by share group name or ID (Default=None).', -) -@cliutils.arg( - '--columns', - metavar='', - type=str, - default=None, - help='Comma separated list of columns to be displayed ' - 'example --columns "export_location,is public".', -) -@cliutils.arg( - '--export-location', - '--export_location', - metavar='', - type=str, - default=None, - action='single_alias', - help='ID or path of the share export location. ' - 'Available only for microversion >= 2.35.', -) -@cliutils.arg( - '--count', - dest='count', - metavar='', - choices=['True', 'False'], - default=False, - help='Display total number of shares to return. ' - 'Available only for microversion >= 2.42.', -) -@cliutils.arg( - '--soft-deleted', - '--soft_deleted', - action='store_true', - help='Get shares in recycle bin. If this parameter is set to ' - 'True(Default=False), will only show shares in recycle bin. ' - 'Available only for microversion >= 2.69.', -) -@cliutils.service_type('sharev2') -def do_list(cs, args): - """List NAS shares with filters.""" - - columns = args.columns - all_projects = int( - os.environ.get( - "ALL_TENANTS", os.environ.get("ALL_PROJECTS", args.all_projects) - ) - ) - if columns is not None: - list_of_keys = _split_columns(columns=columns) - else: - list_of_keys = [ - 'ID', - 'Name', - 'Size', - 'Share Proto', - 'Status', - 'Is Public', - 'Share Type Name', - 'Host', - 'Availability Zone', - ] - if all_projects or args.public: - list_of_keys.append('Project ID') - - empty_obj = type('Empty', (object,), {'id': None}) - share_type = ( - _find_share_type(cs, args.share_type) if args.share_type else empty_obj - ) - - snapshot = ( - _find_share_snapshot(cs, args.snapshot) if args.snapshot else empty_obj - ) - - share_network = ( - _find_share_network(cs, args.share_network) - if args.share_network - else empty_obj - ) - - share_group = None - if args.share_group: - share_group = _find_share_group(cs, args.share_group) - - search_opts = { - 'offset': args.offset, - 'limit': args.limit, - 'all_tenants': all_projects, - 'name': args.name, - 'status': args.status, - 'host': args.host, - 'share_network_id': share_network.id, - 'snapshot_id': snapshot.id, - 'share_type_id': share_type.id, - 'metadata': _extract_metadata(args, allow_empty_key=False), - 'extra_specs': _extract_extra_specs(args), - 'share_server_id': args.share_server_id, - 'project_id': args.project_id, - 'is_public': args.public, - } - if cs.api_version.matches( - api_versions.APIVersion("2.36"), api_versions.APIVersion() - ): - search_opts['name~'] = getattr(args, 'name~') - search_opts['description~'] = getattr(args, 'description~') - search_opts['description'] = getattr(args, 'description') - elif ( - getattr(args, 'name~') - or getattr(args, 'description~') - or getattr(args, 'description') - ): - raise exceptions.CommandError( - "Pattern based filtering (name~, description~ and description)" - " is only available with manila API version >= 2.36" - ) - - if cs.api_version.matches( - api_versions.APIVersion("2.35"), api_versions.APIVersion() - ): - search_opts['export_location'] = args.export_location - elif args.export_location: - raise exceptions.CommandError( - "Filtering by export location is only " - "available with manila API version >= 2.35" - ) - - if args.count and cs.api_version.matches( - api_versions.APIVersion(), api_versions.APIVersion("2.41") - ): - raise exceptions.CommandError( - "Display total number of shares is only " - "available with manila API version >= 2.42" - ) - - if cs.api_version.matches( - api_versions.APIVersion("2.69"), api_versions.APIVersion() - ): - if args.soft_deleted: - search_opts['is_soft_deleted'] = args.soft_deleted - elif args.soft_deleted: - raise exceptions.CommandError( - "Filtering by is_soft_deleted is only " - "available with manila API version >= 2.69" - ) - - if share_group: - search_opts['share_group_id'] = share_group.id - - total_count = 0 - if strutils.bool_from_string(args.count, strict=True): - search_opts['with_count'] = args.count - shares, total_count = cs.shares.list( - search_opts=search_opts, - sort_key=args.sort_key, - sort_dir=args.sort_dir, - ) - else: - shares = cs.shares.list( - search_opts=search_opts, - sort_key=args.sort_key, - sort_dir=args.sort_dir, - ) - # When shell input is "--metadata None", filter metadata={} - if shares and args.metadata: - if "None" in args.metadata: - shares = [share for share in shares if share.metadata == {}] - # NOTE(vponomaryov): usage of 'export_location' and - # 'export_locations' columns may cause scaling issue using API 2.9+ and - # when lots of shares are returned. - if ( - shares - and columns is not None - and 'export_location' in columns - and not hasattr(shares[0], 'export_location') - ): - # NOTE(vponomaryov): we will get here only using API 2.9+ - for share in shares: - els_objs = cs.share_export_locations.list(share) - els = [el.to_dict()['path'] for el in els_objs] - setattr(share, 'export_locations', els) - setattr(share, 'export_location', els[0] if els else None) - cliutils.print_list(shares, list_of_keys, sortby_index=None) - if args.count: - print(f"Shares in total: {total_count}") - - with cs.shares.completion_cache( - 'uuid', manilaclient.v2.shares.Share, mode="w" - ): - for share in shares: - cs.shares.write_to_completion_cache('uuid', share.id) - - with cs.shares.completion_cache( - 'name', manilaclient.v2.shares.Share, mode="w" - ): - for share in shares: - if share.name is not None: - cs.shares.write_to_completion_cache('name', share.name) - - -@cliutils.arg( - '--share-id', - '--share_id', # alias - metavar='', - default=None, - action='single_alias', - help='Filter results by share ID.', -) -@cliutils.arg( - '--columns', - metavar='', - type=str, - default=None, - help='Comma separated list of columns to be displayed ' - 'example --columns "id,host,status".', -) -@cliutils.arg( - '--export-location', - '--export_location', - metavar='', - type=str, - default=None, - action='single_alias', - help='ID or path of the share instance export location. ' - 'Available only for microversion >= 2.35.', -) -@api_versions.wraps("2.3") -def do_share_instance_list(cs, args): - """List share instances (Admin only).""" - share = _find_share(cs, args.share_id) if args.share_id else None - - list_of_keys = [ - 'ID', - 'Share ID', - 'Host', - 'Status', - 'Availability Zone', - 'Share Network ID', - 'Share Server ID', - 'Share Type ID', - ] - - if args.columns is not None: - list_of_keys = _split_columns(columns=args.columns) - - if share: - instances = cs.shares.list_instances(share) - else: - if cs.api_version.matches( - api_versions.APIVersion("2.35"), api_versions.APIVersion() - ): - instances = cs.share_instances.list(args.export_location) - else: - if args.export_location: - raise exceptions.CommandError( - "Filtering by export location is only " - "available with manila API version >= 2.35" - ) - instances = cs.share_instances.list() - - cliutils.print_list(instances, list_of_keys) - - -@api_versions.wraps("2.3", "2.8") -@cliutils.arg( - 'instance', metavar='', help='Name or ID of the share instance.' -) -def do_share_instance_show(cs, args): - """Show details about a share instance.""" - instance = _find_share_instance(cs, args.instance) - _print_share_instance(cs, instance) - - -@api_versions.wraps("2.9") # noqa -@cliutils.arg( - 'instance', metavar='', help='Name or ID of the share instance.' -) -def do_share_instance_show(cs, args): # noqa - """Show details about a share instance (Admin only).""" - instance = _find_share_instance(cs, args.instance) - export_locations = cs.share_instance_export_locations.list(instance) - instance._info['export_locations'] = export_locations - _print_share_instance(cs, instance) - - -@cliutils.arg( - 'instance', - metavar='', - nargs='+', - help='Name or ID of the instance(s) to force delete.', -) -@api_versions.wraps("2.3") -@cliutils.arg( - '--wait', action='store_true', help='Wait for share instance deletion' -) -@cliutils.service_type('sharev2') -def do_share_instance_force_delete(cs, args): - """Force-delete the share instance, regardless of state (Admin only).""" - failure_count = 0 - instances_to_delete = [] - for instance in args.instance: - try: - instance_ref = _find_share_instance(cs, instance) - instances_to_delete.append(instance_ref) - instance_ref.force_delete() - except Exception as e: - failure_count += 1 - print( - f"Delete for share instance {instance} failed: {e}", - file=sys.stderr, - ) - if failure_count == len(args.instance): - raise exceptions.CommandError( - "Unable to force delete any of specified share instances." - ) - if args.wait: - for instance in instances_to_delete: - try: - _wait_for_resource_status( - cs, - instance, - resource_type='share_instance', - expected_status='deleted', - ) - except exceptions.CommandError as e: - print(e, file=sys.stderr) - - -@cliutils.arg( - 'instance', - metavar='', - help='Name or ID of the share instance to modify.', -) -@cliutils.arg( - '--state', - metavar='', - default='available', - help=( - 'Indicate which state to assign the instance. Options include ' - 'available, error, creating, deleting, error_deleting, migrating,' - 'migrating_to. If no state is provided, available will be used.' - ), -) -@api_versions.wraps("2.3") -def do_share_instance_reset_state(cs, args): - """Explicitly update the state of a share instance (Admin only).""" - instance = _find_share_instance(cs, args.instance) - instance.reset_state(args.state) - - -@api_versions.wraps("2.9") -@cliutils.arg( - 'instance', metavar='', help='Name or ID of the share instance.' -) -@cliutils.arg( - '--columns', - metavar='', - type=str, - default=None, - help='Comma separated list of columns to be displayed ' - 'example --columns "id,host,status".', -) -def do_share_instance_export_location_list(cs, args): - """List export locations of a given share instance.""" - if args.columns is not None: - list_of_keys = _split_columns(columns=args.columns) - else: - list_of_keys = [ - 'ID', - 'Path', - 'Is Admin only', - 'Preferred', - ] - instance = _find_share_instance(cs, args.instance) - export_locations = cs.share_instance_export_locations.list(instance) - cliutils.print_list(export_locations, list_of_keys) - - -@api_versions.wraps("2.9") -@cliutils.arg( - 'instance', metavar='', help='Name or ID of the share instance.' -) -@cliutils.arg( - 'export_location', - metavar='', - help='ID of the share instance export location.', -) -def do_share_instance_export_location_show(cs, args): - """Show export location for the share instance.""" - instance = _find_share_instance(cs, args.instance) - export_location = cs.share_instance_export_locations.get( - instance, args.export_location - ) - view_data = export_location._info.copy() - cliutils.print_dict(view_data) - - -@cliutils.arg( - '--all-tenants', - '--all-projects', - action='single_alias', - dest='all_projects', - metavar='<0|1>', - nargs='?', - type=int, - const=1, - default=0, - help='Display information from all projects (Admin only).', -) -@cliutils.arg( - '--name', - metavar='', - type=str, - default=None, - help='Filter results by name.', -) -@cliutils.arg( - '--description', - metavar='', - type=str, - default=None, - help='Filter results by description. ' - 'Available only for microversion >= 2.36.', -) -@cliutils.arg( - '--status', - metavar='', - default=None, - help='Filter results by status.', -) -@cliutils.arg( - '--share-id', - '--share_id', # alias - metavar='', - default=None, - action='single_alias', - help='Filter results by source share ID.', -) -@cliutils.arg( - '--usage', - dest='usage', - metavar='any|used|unused', - nargs='?', - type=str, - const='any', - default=None, - choices=[ - 'any', - 'used', - 'unused', - ], - help='Either filter or not snapshots by its usage. OPTIONAL: Default=any.', -) -@cliutils.arg( - '--limit', - metavar='', - type=int, - default=None, - help='Maximum number of share snapshots to return. ' - 'OPTIONAL: Default=None.', -) -@cliutils.arg( - '--offset', - metavar='', - type=int, - default=None, - help='Set offset to define start point of share snapshots listing. ' - 'OPTIONAL: Default=None.', -) -@cliutils.arg( - '--sort-key', - '--sort_key', # alias - metavar='', - type=str, - default=None, - action='single_alias', - help=( - f'Key to be sorted, available keys are ' - f'{constants.SNAPSHOT_SORT_KEY_VALUES}. ' - 'Default=None.' - ), -) -@cliutils.arg( - '--sort-dir', - '--sort_dir', # alias - metavar='', - type=str, - default=None, - action='single_alias', - help=f'Sort direction, available values are {constants.SORT_DIR_VALUES}. ' - 'OPTIONAL: Default=None.', -) -@cliutils.arg( - '--columns', - metavar='', - type=str, - default=None, - help='Comma separated list of columns to be displayed ' - 'example --columns "id,name".', -) -@cliutils.arg( - '--name~', - metavar='', - type=str, - default=None, - help='Filter results matching a share snapshot name pattern. ' - 'Available only for microversion >= 2.36.', -) -@cliutils.arg( - '--description~', - metavar='', - type=str, - default=None, - help='Filter results matching a share snapshot description pattern. ' - 'Available only for microversion >= 2.36.', -) -@cliutils.arg( - '--metadata', - metavar='', - type=str, - default=None, - nargs='*', - help='Filters results by a metadata key and value. OPTIONAL: ' - 'Default=None, Available only for microversion >= 2.73. ', -) -@cliutils.arg( - '--count', - dest='count', - metavar='', - choices=['True', 'False'], - default=False, - help='Display total number of share snapshots to return. ' - 'Available only for microversion >= 2.79.', -) -def do_snapshot_list(cs, args): - """List all the snapshots.""" - all_projects = int( - os.environ.get( - "ALL_TENANTS", os.environ.get("ALL_PROJECTS", args.all_projects) - ) - ) - if args.columns is not None: - list_of_keys = _split_columns(columns=args.columns) - else: - list_of_keys = [ - 'ID', - 'Share ID', - 'Status', - 'Name', - 'Share Size', - ] - if all_projects: - list_of_keys.append('Project ID') - - empty_obj = type('Empty', (object,), {'id': None}) - share = _find_share(cs, args.share_id) if args.share_id else empty_obj - search_opts = { - 'offset': args.offset, - 'limit': args.limit, - 'all_tenants': all_projects, - 'name': args.name, - 'status': args.status, - 'share_id': share.id, - 'usage': args.usage, - 'metadata': _extract_metadata(args), - } - if cs.api_version.matches( - api_versions.APIVersion("2.36"), api_versions.APIVersion() - ): - search_opts['name~'] = getattr(args, 'name~') - search_opts['description~'] = getattr(args, 'description~') - search_opts['description'] = getattr(args, 'description') - elif ( - getattr(args, 'name~') - or getattr(args, 'description~') - or getattr(args, 'description') - ): - raise exceptions.CommandError( - "Pattern based filtering (name~, description~ and description)" - " is only available with manila API version >= 2.36" - ) - - if args.count and cs.api_version.matches( - api_versions.APIVersion(), api_versions.APIVersion("2.78") - ): - raise exceptions.CommandError( - "Display total number of share snapshots is only " - "available with manila API version >= 2.79" - ) - - total_count = 0 - if strutils.bool_from_string(args.count, strict=True): - search_opts['with_count'] = args.count - snapshots, total_count = cs.share_snapshots.list( - search_opts=search_opts, - sort_key=args.sort_key, - sort_dir=args.sort_dir, - ) - else: - snapshots = cs.share_snapshots.list( - search_opts=search_opts, - sort_key=args.sort_key, - sort_dir=args.sort_dir, - ) - - cliutils.print_list(snapshots, list_of_keys, sortby_index=None) - if args.count: - print(f"Share snapshots in total: {total_count}") - - -@cliutils.arg( - 'snapshot', metavar='', help='Name or ID of the snapshot.' -) -def do_snapshot_show(cs, args): - """Show details about a snapshot.""" - snapshot = _find_share_snapshot(cs, args.snapshot) - export_locations = cs.share_snapshot_export_locations.list( - snapshot=snapshot - ) - snapshot._info['export_locations'] = export_locations - _print_share_snapshot(cs, snapshot) - - -@api_versions.wraps("2.32") -@cliutils.arg( - 'snapshot', metavar='', help='Name or ID of the snapshot.' -) -@cliutils.arg( - '--columns', - metavar='', - type=str, - default=None, - help='Comma separated list of columns to be displayed ' - 'example --columns "id,path".', -) -def do_snapshot_export_location_list(cs, args): - """List export locations of a given snapshot.""" - if args.columns is not None: - list_of_keys = _split_columns(columns=args.columns) - else: - list_of_keys = [ - 'ID', - 'Path', - ] - snapshot = _find_share_snapshot(cs, args.snapshot) - export_locations = cs.share_snapshot_export_locations.list(snapshot) - cliutils.print_list(export_locations, list_of_keys) - - -@api_versions.wraps("2.32") -@cliutils.arg( - 'instance', - metavar='', - help='Name or ID of the snapshot instance.', -) -@cliutils.arg( - '--columns', - metavar='', - type=str, - default=None, - help='Comma separated list of columns to be displayed ' - 'example --columns "id,path,is_admin_only".', -) -def do_snapshot_instance_export_location_list(cs, args): - """List export locations of a given snapshot instance.""" - if args.columns is not None: - list_of_keys = _split_columns(columns=args.columns) - else: - list_of_keys = [ - 'ID', - 'Path', - 'Is Admin only', - ] - instance = _find_share_snapshot_instance(cs, args.instance) - export_locations = cs.share_snapshot_instance_export_locations.list( - instance - ) - cliutils.print_list(export_locations, list_of_keys) - - -@api_versions.wraps("2.32") -@cliutils.arg( - 'snapshot', metavar='', help='Name or ID of the snapshot.' -) -@cliutils.arg( - 'export_location', - metavar='', - help='ID of the share snapshot export location.', -) -def do_snapshot_export_location_show(cs, args): - """Show export location of the share snapshot.""" - snapshot = _find_share_snapshot(cs, args.snapshot) - export_location = cs.share_snapshot_export_locations.get( - args.export_location, snapshot - ) - view_data = export_location._info.copy() - cliutils.print_dict(view_data) - - -@api_versions.wraps("2.32") -@cliutils.arg( - 'snapshot_instance', - metavar='', - help='ID of the share snapshot instance.', -) -@cliutils.arg( - 'export_location', - metavar='', - help='ID of the share snapshot instance export location.', -) -def do_snapshot_instance_export_location_show(cs, args): - """Show export location of the share instance snapshot.""" - snapshot_instance = _find_share_snapshot_instance( - cs, args.snapshot_instance - ) - export_location = cs.share_snapshot_instance_export_locations.get( - args.export_location, snapshot_instance - ) - - view_data = export_location._info.copy() - cliutils.print_dict(view_data) - - -@cliutils.arg( - 'share', metavar='', help='Name or ID of the share to snapshot.' -) -@cliutils.arg( - '--force', - metavar='', - help='Optional flag to indicate whether ' - 'to snapshot a share even if it\'s busy. ' - '(Default=False)', - default=False, -) -@cliutils.arg( - '--name', - metavar='', - default=None, - help='Optional snapshot name. (Default=None)', -) -@cliutils.arg( - '--description', - metavar='', - default=None, - help='Optional snapshot description. (Default=None)', -) -@cliutils.arg( - '--wait', - action='store_true', - default=False, - help='Wait for snapshot to be created.', -) -def do_snapshot_create(cs, args): - """Add a new snapshot.""" - share = _find_share(cs, args.share) - snapshot = cs.share_snapshots.create( - share, args.force, args.name, args.description - ) - if args.wait: - try: - _wait_for_snapshot_status( - cs, snapshot, expected_status='available' - ) - except exceptions.CommandError as e: - print(e, file=sys.stderr) - _print_share_snapshot(cs, snapshot) - - -@cliutils.arg( - 'share', metavar='', help='Name or ID of the share to rename.' -) -@cliutils.arg( - '--name', metavar='', default=None, help='New name for the share.' -) -@cliutils.arg( - '--description', - metavar='', - help='Optional share description. (Default=None)', - default=None, -) -@cliutils.arg( - '--is-public', - '--is_public', # alias - metavar='', - default=None, - type=str, - action="single_alias", - help='Public share is visible for all projects.', -) -def do_update(cs, args): - """Rename a share.""" - kwargs = {} - - if args.name is not None: - kwargs['display_name'] = args.name - if args.description is not None: - kwargs['display_description'] = args.description - if args.is_public is not None: - kwargs['is_public'] = strutils.bool_from_string( - args.is_public, strict=True - ) - if not kwargs: - msg = "Must supply name, description or is_public value." - raise exceptions.CommandError(msg) - _find_share(cs, args.share).update(**kwargs) - - -@cliutils.arg( - 'snapshot', - metavar='', - help='Name or ID of the snapshot to rename.', -) -@cliutils.arg( - 'name', nargs='?', metavar='', help='New name for the snapshot.' -) -@cliutils.arg( - '--description', - metavar='', - help='Optional snapshot description. (Default=None)', - default=None, -) -def do_snapshot_rename(cs, args): - """Rename a snapshot.""" - kwargs = {} - - if args.name is not None: - kwargs['display_name'] = args.name - if args.description is not None: - kwargs['display_description'] = args.description - if not kwargs: - msg = "Must supply either name or description." - raise exceptions.CommandError(msg) - _find_share_snapshot(cs, args.snapshot).update(**kwargs) - - -@cliutils.arg( - 'snapshot', - metavar='', - nargs='+', - help='Name or ID of the snapshot(s) to delete.', -) -@cliutils.arg( - '--wait', - action='store_true', - default=False, - help='Wait for snapshot to be deleted', -) -def do_snapshot_delete(cs, args): - """Remove one or more snapshots.""" - failure_count = 0 - - for snapshot in args.snapshot: - try: - snapshot_ref = _find_share_snapshot(cs, snapshot) - cs.share_snapshots.delete(snapshot_ref) - if args.wait: - _wait_for_snapshot_status( - cs, snapshot, expected_status='deleted' - ) - except Exception as e: - failure_count += 1 - print( - f"Delete for snapshot {snapshot} failed: {e}", - file=sys.stderr, - ) - - if failure_count == len(args.snapshot): - raise exceptions.CommandError( - "Unable to delete any of the specified snapshots." - ) - - -@cliutils.arg( - 'snapshot', - metavar='', - nargs='+', - help='Name or ID of the snapshot(s) to force delete.', -) -@cliutils.arg( - '--wait', action='store_true', help='Wait for snapshot to delete' -) -@cliutils.service_type('sharev2') -def do_snapshot_force_delete(cs, args): - """Attempt force-deletion of one or more snapshots. - - Regardless of the state (Admin only). - """ - failure_count = 0 - snapshots_to_delete = [] - - for snapshot in args.snapshot: - try: - snapshot_ref = _find_share_snapshot(cs, snapshot) - snapshots_to_delete.append(snapshot_ref) - snapshot_ref.force_delete() - except Exception as e: - failure_count += 1 - print( - f"Delete for snapshot {snapshot} failed: {e}", - file=sys.stderr, - ) - - if failure_count == len(args.snapshot): - raise exceptions.CommandError( - "Unable to force delete any of the specified snapshots." - ) - if args.wait: - for snapshot in snapshots_to_delete: - try: - _wait_for_resource_status( - cs, - snapshot, - resource_type='snapshot', - expected_status='deleted', - ) - except exceptions.CommandError as e: - print(e, file=sys.stderr) - - -@cliutils.arg( - 'snapshot', - metavar='', - help='Name or ID of the snapshot to modify.', -) -@cliutils.arg( - '--state', - metavar='', - default='available', - help=( - 'Indicate which state to assign the snapshot. ' - 'Options include available, error, creating, deleting, ' - 'error_deleting. If no state is provided, ' - 'available will be used.' - ), -) -def do_snapshot_reset_state(cs, args): - """Explicitly update the state of a snapshot (Admin only).""" - snapshot = _find_share_snapshot(cs, args.snapshot) - snapshot.reset_state(args.state) - - -@api_versions.wraps("2.19") -@cliutils.arg( - '--snapshot', - metavar='', - default=None, - help='Filter results by share snapshot ID.', -) -@cliutils.arg( - '--columns', - metavar='', - type=str, - default=None, - help='Comma separated list of columns to be displayed ' - 'example --columns "id".', -) -@cliutils.arg( - '--detailed', - metavar='', - default=False, - help='Show detailed information about snapshot instances. (Default=False)', -) -def do_snapshot_instance_list(cs, args): - """List share snapshot instances.""" - snapshot = ( - _find_share_snapshot(cs, args.snapshot) if args.snapshot else None - ) - if args.columns is not None: - list_of_keys = _split_columns(columns=args.columns) - elif args.detailed: - list_of_keys = [ - 'ID', - 'Snapshot ID', - 'Status', - 'Created_at', - 'Updated_at', - 'Share_id', - 'Share_instance_id', - 'Progress', - 'Provider_location', - ] - else: - list_of_keys = ['ID', 'Snapshot ID', 'Status'] - - instances = cs.share_snapshot_instances.list( - detailed=args.detailed, snapshot=snapshot - ) - - cliutils.print_list(instances, list_of_keys) - - -@api_versions.wraps("2.19") -@cliutils.arg( - 'snapshot_instance', - metavar='', - help='ID of the share snapshot instance.', -) -def do_snapshot_instance_show(cs, args): - """Show details about a share snapshot instance.""" - snapshot_instance = _find_share_snapshot_instance( - cs, args.snapshot_instance - ) - export_locations = cs.share_snapshot_instance_export_locations.list( - snapshot_instance - ) - snapshot_instance._info['export_locations'] = export_locations - _print_share_snapshot(cs, snapshot_instance) - - -@cliutils.arg( - 'snapshot_instance', - metavar='', - help='ID of the snapshot instance to modify.', -) -@cliutils.arg( - '--state', - metavar='', - default='available', - help=( - 'Indicate which state to assign the snapshot instance. ' - 'Options include available, error, creating, deleting, ' - 'error_deleting. If no state is provided, available ' - 'will be used.' - ), -) -@api_versions.wraps("2.19") -def do_snapshot_instance_reset_state(cs, args): - """Explicitly update the state of a share snapshot instance.""" - snapshot_instance = _find_share_snapshot_instance( - cs, args.snapshot_instance - ) - snapshot_instance.reset_state(args.state) - - -@cliutils.arg( - 'share', metavar='', help='Name or ID of the share to modify.' -) -@cliutils.arg( - '--state', - metavar='', - default='available', - help=( - 'Indicate which state to assign the share. Options include ' - 'available, error, creating, deleting, error_deleting. If no ' - 'state is provided, available will be used.' - ), -) -def do_reset_state(cs, args): - """Explicitly update the state of a share (Admin only).""" - share = _find_share(cs, args.share) - share.reset_state(args.state) - - -@api_versions.wraps("1.0", "2.25") -@cliutils.arg( - '--neutron-net-id', - '--neutron-net_id', - '--neutron_net_id', - '--neutron_net-id', - metavar='', - default=None, - action='single_alias', - help="Neutron network ID. Used to set up network for share servers.", -) -@cliutils.arg( - '--neutron-subnet-id', - '--neutron-subnet_id', - '--neutron_subnet_id', - '--neutron_subnet-id', - metavar='', - default=None, - action='single_alias', - help="Neutron subnet ID. Used to set up network for share servers. " - "This subnet should belong to specified neutron network.", -) -@cliutils.arg( - '--name', metavar='', default=None, help="Share network name." -) -@cliutils.arg( - '--description', - metavar='', - default=None, - help="Share network description.", -) -def do_share_network_create(cs, args): - """Create a share network to export shares to.""" - values = { - 'neutron_net_id': args.neutron_net_id, - 'neutron_subnet_id': args.neutron_subnet_id, - 'name': args.name, - 'description': args.description, - } - share_network = cs.share_networks.create(**values) - info = share_network._info.copy() - cliutils.print_dict(info) - - -@api_versions.wraps("2.26") # noqa -@cliutils.arg( - '--neutron-net-id', - '--neutron-net_id', - '--neutron_net_id', - '--neutron_net-id', - metavar='', - default=None, - action='single_alias', - help="Neutron network ID. Used to set up network for share servers.", -) -@cliutils.arg( - '--neutron-subnet-id', - '--neutron-subnet_id', - '--neutron_subnet_id', - '--neutron_subnet-id', - metavar='', - default=None, - action='single_alias', - help="Neutron subnet ID. Used to set up network for share servers. " - "This subnet should belong to specified neutron network.", -) -@cliutils.arg( - '--name', metavar='', default=None, help="Share network name." -) -@cliutils.arg( - '--description', - metavar='', - default=None, - help="Share network description.", -) -@cliutils.arg( - '--availability-zone', - '--availability_zone', - '--az', - metavar='', - default=None, - action='single_alias', - help="Availability zone in which the subnet should be created. Share " - "networks can have one or more subnets in different availability " - "zones when the driver is operating with " - "'driver_handles_share_servers' extra_spec set to True. Available " - "only for microversion >= 2.51. (Default=None)", -) -def do_share_network_create(cs, args): # noqa - """Create a share network to export shares to.""" - values = { - 'neutron_net_id': args.neutron_net_id, - 'neutron_subnet_id': args.neutron_subnet_id, - 'name': args.name, - 'description': args.description, - } - if cs.api_version >= api_versions.APIVersion("2.51"): - values['availability_zone'] = args.availability_zone - elif args.availability_zone: - raise exceptions.CommandError( - "Creating share networks with a given az is only " - "available with manila API version >= 2.51" - ) - share_network = cs.share_networks.create(**values) - info = share_network._info.copy() - cliutils.print_dict(info) - - -@api_versions.wraps("1.0", "2.25") -@cliutils.arg( - 'share_network', - metavar='', - help='Name or ID of share network to update.', -) -@cliutils.arg( - '--neutron-net-id', - '--neutron-net_id', - '--neutron_net_id', - '--neutron_net-id', - metavar='', - default=None, - action='single_alias', - help="Neutron network ID. Used to set up network for share servers.", -) -@cliutils.arg( - '--neutron-subnet-id', - '--neutron-subnet_id', - '--neutron_subnet_id', - '--neutron_subnet-id', - metavar='', - default=None, - action='single_alias', - help="Neutron subnet ID. Used to set up network for share servers. " - "This subnet should belong to specified neutron network.", -) -@cliutils.arg( - '--name', metavar='', default=None, help="Share network name." -) -@cliutils.arg( - '--description', - metavar='', - default=None, - help="Share network description.", -) -def do_share_network_update(cs, args): - """Update share network data.""" - values = { - 'neutron_net_id': args.neutron_net_id, - 'neutron_subnet_id': args.neutron_subnet_id, - 'name': args.name, - 'description': args.description, - } - share_network = _find_share_network(cs, args.share_network).update( - **values - ) - info = share_network._info.copy() - cliutils.print_dict(info) - - -@api_versions.wraps("2.26") # noqa -@cliutils.arg( - 'share_network', - metavar='', - help='Name or ID of share network to update.', -) -@cliutils.arg( - '--neutron-net-id', - '--neutron-net_id', - '--neutron_net_id', - '--neutron_net-id', - metavar='', - default=None, - action='single_alias', - help="Neutron network ID. Used to set up network for share servers. " - "This option is deprecated for microversion >= 2.51.", -) -@cliutils.arg( - '--neutron-subnet-id', - '--neutron-subnet_id', - '--neutron_subnet_id', - '--neutron_subnet-id', - metavar='', - default=None, - action='single_alias', - help="Neutron subnet ID. Used to set up network for share servers. " - "This subnet should belong to specified neutron network. " - "This option is deprecated for microversion >= 2.51.", -) -@cliutils.arg( - '--name', metavar='', default=None, help="Share network name." -) -@cliutils.arg( - '--description', - metavar='', - default=None, - help="Share network description.", -) -def do_share_network_update(cs, args): # noqa - """Update share network data.""" - - values = { - 'neutron_net_id': args.neutron_net_id, - 'neutron_subnet_id': args.neutron_subnet_id, - 'name': args.name, - 'description': args.description, - } - share_network = _find_share_network(cs, args.share_network).update( - **values - ) - info = share_network._info.copy() - cliutils.print_dict(info) - - -@cliutils.arg( - 'share_network', - metavar='', - help='Name or ID of the share network to show.', -) -def do_share_network_show(cs, args): - """Retrieve details for a share network.""" - share_network = _find_share_network(cs, args.share_network) - info = share_network._info.copy() - cliutils.print_dict(info) - - -@api_versions.wraps("1.0", "2.25") -@cliutils.arg( - '--all-tenants', - '--all-projects', - action='single_alias', - dest='all_projects', - metavar='<0|1>', - nargs='?', - type=int, - const=1, - default=0, - help='Display information from all projects (Admin only).', -) -@cliutils.arg( - '--project-id', - '--project_id', # alias - metavar='', - action='single_alias', - default=None, - help='Filter results by project ID.', -) -@cliutils.arg( - '--name', metavar='', default=None, help='Filter results by name.' -) -@cliutils.arg( - '--created-since', - '--created_since', # alias - metavar='', - action='single_alias', - default=None, - help='''Return only share networks created since given date. ''' - '''The date is in the format 'yyyy-mm-dd'.''', -) -@cliutils.arg( - '--created-before', - '--created_before', # alias - metavar='', - action='single_alias', - default=None, - help='''Return only share networks created until given date. ''' - '''The date is in the format 'yyyy-mm-dd'.''', -) -@cliutils.arg( - '--security-service', - '--security_service', # alias - metavar='', - action='single_alias', - default=None, - help='Filter results by attached security service.', -) -@cliutils.arg( - '--neutron-net-id', - '--neutron_net_id', - '--neutron_net-id', - '--neutron-net_id', # aliases - metavar='', - action='single_alias', - default=None, - help='Filter results by neutron net ID.', -) -@cliutils.arg( - '--neutron-subnet-id', - '--neutron_subnet_id', - '--neutron-subnet_id', # aliases - '--neutron_subnet-id', # alias - metavar='', - action='single_alias', - default=None, - help='Filter results by neutron subnet ID.', -) -@cliutils.arg( - '--network-type', - '--network_type', # alias - metavar='', - action='single_alias', - default=None, - help='Filter results by network type.', -) -@cliutils.arg( - '--segmentation-id', - '--segmentation_id', # alias - metavar='', - type=int, - action='single_alias', - default=None, - help='Filter results by segmentation ID.', -) -@cliutils.arg( - '--cidr', metavar='', default=None, help='Filter results by CIDR.' -) -@cliutils.arg( - '--ip-version', - '--ip_version', # alias - metavar='', - type=int, - action='single_alias', - default=None, - help='Filter results by IP version.', -) -@cliutils.arg( - '--offset', - metavar='', - type=int, - default=None, - help='Start position of share networks listing.', -) -@cliutils.arg( - '--limit', - metavar='', - type=int, - default=None, - help='Number of share networks to return per request.', -) -@cliutils.arg( - '--columns', - metavar='', - type=str, - default=None, - help='Comma separated list of columns to be displayed ' - 'example --columns "id".', -) -def do_share_network_list(cs, args): - """Get a list of network info.""" - all_projects = int( - os.environ.get( - "ALL_TENANTS", os.environ.get("ALL_PROJECTS", args.all_projects) - ) - ) - search_opts = { - 'all_tenants': all_projects, - 'project_id': args.project_id, - 'name': args.name, - 'created_since': args.created_since, - 'created_before': args.created_before, - 'neutron_net_id': args.neutron_net_id, - 'neutron_subnet_id': args.neutron_subnet_id, - 'network_type': args.network_type, - 'segmentation_id': args.segmentation_id, - 'cidr': args.cidr, - 'ip_version': args.ip_version, - 'offset': args.offset, - 'limit': args.limit, - } - if args.security_service: - search_opts['security_service_id'] = _find_security_service( - cs, args.security_service - ).id - share_networks = cs.share_networks.list(search_opts=search_opts) - fields = ['id', 'name'] - - if args.columns is not None: - fields = _split_columns(columns=args.columns) - - cliutils.print_list(share_networks, fields=fields) - - -@api_versions.wraps("2.26") # noqa -@cliutils.arg( - '--all-tenants', - '--all-projects', - action='single_alias', - dest='all_projects', - metavar='<0|1>', - nargs='?', - type=int, - const=1, - default=0, - help='Display information from all projects (Admin only).', -) -@cliutils.arg( - '--project-id', - '--project_id', # alias - metavar='', - action='single_alias', - default=None, - help='Filter results by project ID.', -) -@cliutils.arg( - '--name', - metavar='', - type=str, - default=None, - help='Filter results by name.', -) -@cliutils.arg( - '--description', - metavar='', - type=str, - default=None, - help='Filter results by description. ' - 'Available only for microversion >= 2.36.', -) -@cliutils.arg( - '--created-since', - '--created_since', # alias - metavar='', - action='single_alias', - default=None, - help='''Return only share networks created since given date. ''' - '''The date is in the format 'yyyy-mm-dd'.''', -) -@cliutils.arg( - '--created-before', - '--created_before', # alias - metavar='', - action='single_alias', - default=None, - help='''Return only share networks created until given date. ''' - '''The date is in the format 'yyyy-mm-dd'.''', -) -@cliutils.arg( - '--security-service', - '--security_service', # alias - metavar='', - action='single_alias', - default=None, - help='Filter results by attached security service.', -) -@cliutils.arg( - '--neutron-net-id', - '--neutron_net_id', - '--neutron_net-id', - '--neutron-net_id', # aliases - metavar='', - action='single_alias', - default=None, - help='Filter results by neutron net ID.', -) -@cliutils.arg( - '--neutron-subnet-id', - '--neutron_subnet_id', - '--neutron-subnet_id', # aliases - '--neutron_subnet-id', # alias - metavar='', - action='single_alias', - default=None, - help='Filter results by neutron subnet ID.', -) -@cliutils.arg( - '--network-type', - '--network_type', # alias - metavar='', - action='single_alias', - default=None, - help='Filter results by network type.', -) -@cliutils.arg( - '--segmentation-id', - '--segmentation_id', # alias - metavar='', - type=int, - action='single_alias', - default=None, - help='Filter results by segmentation ID.', -) -@cliutils.arg( - '--cidr', metavar='', default=None, help='Filter results by CIDR.' -) -@cliutils.arg( - '--ip-version', - '--ip_version', # alias - metavar='', - type=int, - action='single_alias', - default=None, - help='Filter results by IP version.', -) -@cliutils.arg( - '--offset', - metavar='', - type=int, - default=None, - help='Start position of share networks listing.', -) -@cliutils.arg( - '--limit', - metavar='', - type=int, - default=None, - help='Number of share networks to return per request.', -) -@cliutils.arg( - '--columns', - metavar='', - type=str, - default=None, - help='Comma separated list of columns to be displayed ' - 'example --columns "id".', -) -@cliutils.arg( - '--name~', - metavar='', - type=str, - default=None, - help='Filter results matching a share network name pattern. ' - 'Available only for microversion >= 2.36.', -) -@cliutils.arg( - '--description~', - metavar='', - type=str, - default=None, - help='Filter results matching a share network description pattern. ' - 'Available only for microversion >= 2.36.', -) -def do_share_network_list(cs, args): # noqa - """Get a list of share networks""" - all_projects = int( - os.environ.get( - "ALL_TENANTS", os.environ.get("ALL_PROJECTS", args.all_projects) - ) - ) - search_opts = { - 'all_tenants': all_projects, - 'project_id': args.project_id, - 'name': args.name, - 'created_since': args.created_since, - 'created_before': args.created_before, - 'neutron_net_id': args.neutron_net_id, - 'neutron_subnet_id': args.neutron_subnet_id, - 'network_type': args.network_type, - 'segmentation_id': args.segmentation_id, - 'cidr': args.cidr, - 'ip_version': args.ip_version, - 'offset': args.offset, - 'limit': args.limit, - } - if cs.api_version.matches( - api_versions.APIVersion("2.36"), api_versions.APIVersion() - ): - search_opts['name~'] = getattr(args, 'name~') - search_opts['description~'] = getattr(args, 'description~') - search_opts['description'] = getattr(args, 'description') - elif ( - getattr(args, 'name~') - or getattr(args, 'description~') - or getattr(args, 'description') - ): - raise exceptions.CommandError( - "Pattern based filtering (name~, description~ and description)" - " is only available with manila API version >= 2.36" - ) - - if args.security_service: - search_opts['security_service_id'] = _find_security_service( - cs, args.security_service - ).id - share_networks = cs.share_networks.list(search_opts=search_opts) - fields = ['id', 'name'] - - if args.columns is not None: - fields = _split_columns(columns=args.columns) - - cliutils.print_list(share_networks, fields=fields) - - -@cliutils.arg( - 'share_network', - metavar='', - help='Share network name or ID.', -) -@cliutils.arg( - 'security_service', - metavar='', - help='Security service name or ID to associate with.', -) -def do_share_network_security_service_add(cs, args): - """Associate security service with share network.""" - share_network = _find_share_network(cs, args.share_network) - security_service = _find_security_service(cs, args.security_service) - cs.share_networks.add_security_service(share_network, security_service) - - -@cliutils.arg( - 'share_network', - metavar='', - help='Share network name or ID.', -) -@cliutils.arg( - 'security_service', - metavar='', - help='Security service name or ID to associate with.', -) -@cliutils.arg( - '--reset', - metavar='', - choices=['True', 'False'], - required=False, - default=False, - help='Reset and restart the check operation.(Optional, Default=False)', -) -@api_versions.wraps("2.63") -def do_share_network_security_service_add_check(cs, args): - """Associate security service with share network.""" - share_network = _find_share_network(cs, args.share_network) - security_service = _find_security_service(cs, args.security_service) - add_sec_service_result = cs.share_networks.add_security_service_check( - share_network, security_service, reset_operation=args.reset - ) - # result[0] is response code, result[1] is dict body - cliutils.print_dict(add_sec_service_result[1]) - - -@cliutils.arg( - 'share_network', - metavar='', - help='Share network name or ID.', -) -@cliutils.arg( - 'security_service', - metavar='', - help='Security service name or ID to dissociate.', -) -def do_share_network_security_service_remove(cs, args): - """Dissociate security service from share network.""" - share_network = _find_share_network(cs, args.share_network) - security_service = _find_security_service(cs, args.security_service) - cs.share_networks.remove_security_service(share_network, security_service) - - -@cliutils.arg( - 'share_network', - metavar='', - help='Share network name or ID.', -) -@cliutils.arg( - '--columns', - metavar='', - type=str, - default=None, - help='Comma separated list of columns to be displayed ' - 'example --columns "id,name".', -) -def do_share_network_security_service_list(cs, args): - """Get list of security services associated with a given share network.""" - share_network = _find_share_network(cs, args.share_network) - search_opts = { - 'share_network_id': share_network.id, - } - security_services = cs.security_services.list(search_opts=search_opts) - fields = [ - 'id', - 'name', - 'status', - 'type', - ] - - if args.columns is not None: - fields = _split_columns(columns=args.columns) - - cliutils.print_list(security_services, fields=fields) - - -@cliutils.arg( - 'share_network', - metavar='', - help='Share network name or ID.', -) -@cliutils.arg( - 'current_security_service', - metavar='', - help='Current security service name or ID.', -) -@cliutils.arg( - 'new_security_service', - metavar='', - help='New security service name or ID.', -) -@api_versions.wraps("2.63") -def do_share_network_security_service_update(cs, args): - """Update a current security service to a new security service.""" - share_network = _find_share_network(cs, args.share_network) - current_security_service = _find_security_service( - cs, args.current_security_service - ) - new_security_service = _find_security_service( - cs, args.new_security_service - ) - cs.share_networks.update_share_network_security_service( - share_network, current_security_service, new_security_service - ) - - -@cliutils.arg( - 'share_network', - metavar='', - help='Share network name or ID.', -) -@cliutils.arg( - 'current_security_service', - metavar='', - help='Current security service name or ID.', -) -@cliutils.arg( - 'new_security_service', - metavar='', - help='New security service name or ID.', -) -@cliutils.arg( - '--reset', - metavar='', - choices=['True', 'False'], - required=False, - default=False, - help='Reset and start again the check operation.(Optional, Default=False)', -) -@api_versions.wraps("2.63") -def do_share_network_security_service_update_check(cs, args): - """Check if a security service update on the share network is supported. - - This call can be repeated until a successful result is obtained. - """ - share_network = _find_share_network(cs, args.share_network) - current_security_service = _find_security_service( - cs, args.current_security_service - ) - new_security_service = _find_security_service( - cs, args.new_security_service - ) - share_network_update_check = ( - cs.share_networks.update_share_network_security_service_check( - share_network, - current_security_service, - new_security_service, - reset_operation=args.reset, - ) - ) - # result[0] is response code, result[1] is dict body - cliutils.print_dict(share_network_update_check[1]) - - -@cliutils.arg( - 'share_network', - metavar='', - help='Share network name or ID.', -) -@cliutils.arg( - '--state', - metavar='', - default=constants.STATUS_ACTIVE, - help=( - 'Indicate which state to assign the share network. Options include ' - 'active, error, network change. If no state is provided, active ' - 'will be used.' - ), -) -@api_versions.wraps("2.63") -def do_share_network_reset_state(cs, args): - """Explicitly update the state of a share network (Admin only).""" - share_network = _find_share_network(cs, args.share_network) - cs.share_networks.reset_state(share_network, args.state) - - -@cliutils.arg( - 'share_network', - metavar='', - help='Share network name or ID.', -) -@cliutils.arg( - '--neutron-net-id', - '--neutron-net_id', - '--neutron_net_id', - '--neutron_net-id', - metavar='', - default=None, - action='single_alias', - help="Neutron network ID. Used to set up network for share servers. " - "Optional, Default = None.", -) -@cliutils.arg( - '--neutron-subnet-id', - '--neutron-subnet_id', - '--neutron_subnet_id', - '--neutron_subnet-id', - metavar='', - default=None, - action='single_alias', - help="Neutron subnet ID. Used to set up network for share servers. " - "This subnet should belong to specified neutron network. " - "Optional, Default = None.", -) -@cliutils.arg( - '--availability-zone', - '--availability_zone', - '--az', - default=None, - action='single_alias', - metavar='', - help='Optional availability zone that the subnet is available within ' - '(Default=None). If None, the subnet will be considered as being ' - 'available across all availability zones.', -) -def do_share_network_subnet_create(cs, args): - """Add a new subnet into a share network.""" - if xor(bool(args.neutron_net_id), bool(args.neutron_subnet_id)): - raise exceptions.CommandError( - "Both neutron_net_id and neutron_subnet_id should be specified. " - "Alternatively, neither of them should be specified." - ) - - share_network = _find_share_network(cs, args.share_network) - values = { - 'share_network_id': share_network.id, - 'neutron_net_id': args.neutron_net_id, - 'neutron_subnet_id': args.neutron_subnet_id, - 'availability_zone': args.availability_zone, - } - share_network_subnet = cs.share_network_subnets.create(**values) - info = share_network_subnet._info.copy() - cliutils.print_dict(info) - - -@cliutils.arg( - 'share_network', - metavar='', - help='Share network name or ID.', -) -@cliutils.arg( - '--neutron-net-id', - '--neutron-net_id', - '--neutron_net_id', - '--neutron_net-id', - metavar='', - default=None, - action='single_alias', - help="Neutron network ID. Used to set up network for share servers. " - "Optional, Default = None.", -) -@cliutils.arg( - '--neutron-subnet-id', - '--neutron-subnet_id', - '--neutron_subnet_id', - '--neutron_subnet-id', - metavar='', - default=None, - action='single_alias', - help="Neutron subnet ID. Used to set up network for share servers. " - "This subnet should belong to specified neutron network. " - "Optional, Default = None.", -) -@cliutils.arg( - '--availability-zone', - '--availability_zone', - '--az', - default=None, - action='single_alias', - metavar='', - help='Optional availability zone that the subnet is available within ' - '(Default=None). If None, the subnet will be considered as being ' - 'available across all availability zones.', -) -@cliutils.arg( - '--reset', - metavar='', - choices=['True', 'False'], - required=False, - default=False, - help='Reset and start again the check operation.(Optional, Default=False)', -) -@api_versions.wraps("2.70") -def do_share_network_subnet_create_check(cs, args): - """Check if a new subnet can be added to a share network.""" - if xor(bool(args.neutron_net_id), bool(args.neutron_subnet_id)): - raise exceptions.CommandError( - "Both neutron_net_id and neutron_subnet_id should be specified. " - "Alternatively, neither of them should be specified." - ) - - share_network = _find_share_network(cs, args.share_network) - values = { - 'neutron_net_id': args.neutron_net_id, - 'neutron_subnet_id': args.neutron_subnet_id, - 'availability_zone': args.availability_zone, - 'reset_operation': args.reset, - } - subnet_create_check = cs.share_networks.share_network_subnet_create_check( - share_network.id, **values - ) - # result[0] is response code, result[1] is dict body - cliutils.print_dict(subnet_create_check[1]) - - -@cliutils.arg( - 'share_network', - metavar='', - help='Share network name or ID.', -) -@cliutils.arg( - 'share_network_subnet', - metavar='', - nargs='+', - help='Name or ID of share network subnet(s) to be deleted.', -) -def do_share_network_subnet_delete(cs, args): - """Delete one or more share network subnets.""" - failure_count = 0 - share_network_ref = _find_share_network(cs, args.share_network) - - for subnet in args.share_network_subnet: - try: - cs.share_network_subnets.delete(share_network_ref, subnet) - except Exception as e: - failure_count += 1 - print( - f"Deletion of share network subnet {subnet} failed: {e}", - file=sys.stderr, - ) - - if failure_count == len(args.share_network_subnet): - raise exceptions.CommandError( - "Unable to delete any of the specified share network subnets." - ) - - -@cliutils.arg( - 'share_network', - metavar='', - help='Name or ID of share network(s) to which the subnet belongs.', -) -@cliutils.arg( - 'share_network_subnet', - metavar='', - help='Share network subnet ID to show.', -) -def do_share_network_subnet_show(cs, args): - """Show share network subnet.""" - share_network = _find_share_network(cs, args.share_network) - share_network_subnet = cs.share_network_subnets.get( - share_network.id, args.share_network_subnet - ) - view_data = share_network_subnet._info.copy() - cliutils.print_dict(view_data) - - -@cliutils.arg( - 'share_network', - metavar='', - nargs='+', - help='Name or ID of share network(s) to be deleted.', -) -def do_share_network_delete(cs, args): - """Delete one or more share networks.""" - failure_count = 0 - - for share_network in args.share_network: - try: - share_ref = _find_share_network(cs, share_network) - cs.share_networks.delete(share_ref) - except Exception as e: - failure_count += 1 - print( - f"Delete for share network {share_network} failed: {e}", - file=sys.stderr, - ) - - if failure_count == len(args.share_network): - raise exceptions.CommandError( - "Unable to delete any of the specified share networks." - ) - - -@cliutils.arg( - 'type', - metavar='', - help="Security service type: 'ldap', 'kerberos' or 'active_directory'.", -) -@cliutils.arg( - '--dns-ip', - metavar='', - default=None, - help="DNS IP address used inside project's network.", -) -@cliutils.arg( - '--ou', - metavar='', - default=None, - help="Security service OU (Organizational Unit). Available only for " - "microversion >= 2.44.", -) -@cliutils.arg( - '--server', - metavar='', - default=None, - help="Security service IP address or hostname.", -) -@cliutils.arg( - '--domain', - metavar='', - default=None, - help="Security service domain.", -) -@cliutils.arg( - '--user', - metavar='', - default=None, - help="Security service user or group used by project.", -) -@cliutils.arg( - '--password', - metavar='', - default=None, - help="Password used by user.", -) -@cliutils.arg( - '--name', metavar='', default=None, help="Security service name." -) -@cliutils.arg( - '--default-ad-site', - metavar='', - dest='default_ad_site', - default=None, - help="Default AD site. Available only for microversion >= 2.76. Can " - "be provided in the place of '--server' but not along with it.", -) -@cliutils.arg( - '--description', - metavar='', - default=None, - help="Security service description.", -) -def do_security_service_create(cs, args): - """Create security service used by project.""" - values = { - 'dns_ip': args.dns_ip, - 'server': args.server, - 'domain': args.domain, - 'user': args.user, - 'password': args.password, - 'name': args.name, - 'description': args.description, - } - - if cs.api_version.matches( - api_versions.APIVersion("2.44"), api_versions.APIVersion() - ): - values['ou'] = args.ou - elif args.ou: - raise exceptions.CommandError( - "Security service Organizational Unit (ou) option " - "is only available with manila API version >= 2.44" - ) - - if cs.api_version.matches( - api_versions.APIVersion("2.76"), api_versions.APIVersion() - ): - values['default_ad_site'] = args.default_ad_site - elif args.default_ad_site: - raise exceptions.CommandError( - "Default AD site option is only available with " - "manila API version >= 2.76" - ) - - if args.type == 'active_directory': - if args.server and args.default_ad_site: - raise exceptions.CommandError( - "Cannot create security service because both " - "server and 'default_ad_site' were provided. " - "Specify either server or 'default_ad_site'." - ) - - security_service = cs.security_services.create(args.type, **values) - info = security_service._info.copy() - cliutils.print_dict(info) - - -@cliutils.arg( - 'security_service', - metavar='', - help='Security service name or ID to update.', -) -@cliutils.arg( - '--dns-ip', - metavar='', - default=None, - help="DNS IP address used inside project's network.", -) -@cliutils.arg( - '--ou', - metavar='', - default=None, - help="Security service OU (Organizational Unit). Available only for " - "microversion >= 2.44.", -) -@cliutils.arg( - '--server', - metavar='', - default=None, - help="Security service IP address or hostname.", -) -@cliutils.arg( - '--domain', - metavar='', - default=None, - help="Security service domain.", -) -@cliutils.arg( - '--user', - metavar='', - default=None, - help="Security service user or group used by project.", -) -@cliutils.arg( - '--password', - metavar='', - default=None, - help="Password used by user.", -) -@cliutils.arg( - '--name', metavar='', default=None, help="Security service name." -) -@cliutils.arg( - '--default-ad-site', - metavar='', - dest='default_ad_site', - default=None, - help="Default AD site. Available only for microversion >= 2.76.", -) -@cliutils.arg( - '--description', - metavar='', - default=None, - help="Security service description.", -) -def do_security_service_update(cs, args): - """Update security service.""" - values = { - 'dns_ip': args.dns_ip, - 'server': args.server, - 'domain': args.domain, - 'user': args.user, - 'password': args.password, - 'name': args.name, - 'description': args.description, - } - - if cs.api_version.matches( - api_versions.APIVersion("2.44"), api_versions.APIVersion() - ): - values['ou'] = args.ou - elif args.ou: - raise exceptions.CommandError( - "Security service Organizational Unit (ou) option " - "is only available with manila API version >= 2.44" - ) - - if cs.api_version.matches( - api_versions.APIVersion("2.76"), api_versions.APIVersion() - ): - values['default_ad_site'] = args.default_ad_site - elif args.default_ad_site: - raise exceptions.CommandError( - "Default AD site option is only available with " - "manila API version >= 2.76" - ) - - security_service = _find_security_service( - cs, args.security_service - ).update(**values) - cliutils.print_dict(security_service._info) - - -@cliutils.arg( - 'security_service', - metavar='', - help='Security service name or ID to show.', -) -def do_security_service_show(cs, args): - """Show security service.""" - security_service = _find_security_service(cs, args.security_service) - info = security_service._info.copy() - cliutils.print_dict(info) - - -@cliutils.arg( - '--all-tenants', - '--all-projects', - action='single_alias', - dest='all_projects', - metavar='<0|1>', - nargs='?', - type=int, - const=1, - default=0, - help='Display information from all projects (Admin only).', -) -@cliutils.arg( - '--share-network', - '--share_network', # alias - metavar='', - action='single_alias', - default=None, - help='Filter results by share network id or name.', -) -@cliutils.arg( - '--status', - metavar='', - default=None, - help='Filter results by status.', -) -@cliutils.arg( - '--name', metavar='', default=None, help='Filter results by name.' -) -@cliutils.arg( - '--type', metavar='', default=None, help='Filter results by type.' -) -@cliutils.arg( - '--user', - metavar='', - default=None, - help='Filter results by user or group used by projects.', -) -@cliutils.arg( - '--dns-ip', - '--dns_ip', # alias - metavar='', - action='single_alias', - default=None, - help="Filter results by DNS IP address used inside project's network.", -) -@cliutils.arg( - '--ou', - metavar='', - default=None, - help="Filter results by security service OU (Organizational Unit)." - " Available only for microversion >= 2.44.", -) -@cliutils.arg( - '--server', - metavar='', - default=None, - help="Filter results by security service IP address or hostname.", -) -@cliutils.arg( - '--domain', - metavar='', - default=None, - help="Filter results by domain.", -) -@cliutils.arg( - '--detailed', - dest='detailed', - metavar='<0|1>', - nargs='?', - type=int, - const=1, - default=0, - help="Show detailed information about filtered security services.", -) -@cliutils.arg( - '--offset', - metavar="", - default=None, - help='Start position of security services listing.', -) -@cliutils.arg( - '--limit', - metavar="", - default=None, - help='Number of security services to return per request.', -) -@cliutils.arg( - '--default-ad-site', - metavar='', - dest='default_ad_site', - default=None, - help="Default AD site. Available only for microversion >= 2.76.", -) -@cliutils.arg( - '--columns', - metavar='', - type=str, - default=None, - help='Comma separated list of columns to be displayed ' - 'example --columns "name,type".', -) -def do_security_service_list(cs, args): - """Get a list of security services.""" - all_projects = int( - os.environ.get( - "ALL_TENANTS", os.environ.get("ALL_PROJECTS", args.all_projects) - ) - ) - search_opts = { - 'all_tenants': all_projects, - 'status': args.status, - 'name': args.name, - 'type': args.type, - 'user': args.user, - 'dns_ip': args.dns_ip, - 'server': args.server, - 'domain': args.domain, - 'offset': args.offset, - 'limit': args.limit, - } - - if cs.api_version.matches( - api_versions.APIVersion("2.44"), api_versions.APIVersion() - ): - search_opts['ou'] = args.ou - elif args.ou: - raise exceptions.CommandError( - "Security service Organizational Unit (ou) option " - "is only available with manila API version >= 2.44" - ) - - if cs.api_version.matches( - api_versions.APIVersion("2.76"), api_versions.APIVersion() - ): - search_opts['default_ad_site'] = args.default_ad_site - elif args.ou: - raise exceptions.CommandError( - "Security service Default AD site option " - "is only available with manila API version >= 2.76" - ) - - if args.share_network: - search_opts['share_network_id'] = _find_share_network( - cs, args.share_network - ).id - security_services = cs.security_services.list( - search_opts=search_opts, detailed=args.detailed - ) - fields = [ - 'id', - 'name', - 'status', - 'type', - ] - if args.columns is not None: - fields = _split_columns(columns=args.columns) - - if args.detailed: - fields.append('share_networks') - cliutils.print_list(security_services, fields=fields) - - -@cliutils.arg( - 'security_service', - metavar='', - nargs='+', - help='Name or ID of the security service(s) to delete.', -) -def do_security_service_delete(cs, args): - """Delete one or more security services.""" - failure_count = 0 - - for security_service in args.security_service: - try: - security_ref = _find_security_service(cs, security_service) - cs.security_services.delete(security_ref) - except Exception as e: - failure_count += 1 - print( - f"Delete for security service {security_service} failed: {e}", - file=sys.stderr, - ) - - if failure_count == len(args.security_service): - raise exceptions.CommandError( - "Unable to delete any of the specified security services." - ) - - -@cliutils.arg( - '--host', - metavar='', - default=None, - help='Filter results by name of host.', -) -@cliutils.arg( - '--status', - metavar='', - default=None, - help='Filter results by status.', -) -@cliutils.arg( - '--share-network', - metavar='', - default=None, - help='Filter results by share network.', -) -@cliutils.arg( - '--project-id', - metavar='', - default=None, - help='Filter results by project ID.', -) -@cliutils.arg( - '--columns', - metavar='', - type=str, - default=None, - help='Comma separated list of columns to be displayed ' - 'example --columns "id,host,status".', -) -@cliutils.arg( - '--share-network-subnet', - '--share_network_subnet', - type=str, - metavar='', - help="Filter results by share network subnet that the share server's " - "network allocation exists whithin. Available for micro version " - ">= 2.51 (Optional, Default=None).", - default=None, -) -def do_share_server_list(cs, args): - """List all share servers (Admin only).""" - search_opts = { - "host": args.host, - "share_network": args.share_network, - "status": args.status, - "project_id": args.project_id, - } - fields = [ - "Id", - "Host", - "Status", - "Share Network", - "Project Id", - "Updated_at", - ] - - if cs.api_version < api_versions.APIVersion("2.51"): - if getattr(args, 'share_network_subnet'): - raise exceptions.CommandError( - "Share network subnet option is only available with manila " - "API version >= 2.51" - ) - elif cs.api_version < api_versions.APIVersion("2.70"): - search_opts.update( - {'share_network_subnet_id': args.share_network_subnet} - ) - fields.append("Share Network Subnet Id") - else: - search_opts.update( - {'share_network_subnet_id': args.share_network_subnet} - ) - fields.append("Share Network Subnet IDs") - - if args.columns is not None: - fields = _split_columns(columns=args.columns) - - share_servers = cs.share_servers.list(search_opts=search_opts) - cliutils.print_list(share_servers, fields=fields) - - -@cliutils.arg('id', metavar='', type=str, help='ID of share server.') -def do_share_server_show(cs, args): - """Show share server info (Admin only).""" - share_server = cs.share_servers.get(args.id) - # All 'backend_details' data already present as separated strings, - # so remove big dict from view. - if "backend_details" in share_server._info: - del share_server._info["backend_details"] - cliutils.print_dict(share_server._info) - - -@cliutils.arg('id', metavar='', type=str, help='ID of share server.') -def do_share_server_details(cs, args): - """Show share server details (Admin only).""" - details = cs.share_servers.details(args.id) - cliutils.print_dict(details._info) - - -@cliutils.arg( - 'id', - metavar='', - nargs='+', - type=str, - help='ID of the share server(s) to delete.', -) -@cliutils.arg( - '--wait', action='store_true', help='Wait for share server to delete' -) -@cliutils.service_type('sharev2') -def do_share_server_delete(cs, args): - """Delete one or more share servers (Admin only).""" - - failure_count = 0 - share_servers_to_delete = [] - - for server_id in args.id: - try: - id_ref = _find_share_server(cs, server_id) - share_servers_to_delete.append(id_ref) - id_ref.delete() - except Exception as e: - failure_count += 1 - print( - f"Delete for share server {server_id} failed: {e}", - file=sys.stderr, - ) - - if failure_count == len(args.id): - raise exceptions.CommandError( - "Unable to delete any of the specified share servers." - ) - - if args.wait: - for share_server in share_servers_to_delete: - try: - _wait_for_resource_status( - cs, - share_server, - resource_type='share_server', - expected_status='deleted', - ) - except exceptions.CommandError as e: - print(e, file=sys.stderr) - - -@cliutils.arg( - '--columns', - metavar='', - type=str, - default=None, - help='Comma separated list of columns to be displayed ' - 'example --columns "id,name".', -) -def do_availability_zone_list(cs, args): - """List all availability zones.""" - - if args.columns is not None: - fields = _split_columns(columns=args.columns) - else: - fields = ("Id", "Name", "Created_At", "Updated_At") - - availability_zones = cs.availability_zones.list() - cliutils.print_list(availability_zones, fields=fields) - - -@cliutils.arg( - '--host', metavar='', default=None, help='Name of host.' -) -@cliutils.arg( - '--binary', metavar='', default=None, help='Service binary.' -) -@cliutils.arg( - '--status', - metavar='', - default=None, - help='Filter results by status.', -) -@cliutils.arg( - '--state', metavar='', default=None, help='Filter results by state.' -) -@cliutils.arg( - '--zone', metavar='', default=None, help='Availability zone.' -) -@cliutils.arg( - '--columns', - metavar='', - type=str, - default=None, - help='Comma separated list of columns to be displayed ' - 'example --columns "id,host".', -) -def do_service_list(cs, args): - """List all services (Admin only).""" - search_opts = { - 'status': args.status, - 'host': args.host, - 'binary': args.binary, - 'zone': args.zone, - 'state': args.state, - } - fields = ["Id", "Binary", "Host", "Zone", "Status", "State", "Updated_at"] - - if args.columns is not None: - fields = _split_columns(columns=args.columns) - - services = cs.services.list(search_opts=search_opts) - cliutils.print_list(services, fields=fields) - - -@cliutils.arg( - 'host', - metavar='', - help="Host name as 'example_host@example_backend'.", -) -@cliutils.arg( - 'binary', - metavar='', - help="Service binary, could be 'manila-share' or 'manila-scheduler'.", -) -def do_service_enable(cs, args): - """Enables 'manila-share' or 'manila-scheduler' services (Admin only).""" - columns = ("Host", "Binary", "Enabled") - result = cs.services.enable(args.host, args.binary) - result.enabled = not result.disabled - cliutils.print_list([result], columns) - - -@cliutils.arg( - 'host', - metavar='', - help="Host name as 'example_host@example_backend'.", -) -@cliutils.arg( - 'binary', - metavar='', - help="Service binary, could be 'manila-share' or 'manila-scheduler'.", -) -def do_service_disable(cs, args): - """Disables 'manila-share' or 'manila-scheduler' services (Admin only).""" - columns = ("Host", "Binary", "Enabled") - result = cs.services.disable(args.host, args.binary) - result.enabled = not result.disabled - cliutils.print_list([result], columns) - - -def _print_dict(data_dict): - formatted_data = [] - - for date in data_dict: - formatted_data.append(f"{date} : {data_dict[date]}") - - return "\n".join(formatted_data) - - -@cliutils.arg( - '--host', - metavar='', - type=str, - default='.*', - help='Filter results by host name. Regular expressions are supported.', -) -@cliutils.arg( - '--backend', - metavar='', - type=str, - default='.*', - help='Filter results by backend name. Regular expressions are supported.', -) -@cliutils.arg( - '--pool', - metavar='', - type=str, - default='.*', - help='Filter results by pool name. Regular expressions are supported.', -) -@cliutils.arg( - '--columns', - metavar='', - type=str, - default=None, - help='Comma separated list of columns to be displayed ' - 'example --columns "name,host".', -) -@cliutils.arg( - '--detail', - '--detailed', - action='store_true', - help='Show detailed information about pools. If this parameter is set ' - 'to True, --columns parameter will be ignored if present. ' - '(Default=False)', -) -@cliutils.arg( - '--share-type', - '--share_type', - '--share-type-id', - '--share_type_id', - metavar='', - type=str, - default=None, - action='single_alias', - help='Filter results by share type name or ID. (Default=None)' - 'Available only for microversion >= 2.23.', -) -def do_pool_list(cs, args): - """List all backend storage pools known to the scheduler (Admin only).""" - - search_opts = { - 'host': args.host, - 'backend': args.backend, - 'pool': args.pool, - 'share_type': args.share_type, - } - - if args.detail: - fields = ["Name", "Host", "Backend", "Pool", "Capabilities"] - else: - fields = ["Name", "Host", "Backend", "Pool"] - - pools = cs.pools.list(detailed=args.detail, search_opts=search_opts) - if args.columns is not None: - fields = _split_columns(columns=args.columns) - pools = cs.pools.list(detailed=True, search_opts=search_opts) - - if args.detail: - for info in pools: - backend = dict() - backend['name'] = info.name - backend.update(info.capabilities) - cliutils.print_dict(backend) - else: - cliutils.print_list(pools, fields=fields) - - -@cliutils.arg( - 'share', metavar='', help='Name or ID of share to extend.' -) -@cliutils.arg( - 'new_size', - metavar='', - type=int, - help='New size of share, in GiBs.', -) -@cliutils.arg('--wait', action='store_true', help='Wait for share extension') -@cliutils.arg( - '--force', - action='store_true', - help='Force attempt the extension of the share, only available with ' - 'microversion 2.64 and higher. (admin only)', -) -@cliutils.service_type('sharev2') -def do_extend(cs, args): - """Increases the size of an existing share.""" - share = _find_share(cs, args.share) - force = False - if args.force: - if cs.api_version < api_versions.APIVersion("2.64"): - raise exceptions.CommandError( - "args 'force' is available only starting with " - "'2.64' API microversion." - ) - force = True - if force: - cs.shares.extend(share, args.new_size, force=force) - else: - cs.shares.extend(share, args.new_size) - - if args.wait: - share = _wait_for_share_status(cs, share) - else: - share = _find_share(cs, args.share) - _print_share(cs, share) - - -@cliutils.arg( - 'share', metavar='', help='Name or ID of share to shrink.' -) -@cliutils.arg( - 'new_size', - metavar='', - type=int, - help='New size of share, in GiBs.', -) -@cliutils.arg('--wait', action='store_true', help='Wait for share shrinkage') -@cliutils.service_type('sharev2') -def do_shrink(cs, args): - """Decreases the size of an existing share.""" - share = _find_share(cs, args.share) - cs.shares.shrink(share, args.new_size) - - if args.wait: - share = _wait_for_share_status(cs, share) - else: - share = _find_share(cs, args.share) - _print_share(cs, share) - - -############################################################################## -# -# Share types -# -############################################################################## - - -def _print_type_extra_specs(share_type): - """Prints share type extra specs or share group type specs.""" - try: - return _print_dict(share_type.get_keys()) - except exceptions.NotFound: - return None - - -def _print_type_required_extra_specs(share_type): - try: - return _print_dict(share_type.get_required_keys()) - except exceptions.NotFound: - return "N/A" - - -def _print_type_optional_extra_specs(share_type): - try: - return _print_dict(share_type.get_optional_keys()) - except exceptions.NotFound: - return "N/A" - - -def _is_share_type_public(share_type): - return 'public' if share_type.is_public else 'private' - - -def _print_share_type_list( - stypes, default_share_type=None, columns=None, description=False -): - def _is_default(share_type): - if hasattr(share_type, 'is_default'): - return 'YES' if share_type.is_default else '-' - elif default_share_type: - default = default_share_type.id - return 'YES' if share_type.id == default else '-' - else: - return '-' - - formatters = { - 'visibility': _is_share_type_public, - 'is_default': _is_default, - 'required_extra_specs': _print_type_required_extra_specs, - 'optional_extra_specs': _print_type_optional_extra_specs, - } - - for stype in stypes: - stype = stype.to_dict() - stype['visibility'] = stype.pop('is_public', 'unknown') - - fields = [ - 'ID', - 'Name', - 'visibility', - 'is_default', - 'required_extra_specs', - 'optional_extra_specs', - ] - if description: - fields.append('Description') - if columns is not None: - fields = _split_columns(columns=columns, title=False) - - cliutils.print_list(stypes, fields, formatters) - - -def _print_share_type(stype, default_share_type=None, show_des=False): - def _is_default(share_type): - if hasattr(share_type, 'is_default'): - return 'YES' if share_type.is_default else '-' - return '-' - - stype_dict = { - 'ID': stype.id, - 'Name': stype.name, - 'Visibility': _is_share_type_public(stype), - 'is_default': _is_default(stype), - 'required_extra_specs': _print_type_required_extra_specs(stype), - 'optional_extra_specs': _print_type_optional_extra_specs(stype), - } - if show_des: - stype_dict['Description'] = stype.description - cliutils.print_dict(stype_dict) - - -def _print_type_and_extra_specs_list(stypes, columns=None): - """Prints extra specs for a list of share types or share group types.""" - formatters = { - 'all_extra_specs': _print_type_extra_specs, - } - fields = ['ID', 'Name', 'all_extra_specs'] - - if columns is not None: - fields = _split_columns(columns=columns, title=False) - - cliutils.print_list(stypes, fields, formatters) - - -def _find_share_type(cs, stype): - """Get a share type by name or ID.""" - return apiclient_utils.find_resource(cs.share_types, stype) - - -@cliutils.arg( - '--all', - dest='all', - action='store_true', - default=False, - help='Display all share types whatever public or private ' - 'OPTIONAL: Default=False. (Admin only).', -) -@cliutils.arg( - '--extra-specs', - '--extra_specs', - type=str, - nargs='*', - metavar='', - action='single_alias', - default=None, - help='Filters results by a extra specs key and value of share type that ' - 'was used for share creation. Available only for microversion >= ' - '2.43. OPTIONAL: Default=None.', -) -@cliutils.arg( - '--columns', - metavar='', - type=str, - default=None, - help='Comma separated list of columns to be displayed ' - 'example --columns "id,name".', -) -def do_type_list(cs, args): - """Print a list of available 'share types'.""" - search_opts = None - show_all = args.all - extra_specs = _extract_extra_specs(args) - if extra_specs: - if cs.api_version < api_versions.APIVersion("2.43"): - raise exceptions.CommandError( - "Filter by 'extra_specs' is available only starting with " - "'2.43' API microversion." - ) - search_opts = {'extra_specs': extra_specs} - - share_types = cs.share_types.list( - show_all=show_all, search_opts=search_opts - ) - default = None - if share_types and not hasattr(share_types[0], 'is_default'): - if ( - args.columns and 'is_default' in args.columns - ) or args.columns is None: - default = cs.share_types.get() - - show_des = cs.api_version.matches( - api_versions.APIVersion("2.41"), api_versions.APIVersion() - ) - _print_share_type_list( - share_types, - default_share_type=default, - columns=args.columns, - description=show_des, - ) - - -@cliutils.arg( - 'share_type', metavar='', help='Name or ID of the share type.' -) -def do_type_show(cs, args): - """Show share type details.""" - share_type = _find_share_type(cs, args.share_type) - default = None - if share_type and not hasattr(share_type, 'is_default'): - default = cs.share_types.get() - _print_type_show(share_type, default_share_type=default) - - -@cliutils.arg( - '--columns', - metavar='', - type=str, - default=None, - help='Comma separated list of columns to be displayed ' - 'example --columns "id,name".', -) -def do_extra_specs_list(cs, args): - """Print a list of current 'share types and extra specs' (Admin Only).""" - stypes = cs.share_types.list() - _print_type_and_extra_specs_list(stypes, columns=args.columns) - - -@cliutils.arg('name', metavar='', help="Name of the new share type.") -@cliutils.arg( - 'spec_driver_handles_share_servers', - metavar='', - type=str, - help="Required extra specification. " - "Valid values are 'true'/'1' and 'false'/'0'.", -) -@cliutils.arg( - '--description', - metavar='', - type=str, - default=None, - help='Filter results by description. ' - 'Available only for microversion >= 2.41.', -) -@cliutils.arg( - '--snapshot_support', - '--snapshot-support', - metavar='', - action='single_alias', - help="Boolean extra spec used for filtering of back ends by their " - "capability to create share snapshots.", -) -@cliutils.arg( - '--create_share_from_snapshot_support', - '--create-share-from-snapshot-support', - metavar='', - action='single_alias', - help="Boolean extra spec used for filtering of back ends by their " - "capability to create shares from snapshots.", -) -@cliutils.arg( - '--revert_to_snapshot_support', - '--revert-to-snapshot-support', - metavar='', - action='single_alias', - help="Boolean extra spec used for filtering of back ends by their " - "capability to revert shares to snapshots. (Default is False).", -) -@cliutils.arg( - '--mount_snapshot_support', - '--mount-snapshot-support', - metavar='', - action='single_alias', - help="Boolean extra spec used for filtering of back ends by their " - "capability to mount share snapshots. (Default is False).", -) -@cliutils.arg( - '--extra-specs', - '--extra_specs', # alias - type=str, - nargs='*', - metavar='', - action='single_alias', - help="Extra specs key and value of share type that will be" - " used for share type creation. OPTIONAL: Default=None." - " example --extra-specs thin_provisioning=' True', " - "replication_type=readable.", - default=None, -) -@cliutils.arg( - '--is_public', - '--is-public', - metavar='', - action='single_alias', - help="Make type accessible to the public (default true).", -) -def do_type_create(cs, args): - """Create a new share type (Admin only).""" - kwargs = { - "name": args.name, - "is_public": strutils.bool_from_string(args.is_public, default=True), - } - try: - kwargs['spec_driver_handles_share_servers'] = ( - strutils.bool_from_string( - args.spec_driver_handles_share_servers, strict=True - ) - ) - except ValueError as e: - msg = ( - "Argument spec_driver_handles_share_servers " - f"argument is not valid: {str(e)}" - ) - raise exceptions.CommandError(msg) - - kwargs['extra_specs'] = _extract_extra_specs(args) - - if 'driver_handles_share_servers' in kwargs['extra_specs']: - msg = ( - "Argument 'driver_handles_share_servers' is already " - "set via positional argument." - ) - raise exceptions.CommandError(msg) - - show_des = False - if cs.api_version.matches( - api_versions.APIVersion("2.41"), api_versions.APIVersion() - ): - show_des = True - kwargs['description'] = getattr(args, 'description') - elif getattr(args, 'description'): - raise exceptions.CommandError( - "Pattern based option (description)" - " is only available with manila API version >= 2.41" - ) - - boolean_keys = ( - 'snapshot_support', - 'create_share_from_snapshot_support', - 'revert_to_snapshot_support', - 'mount_snapshot_support', - ) - for key in boolean_keys: - value = getattr(args, key) - - if value is not None and key in kwargs['extra_specs']: - msg = f"Argument '{key}' value specified twice." - raise exceptions.CommandError(msg) - - try: - if value: - kwargs['extra_specs'][key] = strutils.bool_from_string( - value, strict=True - ) - elif key in kwargs['extra_specs']: - kwargs['extra_specs'][key] = strutils.bool_from_string( - kwargs['extra_specs'][key], strict=True - ) - except ValueError as e: - msg = ( - f"Argument '{key}' is of boolean " - f"type and has invalid value: {str(e)}" - ) - raise exceptions.CommandError(msg) - - stype = cs.share_types.create(**kwargs) - _print_share_type(stype, show_des=show_des) - - -@cliutils.arg( - 'id', metavar='', help="Name or ID of the share type to update." -) -@cliutils.arg( - '--name', metavar='', type=str, help="New name of share type." -) -@cliutils.arg( - '--description', - metavar='', - type=str, - default=None, - help="New description of share type.", -) -@cliutils.arg( - '--is-public', - '--is_public', - metavar='', - action='single_alias', - help="New visibility of the share type. If set to True, share type will " - "be available to all projects in the cloud.", -) -@api_versions.wraps("2.50") -def do_type_update(cs, args): - """Update share type name, description, and/or visibility. (Admin only).""" - name = getattr(args, 'name') - description = getattr(args, 'description') - is_public = getattr(args, 'is_public') - if not name and description is None and is_public is None: - msg = ( - "A description and/or non-empty name and/or boolean is_public " - "must be supplied to update the respective attributes of the " - "share type." - ) - raise exceptions.CommandError(msg) - kwargs = {} - kwargs['name'] = name - if is_public: - try: - kwargs['is_public'] = strutils.bool_from_string( - is_public, strict=True - ) - except ValueError as e: - raise exceptions.CommandError( - "The value of 'is_public' is invalid: %s", str(e) - ) - - kwargs['description'] = description - stype = _find_share_type(cs, args.id) - stype = stype.update(**kwargs) - _print_share_type(stype, show_des=True) - - -@cliutils.arg( - 'id', - metavar='', - nargs='+', - help="Name or ID of the share type(s) to delete.", -) -def do_type_delete(cs, args): - """Delete one or more specific share types (Admin only).""" - - failure_count = 0 - - for name_or_id in args.id: - try: - id_ref = _find_share_type(cs, name_or_id) - cs.share_types.delete(id_ref) - except Exception as e: - failure_count += 1 - print( - f"Delete for share type {name_or_id} failed: {e}", - file=sys.stderr, - ) - - if failure_count == len(args.id): - raise exceptions.CommandError( - "Unable to delete any of the specified share types." - ) - - -@cliutils.arg('stype', metavar='', help="Name or ID of the share type.") -@cliutils.arg( - 'action', - metavar='', - choices=['set', 'unset'], - help="Actions: 'set' or 'unset'.", -) -@cliutils.arg( - 'metadata', - metavar='', - nargs='*', - default=None, - help='Extra_specs to set or unset (only key is necessary to unset).', -) -def do_type_key(cs, args): - """Set or unset extra_spec for a share type (Admin only).""" - stype = _find_share_type(cs, args.stype) - - if args.metadata is not None: - keypair = _extract_metadata(args) - - if args.action == 'set': - stype.set_keys(keypair) - elif args.action == 'unset': - stype.unset_keys(list(keypair)) - - -@cliutils.arg( - 'share_type', - metavar='', - help="Filter results by share type name or ID.", -) -def do_type_access_list(cs, args): - """Print access information about the given share type (Admin only).""" - share_type = _find_share_type(cs, args.share_type) - if share_type.is_public: - raise exceptions.CommandError( - "Forbidden to get access list for public share type." - ) - access_list = cs.share_type_access.list(share_type) - - columns = ['Project_ID'] - cliutils.print_list(access_list, columns) - - -@cliutils.arg( - 'share_type', - metavar='', - help="Share type name or ID to add access for the given project.", -) -@cliutils.arg( - 'project_id', - metavar='', - help='Project ID to add share type access for.', -) -def do_type_access_add(cs, args): - """Adds share type access for the given project (Admin only).""" - vtype = _find_share_type(cs, args.share_type) - cs.share_type_access.add_project_access(vtype, args.project_id) - - -@cliutils.arg( - 'share_type', - metavar='', - help=('Share type name or ID to remove access for the given project.'), -) -@cliutils.arg( - 'project_id', - metavar='', - help='Project ID to remove share type access for.', -) -def do_type_access_remove(cs, args): - """Removes share type access for the given project (Admin only).""" - vtype = _find_share_type(cs, args.share_type) - cs.share_type_access.remove_project_access(vtype, args.project_id) - - -############################################################################## -# -# Share group types -# -############################################################################## - - -def _print_share_group_type_list( - share_group_types, default_share_group_type=None, columns=None -): - def _is_default(share_group_type): - if hasattr(share_group_type, 'is_default'): - return 'YES' if share_group_type.is_default else '-' - elif default_share_group_type: - default = default_share_group_type.id - return 'YES' if share_group_type.id == default else '-' - else: - return '-' - - formatters = { - 'visibility': _is_share_type_public, - 'is_default': _is_default, - } - - for sg_type in share_group_types: - sg_type = sg_type.to_dict() - sg_type['visibility'] = sg_type.pop('is_public', 'unknown') - - fields = [ - 'ID', - 'Name', - 'visibility', - 'is_default', - ] - if columns is not None: - fields = _split_columns(columns=columns, title=False) - - cliutils.print_list( - share_group_types, fields, formatters, sortby_index=None - ) - - -def _print_share_group_type(share_group_type, default_share_type=None): - def _is_default(share_group_type): - if hasattr(share_group_type, 'is_default'): - return 'YES' if share_group_type.is_default else '-' - return '-' - - share_group_type_dict = { - 'ID': share_group_type.id, - 'Name': share_group_type.name, - 'Visibility': _is_share_type_public(share_group_type), - 'is_default': _is_default(share_group_type), - } - cliutils.print_dict(share_group_type_dict) - - -def _find_share_group_type(cs, sg_type): - """Get a share group type by name or ID.""" - return apiclient_utils.find_resource(cs.share_group_types, sg_type) - - -@cliutils.arg( - '--all', - dest='all', - action='store_true', - default=False, - help='Display all share group types (Admin only).', -) -@cliutils.arg( - '--columns', - metavar='', - type=str, - default=None, - help='Comma separated list of columns to be displayed ' - 'example --columns "id,name".', -) -@cliutils.service_type('sharev2') -def do_share_group_type_list(cs, args): - """Print a list of available 'share group types'.""" - - sg_types = cs.share_group_types.list(show_all=args.all) - - default = None - if sg_types and not hasattr(sg_types[0], 'is_default'): - if ( - args.columns and 'is_default' in args.columns - ) or args.columns is None: - default = cs.share_group_types.get() - - _print_share_group_type_list( - sg_types, default_share_group_type=default, columns=args.columns - ) - - -@cliutils.arg( - '--columns', - metavar='', - type=str, - default=None, - help='Comma separated list of columns to be displayed ' - 'example --columns "id,name".', -) -@cliutils.service_type('sharev2') -def do_share_group_type_specs_list(cs, args): - """Print a list of 'share group types specs' (Admin Only).""" - - sg_types = cs.share_group_types.list() - _print_type_and_extra_specs_list(sg_types, columns=args.columns) - - -@cliutils.arg( - 'name', metavar='', help='Name of the new share group type.' -) -@cliutils.arg( - 'share_types', - metavar='', - type=str, - help='Comma-separated list of share type names or IDs.', -) -@cliutils.arg( - '--is_public', - '--is-public', - metavar='', - action='single_alias', - help='Make type accessible to the public (default true).', -) -@cliutils.arg( - '--group-specs', - '--group_specs', - metavar='', - type=str, - nargs='*', - action='single_alias', - default=None, - help='Share Group type extra specs by key and value. ' - 'OPTIONAL: Default=None. ' - 'Example: "--group-specs consistent_snapshot_support=host".', -) -@cliutils.service_type('sharev2') -def do_share_group_type_create(cs, args): - """Create a new share group type (Admin only).""" - - share_types = [ - _find_share_type(cs, share_type) - for share_type in args.share_types.split(',') - ] - - kwargs = { - 'share_types': share_types, - 'name': args.name, - 'is_public': strutils.bool_from_string(args.is_public, default=True), - } - if args.group_specs is not None: - kwargs['group_specs'] = _extract_group_specs(args) - - sg_type = cs.share_group_types.create(**kwargs) - _print_share_group_type(sg_type) - - -@cliutils.arg( - 'id', metavar='', help="Name or ID of the share group type to delete." -) -@cliutils.service_type('sharev2') -def do_share_group_type_delete(cs, args): - """Delete a specific share group type (Admin only).""" - share_group_type = _find_share_group_type(cs, args.id) - cs.share_group_types.delete(share_group_type) - - -@cliutils.arg( - 'share_group_type', - metavar='', - help="Name or ID of the share group type.", -) -@cliutils.arg( - 'action', - metavar='', - choices=['set', 'unset'], - help="Actions: 'set' or 'unset'.", -) -@cliutils.arg( - 'group_specs', - metavar='', - nargs='*', - default=None, - help='Group specs to set or unset (only key is necessary to unset).', -) -@cliutils.service_type('sharev2') -def do_share_group_type_key(cs, args): - """Set or unset group_spec for a share group type (Admin only).""" - sg_type = _find_share_group_type(cs, args.share_group_type) - if args.group_specs is not None: - keypair = _extract_group_specs(args) - if args.action == 'set': - sg_type.set_keys(keypair) - elif args.action == 'unset': - sg_type.unset_keys(list(keypair)) - - -@cliutils.arg( - 'share_group_type', - metavar='', - help="Filter results by share group type name or ID.", -) -def do_share_group_type_access_list(cs, args): - """Print access information about a share group type (Admin only).""" - share_group_type = _find_share_group_type(cs, args.share_group_type) - if share_group_type.is_public: - raise exceptions.CommandError( - "Forbidden to get access list for public share group type." - ) - access_list = cs.share_group_type_access.list(share_group_type) - columns = ['Project_ID'] - cliutils.print_list(access_list, columns) - - -@cliutils.arg( - 'share_group_type', - metavar='', - help='Share group type name or ID to add access for the given project.', -) -@cliutils.arg( - 'project_id', - metavar='', - help='Project ID to add share group type access for.', -) -def do_share_group_type_access_add(cs, args): - """Adds share group type access for the given project (Admin only).""" - share_group_type = _find_share_group_type(cs, args.share_group_type) - cs.share_group_type_access.add_project_access( - share_group_type, args.project_id - ) - - -@cliutils.arg( - 'share_group_type', - metavar='', - help='Share group type name or ID to remove access for the given project.', -) -@cliutils.arg( - 'project_id', - metavar='', - help='Project ID to remove share group type access for.', -) -def do_share_group_type_access_remove(cs, args): - """Removes share group type access for the given project (Admin only).""" - share_group_type = _find_share_group_type(cs, args.share_group_type) - cs.share_group_type_access.remove_project_access( - share_group_type, args.project_id - ) - - -############################################################################## -# -# Share groups -# -############################################################################## - - -@cliutils.arg( - '--name', - metavar='', - help='Optional share group name. (Default=None)', - default=None, -) -@cliutils.arg( - '--description', - metavar='', - help='Optional share group description. (Default=None)', - default=None, -) -@cliutils.arg( - '--share-types', - '--share_types', - metavar='', - type=str, - default=None, - action='single_alias', - help='Comma-separated list of share types. (Default=None)', -) -@cliutils.arg( - '--share-group-type', - '--share_group_type', - '--type', - metavar='', - type=str, - default=None, - action='single_alias', - help="Share group type name or ID of the share group to be created. " - "(Default=None)", -) -@cliutils.arg( - '--share-network', - '--share_network', - metavar='', - type=str, - default=None, - action='single_alias', - help='Specify share network name or id.', -) -@cliutils.arg( - '--source-share-group-snapshot', - '--source_share_group_snapshot', - metavar='', - type=str, - action='single_alias', - help='Optional share group snapshot name or ID to create the share group ' - 'from. (Default=None)', - default=None, -) -@cliutils.arg( - '--availability-zone', - '--availability_zone', - '--az', - default=None, - action='single_alias', - metavar='', - help='Optional availability zone in which group should be created. ' - '(Default=None)', -) -@cliutils.arg( - '--wait', - action='store_true', - default=False, - help='Wait for share group to create', -) -@cliutils.service_type('sharev2') -def do_share_group_create(cs, args): - """Creates a new share group.""" - share_types = [] - if args.share_types: - s_types = args.share_types.split(',') - for s_type in s_types: - share_type = _find_share_type(cs, s_type) - share_types.append(share_type) - - share_group_type = None - if args.share_group_type: - share_group_type = _find_share_group_type(cs, args.share_group_type) - - share_network = None - if args.share_network: - share_network = _find_share_network(cs, args.share_network) - - share_group_snapshot = None - if args.source_share_group_snapshot: - share_group_snapshot = _find_share_group_snapshot( - cs, args.source_share_group_snapshot - ) - - kwargs = { - 'share_group_type': share_group_type, - 'share_types': share_types or None, - 'name': args.name, - 'description': args.description, - 'availability_zone': args.availability_zone, - 'source_share_group_snapshot': share_group_snapshot, - 'share_network': share_network, - } - - share_group = cs.share_groups.create(**kwargs) - - if args.wait: - try: - share_group = _wait_for_resource_status( - cs, - share_group, - resource_type='share_group', - expected_status='available', - ) - except exceptions.CommandError as e: - print(e, file=sys.stderr) - - _print_share_group(cs, share_group) - - -@cliutils.arg( - '--all-tenants', - '--all-projects', - action='single_alias', - dest='all_projects', - metavar='<0|1>', - nargs='?', - type=int, - const=1, - default=0, - help='Display information from all projects (Admin only).', -) -@cliutils.arg( - '--name', - metavar='', - type=str, - default=None, - help='Filter results by name.', -) -@cliutils.arg( - '--description', - metavar='', - type=str, - default=None, - help='Filter results by description. ' - 'Available only for microversion >= 2.36.', -) -@cliutils.arg( - '--status', - metavar='', - type=str, - default=None, - help='Filter results by status.', -) -@cliutils.arg( - '--share-server-id', - '--share-server_id', - '--share_server-id', - '--share_server_id', - metavar='', - type=str, - default=None, - action='single_alias', - help='Filter results by share server ID (Admin only).', -) -@cliutils.arg( - '--share-group-type', - '--share-group-type-id', - '--share_group_type', - '--share_group_type_id', - metavar='', - type=str, - default=None, - action='single_alias', - help='Filter results by a share group type ID or name that was used for ' - 'share group creation.', -) -@cliutils.arg( - '--snapshot', - metavar='', - type=str, - default=None, - help='Filter results by share group snapshot name or ID that was used to ' - 'create the share group.', -) -@cliutils.arg( - '--host', metavar='', default=None, help='Filter results by host.' -) -@cliutils.arg( - '--share-network', - '--share_network', - metavar='', - type=str, - default=None, - action='single_alias', - help='Filter results by share-network name or ID.', -) -@cliutils.arg( - '--project-id', - '--project_id', - metavar='', - type=str, - default=None, - action='single_alias', - help="Filter results by project ID. Useful with set key '--all-projects'.", -) -@cliutils.arg( - '--limit', - metavar='', - type=int, - default=None, - help='Maximum number of share groups to return. (Default=None)', -) -@cliutils.arg( - '--offset', - metavar="", - default=None, - help='Start position of share group listing.', -) -@cliutils.arg( - '--sort-key', - '--sort_key', - metavar='', - type=str, - default=None, - action='single_alias', - help=( - f'Key to be sorted, available keys are ' - f'{constants.SHARE_GROUP_SORT_KEY_VALUES}. Default=None.' - ), -) -@cliutils.arg( - '--sort-dir', - '--sort_dir', - metavar='', - type=str, - default=None, - action='single_alias', - help=f'Sort direction, available values are {constants.SORT_DIR_VALUES}. ' - 'OPTIONAL: Default=None.', -) -@cliutils.arg( - '--columns', - metavar='', - type=str, - default=None, - help='Comma separated list of columns to be displayed ' - 'example --columns "id,name".', -) -@cliutils.arg( - '--name~', - metavar='', - type=str, - default=None, - help='Filter results matching a share group name pattern. ' - 'Available only for microversion >= 2.36.', -) -@cliutils.arg( - '--description~', - metavar='', - type=str, - default=None, - help='Filter results matching a share group description pattern. ' - 'Available only for microversion >= 2.36.', -) -@cliutils.service_type('sharev2') -def do_share_group_list(cs, args): - """List share groups with filters.""" - if args.columns is not None: - list_of_keys = _split_columns(columns=args.columns) - else: - list_of_keys = ('ID', 'Name', 'Status', 'Description') - - all_projects = int( - os.environ.get( - "ALL_TENANTS", os.environ.get("ALL_PROJECTS", args.all_projects) - ) - ) - empty_obj = type('Empty', (object,), {'id': None}) - sg_type = ( - _find_share_group_type(cs, args.share_group_type) - if args.share_group_type - else empty_obj - ) - snapshot = ( - _find_share_snapshot(cs, args.snapshot) if args.snapshot else empty_obj - ) - share_network = ( - _find_share_network(cs, args.share_network) - if args.share_network - else empty_obj - ) - - search_opts = { - 'offset': args.offset, - 'limit': args.limit, - 'all_tenants': all_projects, - 'name': args.name, - 'status': args.status, - 'share_server_id': args.share_server_id, - 'share_group_type_id': sg_type.id, - 'source_share_group_snapshot_id': snapshot.id, - 'host': args.host, - 'share_network_id': share_network.id, - 'project_id': args.project_id, - } - if cs.api_version.matches( - api_versions.APIVersion("2.36"), api_versions.APIVersion() - ): - search_opts['name~'] = getattr(args, 'name~') - search_opts['description~'] = getattr(args, 'description~') - search_opts['description'] = getattr(args, 'description') - elif ( - getattr(args, 'name~') - or getattr(args, 'description~') - or getattr(args, 'description') - ): - raise exceptions.CommandError( - "Pattern based filtering (name~, description~ and description)" - " is only available with manila API version >= 2.36" - ) - - share_groups = cs.share_groups.list( - search_opts=search_opts, sort_key=args.sort_key, sort_dir=args.sort_dir - ) - cliutils.print_list(share_groups, fields=list_of_keys, sortby_index=None) - - -@cliutils.arg( - 'share_group', - metavar='', - help='Name or ID of the share group.', -) -@cliutils.service_type('sharev2') -def do_share_group_show(cs, args): - """Show details about a share group.""" - share_group = _find_share_group(cs, args.share_group) - _print_share_group(cs, share_group) - - -@cliutils.arg( - 'share_group', - metavar='', - help='Name or ID of the share group to update.', -) -@cliutils.arg( - '--name', - metavar='', - default=None, - help='Optional new name for the share group. (Default=None)', -) -@cliutils.arg( - '--description', - metavar='', - help='Optional share group description. (Default=None)', - default=None, -) -@cliutils.service_type('sharev2') -def do_share_group_update(cs, args): - """Update a share group.""" - kwargs = {} - - if args.name is not None: - kwargs['name'] = args.name - if args.description is not None: - kwargs['description'] = args.description - - if not kwargs: - msg = "Must supply name and/or description" - raise exceptions.CommandError(msg) - share_group = _find_share_group(cs, args.share_group) - share_group = cs.share_groups.update(share_group, **kwargs) - _print_share_group(cs, share_group) - - -@cliutils.arg( - 'share_group', - metavar='', - nargs='+', - help='Name or ID of the share group(s).', -) -@cliutils.arg( - '--force', - action='store_true', - default=False, - help='Attempt to force delete the share group (Default=False)' - ' (Admin only).', -) -@cliutils.arg( - '--wait', - action='store_true', - default=False, - help='Wait for share group to delete', -) -@cliutils.service_type('sharev2') -def do_share_group_delete(cs, args): - """Delete one or more share groups.""" - failure_count = 0 - share_group_to_delete = [] - - for share_group in args.share_group: - try: - share_group_ref = _find_share_group(cs, share_group) - share_group_to_delete.append(share_group_ref) - share_group_ref.delete(args.force) - except Exception as e: - failure_count += 1 - print( - f"Delete for share group {share_group} failed: {e}", - file=sys.stderr, - ) - - if failure_count == len(args.share_group): - raise exceptions.CommandError( - "Unable to delete any of the specified share groups." - ) - - if args.wait: - for share_group in share_group_to_delete: - try: - _wait_for_resource_status( - cs, - share_group, - resource_type='share_group', - expected_status='deleted', - ) - except exceptions.CommandError as e: - print(e, file=sys.stderr) - - -@cliutils.arg( - 'share_group', - metavar='', - help='Name or ID of the share group to modify.', -) -@cliutils.arg( - '--state', - metavar='', - default='available', - help=( - 'Indicate which state to assign the share group. ' - 'Options include available, error, creating, deleting, ' - 'error_deleting. If no state is provided, ' - 'available will be used.' - ), -) -@cliutils.service_type('sharev2') -def do_share_group_reset_state(cs, args): - """Explicitly update the state of a share group - - (Admin only). - """ - share_group = _find_share_group(cs, args.share_group) - cs.share_groups.reset_state(share_group, args.state) - - -############################################################################## -# -# Share group snapshots -# -############################################################################## - - -@cliutils.arg( - 'share_group', - metavar='', - help='Name or ID of the share group.', -) -@cliutils.arg( - '--name', - metavar='', - help='Optional share group snapshot name. (Default=None)', - default=None, -) -@cliutils.arg( - '--description', - metavar='', - help='Optional share group snapshot description. (Default=None)', - default=None, -) -@cliutils.arg( - '--wait', - action='store_true', - default=False, - help='Wait for share group snapshot to be created', -) -@cliutils.service_type('sharev2') -def do_share_group_snapshot_create(cs, args): - """Creates a new share group snapshot.""" - kwargs = {'name': args.name, 'description': args.description} - share_group = _find_share_group(cs, args.share_group) - sg_snapshot = cs.share_group_snapshots.create(share_group.id, **kwargs) - if args.wait: - _wait_for_resource_status( - cs, - sg_snapshot, - resource_type='share_group_snapshot', - expected_status='available', - ) - _print_share_group_snapshot(cs, sg_snapshot) - - -@cliutils.arg( - '--all-tenants', - '--all-projects', - action='single_alias', - dest='all_projects', - metavar='<0|1>', - nargs='?', - type=int, - const=1, - default=0, - help='Display information from all projects (Admin only).', -) -@cliutils.arg( - '--name', metavar='', default=None, help='Filter results by name.' -) -@cliutils.arg( - '--status', - metavar='', - default=None, - help='Filter results by status.', -) -@cliutils.arg( - '--share-group-id', - '--share_group_id', - metavar='', - default=None, - action='single_alias', - help='Filter results by share group ID.', -) -@cliutils.arg( - '--limit', - metavar='', - type=int, - default=None, - help='Maximum number of share group snapshots to return. (Default=None)', -) -@cliutils.arg( - '--offset', - metavar="", - default=None, - help='Start position of share group snapshot listing.', -) -@cliutils.arg( - '--sort-key', - '--sort_key', - metavar='', - type=str, - default=None, - action='single_alias', - help=( - f'Key to be sorted, available keys are ' - f'{constants.SHARE_GROUP_SNAPSHOT_SORT_KEY_VALUES}. Default=None.' - ), -) -@cliutils.arg( - '--sort-dir', - '--sort_dir', - metavar='', - type=str, - default=None, - action='single_alias', - help=f'Sort direction, available values are {constants.SORT_DIR_VALUES}. ' - 'OPTIONAL: Default=None.', -) -@cliutils.arg( - '--detailed', - dest='detailed', - default=True, - help='Show detailed information about share group snapshots.', -) -@cliutils.arg( - '--columns', - metavar='', - type=str, - default=None, - help='Comma separated list of columns to be displayed ' - 'example --columns "id,name".', -) -@cliutils.service_type('sharev2') -def do_share_group_snapshot_list(cs, args): - """List share group snapshots with filters.""" - if args.columns is not None: - list_of_keys = _split_columns(columns=args.columns) - else: - list_of_keys = ('id', 'name', 'status', 'description') - - all_projects = int( - os.environ.get( - "ALL_TENANTS", os.environ.get("ALL_PROJECTS", args.all_projects) - ) - ) - - search_opts = { - 'offset': args.offset, - 'limit': args.limit, - 'all_tenants': all_projects, - 'name': args.name, - 'status': args.status, - 'share_group_id': args.share_group_id, - } - share_group_snapshots = cs.share_group_snapshots.list( - detailed=args.detailed, - search_opts=search_opts, - sort_key=args.sort_key, - sort_dir=args.sort_dir, - ) - cliutils.print_list( - share_group_snapshots, fields=list_of_keys, sortby_index=None - ) - - -@cliutils.arg( - 'share_group_snapshot', - metavar='', - help='Name or ID of the share group snapshot.', -) -@cliutils.service_type('sharev2') -def do_share_group_snapshot_show(cs, args): - """Show details about a share group snapshot.""" - sg_snapshot = _find_share_group_snapshot(cs, args.share_group_snapshot) - _print_share_group_snapshot(cs, sg_snapshot) - - -@cliutils.arg( - 'share_group_snapshot', - metavar='', - help='Name or ID of the share group snapshot.', -) -@cliutils.arg( - '--columns', - metavar='', - type=str, - default=None, - help='Comma separated list of columns to be displayed ' - 'example --columns "id,name".', -) -@cliutils.service_type('sharev2') -def do_share_group_snapshot_list_members(cs, args): - """List members of a share group snapshot.""" - if args.columns is not None: - list_of_keys = _split_columns(columns=args.columns) - else: - list_of_keys = ('Share ID', 'Size') - - sg_snapshot = _find_share_group_snapshot(cs, args.share_group_snapshot) - members = [ - type('ShareGroupSnapshotMember', (object,), member) - for member in sg_snapshot._info.get('members', []) - ] - cliutils.print_list(members, fields=list_of_keys) - - -@cliutils.arg( - '--state', - metavar='', - default='available', - help=( - 'Indicate which state to assign the share group snapshot. ' - 'Options include available, error, creating, deleting, ' - 'error_deleting. If no state is provided, ' - 'available will be used.' - ), -) -@cliutils.arg( - 'share_group_snapshot', - metavar='', - help='Name or ID of the share group snapshot.', -) -@cliutils.service_type('sharev2') -def do_share_group_snapshot_reset_state(cs, args): - """Explicitly update the state of a share group snapshot - - (Admin only). - """ - sg_snapshot = _find_share_group_snapshot(cs, args.share_group_snapshot) - cs.share_group_snapshots.reset_state(sg_snapshot, args.state) - - -@cliutils.arg( - 'share_group_snapshot', - metavar='', - help='Name or ID of the share group snapshot to update.', -) -@cliutils.arg( - '--name', - metavar='', - default=None, - help='Optional new name for the share group snapshot. (Default=None)', -) -@cliutils.arg( - '--description', - metavar='', - help='Optional share group snapshot description. (Default=None)', - default=None, -) -@cliutils.service_type('sharev2') -def do_share_group_snapshot_update(cs, args): - """Update a share group snapshot.""" - kwargs = {} - - if args.name is not None: - kwargs['name'] = args.name - - if args.description is not None: - kwargs['description'] = args.description - - if not kwargs: - msg = "Must supply name and/or description" - raise exceptions.CommandError(msg) - - sg_snapshot = _find_share_group_snapshot(cs, args.share_group_snapshot) - cs.share_group_snapshots.update(sg_snapshot, **kwargs) - - -@cliutils.arg( - 'share_group_snapshot', - metavar='', - nargs='+', - help='Name or ID of the share group snapshot(s) to delete.', -) -@cliutils.arg( - '--force', - action='store_true', - default=False, - help='Attempt to force delete the share group snapshot(s) (Default=False)' - ' (Admin only).', -) -@cliutils.arg( - '--wait', - action='store_true', - default=False, - help='Wait for share group snapshot to be deleted', -) -@cliutils.service_type('sharev2') -def do_share_group_snapshot_delete(cs, args): - """Remove one or more share group snapshots.""" - failure_count = 0 - kwargs = {} - - kwargs['force'] = args.force - - for sg_snapshot in args.share_group_snapshot: - try: - sg_snapshot_ref = _find_share_group_snapshot(cs, sg_snapshot) - cs.share_group_snapshots.delete(sg_snapshot_ref, **kwargs) - if args.wait: - _wait_for_resource_status( - cs, - sg_snapshot, - resource_type='share_group_snapshot', - expected_status='deleted', - ) - except Exception as e: - failure_count += 1 - print( - f"Delete for share group snapshot {sg_snapshot} failed: {e}", - file=sys.stderr, - ) - - if failure_count == len(args.share_group_snapshot): - raise exceptions.CommandError( - "Unable to delete any of the specified share group snapshots." - ) - - -############################################################################## -# -# Share replicas -# -############################################################################## - - -@cliutils.arg( - '--share-id', - '--share_id', - '--si', # alias - metavar='', - default=None, - action='single_alias', - help='List replicas belonging to share.', -) -@cliutils.arg( - '--columns', - metavar='', - type=str, - default=None, - help='Comma separated list of columns to be displayed ' - 'example --columns "replica_state,id".', -) -@api_versions.wraps("2.11") -def do_share_replica_list(cs, args): - """List share replicas.""" - share = _find_share(cs, args.share_id) if args.share_id else None - - if args.columns is not None: - list_of_keys = _split_columns(columns=args.columns) - else: - list_of_keys = [ - 'ID', - 'Status', - 'Replica State', - 'Share ID', - 'Host', - 'Availability Zone', - 'Updated At', - ] - - if share: - replicas = cs.share_replicas.list(share) - else: - replicas = cs.share_replicas.list() - - cliutils.print_list(replicas, list_of_keys) - - -@api_versions.wraps("2.11", "2.66") -@cliutils.arg( - 'share', metavar='', help='Name or ID of the share to replicate.' -) -@cliutils.arg( - '--availability-zone', - '--availability_zone', - '--az', - default=None, - action='single_alias', - metavar='', - help='Optional Availability zone in which replica should be created.', -) -def do_share_replica_create(cs, args): - """Create a share replica.""" - share = _find_share(cs, args.share) - - body = { - 'share': share, - 'availability_zone': args.availability_zone, - } - replica = cs.share_replicas.create(**body) - _print_share_replica(cs, replica) - - -@api_versions.wraps("2.67", "2.71") -@cliutils.arg( - 'share', metavar='', help='Name or ID of the share to replicate.' -) -@cliutils.arg( - '--availability-zone', - '--availability_zone', - '--az', - default=None, - action='single_alias', - metavar='', - help='Optional Availability zone in which replica should be created.', -) -@cliutils.arg( - '--scheduler-hints', - '--scheduler_hints', - '--sh', - metavar='', - nargs='*', - help='Scheduler hints for the share replica as key=value pairs, ' - 'Supported key is only_host. Available for microversion >= 2.67. ', - default=None, -) -def do_share_replica_create(cs, args): # noqa - """Create a share replica.""" - share = _find_share(cs, args.share) - - scheduler_hints = {} - if args.scheduler_hints: - hints = _extract_key_value_options(args, 'scheduler_hints') - if 'only_host' not in hints.keys() or len(hints) > 1: - raise exceptions.CommandError( - "The only valid key supported with the --scheduler-hints " - "argument is 'only_host'." - ) - scheduler_hints['only_host'] = hints.get('only_host') - - body = { - 'share': share, - 'availability_zone': args.availability_zone, - } - if scheduler_hints: - body['scheduler_hints'] = scheduler_hints - - replica = cs.share_replicas.create(**body) - _print_share_replica(cs, replica) - - -@api_versions.wraps("2.72") -@cliutils.arg( - 'share', metavar='', help='Name or ID of the share to replicate.' -) -@cliutils.arg( - '--availability-zone', - '--availability_zone', - '--az', - default=None, - action='single_alias', - metavar='', - help='Optional Availability zone in which replica should be created.', -) -@cliutils.arg( - '--scheduler-hints', - '--scheduler_hints', - '--sh', - metavar='', - nargs='*', - help='Scheduler hints for the share replica as key=value pairs, ' - 'Supported key is only_host. Available for microversion >= 2.67. ', - default=None, -) -@cliutils.arg( - '--share-network', - '--share_network', - metavar='', - default=None, - action='single_alias', - help='Optional network info ID or name. ' - 'Available only for microversion >= 2.72', -) -@cliutils.arg( - '--wait', - action='store_true', - default=False, - help='Wait for share replica to be created', -) -def do_share_replica_create(cs, args): # noqa - """Create a share replica.""" - share = _find_share(cs, args.share) - - scheduler_hints = {} - if args.scheduler_hints: - hints = _extract_key_value_options(args, 'scheduler_hints') - if 'only_host' not in hints.keys() or len(hints) > 1: - raise exceptions.CommandError( - "The only valid key supported with the --scheduler-hints " - "argument is 'only_host'." - ) - scheduler_hints['only_host'] = hints.get('only_host') - - share_network = None - if args.share_network: - share_network = _find_share_network(cs, args.share_network) - - body = { - 'share': share, - 'availability_zone': args.availability_zone, - } - if scheduler_hints: - body['scheduler_hints'] = scheduler_hints - - if share_network: - body['share_network'] = share_network - - replica = cs.share_replicas.create(**body) - if args.wait: - _wait_for_resource_status( - cs, - replica, - resource_type='share_replica', - expected_status='available', - ) - _print_share_replica(cs, replica) - - -@cliutils.arg('replica', metavar='', help='ID of the share replica.') -@api_versions.wraps("2.11", "2.46") -def do_share_replica_show(cs, args): - """Show details about a replica.""" - - replica = cs.share_replicas.get(args.replica) - _print_share_replica(cs, replica) - - -@api_versions.wraps("2.47") # noqa -@cliutils.arg('replica', metavar='', help='ID of the share replica.') -def do_share_replica_show(cs, args): # noqa - """Show details about a replica.""" - - replica = cs.share_replicas.get(args.replica) - export_locations = cs.share_replica_export_locations.list(replica) - replica._info['export_locations'] = export_locations - _print_share_replica(cs, replica) - - -@cliutils.arg( - 'replica', metavar='', nargs='+', help='ID of the share replica.' -) -@cliutils.arg( - '--force', - action='store_true', - default=False, - help='Attempt to force deletion of a replica on its backend. Using ' - 'this option will purge the replica from Manila even if it ' - 'is not cleaned up on the backend. Defaults to False.', -) -@cliutils.arg( - '--wait', - action='store_true', - default=False, - help='Wait for share replica to be deleted', -) -@api_versions.wraps("2.11") -def do_share_replica_delete(cs, args): - """Remove one or more share replicas.""" - failure_count = 0 - kwargs = {"force": args.force} - - for replica in args.replica: - try: - replica_ref = _find_share_replica(cs, replica) - cs.share_replicas.delete(replica_ref, **kwargs) - if args.wait: - _wait_for_resource_status( - cs, - replica_ref, - resource_type='share_replica', - expected_status='deleted', - ) - except Exception as e: - failure_count += 1 - print( - f"Delete for share replica {replica} failed: {e}", - file=sys.stderr, - ) - - if failure_count == len(args.replica): - raise exceptions.CommandError( - "Unable to delete any of the specified replicas." - ) - - -@cliutils.arg('replica', metavar='', help='ID of the share replica.') -@api_versions.wraps("2.11", "2.74") -def do_share_replica_promote(cs, args): - """Promote specified replica to 'active' replica_state.""" - replica = _find_share_replica(cs, args.replica) - cs.share_replicas.promote(replica) - - -@cliutils.arg('replica', metavar='', help='ID of the share replica.') -@cliutils.arg( - '--quiesce-wait-time', - metavar='', - default=None, - help='Quiesce wait time in seconds. Available for microversion >= 2.75', -) -@cliutils.arg( - '--wait', - action='store_true', - default=False, - help='Wait for share replica to be promoted', -) -@api_versions.wraps("2.75") # noqa -def do_share_replica_promote(cs, args): # noqa - """Promote specified replica to 'active' replica_state.""" - replica = _find_share_replica(cs, args.replica) - - quiesce_wait_time = None - if args.quiesce_wait_time: - quiesce_wait_time = args.quiesce_wait_time - cs.share_replicas.promote(replica, quiesce_wait_time) - if args.wait: - _wait_for_resource_status( - cs, - replica, - resource_type='share_replica', - expected_status='active', - status_attr='replica_state', - ) - - -@api_versions.wraps("2.47") -@cliutils.arg('replica', metavar='', help='ID of the share replica.') -@cliutils.arg( - '--columns', - metavar='', - type=str, - default=None, - help='Comma separated list of columns to be displayed ' - 'example --columns "id,path,replica_state".', -) -def do_share_replica_export_location_list(cs, args): - """List export locations of a share replica.""" - if args.columns is not None: - list_of_keys = _split_columns(columns=args.columns) - else: - list_of_keys = [ - 'ID', - 'Availability Zone', - 'Replica State', - 'Preferred', - 'Path', - ] - replica = _find_share_replica(cs, args.replica) - export_locations = cs.share_replica_export_locations.list(replica) - cliutils.print_list(export_locations, list_of_keys) - - -@api_versions.wraps("2.47") -@cliutils.arg( - 'replica', metavar='', help='Name or ID of the share replica.' -) -@cliutils.arg( - 'export_location', - metavar='', - help='ID of the share replica export location.', -) -def do_share_replica_export_location_show(cs, args): - """Show details of a share replica's export location.""" - replica = _find_share_replica(cs, args.replica) - export_location = cs.share_replica_export_locations.get( - replica, args.export_location - ) - view_data = export_location._info.copy() - cliutils.print_dict(view_data) - - -@cliutils.arg( - 'replica', metavar='', help='ID of the share replica to modify.' -) -@cliutils.arg( - '--state', - metavar='', - default='available', - help=( - 'Indicate which state to assign the replica. Options include ' - 'available, error, creating, deleting, error_deleting. If no ' - 'state is provided, available will be used.' - ), -) -@api_versions.wraps("2.11") -def do_share_replica_reset_state(cs, args): - """Explicitly update the 'status' of a share replica.""" - replica = _find_share_replica(cs, args.replica) - cs.share_replicas.reset_state(replica, args.state) - - -@cliutils.arg( - 'replica', metavar='', help='ID of the share replica to modify.' -) -@cliutils.arg( - '--replica-state', - '--replica_state', - '--state', # alias for user sanity - metavar='', - default='out_of_sync', - action='single_alias', - help=( - 'Indicate which replica_state to assign the replica. Options ' - 'include in_sync, out_of_sync, active, error. If no ' - 'state is provided, out_of_sync will be used.' - ), -) -@api_versions.wraps("2.11") -def do_share_replica_reset_replica_state(cs, args): - """Explicitly update the 'replica_state' of a share replica.""" - replica = _find_share_replica(cs, args.replica) - cs.share_replicas.reset_replica_state(replica, args.replica_state) - - -@cliutils.arg( - 'replica', metavar='', help='ID of the share replica to resync.' -) -@api_versions.wraps("2.11") -def do_share_replica_resync(cs, args): - """Attempt to update the share replica with its 'active' mirror.""" - replica = _find_share_replica(cs, args.replica) - cs.share_replicas.resync(replica) - - -############################################################################## -# -# Share Transfer -# -############################################################################## - - -def _print_share_transfer(transfer): - info = transfer._info.copy() - info.pop('links', None) - - cliutils.print_dict(info) - - -@api_versions.wraps("2.77") -@cliutils.arg( - 'share', metavar='', help='Name or ID of share to transfer.' -) -@cliutils.arg( - '--name', - metavar='', - default=None, - help='Transfer name. Default=None.', -) -def do_share_transfer_create(cs, args): - """Creates a share transfer.""" - share = _find_share(cs, args.share) - transfer = cs.transfers.create(share.id, args.name) - _print_share_transfer(transfer) - - -@api_versions.wraps("2.77") -@cliutils.arg( - 'transfer', - metavar='', - nargs='+', - help='ID or name of the transfer(s).', -) -def do_share_transfer_delete(cs, args): - """Remove one or more transfers.""" - failure_count = 0 - - for transfer in args.transfer: - try: - transfer_ref = _find_share_transfer(cs, transfer) - transfer_ref.delete() - except Exception as e: - failure_count += 1 - print( - f"Delete for share transfer {transfer} failed: {e}", - file=sys.stderr, - ) - - if failure_count == len(args.transfer): - raise exceptions.CommandError( - "Unable to delete any of the specified transfers." - ) - - -@api_versions.wraps("2.77") -@cliutils.arg( - 'transfer', metavar='', help='ID of transfer to accept.' -) -@cliutils.arg( - 'auth_key', - metavar='', - help='Authentication key of transfer to accept.', -) -@cliutils.arg( - '--clear-rules', - '--clear_rules', - dest='clear_rules', - action='store_true', - default=False, - help="Whether manila should clean up the access rules after the " - "transfer is complete. (Default=False)", -) -def do_share_transfer_accept(cs, args): - """Accepts a share transfer.""" - cs.transfers.accept( - args.transfer, args.auth_key, clear_access_rules=args.clear_rules - ) - - -@api_versions.wraps("2.77") -@cliutils.arg( - '--all-tenants', - '--all-projects', - action='single_alias', - dest='all_projects', - metavar='<0|1>', - nargs='?', - type=int, - const=1, - default=0, - help='Shows details for all tenants. (Admin only).', -) -@cliutils.arg( - '--name', - metavar='', - default=None, - action='single_alias', - help='Transfer name. Default=None.', -) -@cliutils.arg( - '--id', - metavar='', - default=None, - action='single_alias', - help='Transfer ID. Default=None.', -) -@cliutils.arg( - '--resource-type', - '--resource_type', - metavar='', - default=None, - action='single_alias', - help='Transfer type, which can be share or network. Default=None.', -) -@cliutils.arg( - '--resource-id', - '--resource_id', - metavar='', - default=None, - action='single_alias', - help='Transfer resource id. Default=None.', -) -@cliutils.arg( - '--source-project-id', - '--source_project_id', - metavar='', - default=None, - action='single_alias', - help='Transfer source project id. Default=None.', -) -@cliutils.arg( - '--limit', - metavar='', - type=int, - default=None, - help='Maximum number of messages to return. (Default=None)', -) -@cliutils.arg( - '--offset', - metavar="", - default=None, - help='Start position of message listing.', -) -@cliutils.arg( - '--sort-key', - '--sort_key', - metavar='', - type=str, - default=None, - action='single_alias', - help=( - f'Key to be sorted, available keys are ' - f'{constants.SHARE_TRANSFER_SORT_KEY_VALUES}. Default=None.' - ), -) -@cliutils.arg( - '--sort-dir', - '--sort_dir', - metavar='', - type=str, - default=None, - action='single_alias', - help=f'Sort direction, available values are {constants.SORT_DIR_VALUES}. ' - 'Optional: Default=None.', -) -@cliutils.arg( - '--detailed', - dest='detailed', - metavar='<0|1>', - nargs='?', - type=int, - const=1, - default=0, - help="Show detailed information about filtered share transfers.", -) -@cliutils.arg( - '--columns', - metavar='', - type=str, - default=None, - help='Comma separated list of columns to be displayed ' - 'example --columns "id,resource_id".', -) -def do_share_transfer_list(cs, args): - """Lists all transfers.""" - if args.columns is not None: - list_of_keys = _split_columns(columns=args.columns) - else: - list_of_keys = ['ID', 'Name', 'Resource Type', 'Resource Id'] - - if args.detailed: - list_of_keys.extend( - [ - 'Created At', - 'Expires At', - 'Source Project Id', - 'Destination Project Id', - 'Accepted', - ] - ) - - all_projects = int( - os.environ.get( - "ALL_TENANTS", os.environ.get("ALL_PROJECTS", args.all_projects) - ) - ) - - search_opts = { - 'offset': args.offset, - 'limit': args.limit, - 'all_tenants': all_projects, - 'id': args.id, - 'name': args.name, - 'resource_type': args.resource_type, - 'resource_id': args.resource_id, - 'source_project_id': args.source_project_id, - } - share_transfers = cs.transfers.list( - detailed=args.detailed, - search_opts=search_opts, - sort_key=args.sort_key, - sort_dir=args.sort_dir, - ) - cliutils.print_list( - share_transfers, fields=list_of_keys, sortby_index=None - ) - - -@api_versions.wraps("2.77") -@cliutils.arg( - 'transfer', metavar='', help='Name or ID of transfer to show.' -) -def do_share_transfer_show(cs, args): - """Delete a transfer.""" - transfer = _find_share_transfer(cs, args.transfer) - _print_share_transfer(transfer) - - -############################################################################## -# -# User Messages -# -############################################################################## - - -@api_versions.wraps("2.37") -@cliutils.arg( - '--resource_id', - '--resource-id', - '--resource', - metavar='', - default=None, - action='single_alias', - help='Filters results by a resource uuid. Default=None.', -) -@cliutils.arg( - '--resource_type', - '--resource-type', - metavar='', - default=None, - action='single_alias', - help='Filters results by a resource type. Default=None. ' - 'Example: "manila message-list --resource_type share"', -) -@cliutils.arg( - '--action_id', - '--action-id', - '--action', - metavar='', - default=None, - action='single_alias', - help='Filters results by action id. Default=None.', -) -@cliutils.arg( - '--detail_id', - '--detail-id', - '--detail', - metavar='', - default=None, - action='single_alias', - help='Filters results by detail id. Default=None.', -) -@cliutils.arg( - '--request_id', - '--request-id', - '--request', - metavar='', - default=None, - action='single_alias', - help='Filters results by request id. Default=None.', -) -@cliutils.arg( - '--level', - '--message_level', - '--message-level', - metavar='', - default=None, - action='single_alias', - help='Filters results by the message level. Default=None. ' - 'Example: "manila message-list --level ERROR".', -) -@cliutils.arg( - '--limit', - metavar='', - type=int, - default=None, - help='Maximum number of messages to return. (Default=None)', -) -@cliutils.arg( - '--offset', - metavar="", - default=None, - help='Start position of message listing.', -) -@cliutils.arg( - '--sort-key', - '--sort_key', - metavar='', - type=str, - default=None, - action='single_alias', - help=( - f'Key to be sorted, available keys are ' - f'{constants.MESSAGE_SORT_KEY_VALUES}. Default=desc.' - ), -) -@cliutils.arg( - '--sort-dir', - '--sort_dir', - metavar='', - type=str, - default=None, - action='single_alias', - help=f'Sort direction, available values are {constants.SORT_DIR_VALUES}. ' - 'OPTIONAL: Default=None.', -) -@cliutils.arg( - '--columns', - metavar='', - type=str, - default=None, - help='Comma separated list of columns to be displayed ' - 'example --columns "resource_id,user_message".', -) -@cliutils.arg( - '--since', - metavar='', - default=None, - help='Return only user messages created since given date. ' - 'The date format must be conforming to ISO8601. ' - 'Available only for microversion >= 2.52.', -) -@cliutils.arg( - '--before', - metavar='', - default=None, - help='Return only user messages created before given date. ' - 'The date format must be conforming to ISO8601. ' - 'Available only for microversion >= 2.52.', -) -def do_message_list(cs, args): - """Lists all messages.""" - if args.columns is not None: - list_of_keys = _split_columns(columns=args.columns) - else: - list_of_keys = [ - 'ID', - 'Resource Type', - 'Resource ID', - 'Action ID', - 'User Message', - 'Detail ID', - 'Created At', - ] - - search_opts = { - 'offset': args.offset, - 'limit': args.limit, - 'request_id': args.request_id, - 'resource_type': args.resource_type, - 'resource_id': args.resource_id, - 'action_id': args.action_id, - 'detail_id': args.detail_id, - 'message_level': args.level, - } - if cs.api_version < api_versions.APIVersion("2.52"): - msg = ( - "Filtering messages by 'since' and 'before' is possible only " - "with Manila API version >=2.52" - ) - if getattr(args, 'since') or getattr(args, 'before'): - raise exceptions.CommandError(msg) - else: - search_opts['created_since'] = args.since - search_opts['created_before'] = args.before - - messages = cs.messages.list( - search_opts=search_opts, sort_key=args.sort_key, sort_dir=args.sort_dir - ) - cliutils.print_list(messages, fields=list_of_keys, sortby_index=None) - - -@cliutils.arg('message', metavar='', help='ID of the message.') -@api_versions.wraps("2.37") -def do_message_show(cs, args): - """Show details about a message.""" - - message = cs.messages.get(args.message) - _print_message(message) - - -@api_versions.wraps("2.37") -@cliutils.arg( - 'message', metavar='', nargs='+', help='ID of the message(s).' -) -def do_message_delete(cs, args): - """Remove one or more messages.""" - failure_count = 0 - - for message in args.message: - try: - message_ref = _find_message(cs, message) - cs.messages.delete(message_ref) - except Exception as e: - failure_count += 1 - print( - f"Delete for message {message} failed: {e}", - file=sys.stderr, - ) - - if failure_count == len(args.message): - raise exceptions.CommandError( - "Unable to delete any of the specified messages." - ) - - -def _print_message(message): - message_dict = { - 'id': message.id, - 'resource_type': message.resource_type, - 'resource_id': message.resource_id, - 'action_id': message.action_id, - 'user_message': message.user_message, - 'message_level': message.message_level, - 'detail_id': message.detail_id, - 'created_at': message.created_at, - 'expires_at': message.expires_at, - 'request_id': message.request_id, - } - cliutils.print_dict(message_dict) diff --git a/pyproject.toml b/pyproject.toml index 7b114c9b..27125510 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,9 +30,6 @@ classifiers = [ Homepage = "https://docs.openstack.org/python-manilaclient/" Repository = "https://opendev.org/openstack/python-manilaclient/" -[project.scripts] -manila = "manilaclient.shell:main" - [project.entry-points."oslo.config.opts"] "manilaclient.config" = "manilaclient.config:list_opts" diff --git a/releasenotes/notes/remove-python-client-a142b99ccc89731c.yaml b/releasenotes/notes/remove-python-client-a142b99ccc89731c.yaml new file mode 100644 index 00000000..7dd6380e --- /dev/null +++ b/releasenotes/notes/remove-python-client-a142b99ccc89731c.yaml @@ -0,0 +1,5 @@ +--- +upgrade: + The "manila" CLI utility has been removed in this release. The + mapping/decoder documentation still exists to provide transition + to users that are unfamiliar with the "openstack" CLI. diff --git a/tools/manila.bash_completion b/tools/manila.bash_completion deleted file mode 100644 index 8491e8ab..00000000 --- a/tools/manila.bash_completion +++ /dev/null @@ -1,15 +0,0 @@ -_manila() -{ - local cur prev opts - COMPREPLY=() - cur="${COMP_WORDS[COMP_CWORD]}" - prev="${COMP_WORDS[COMP_CWORD-1]}" - - opts="$(manila bash_completion)" - - COMPLETION_CACHE=~/.cache/manilaclient/*/*-cache - opts+=" "$(cat $COMPLETION_CACHE 2> /dev/null | tr '\n' ' ') - - COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) -} -complete -F _manila manila From b46eeee2f2b81d00652623baa23a064aef679c12 Mon Sep 17 00:00:00 2001 From: Goutham Pacha Ravi Date: Mon, 19 Jan 2026 14:30:56 -0800 Subject: [PATCH 32/52] Add requests-mock to test-requirements.txt Signed-off-by: Goutham Pacha Ravi Change-Id: Ie7aafaabb3e405b105d469a9b7c345bf38b0de34 --- test-requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/test-requirements.txt b/test-requirements.txt index 79d70223..da2474ff 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1,6 +1,7 @@ coverage!=4.4,>=4.0 # Apache-2.0 ddt>=1.0.1 # MIT fixtures>=3.0.0 # Apache-2.0/BSD +requests-mock>=1.2.0 # Apache-2.0 stestr>=2.0.0 # Apache-2.0 tempest>=17.1.0 # Apache-2.0 testtools>=2.2.0 # MIT From eb256137411313f3ac3fb640a9dcfb0cb17e5924 Mon Sep 17 00:00:00 2001 From: Goutham Pacha Ravi Date: Tue, 20 Jan 2026 14:45:32 -0800 Subject: [PATCH 33/52] Switch auth to keystoneauth Implements: bp/switch-to-keystoneauth Change-Id: Ida8991ad04660bcd2cd8a34b7a45772b992c8056 Signed-off-by: Goutham Pacha Ravi --- manilaclient/tests/unit/v2/test_client.py | 189 +++++++++--------- manilaclient/v1/client.py | 88 ++++---- manilaclient/v2/client.py | 86 ++++---- ...-keystoneauth-params-ebbaaf6be4df4bb7.yaml | 12 ++ requirements.txt | 2 +- 5 files changed, 208 insertions(+), 169 deletions(-) create mode 100644 releasenotes/notes/deprecate-keystoneauth-params-ebbaaf6be4df4bb7.yaml diff --git a/manilaclient/tests/unit/v2/test_client.py b/manilaclient/tests/unit/v2/test_client.py index 409dc82e..d3c38e9f 100644 --- a/manilaclient/tests/unit/v2/test_client.py +++ b/manilaclient/tests/unit/v2/test_client.py @@ -82,22 +82,32 @@ def test_auth_via_token(self): self.assertIsNotNone(c.client) self.assertIsNone(c.keystone_client) - @mock.patch.object(client.Client, '_get_keystone_client', mock.Mock()) - def test_valid_region_name_v1(self): + @mock.patch.object(client.Client, '_get_keystone_auth_and_session') + def test_valid_region_name_v1(self, mock_get_auth): self.mock_object(client.httpclient, 'HTTPClient') - kc = client.Client._get_keystone_client.return_value - kc.service_catalog = mock.Mock() - kc.service_catalog.get_endpoints = mock.Mock(return_value=self.catalog) + self.mock_object(client.adapter, 'LegacyJsonAdapter') + + # Mock the auth and session returned by _get_keystone_auth_and_session + mock_auth = mock.Mock() + mock_session = mock.Mock() + mock_get_auth.return_value = (mock_auth, mock_session) + + # Mock the adapter to return token and endpoint + mocked_adapter = client.adapter.LegacyJsonAdapter.return_value + mocked_adapter.session.get_token.return_value = 'fake_token' + mocked_adapter.session.get_endpoint.return_value = 'http://1.2.3.4' + mocked_adapter.auth = mock_auth + c = client.Client( api_version=manilaclient.API_DEPRECATED_VERSION, service_type="share", region_name='TestRegion', ) - self.assertTrue(client.Client._get_keystone_client.called) - kc.service_catalog.get_endpoints.assert_called_with('share') + + self.assertTrue(mock_get_auth.called) client.httpclient.HTTPClient.assert_called_with( 'http://1.2.3.4', - mock.ANY, + 'fake_token', 'python-manilaclient', insecure=False, cacert=None, @@ -109,43 +119,67 @@ def test_valid_region_name_v1(self): ) self.assertIsNotNone(c.client) - @mock.patch.object(client.Client, '_get_keystone_client', mock.Mock()) - def test_nonexistent_region_name(self): - kc = client.Client._get_keystone_client.return_value - kc.service_catalog = mock.Mock() - kc.service_catalog.get_endpoints = mock.Mock(return_value=self.catalog) + @mock.patch.object(client.Client, '_get_keystone_auth_and_session') + def test_nonexistent_region_name(self, mock_get_auth): + self.mock_object(client.adapter, 'LegacyJsonAdapter') + + # Mock the auth and session returned by _get_keystone_auth_and_session + mock_auth = mock.Mock() + mock_session = mock.Mock() + mock_get_auth.return_value = (mock_auth, mock_session) + + # Mock the adapter to return token but no endpoint (None) + mocked_adapter = client.adapter.LegacyJsonAdapter.return_value + mocked_adapter.session.get_token.return_value = 'fake_token' + mocked_adapter.session.get_endpoint.return_value = None + mocked_adapter.auth = mock_auth + self.assertRaises( RuntimeError, client.Client, api_version=manilaclient.API_MAX_VERSION, region_name='FakeRegion', ) - self.assertTrue(client.Client._get_keystone_client.called) - kc.service_catalog.get_endpoints.assert_called_with('sharev2') + self.assertTrue(mock_get_auth.called) + mocked_adapter.session.get_endpoint.assert_called_with( + mock_auth, + interface='publicURL', + service_type='sharev2', + region_name='FakeRegion', + ) - @mock.patch.object(client.Client, '_get_keystone_client', mock.Mock()) - def test_regions_with_same_name(self): + @mock.patch.object(client.Client, '_get_keystone_auth_and_session') + def test_regions_with_same_name(self, mock_get_auth): self.mock_object(client.httpclient, 'HTTPClient') - catalog = { - 'sharev2': [ - {'region': 'FirstRegion', 'publicURL': 'http://1.2.3.4'}, - {'region': 'secondregion', 'publicURL': 'http://1.1.1.1'}, - {'region': 'SecondRegion', 'publicURL': 'http://2.2.2.2'}, - ], - } - kc = client.Client._get_keystone_client.return_value - kc.service_catalog = mock.Mock() - kc.service_catalog.get_endpoints = mock.Mock(return_value=catalog) + self.mock_object(client.adapter, 'LegacyJsonAdapter') + + # Mock the auth and session returned by _get_keystone_auth_and_session + mock_auth = mock.Mock() + mock_session = mock.Mock() + mock_get_auth.return_value = (mock_auth, mock_session) + + # Mock the adapter to return token and endpoint + mocked_adapter = client.adapter.LegacyJsonAdapter.return_value + mocked_adapter.session.get_token.return_value = 'fake_token' + mocked_adapter.session.get_endpoint.return_value = 'http://2.2.2.2' + mocked_adapter.auth = mock_auth + c = client.Client( api_version=manilaclient.API_MIN_VERSION, service_type='sharev2', region_name='SecondRegion', ) - self.assertTrue(client.Client._get_keystone_client.called) - kc.service_catalog.get_endpoints.assert_called_with('sharev2') + + self.assertTrue(mock_get_auth.called) + mocked_adapter.session.get_endpoint.assert_called_with( + mock_auth, + interface='publicURL', + service_type='sharev2', + region_name='SecondRegion', + ) client.httpclient.HTTPClient.assert_called_with( 'http://2.2.2.2', - mock.ANY, + 'fake_token', 'python-manilaclient', insecure=False, cacert=None, @@ -219,68 +253,29 @@ def fake_url_for(version): return None self.mock_object(client.httpclient, 'HTTPClient') - self.mock_object(client.ks_client, 'Client') + self.mock_object(client.identity.v3, 'Password') + self.mock_object(client.adapter, 'LegacyJsonAdapter') self.mock_object(client.session.discover, 'Discover') self.mock_object(client.session, 'Session') client_args = self._get_client_args(**kwargs) client_args['api_version'] = manilaclient.API_MIN_VERSION self.auth_url = client_args['auth_url'] - catalog = { - 'share': [ - { - 'region': 'SecondRegion', - 'region_id': 'SecondRegion', - 'url': 'http://4.4.4.4', - 'interface': 'public', - }, - ], - 'sharev2': [ - { - 'region': 'FirstRegion', - 'interface': 'public', - 'region_id': 'SecondRegion', - 'url': 'http://1.1.1.1', - }, - { - 'region': 'secondregion', - 'interface': 'public', - 'region_id': 'SecondRegion', - 'url': 'http://2.2.2.2', - }, - { - 'region': 'SecondRegion', - 'interface': 'internal', - 'region_id': 'SecondRegion', - 'url': 'http://3.3.3.1', - }, - { - 'region': 'SecondRegion', - 'interface': 'public', - 'region_id': 'SecondRegion', - 'url': 'http://3.3.3.3', - }, - { - 'region': 'SecondRegion', - 'interface': 'admin', - 'region_id': 'SecondRegion', - 'url': 'http://3.3.3.2', - }, - ], - } + client.session.discover.Discover.return_value.url_for.side_effect = ( fake_url_for ) - client.ks_client.Client.return_value.auth_token.return_value = ( - 'fake_token' - ) - mocked_ks_client = client.ks_client.Client.return_value - mocked_ks_client.service_catalog.get_endpoints.return_value = catalog + + # Mock the adapter to return token and endpoint + mocked_adapter = client.adapter.LegacyJsonAdapter.return_value + mocked_adapter.session.get_token.return_value = 'fake_token' + mocked_adapter.session.get_endpoint.return_value = 'http://3.3.3.3' + mocked_adapter.auth = client.identity.v3.Password.return_value client.Client(**client_args) client.httpclient.HTTPClient.assert_called_with( 'http://3.3.3.3', - mock.ANY, + 'fake_token', 'python-manilaclient', insecure=False, cacert=None, @@ -291,9 +286,8 @@ def fake_url_for(version): api_version=manilaclient.API_MIN_VERSION, ) - client.ks_client.Client.assert_called_with( - session=mock.ANY, - version=(3, 0), + # Verify identity.v3.Password was called with correct credentials + client.identity.v3.Password.assert_called_with( auth_url='url_v3.0', username=client_args['username'], password=client_args.get('password'), @@ -306,18 +300,35 @@ def fake_url_for(version): project_name=client_args['project_name'], project_domain_name=client_args['project_domain_name'], project_domain_id=client_args['project_domain_id'], + ) + + # Verify LegacyJsonAdapter was created + client.adapter.LegacyJsonAdapter.assert_called_with( + session=mock.ANY, + auth=mock.ANY, + interface=client_args['endpoint_type'], + service_type=client_args['service_type'], + service_name=None, region_name=client_args['region_name'], ) - mocked_ks_client.service_catalog.get_endpoints.assert_called_with( - client_args['service_type'] + + # Verify session.get_token() was called + mocked_adapter.session.get_token.assert_called_with(mock.ANY) + + # Verify session.get_endpoint() was called + mocked_adapter.session.get_endpoint.assert_called_with( + mock.ANY, + interface=client_args['endpoint_type'], + service_type=client_args['service_type'], + region_name=client_args['region_name'], ) - mocked_ks_client.authenticate.assert_called_with() - @mock.patch.object(client.ks_client, 'Client', mock.Mock()) @mock.patch.object(client.session.discover, 'Discover', mock.Mock()) @mock.patch.object(client.session, 'Session', mock.Mock()) def test_client_init_no_session_no_auth_token_endpoint_not_found(self): self.mock_object(client.httpclient, 'HTTPClient') + self.mock_object(client.identity.v3, 'Password') + self.mock_object(client.adapter, 'LegacyJsonAdapter') client_args = self._get_client_args( auth_urli='fake_url', password='foo_password', @@ -325,7 +336,6 @@ def test_client_init_no_session_no_auth_token_endpoint_not_found(self): ) discover = client.session.discover.Discover discover.return_value.url_for.return_value = None - mocked_ks_client = client.ks_client.Client.return_value self.assertRaises( exceptions.CommandError, client.Client, **client_args @@ -334,6 +344,5 @@ def test_client_init_no_session_no_auth_token_endpoint_not_found(self): self.assertTrue(client.session.Session.called) self.assertTrue(client.session.discover.Discover.called) self.assertFalse(client.httpclient.HTTPClient.called) - self.assertFalse(client.ks_client.Client.called) - self.assertFalse(mocked_ks_client.service_catalog.get_endpoints.called) - self.assertFalse(mocked_ks_client.authenticate.called) + self.assertFalse(client.identity.v3.Password.called) + self.assertFalse(client.adapter.LegacyJsonAdapter.called) diff --git a/manilaclient/v1/client.py b/manilaclient/v1/client.py index 9f82b427..3a8d6a41 100644 --- a/manilaclient/v1/client.py +++ b/manilaclient/v1/client.py @@ -13,8 +13,8 @@ from debtcollector import removals from keystoneauth1 import adapter +from keystoneauth1 import identity from keystoneauth1 import session -from keystoneclient import client as ks_client import manilaclient from manilaclient.common import constants @@ -50,7 +50,7 @@ class Client: Or, alternatively, you can create a client instance using the keystoneauth1.session API:: - >>> from keystoneclient.auth.identity import v3 + >>> from keystoneauth1.identity import v3 >>> from keystoneauth1 import session >>> from manilaclient import client >>> auth = v3.Password(auth_url=AUTH_URL, @@ -68,6 +68,24 @@ class Client: ... """ + @removals.removed_kwarg( + 'use_keyring', + message='This parameter is no longer supported and has no effect.', + version='5.8.0', + removal_version='6.0.0', + ) + @removals.removed_kwarg( + 'force_new_token', + message='This parameter is no longer supported and has no effect.', + version='5.8.0', + removal_version='6.0.0', + ) + @removals.removed_kwarg( + 'cached_token_lifetime', + message='This parameter is no longer supported and has no effect.', + version='5.8.0', + removal_version='6.0.0', + ) def __init__( self, username=None, @@ -124,10 +142,6 @@ def __init__( self.cert = cert self.insecure = insecure - self.use_keyring = use_keyring - self.force_new_token = force_new_token - self.cached_token_lifetime = cached_token_lifetime - if input_auth_token and not service_catalog_url: msg = ( "For token-based authentication you should " @@ -144,6 +158,7 @@ def __init__( # if token is provided. if not input_auth_token: if session: + # Modern path - session provided by caller (e.g., OSC plugin) self.keystone_client = adapter.LegacyJsonAdapter( session=session, auth=auth, @@ -153,36 +168,30 @@ def __init__( region_name=region_name, ) input_auth_token = self.keystone_client.session.get_token(auth) - else: - self.keystone_client = self._get_keystone_client() - input_auth_token = self.keystone_client.auth_token + # Legacy path - create auth plugin and session ourselves + auth, ks_session = self._get_keystone_auth_and_session() + self.keystone_client = adapter.LegacyJsonAdapter( + session=ks_session, + auth=auth, + interface=endpoint_type, + service_type=service_type, + service_name=service_name, + region_name=region_name, + ) + input_auth_token = self.keystone_client.session.get_token(auth) if not input_auth_token: raise RuntimeError("Not Authorized") - if session and not service_catalog_url: + if not service_catalog_url: + # Use keystoneauth1 session endpoint discovery service_catalog_url = self.keystone_client.session.get_endpoint( - auth, interface=endpoint_type, service_type=service_type + self.keystone_client.auth, + interface=endpoint_type, + service_type=service_type, + region_name=region_name, ) - elif not service_catalog_url: - catalog = self.keystone_client.service_catalog.get_endpoints( - service_type - ) - for catalog_entry in catalog.get(service_type, []): - if catalog_entry.get("interface") == ( - endpoint_type.lower().split("url")[0] - ) or catalog_entry.get(endpoint_type): - if region_name and not region_name == ( - catalog_entry.get( - "region", catalog_entry.get("region_id") - ) - ): - continue - service_catalog_url = catalog_entry.get( - "url", catalog_entry.get(endpoint_type) - ) - break if not service_catalog_url: raise RuntimeError("Could not find Manila endpoint in catalog") @@ -227,17 +236,21 @@ def _load_extensions(self, extensions): if extension.manager_class: setattr(self, extension.name, extension.manager_class(self)) - def _get_keystone_client(self): - # First create a Keystone session + def _get_keystone_auth_and_session(self): + """Create keystoneauth1 auth plugin and session for authentication. + + Returns: + tuple: (auth_plugin, session) for use with keystoneauth1 + """ + # Create session with SSL settings if self.insecure: verify = False else: verify = self.cacert or True ks_session = session.Session(verify=verify, cert=self.cert) - # Discover the supported keystone versions using the given url + # Discover Keystone v3 endpoint ks_discover = session.discover.Discover(ks_session, self.auth_url) - auth_url = ks_discover.url_for('v3.0') if not auth_url: raise exceptions.CommandError( @@ -245,9 +258,8 @@ def _get_keystone_client(self): 'with using the given auth_url.' ) - keystone_client = ks_client.Client( - session=ks_session, - version=(3, 0), + # Create v3 Password auth plugin + auth = identity.v3.Password( auth_url=auth_url, username=self.username, password=self.password, @@ -258,8 +270,6 @@ def _get_keystone_client(self): project_name=self.project_name, project_domain_name=self.project_domain_name, project_domain_id=self.project_domain_id, - region_name=self.region_name, ) - keystone_client.authenticate() - return keystone_client + return auth, ks_session diff --git a/manilaclient/v2/client.py b/manilaclient/v2/client.py index 6fc214e4..9acb079f 100644 --- a/manilaclient/v2/client.py +++ b/manilaclient/v2/client.py @@ -10,9 +10,10 @@ # License for the specific language governing permissions and limitations # under the License. +from debtcollector import removals from keystoneauth1 import adapter +from keystoneauth1 import identity from keystoneauth1 import session -from keystoneclient import client as ks_client import manilaclient from manilaclient.common import constants @@ -64,7 +65,7 @@ class Client: Or, alternatively, you can create a client instance using the keystoneauth1.session API:: - >>> from keystoneclient.auth.identity import v3 + >>> from keystoneauth1.identity import v3 >>> from keystoneauth1 import session >>> from manilaclient import client >>> auth = v3.Password(auth_url=AUTH_URL, @@ -82,6 +83,24 @@ class Client: ... """ + @removals.removed_kwarg( + 'use_keyring', + message='This parameter is no longer supported and has no effect.', + version='5.8.0', + removal_version='6.0.0', + ) + @removals.removed_kwarg( + 'force_new_token', + message='This parameter is no longer supported and has no effect.', + version='5.8.0', + removal_version='6.0.0', + ) + @removals.removed_kwarg( + 'cached_token_lifetime', + message='This parameter is no longer supported and has no effect.', + version='5.8.0', + removal_version='6.0.0', + ) def __init__( self, username=None, @@ -138,10 +157,6 @@ def __init__( self.cert = cert self.insecure = insecure - self.use_keyring = use_keyring - self.force_new_token = force_new_token - self.cached_token_lifetime = cached_token_lifetime - if input_auth_token and not service_catalog_url: msg = ( "For token-based authentication you should " @@ -158,6 +173,7 @@ def __init__( # if token is provided. if not input_auth_token: if session: + # Modern path - session provided by caller (e.g., OSC plugin) self.keystone_client = adapter.LegacyJsonAdapter( session=session, auth=auth, @@ -167,39 +183,30 @@ def __init__( region_name=region_name, ) input_auth_token = self.keystone_client.session.get_token(auth) - else: - self.keystone_client = self._get_keystone_client() - input_auth_token = self.keystone_client.auth_token + # Legacy path - create auth plugin and session ourselves + auth, ks_session = self._get_keystone_auth_and_session() + self.keystone_client = adapter.LegacyJsonAdapter( + session=ks_session, + auth=auth, + interface=endpoint_type, + service_type=service_type, + service_name=service_name, + region_name=region_name, + ) + input_auth_token = self.keystone_client.session.get_token(auth) if not input_auth_token: raise RuntimeError("Not Authorized") - if session and not service_catalog_url: + if not service_catalog_url: + # Use keystoneauth1 session endpoint discovery service_catalog_url = self.keystone_client.session.get_endpoint( - auth, + self.keystone_client.auth, interface=endpoint_type, service_type=service_type, region_name=region_name, ) - elif not service_catalog_url: - catalog = self.keystone_client.service_catalog.get_endpoints( - service_type - ) - for catalog_entry in catalog.get(service_type, []): - if catalog_entry.get("interface") == ( - endpoint_type.lower().split("url")[0] - ) or catalog_entry.get(endpoint_type): - if region_name and not region_name == ( - catalog_entry.get( - "region", catalog_entry.get("region_id") - ) - ): - continue - service_catalog_url = catalog_entry.get( - "url", catalog_entry.get(endpoint_type) - ) - break if not service_catalog_url: raise RuntimeError("Could not find Manila endpoint in catalog") @@ -292,17 +299,21 @@ def _load_extensions(self, extensions): if extension.manager_class: setattr(self, extension.name, extension.manager_class(self)) - def _get_keystone_client(self): - # First create a Keystone session + def _get_keystone_auth_and_session(self): + """Create keystoneauth1 auth plugin and session for authentication. + + Returns: + tuple: (auth_plugin, session) for use with keystoneauth1 + """ + # Create session with SSL settings if self.insecure: verify = False else: verify = self.cacert or True ks_session = session.Session(verify=verify, cert=self.cert) - # Discover the supported keystone versions using the given url + # Discover Keystone v3 endpoint ks_discover = session.discover.Discover(ks_session, self.auth_url) - auth_url = ks_discover.url_for('v3.0') if not auth_url: raise exceptions.CommandError( @@ -310,9 +321,8 @@ def _get_keystone_client(self): 'with using the given auth_url.' ) - keystone_client = ks_client.Client( - session=ks_session, - version=(3, 0), + # Create v3 Password auth plugin + auth = identity.v3.Password( auth_url=auth_url, username=self.username, password=self.password, @@ -323,8 +333,6 @@ def _get_keystone_client(self): project_name=self.project_name, project_domain_name=self.project_domain_name, project_domain_id=self.project_domain_id, - region_name=self.region_name, ) - keystone_client.authenticate() - return keystone_client + return auth, ks_session diff --git a/releasenotes/notes/deprecate-keystoneauth-params-ebbaaf6be4df4bb7.yaml b/releasenotes/notes/deprecate-keystoneauth-params-ebbaaf6be4df4bb7.yaml new file mode 100644 index 00000000..14065910 --- /dev/null +++ b/releasenotes/notes/deprecate-keystoneauth-params-ebbaaf6be4df4bb7.yaml @@ -0,0 +1,12 @@ +--- +deprecations: + - | + Legacy keystoneclient options "use_keyring", "force_new_token" + and "cached_token_lifetime" were dropped. Using these options + will have no effect with this release and will cause an error + in a future release. +security: + - | + The use of the keystoneclient library has been replaced with keystoneauth. + The latter library is better maintained and has more auth options that are + now usable with manilaclient. diff --git a/requirements.txt b/requirements.txt index 643648ee..68a76f22 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,5 +11,5 @@ oslo.utils>=3.33.0 # Apache-2.0 PrettyTable>=0.7.1 # BSD requests>=2.14.2 # Apache-2.0 osc-lib>=3.2.0 # Apache-2.0 -python-keystoneclient>=3.8.0 # Apache-2.0 +keystoneauth1>=3.0.0 # Apache-2.0 debtcollector>=1.2.0 # Apache-2.0 From e4edf76825c351cde2a486dbefed2a00211c5055 Mon Sep 17 00:00:00 2001 From: Eunkyung99 Date: Tue, 2 Dec 2025 10:39:38 +0900 Subject: [PATCH 34/52] Add mount_point_name option for manage shares Implemented mount_point_name option for share manage API from microversion 2.92. Added mount_point_name set support. Implements: blueprint manage-with-mount-point-name Change-Id: Ifad39b7cbb836723416e403ad5b4bf7fa0bb195d Signed-off-by: eunkyung --- manilaclient/api_versions.py | 2 +- manilaclient/osc/v2/share.py | 18 ++++++++++ manilaclient/tests/unit/v2/test_shares.py | 22 ++++++++++++ manilaclient/v2/shares.py | 35 ++++++++++++++++++- ...ith-mount-point-name-69be3a8aa4fcaa1f.yaml | 4 +++ 5 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 releasenotes/notes/bp-manage-with-mount-point-name-69be3a8aa4fcaa1f.yaml diff --git a/manilaclient/api_versions.py b/manilaclient/api_versions.py index 09eb8fd1..73601af2 100644 --- a/manilaclient/api_versions.py +++ b/manilaclient/api_versions.py @@ -27,7 +27,7 @@ LOG = logging.getLogger(__name__) -MAX_VERSION = '2.91' +MAX_VERSION = '2.92' MIN_VERSION = '2.0' DEPRECATED_VERSION = '1.0' _VERSIONED_METHOD_MAP = {} diff --git a/manilaclient/osc/v2/share.py b/manilaclient/osc/v2/share.py index de269894..c32e9ce2 100644 --- a/manilaclient/osc/v2/share.py +++ b/manilaclient/osc/v2/share.py @@ -1171,6 +1171,15 @@ def get_parser(self, prog_name): '(Default=None)' ), ) + parser.add_argument( + '--mount-point-name', + metavar="", + default=None, + help=_( + 'Optional custom export location. Available only for ' + 'microversion >= 2.92. (Default=None)' + ), + ) parser.add_argument( "--wait", action='store_true', @@ -1221,6 +1230,15 @@ def take_action(self, parsed_args): 'API microversion >= 2.49' ) + if parsed_args.mount_point_name: + if share_client.api_version >= api_versions.APIVersion("2.92"): + kwargs['mount_point_name'] = parsed_args.mount_point_name + else: + raise exceptions.CommandError( + 'Setting share mount point name is available only for ' + 'API microversion >= 2.92' + ) + share = share_client.shares.manage(**kwargs) if parsed_args.wait: diff --git a/manilaclient/tests/unit/v2/test_shares.py b/manilaclient/tests/unit/v2/test_shares.py index 1ee49411..038e202a 100644 --- a/manilaclient/tests/unit/v2/test_shares.py +++ b/manilaclient/tests/unit/v2/test_shares.py @@ -236,6 +236,7 @@ def test_restore_share(self): ("2.8", "/shares/manage", True), ("2.8", "/shares/manage", False), ("2.49", "/shares/manage", False, '1234'), + ("2.92", "/shares/manage", False, None, 'fake_mount_pt1'), ) @ddt.unpack def test_manage_share( @@ -244,6 +245,7 @@ def test_manage_share( resource_path, is_public=False, share_server_id=None, + mount_point_name=None, ): service_host = "fake_service_host" protocol = "fake_protocol" @@ -266,6 +268,9 @@ def test_manage_share( if version >= api_versions.APIVersion('2.8'): expected_body["is_public"] = is_public + if version >= api_versions.APIVersion('2.92'): + expected_body["mount_point_name"] = mount_point_name + mock_microversion = mock.Mock(api_version=version) manager = shares.ShareManager(api=mock_microversion) @@ -297,6 +302,22 @@ def test_manage_share( description, is_public, ) + elif ( + api_versions.APIVersion('2.49') + <= version + < api_versions.APIVersion('2.92') + ): + result = manager.manage( + service_host, + protocol, + export_path, + driver_options, + share_type, + name, + description, + is_public, + share_server_id, + ) else: result = manager.manage( service_host, @@ -308,6 +329,7 @@ def test_manage_share( description, is_public, share_server_id, + mount_point_name, ) self.assertEqual(manager._create.return_value, result) diff --git a/manilaclient/v2/shares.py b/manilaclient/v2/shares.py index 73c2f8a0..a48fce68 100644 --- a/manilaclient/v2/shares.py +++ b/manilaclient/v2/shares.py @@ -287,6 +287,7 @@ def _do_manage( description=None, is_public=None, share_server_id=None, + mount_point_name=None, resource_path="/shares/manage", ): """Manage some existing share. @@ -300,6 +301,7 @@ def _do_manage( :param description: - description for new share :param is_public: - visibility for new share :param share_server_id: text - id of share server associated with share + :param mount_point_name: text - mount point name of share """ driver_options = driver_options if driver_options else dict() body = { @@ -316,6 +318,9 @@ def _do_manage( if is_public is not None: body['is_public'] = is_public + if mount_point_name is not None: + body['mount_point_name'] = mount_point_name + return self._create(resource_path, {'share': body}, 'share') @api_versions.wraps("1.0", "2.6") @@ -386,7 +391,7 @@ def manage( # noqa resource_path="/shares/manage", ) - @api_versions.wraps("2.49") # noqa + @api_versions.wraps("2.49", "2.91") # noqa def manage( # noqa self, service_host, @@ -412,6 +417,34 @@ def manage( # noqa resource_path="/shares/manage", ) + @api_versions.wraps("2.92") # noqa + def manage( # noqa + self, + service_host, + protocol, + export_path, + driver_options=None, + share_type=None, + name=None, + description=None, + is_public=False, + share_server_id=None, + mount_point_name=None, + ): + return self._do_manage( + service_host, + protocol, + export_path, + driver_options=driver_options, + share_type=share_type, + name=name, + description=description, + is_public=is_public, + share_server_id=share_server_id, + mount_point_name=mount_point_name, + resource_path="/shares/manage", + ) + @api_versions.wraps("1.0", "2.6") def unmanage(self, share): """Unmanage a share. diff --git a/releasenotes/notes/bp-manage-with-mount-point-name-69be3a8aa4fcaa1f.yaml b/releasenotes/notes/bp-manage-with-mount-point-name-69be3a8aa4fcaa1f.yaml new file mode 100644 index 00000000..d8f70817 --- /dev/null +++ b/releasenotes/notes/bp-manage-with-mount-point-name-69be3a8aa4fcaa1f.yaml @@ -0,0 +1,4 @@ +--- +features: + - Updated CLI command for managing shares to accept + ``mount_point_name`` parameter as a option. From 495f213c433d6ab532d4ade30bdde1ce687fea02 Mon Sep 17 00:00:00 2001 From: Kiran Pawar Date: Mon, 9 Feb 2026 12:51:30 +0000 Subject: [PATCH 35/52] fix share server get migration progress When share server migration is completed, get migration progress query fails since source share server is deleted in Manila. However, Manila is able to return status i.e. 100% when queried using source share server. The manilaclient is fixed to handle this scenario. Closes-bug: #2068732 Change-Id: Ia4ac62e740ca6a2882fbeadc6b60ebea3edc1b5e Signed-off-by: Kiran Pawar --- manilaclient/osc/v2/share_servers.py | 5 ++--- manilaclient/tests/unit/osc/v2/test_share_servers.py | 9 +++++++++ ...progress-on-source-share-server-7ef327dcdedcfbd6.yaml | 5 +++++ 3 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 releasenotes/notes/bug-2068732-fix-migration-get-progress-on-source-share-server-7ef327dcdedcfbd6.yaml diff --git a/manilaclient/osc/v2/share_servers.py b/manilaclient/osc/v2/share_servers.py index 8db3e2bb..6ed479f7 100644 --- a/manilaclient/osc/v2/share_servers.py +++ b/manilaclient/osc/v2/share_servers.py @@ -639,10 +639,9 @@ def get_parser(self, prog_name): def take_action(self, parsed_args): share_client = self.app.client_manager.share if share_client.api_version >= api_versions.APIVersion("2.57"): - share_server = osc_utils.find_resource( - share_client.share_servers, parsed_args.share_server + result = share_client.share_servers.migration_get_progress( + parsed_args.share_server ) - result = share_server.migration_get_progress() return self.dict2columns(result) else: raise exceptions.CommandError( diff --git a/manilaclient/tests/unit/osc/v2/test_share_servers.py b/manilaclient/tests/unit/osc/v2/test_share_servers.py index 77409107..7ffd28a8 100644 --- a/manilaclient/tests/unit/osc/v2/test_share_servers.py +++ b/manilaclient/tests/unit/osc/v2/test_share_servers.py @@ -651,6 +651,11 @@ def setUp(self): ) self.share_networks_mock.get.return_value = self.new_share_network + migration_dict = { + 'total_progress': 'fake', + 'task_state': 'migration_in_progress', + 'destination_share_server_id': 'fake_id', + } self.share_server = manila_fakes.FakeShareServer.create_one_server( attrs={ 'status': 'migrating', @@ -659,6 +664,10 @@ def setUp(self): methods={'migration_get_progress': None}, ) self.servers_mock.get.return_value = self.share_server + share_client = self.app.client_manager.share + share_client.share_servers.migration_get_progress.return_value = ( + migration_dict + ) # Get the command objects to test self.cmd = osc_share_servers.ShareServerMigrationShow(self.app, None) diff --git a/releasenotes/notes/bug-2068732-fix-migration-get-progress-on-source-share-server-7ef327dcdedcfbd6.yaml b/releasenotes/notes/bug-2068732-fix-migration-get-progress-on-source-share-server-7ef327dcdedcfbd6.yaml new file mode 100644 index 00000000..fbe7711d --- /dev/null +++ b/releasenotes/notes/bug-2068732-fix-migration-get-progress-on-source-share-server-7ef327dcdedcfbd6.yaml @@ -0,0 +1,5 @@ +--- +fixes: + - | + Fixed an issue while getting share server migration progress for source + share server after migration is completed. From bb847614445bb755dacc6e908bea26b8c025fbec Mon Sep 17 00:00:00 2001 From: Carlos Eduardo Date: Fri, 13 Sep 2024 17:11:56 -0300 Subject: [PATCH 36/52] Support filtering services by ensuring field This change implements an additional filter option to the `openstack share service list` command, following the recently added `ensuring` field in the services entity. Change-Id: Iadffe9307861aba042ed65ea29506ca648437b23 Signed-off-by: Carlos da Silva --- manilaclient/api_versions.py | 2 +- manilaclient/osc/v2/services.py | 17 ++++++++++++++++- ...ng-filter-for-services-eedbead009d3505f.yaml | 5 +++++ 3 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 releasenotes/notes/add-ensuring-filter-for-services-eedbead009d3505f.yaml diff --git a/manilaclient/api_versions.py b/manilaclient/api_versions.py index 73601af2..de0014b2 100644 --- a/manilaclient/api_versions.py +++ b/manilaclient/api_versions.py @@ -27,7 +27,7 @@ LOG = logging.getLogger(__name__) -MAX_VERSION = '2.92' +MAX_VERSION = '2.93' MIN_VERSION = '2.0' DEPRECATED_VERSION = '1.0' _VERSIONED_METHOD_MAP = {} diff --git a/manilaclient/osc/v2/services.py b/manilaclient/osc/v2/services.py index 4206dcac..757eeca4 100644 --- a/manilaclient/osc/v2/services.py +++ b/manilaclient/osc/v2/services.py @@ -138,6 +138,13 @@ def get_parser(self, prog_name): default=None, help=_("Filter services by their availability zone."), ) + parser.add_argument( + "--ensuring", + metavar="", + choices=['True', 'False'], + default=None, + help=_("Filter services running ensure shares or not."), + ) return parser def take_action(self, parsed_args): @@ -150,6 +157,14 @@ def take_action(self, parsed_args): 'state': parsed_args.state, 'zone': parsed_args.zone, } + if parsed_args.ensuring: + if share_client.api_version < api_versions.APIVersion("2.93"): + raise exceptions.CommandError( + "Filtering services whether they are running ensure " + "shares or not is only supported by manila API version " + ">= 2.93" + ) + search_opts['ensuring'] = parsed_args.ensuring services = share_client.services.list(search_opts=search_opts) @@ -164,7 +179,7 @@ def take_action(self, parsed_args): ] if share_client.api_version >= api_versions.APIVersion("2.83"): columns.append('Disabled Reason') - if share_client.api_version >= api_versions.APIVersion("2.86"): + if share_client.api_version >= api_versions.APIVersion("2.93"): columns.append('Ensuring') data = ( diff --git a/releasenotes/notes/add-ensuring-filter-for-services-eedbead009d3505f.yaml b/releasenotes/notes/add-ensuring-filter-for-services-eedbead009d3505f.yaml new file mode 100644 index 00000000..3f560b6c --- /dev/null +++ b/releasenotes/notes/add-ensuring-filter-for-services-eedbead009d3505f.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + It is now possible to filter services that have their status set to + `ensuring` with a new option in the `service list` command. From e01c79c005629a82233b615cc2bb2fa132243a19 Mon Sep 17 00:00:00 2001 From: Takashi Kajinami Date: Sat, 21 Feb 2026 20:08:54 +0900 Subject: [PATCH 37/52] Remove unused Makefile for doc We've not been using this for long since we introduced the tox targets for doc lint and build. Also remove .gitignore in the subdirectory to maintain ignored files in a single place. Change-Id: I6becc9b0f6f7308d12bc82944f786474421362a4 Signed-off-by: Takashi Kajinami --- doc/.gitignore | 1 - doc/Makefile | 90 -------------------------------------------------- 2 files changed, 91 deletions(-) delete mode 100644 doc/.gitignore delete mode 100644 doc/Makefile diff --git a/doc/.gitignore b/doc/.gitignore deleted file mode 100644 index 567609b1..00000000 --- a/doc/.gitignore +++ /dev/null @@ -1 +0,0 @@ -build/ diff --git a/doc/Makefile b/doc/Makefile deleted file mode 100644 index 76a65711..00000000 --- a/doc/Makefile +++ /dev/null @@ -1,90 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -SPHINXSOURCE = source -PAPER = -BUILDDIR = build - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) $(SPHINXSOURCE) - -.PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest - -help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - -clean: - -rm -rf $(BUILDDIR)/* - -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/python-manilaclient.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/python-manilaclient.qhc" - -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ - "run these through (pdf)latex." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." From a29ecbe2b617afc1b2ba20887e6d4f0a9a5ba91a Mon Sep 17 00:00:00 2001 From: Kiran Pawar Date: Tue, 2 Dec 2025 14:40:40 +0000 Subject: [PATCH 38/52] Add support for QoS type and specs (2.94) - Qos type and its specs - Create/Delete/Update/List/Show APIs. partially-implements: blueprint qos-types Signed-off-by: Kiran Pawar Depends-On: https://review.opendev.org/c/openstack/manila/+/967822 Change-Id: I10a9b7a40d07516a540da35265336a8febe588cc Signed-off-by: Goutham Pacha Ravi --- doc/source/cli/osc/v2/index.rst | 7 + manilaclient/api_versions.py | 2 +- manilaclient/common/constants.py | 9 + manilaclient/osc/v2/qos_types.py | 390 ++++++++++++++++ manilaclient/tests/functional/osc/base.py | 33 ++ .../tests/functional/osc/test_qos_types.py | 146 ++++++ manilaclient/tests/unit/osc/v2/fakes.py | 75 +++ .../tests/unit/osc/v2/test_qos_types.py | 440 ++++++++++++++++++ manilaclient/tests/unit/v2/fakes.py | 56 +++ manilaclient/tests/unit/v2/test_qos_types.py | 180 +++++++ manilaclient/v2/client.py | 2 + manilaclient/v2/qos_types.py | 185 ++++++++ pyproject.toml | 6 + ...r-qos-type-and-specs-2b5ce0002721cdb3.yaml | 6 + 14 files changed, 1536 insertions(+), 1 deletion(-) create mode 100644 manilaclient/osc/v2/qos_types.py create mode 100644 manilaclient/tests/functional/osc/test_qos_types.py create mode 100644 manilaclient/tests/unit/osc/v2/test_qos_types.py create mode 100644 manilaclient/tests/unit/v2/test_qos_types.py create mode 100644 manilaclient/v2/qos_types.py create mode 100644 releasenotes/notes/add-support-for-qos-type-and-specs-2b5ce0002721cdb3.yaml diff --git a/doc/source/cli/osc/v2/index.rst b/doc/source/cli/osc/v2/index.rst index 53420859..6946f4c8 100644 --- a/doc/source/cli/osc/v2/index.rst +++ b/doc/source/cli/osc/v2/index.rst @@ -221,3 +221,10 @@ resource locks .. autoprogram-cliff:: openstack.share.v2 :command: share lock * + +========= +qos types +========= + +.. autoprogram-cliff:: openstack.share.v2 + :command: share qos type * diff --git a/manilaclient/api_versions.py b/manilaclient/api_versions.py index de0014b2..62148791 100644 --- a/manilaclient/api_versions.py +++ b/manilaclient/api_versions.py @@ -27,7 +27,7 @@ LOG = logging.getLogger(__name__) -MAX_VERSION = '2.93' +MAX_VERSION = '2.94' MIN_VERSION = '2.0' DEPRECATED_VERSION = '1.0' _VERSIONED_METHOD_MAP = {} diff --git a/manilaclient/common/constants.py b/manilaclient/common/constants.py index d738dd9a..f148ae79 100644 --- a/manilaclient/common/constants.py +++ b/manilaclient/common/constants.py @@ -113,6 +113,14 @@ 'project_id', ) +QOS_TYPE_SORT_KEY_VALUES = ( + 'id', + 'name', + 'created_at', + 'updated_at', +) + + TASK_STATE_MIGRATION_SUCCESS = 'migration_success' TASK_STATE_MIGRATION_ERROR = 'migration_error' TASK_STATE_MIGRATION_CANCELLED = 'migration_cancelled' @@ -172,3 +180,4 @@ REPLICA_PRE_GRADUATION_VERSION = '2.55' SHARE_TRANSFER_VERSION = '2.77' RESOURCE_LOCK_VERSION = '2.81' +QOS_TYPE_VERSION = '2.94' diff --git a/manilaclient/osc/v2/qos_types.py b/manilaclient/osc/v2/qos_types.py new file mode 100644 index 00000000..0b8edc74 --- /dev/null +++ b/manilaclient/osc/v2/qos_types.py @@ -0,0 +1,390 @@ +# Copyright (c) 2025 Cloudification GmbH. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import logging + +from osc_lib.cli import parseractions +from osc_lib.command import command +from osc_lib import exceptions +from osc_lib import utils as oscutils + +from manilaclient.common._i18n import _ +from manilaclient.common.apiclient import utils as apiutils +from manilaclient.common import constants +from manilaclient.osc import utils + +LOG = logging.getLogger(__name__) + +ATTRIBUTES = [ + 'id', + 'name', + 'description', + 'specs', + 'created_at', + 'updated_at', +] + + +def format_qos_type(qos_type, formatter='table'): + specs = qos_type.specs + if formatter == 'table': + qos_type._info.update({'specs': utils.format_properties(specs)}) + else: + qos_type._info.update({'specs': specs}) + return qos_type + + +class CreateQosType(command.ShowOne): + """Create new qos type.""" + + _description = _("Create new qos type") + + def get_parser(self, prog_name): + parser = super().get_parser(prog_name) + parser.add_argument( + 'name', + metavar="", + help=_('QoS type name. This must be unique.'), + ) + parser.add_argument( + "--description", + metavar="", + default=None, + help=_("QoS type description."), + ) + parser.add_argument( + "--spec", + type=str, + metavar='', + action='append', + default=None, + help=_( + "Spec key and value of QoS type that will be" + " used for QoS type creation. OPTIONAL: Default=None." + " Example: --spec qos_type='fixed' --spec peak_iops=300." + ), + ) + return parser + + def take_action(self, parsed_args): + share_client = self.app.client_manager.share + + kwargs = {'name': parsed_args.name} + if parsed_args.description: + kwargs['description'] = parsed_args.description + + if parsed_args.spec: + specs = utils.extract_properties(parsed_args.spec) + kwargs['specs'] = specs + + qos_type = share_client.qos_types.create(**kwargs) + formatted_type = format_qos_type(qos_type, parsed_args.formatter) + + return ( + ATTRIBUTES, + oscutils.get_dict_properties(formatted_type._info, ATTRIBUTES), + ) + + +class DeleteQosType(command.Command): + """Delete a qos type.""" + + _description = _("Delete a qos type") + + def get_parser(self, prog_name): + parser = super().get_parser(prog_name) + parser.add_argument( + 'qos_types', + metavar="", + nargs="+", + help=_("Name or ID of the qos type(s) to delete"), + ) + return parser + + def take_action(self, parsed_args): + share_client = self.app.client_manager.share + result = 0 + + for qos_type in parsed_args.qos_types: + try: + qos_type_obj = apiutils.find_resource( + share_client.qos_types, qos_type + ) + + share_client.qos_types.delete(qos_type_obj) + except Exception as e: + result += 1 + LOG.error( + _( + "Failed to delete qos type with " + "name or ID '%(qos_type)s': %(e)s" + ), + {'qos_type': qos_type, 'e': e}, + ) + + if result > 0: + total = len(parsed_args.qos_types) + msg = _("%(result)s of %(total)s qos types failed to delete.") % { + 'result': result, + 'total': total, + } + raise exceptions.CommandError(msg) + + +class SetQosType(command.Command): + """Set qos type description or specs.""" + + _description = _("Set qos type description or specs") + + def get_parser(self, prog_name): + parser = super().get_parser(prog_name) + parser.add_argument( + 'qos_type', + metavar="", + help=_("Name or ID of the qos type to modify"), + ) + parser.add_argument( + "--description", + metavar="", + default=None, + help=_("New description of qos type."), + ) + parser.add_argument( + "--spec", + type=str, + metavar='', + action='append', + default=None, + help=_( + "Spec key and value of qos type that will be " + "used for QoS type. OPTIONAL: Default=None. For " + "example --spec qos_type='fixed' --spec peak_iops=300" + ), + ) + return parser + + def take_action(self, parsed_args): + share_client = self.app.client_manager.share + + qos_type = apiutils.find_resource( + share_client.qos_types, parsed_args.qos_type + ) + + kwargs = {} + if parsed_args.description: + kwargs['description'] = parsed_args.description + if kwargs: + try: + qos_type.update(**kwargs) + except Exception as e: + raise exceptions.CommandError( + _("Failed to set qos type description: %s") % e + ) + + # These are dict of key=value to be added as qos type specs. + if parsed_args.spec: + specs = utils.extract_properties(parsed_args.spec) + try: + qos_type.set_keys(specs) + except Exception as e: + raise exceptions.CommandError( + _("Failed to set qos type spec: %s") % e + ) + + +class UnsetQosType(command.Command): + """Unset qos type specs.""" + + _description = _("Unset qos type specs") + + def get_parser(self, prog_name): + parser = super().get_parser(prog_name) + parser.add_argument( + 'qos_type', + metavar="", + help=_("Name or ID of the qos type to modify"), + ) + parser.add_argument( + "--description", + action='store_true', + help=_("Unset qos type description."), + ) + parser.add_argument( + '--spec', + metavar='', + action='append', + help=_('Remove specified spec from this qos type'), + ) + return parser + + def take_action(self, parsed_args): + share_client = self.app.client_manager.share + + qos_type = apiutils.find_resource( + share_client.qos_types, parsed_args.qos_type + ) + + kwargs = {} + if parsed_args.description: + kwargs['description'] = None + if kwargs: + try: + qos_type.update(**kwargs) + except Exception as e: + raise exceptions.CommandError( + _("Failed to unset qos type description: %s") % e + ) + + # These are list of keys to be deleted from qos type specs. + if parsed_args.spec: + try: + qos_type.unset_keys(parsed_args.spec) + except Exception as e: + raise exceptions.CommandError( + _("Failed to remove qos type spec: %s") % e + ) + + +class ListQosType(command.Lister): + """List Qos Types.""" + + _description = _("List qos types") + + def get_parser(self, prog_name): + parser = super().get_parser(prog_name) + parser.add_argument( + '--name', + metavar="", + default=None, + help=_('Filter results by name. Default=None.'), + ) + parser.add_argument( + '--description', + metavar="", + default=None, + help=_("Filter results by description. Default=None."), + ) + parser.add_argument( + "--name~", + metavar="", + default=None, + help=_("Filter results matching a qos name pattern. "), + ) + parser.add_argument( + '--description~', + metavar="", + default=None, + help=_("Filter results matching a qos description pattern."), + ) + parser.add_argument( + "--limit", + metavar="", + type=int, + default=None, + action=parseractions.NonNegativeAction, + help=_("Limit the number of qos types returned. Default=None."), + ) + parser.add_argument( + '--offset', + metavar="", + default=None, + help=_('Start position of qos type records listing.'), + ) + parser.add_argument( + '--sort-key', + '--sort_key', + metavar='', + type=str, + default=None, + help=_( + 'Key to be sorted with, available keys are ' + '%(keys)s. Default=None.' + ) + % {'keys': constants.QOS_TYPE_SORT_KEY_VALUES}, + ) + parser.add_argument( + '--sort-dir', + '--sort_dir', + metavar='', + type=str, + default=None, + help=_( + 'Sort direction, available values are ' + '%(dirs)s. OPTIONAL: Default=None.' + ) + % {'dirs': constants.SORT_DIR_VALUES}, + ) + return parser + + def take_action(self, parsed_args): + share_client = self.app.client_manager.share + + search_opts = { + 'name': parsed_args.name, + 'description': parsed_args.description, + 'limit': parsed_args.limit, + 'offset': parsed_args.offset, + } + search_opts['name~'] = getattr(parsed_args, 'name~') + search_opts['description~'] = getattr(parsed_args, 'description~') + + qos_types = share_client.qos_types.list( + search_opts=search_opts, + sort_key=parsed_args.sort_key, + sort_dir=parsed_args.sort_dir, + ) + + formatted_types = [] + for qos_type in qos_types: + formatted_types.append( + format_qos_type(qos_type, parsed_args.formatter) + ) + + values = ( + oscutils.get_dict_properties(s._info, ATTRIBUTES) + for s in formatted_types + ) + + columns = utils.format_column_headers(ATTRIBUTES) + + return (columns, values) + + +class ShowQosType(command.ShowOne): + """Show a qos type.""" + + _description = _("Display qos type details") + + def get_parser(self, prog_name): + parser = super().get_parser(prog_name) + parser.add_argument( + 'qos_type', + metavar="", + help=_("Qos type to display (name or ID)"), + ) + return parser + + def take_action(self, parsed_args): + share_client = self.app.client_manager.share + + qos_type = apiutils.find_resource( + share_client.qos_types, parsed_args.qos_type + ) + + formatted_type = format_qos_type(qos_type, parsed_args.formatter) + + return ( + ATTRIBUTES, + oscutils.get_dict_properties(formatted_type._info, ATTRIBUTES), + ) diff --git a/manilaclient/tests/functional/osc/base.py b/manilaclient/tests/functional/osc/base.py index 4c29fdee..8bee30e4 100644 --- a/manilaclient/tests/functional/osc/base.py +++ b/manilaclient/tests/functional/osc/base.py @@ -563,3 +563,36 @@ def create_backup( ) return backup_object + + def create_qos_type( + self, + name=None, + description=None, + specs=None, + add_cleanup=True, + client=None, + formatter=None, + ): + name = name or data_utils.rand_name('autotest_qos_type_name') + specs = specs or {} + + cmd = f'create {name} ' + if description: + cmd += f' --description {description}' + if specs: + q_specs = '' + for key, value in specs.items(): + q_specs += f' --spec {key}={value}' + cmd += q_specs + + if formatter == 'json': + cmd = f'share qos type {cmd} -f {formatter} ' + qos_type = json.loads(self.openstack(cmd, client=client)) + else: + qos_type = self.dict_result('share qos type', cmd, client=client) + + if add_cleanup: + self.addCleanup( + self.openstack, f'share qos type delete {qos_type["id"]}' + ) + return qos_type diff --git a/manilaclient/tests/functional/osc/test_qos_types.py b/manilaclient/tests/functional/osc/test_qos_types.py new file mode 100644 index 00000000..83d61724 --- /dev/null +++ b/manilaclient/tests/functional/osc/test_qos_types.py @@ -0,0 +1,146 @@ +# Copyright (c) 2025 Cloudification GmbH. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import json + +from manilaclient.tests.functional.osc import base + + +class QosTypesCLITest(base.OSCClientTestBase): + def test_qos_type_create(self): + name = 'test_qos_type' + description = 'Description' + qos_type = self.create_qos_type(name=name, description=description) + + self.assertEqual(name, qos_type["name"]) + self.assertEqual(description, qos_type["description"]) + + qos_types_list = self.listing_result('share qos type', 'list') + self.assertIn(qos_type["id"], [item['ID'] for item in qos_types_list]) + + def test_qos_type_create_specs(self): + name = 'test_qos_type2' + qos_type = self.create_qos_type( + name=name, + specs={"foo": "bar", "manila": "gazpacho"}, + formatter='json', + ) + + specs = qos_type["specs"] + self.assertEqual("bar", specs["foo"]) + self.assertEqual("gazpacho", specs["manila"]) + + def test_qos_type_create_specs_using_command(self): + self.openstack( + 'share qos type create test_qos_type2_cli ' + '--description test_cli --spec foo1=bar1 --spec foo2=bar2' + ) + self.addCleanup( + self.openstack, 'share qos type delete test_qos_type2_cli' + ) + + qos_type = json.loads( + self.openstack('share qos type show test_qos_type2_cli -f json') + ) + + self.assertEqual('test_cli', qos_type["description"]) + self.assertEqual('bar1', qos_type["specs"]["foo1"]) + self.assertEqual('bar2', qos_type["specs"]["foo2"]) + + def test_qos_type_delete(self): + qos_type_1 = self.create_qos_type( + name='test_qos_type3', add_cleanup=False + ) + qos_type_2 = self.create_qos_type( + name='test_qos_type4', add_cleanup=False + ) + + self.openstack( + f'share qos type delete {qos_type_1["id"]} {qos_type_2["id"]}' + ) + + self.check_object_deleted('share qos type', qos_type_1["id"]) + self.check_object_deleted('share qos type', qos_type_2["id"]) + + def test_qos_type_set(self): + qos_type = self.create_qos_type(name='test_qos_type5') + + self.openstack( + f'share qos type set {qos_type["id"]} --description Description' + ' --spec foo=bar2' + ) + + qos_type = json.loads( + self.openstack(f'share qos type show {qos_type["id"]} -f json') + ) + + self.assertEqual('Description', qos_type["description"]) + self.assertEqual('bar2', qos_type["specs"]["foo"]) + + def test_qos_type_unset(self): + qos_type = self.create_qos_type( + name='test_qos_type6', specs={'foo': 'bar', 'foo1': 'bar1'} + ) + + self.openstack( + f'share qos type unset {qos_type["id"]} --spec foo --spec foo1' + ) + + qos_type = json.loads( + self.openstack(f'share qos type show {qos_type["id"]} -f json') + ) + + self.assertNotIn('foo', qos_type["specs"]) + self.assertNotIn('foo1', qos_type["specs"]) + + def test_qos_type_list(self): + qos_type_1 = self.create_qos_type(name='test_qos_type7') + qos_type_2 = self.create_qos_type( + name='test_qos_type8', specs={'foo': 'bar'} + ) + + types_list = self.listing_result( + 'share qos type', 'list', client=self.admin_client + ) + + self.assertTableStruct( + types_list, + [ + 'ID', + 'Name', + 'Description', + 'Specs', + ], + ) + id_list = [item['ID'] for item in types_list] + self.assertIn(qos_type_1['id'], id_list) + self.assertIn(qos_type_2['id'], id_list) + + types_list = self.listing_result('share qos type', 'list') + + id_list = [item['ID'] for item in types_list] + self.assertIn(qos_type_1['id'], id_list) + self.assertIn(qos_type_2['id'], id_list) + + def test_qos_type_show(self): + qos_type = self.create_qos_type( + name='test_qos_type10', specs={'foo': 'bar'} + ) + + result = json.loads( + self.openstack(f'share qos type show {qos_type["id"]} -f json') + ) + + self.assertEqual(qos_type["name"], result["name"]) + self.assertEqual('bar', result["specs"]["foo"]) diff --git a/manilaclient/tests/unit/osc/v2/fakes.py b/manilaclient/tests/unit/osc/v2/fakes.py index 7387e2c5..5e5cdd83 100644 --- a/manilaclient/tests/unit/osc/v2/fakes.py +++ b/manilaclient/tests/unit/osc/v2/fakes.py @@ -64,6 +64,7 @@ def __init__(self, **kwargs): self.share_group_type_access = mock.Mock() self.share_servers = mock.Mock() self.resource_locks = mock.Mock() + self.qos_types = mock.Mock() class TestShare(osc_utils.TestCommand): @@ -1626,3 +1627,77 @@ def create_share_backups(attrs=None, count=2): for n in range(0, count): share_backups.append(FakeShareBackup.create_one_backup(attrs)) return share_backups + + +class FakeQosType: + """Fake one or more qos types""" + + @staticmethod + def create_one_qostype(attrs=None, methods=None): + """Create a fake qos type + + :param Dictionary attrs: + A dictionary with all attributes + :return: + A FakeResource object, with project_id, resource and so on + """ + + attrs = attrs or {} + methods = methods or {} + + qos_type_info = { + "id": 'qos-type-id-' + uuid.uuid4().hex, + "name": 'qos-type-name-' + uuid.uuid4().hex, + "description": 'qos-type-description-' + uuid.uuid4().hex, + "specs": { + "expected_iops": "2000", + "peak_iops": "5000", + }, + "created_at": 'time-' + uuid.uuid4().hex, + "updated_at": 'time-' + uuid.uuid4().hex, + } + + qos_type_info.update(attrs) + qos_type = osc_fakes.FakeResource( + info=copy.deepcopy(qos_type_info), methods=methods, loaded=True + ) + return qos_type + + @staticmethod + def create_qos_types(attrs=None, count=2): + """Create multiple fake qos types. + + :param Dictionary attrs: + A dictionary with all attributes + :param Integer count: + The number of qos types to be faked + :return: + A list of FakeResource objects + """ + + qos_types = [] + for n in range(0, count): + qos_types.append(FakeQosType.create_one_qostype(attrs)) + + return qos_types + + @staticmethod + def get_qos_types(qos_types=None, count=2): + """Get an iterable MagicMock object with a list of faked types. + + If types list is provided, then initialize the Mock object with the + list. Otherwise create one. + + :param List types: + A list of FakeResource objects faking types + :param Integer count: + The number of types to be faked + :return + An iterable Mock object with side_effect set to a list of faked + types + """ + + if qos_types is None: + qos_types = FakeQosType.create_qos_types(count) + + return mock.Mock(side_effect=qos_types) diff --git a/manilaclient/tests/unit/osc/v2/test_qos_types.py b/manilaclient/tests/unit/osc/v2/test_qos_types.py new file mode 100644 index 00000000..d23b6cc5 --- /dev/null +++ b/manilaclient/tests/unit/osc/v2/test_qos_types.py @@ -0,0 +1,440 @@ +# Copyright (c) 2025 Cloudification GmbH. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +from unittest import mock + +from osc_lib import exceptions +from osc_lib import utils as oscutils + +from manilaclient import api_versions +from manilaclient.common.apiclient.exceptions import BadRequest +from manilaclient.common.apiclient.exceptions import NotFound +from manilaclient.osc import utils +from manilaclient.osc.v2 import qos_types as osc_qos_types +from manilaclient.tests.unit.osc import osc_utils +from manilaclient.tests.unit.osc.v2 import fakes as manila_fakes + +COLUMNS = [ + 'id', + 'name', + 'description', + 'specs', + 'created_at', + 'updated_at', +] + + +class TestQosType(manila_fakes.TestShare): + def setUp(self): + super().setUp() + + self.qos_types_mock = self.app.client_manager.share.qos_types + self.qos_types_mock.reset_mock() + self.app.client_manager.share.api_version = api_versions.APIVersion( + api_versions.MAX_VERSION + ) + + +class TestQosTypeCreate(TestQosType): + def setUp(self): + super().setUp() + + self.new_qos_type = manila_fakes.FakeQosType.create_one_qostype() + self.qos_types_mock.create.return_value = self.new_qos_type + + # Get the command object to test + self.cmd = osc_qos_types.CreateQosType(self.app, None) + + self.data = [ + self.new_qos_type.id, + self.new_qos_type.name, + self.new_qos_type.description, + ('expected_iops : 2000\npeak_iops : 5000'), + self.new_qos_type.created_at, + self.new_qos_type.updated_at, + ] + + self.raw_data = [ + self.new_qos_type.id, + self.new_qos_type.name, + self.new_qos_type.description, + { + 'expected_iops': '2000', + 'peak_iops': '5000', + }, + self.new_qos_type.created_at, + self.new_qos_type.updated_at, + ] + + def test_qos_type_create_required_args(self): + """Verifies required arguments.""" + + arglist = [self.new_qos_type.name] + verifylist = [ + ('name', self.new_qos_type.name), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + + self.qos_types_mock.create.assert_called_with( + name=self.new_qos_type.name, + ) + + self.assertCountEqual(COLUMNS, columns) + self.assertCountEqual(self.data, data) + + def test_qos_type_create_json_format(self): + """Verifies --format json.""" + + arglist = [self.new_qos_type.name, '-f', 'json'] + verifylist = [ + ('name', self.new_qos_type.name), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + + self.qos_types_mock.create.assert_called_with( + name=self.new_qos_type.name, + ) + + self.assertCountEqual(COLUMNS, columns) + self.assertCountEqual(self.raw_data, data) + + def test_qos_type_create_missing_required_arg(self): + """Verifies missing required arguments.""" + + arglist = [] + verifylist = [] + + self.assertRaises( + osc_utils.ParserException, + self.check_parser, + self.cmd, + arglist, + verifylist, + ) + + def test_qos_type_create_specs(self): + arglist = [ + self.new_qos_type.name, + '--spec', + 'peak_iops=100', + '--spec', + 'expected_iops=20', + ] + verifylist = [ + ('name', self.new_qos_type.name), + ('spec', ['peak_iops=100', 'expected_iops=20']), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + + self.qos_types_mock.create.assert_called_with( + name=self.new_qos_type.name, + specs={'peak_iops': '100', 'expected_iops': '20'}, + ) + + self.assertCountEqual(COLUMNS, columns) + self.assertCountEqual(self.data, data) + + +class TestQosTypeDelete(TestQosType): + qos_types = manila_fakes.FakeQosType.create_qos_types(count=2) + + def setUp(self): + super().setUp() + + self.qos_types_mock.get = manila_fakes.FakeQosType.get_qos_types( + self.qos_types + ) + self.qos_types_mock.delete.return_value = None + + # Get the command object to test + self.cmd = osc_qos_types.DeleteQosType(self.app, None) + + def test_qos_type_delete_one(self): + arglist = [self.qos_types[0].id] + + verifylist = [('qos_types', [self.qos_types[0].id])] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + result = self.cmd.take_action(parsed_args) + self.qos_types_mock.delete.assert_called_with(self.qos_types[0]) + self.assertIsNone(result) + + def test_qos_type_delete_multiple(self): + arglist = [] + for t in self.qos_types: + arglist.append(t.id) + verifylist = [ + ('qos_types', arglist), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + result = self.cmd.take_action(parsed_args) + + calls = [] + for t in self.qos_types: + calls.append(mock.call(t)) + self.qos_types_mock.delete.assert_has_calls(calls) + self.assertIsNone(result) + + def test_delete_qos_type_with_exception(self): + arglist = [ + 'non_existing_type', + ] + verifylist = [ + ('qos_types', arglist), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + self.qos_types_mock.delete.side_effect = exceptions.CommandError() + self.assertRaises( + exceptions.CommandError, self.cmd.take_action, parsed_args + ) + + +class TestQosTypeSet(TestQosType): + def setUp(self): + super().setUp() + + self.qos_type = manila_fakes.FakeQosType.create_one_qostype( + methods={'set_keys': None, 'update': None} + ) + self.qos_types_mock.get.return_value = self.qos_type + + # Get the command object to test + self.cmd = osc_qos_types.SetQosType(self.app, None) + + def test_qos_type_set_specs(self): + arglist = [ + self.qos_type.id, + '--spec', + 'peak_iops=100', + ] + verifylist = [ + ('qos_type', self.qos_type.id), + ('spec', ['peak_iops=100']), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + result = self.cmd.take_action(parsed_args) + self.qos_type.set_keys.assert_called_with({'peak_iops': '100'}) + self.assertIsNone(result) + + def test_qos_type_set_description(self): + arglist = [self.qos_type.id, '--description', 'new description'] + verifylist = [ + ('qos_type', self.qos_type.id), + ('description', 'new description'), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + result = self.cmd.take_action(parsed_args) + self.qos_type.update.assert_called_with(description='new description') + self.assertIsNone(result) + + def test_qos_type_set_specs_exception(self): + arglist = [ + self.qos_type.id, + '--spec', + 'peak_iops=100', + ] + verifylist = [ + ('qos_type', self.qos_type.id), + ('spec', ['peak_iops=100']), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + self.qos_type.set_keys.side_effect = BadRequest() + self.assertRaises( + exceptions.CommandError, self.cmd.take_action, parsed_args + ) + + +class TestQosTypeUnset(TestQosType): + def setUp(self): + super().setUp() + + self.qos_type = manila_fakes.FakeQosType.create_one_qostype( + methods={'unset_keys': None, 'update': None} + ) + + self.qos_types_mock.get.return_value = self.qos_type + + # Get the command object to test + self.cmd = osc_qos_types.UnsetQosType(self.app, None) + + def test_qos_type_unset_description(self): + arglist = [self.qos_type.id, '--description'] + verifylist = [ + ('qos_type', self.qos_type.id), + ('description', True), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + result = self.cmd.take_action(parsed_args) + self.qos_type.update.assert_called_with(description=None) + self.assertIsNone(result) + + def test_qos_type_unset_specs(self): + arglist = [self.qos_type.id, '--spec', 'peak_iops'] + verifylist = [ + ('qos_type', self.qos_type.id), + ('spec', ['peak_iops']), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + result = self.cmd.take_action(parsed_args) + self.qos_type.unset_keys.assert_called_with(['peak_iops']) + self.assertIsNone(result) + + def test_qos_type_unset_exception(self): + arglist = [self.qos_type.id, '--spec', 'peak_iops'] + verifylist = [ + ('qos_type', self.qos_type.id), + ('spec', ['peak_iops']), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + self.qos_type.unset_keys.side_effect = NotFound() + self.assertRaises( + exceptions.CommandError, self.cmd.take_action, parsed_args + ) + + +class TestQosTypeList(TestQosType): + qos_types = manila_fakes.FakeQosType.create_qos_types() + columns = utils.format_column_headers(COLUMNS) + + def setUp(self): + super().setUp() + + self.qos_types_mock.list.return_value = self.qos_types + + # Get the command object to test + self.cmd = osc_qos_types.ListQosType(self.app, None) + + self.values = ( + oscutils.get_dict_properties(s._info, COLUMNS) + for s in self.qos_types + ) + + def test_qos_type_list(self): + arglist = [] + verifylist = [] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + self.qos_types_mock.list.assert_called_once_with( + search_opts={ + 'offset': None, + 'limit': None, + 'name': None, + 'description': None, + 'name~': None, + 'description~': None, + }, + sort_key=None, + sort_dir=None, + ) + self.assertEqual(self.columns, columns) + self.assertEqual(list(self.values), list(data)) + + def test_qos_type_list_by_name(self): + arglist = ['--name', 'fake_name'] + verifylist = [('name', 'fake_name')] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + self.qos_types_mock.list.assert_called_with( + search_opts={ + 'offset': None, + 'limit': None, + 'name': 'fake_name', + 'description': None, + 'name~': None, + 'description~': None, + }, + sort_key=None, + sort_dir=None, + ) + self.assertEqual(self.columns, columns) + self.assertEqual(list(self.values), list(data)) + + +class TestQosTypeShow(TestQosType): + def setUp(self): + super().setUp() + + self.qos_type = manila_fakes.FakeQosType.create_one_qostype() + + self.qos_types_mock.get.return_value = self.qos_type + + # Get the command object to test + self.cmd = osc_qos_types.ShowQosType(self.app, None) + + self.data = [ + self.qos_type.id, + self.qos_type.name, + self.qos_type.description, + ('expected_iops : 2000\npeak_iops : 5000'), + self.qos_type.created_at, + self.qos_type.updated_at, + ] + + self.raw_data = [ + self.qos_type.id, + self.qos_type.name, + self.qos_type.description, + { + 'expected_iops': '2000', + 'peak_iops': '5000', + }, + self.qos_type.created_at, + self.qos_type.updated_at, + ] + + def test_qos_type_show(self): + arglist = [self.qos_type.id] + verifylist = [("qos_type", self.qos_type.id)] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + self.qos_types_mock.get.assert_called_with(self.qos_type.id) + + self.assertCountEqual(COLUMNS, columns) + self.assertCountEqual(self.data, data) + + def test_qos_type_show_json_format(self): + arglist = [ + self.qos_type.id, + '-f', + 'json', + ] + verifylist = [("qos_type", self.qos_type.id)] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + self.qos_types_mock.get.assert_called_with(self.qos_type.id) + + self.assertCountEqual(COLUMNS, columns) + self.assertCountEqual(self.raw_data, data) diff --git a/manilaclient/tests/unit/v2/fakes.py b/manilaclient/tests/unit/v2/fakes.py index 8484831a..52dee6e8 100644 --- a/manilaclient/tests/unit/v2/fakes.py +++ b/manilaclient/tests/unit/v2/fakes.py @@ -1236,6 +1236,62 @@ def delete_types_1_extra_specs_k(self, **kw): def delete_types_1(self, **kw): return (202, {}, None) + def get_qos_types(self, **kw): + response_body = { + 'qos_types': [ + { + 'id': 1, + 'name': 'test-type-1', + 'specs': {'test1': 'test1'}, + }, + { + 'id': 2, + 'name': 'test-type-2', + 'specs': {'test1': 'test1'}, + }, + ] + } + + return 200, {}, response_body + + def get_qos_types_1(self, **kw): + return ( + 200, + {}, + { + 'qos_type': { + 'id': 1, + 'name': 'test-qos-type-1', + 'specs': {'test1': 'test1'}, + } + }, + ) + + def post_qos_types(self, body, **kw): + qos_type = body['qos_type'] + return ( + 202, + {}, + { + 'qos_type': { + 'id': 3, + 'name': 'test-qos-type-3', + 'description': 'test description', + 'specs': qos_type['specs'], + } + }, + ) + + def post_qos_types_1_specs(self, body, **kw): + assert list(body) == ['specs'] + return (200, {}, {'specs': {'k': 'v'}}) + + def delete_qos_types_1_specs_k(self, **kw): + return (204, {}, None) + + def delete_qos_types_1(self, **kw): + return (202, {}, None) + def get_types_3_os_share_type_access(self, **kw): return ( 200, diff --git a/manilaclient/tests/unit/v2/test_qos_types.py b/manilaclient/tests/unit/v2/test_qos_types.py new file mode 100644 index 00000000..624b3660 --- /dev/null +++ b/manilaclient/tests/unit/v2/test_qos_types.py @@ -0,0 +1,180 @@ +# Copyright (c) 2025 Cloudification GmbH. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import copy +from unittest import mock + +import ddt + +from manilaclient import api_versions +from manilaclient.common import constants +from manilaclient import config +from manilaclient.tests.unit import utils +from manilaclient.tests.unit.v2 import fakes +from manilaclient.v2 import qos_types + +cs = fakes.FakeClient(api_versions.APIVersion(constants.QOS_TYPE_VERSION)) + +CONF = config.CONF + +LATEST_MICROVERSION = CONF.max_api_microversion + + +@ddt.ddt +class QosTypesTest(utils.TestCase): + def setUp(self): + super().setUp() + microversion = api_versions.APIVersion(constants.QOS_TYPE_VERSION) + mock_microversion = mock.Mock(api_version=microversion) + self.manager = qos_types.QosTypeManager(api=mock_microversion) + + @ddt.data( + {'expected_iops': '100'}, + {'peak_iops': '500', 'expected_iops': '100'}, + ) + def test_init(self, specs): + info = {'specs': specs} + + qos_type = qos_types.QosType(qos_types.QosTypeManager, info) + + self.assertTrue(hasattr(qos_type, '_specs')) + self.assertIsInstance(qos_type._specs, dict) + + def test_list_types(self): + tl = cs.qos_types.list() + cs.assert_called('GET', '/qos-types') + for t in tl: + t.api_version = api_versions.APIVersion(constants.QOS_TYPE_VERSION) + self.assertIsInstance(t, qos_types.QosType) + self.assertTrue(callable(getattr(t, 'get_keys', ''))) + self.assertEqual({'test1': 'test1'}, t.get_keys()) + + @ddt.data( + {'qos_type': 'fixed', 'max_iops': '100'}, + {'qos_type': 'adaptive', 'peak_iops': '200'}, + {'qos_type': 'fixed', 'max_iops': '100', 'expected_iops': '100'}, + ) + def test_create(self, specs): + specs = copy.copy(specs) + + self.mock_object( + self.manager, '_create', mock.Mock(return_value="fake") + ) + + result = self.manager.create( + 'test-qos-type-1', + specs=specs, + ) + + if specs is None: + specs = {} + + expected_specs = dict(specs) + + expected_body = { + "qos_type": { + "name": 'test-qos-type-1', + "specs": expected_specs, + } + } + + self.manager._create.assert_called_once_with( + "/qos-types", expected_body, "qos_type" + ) + self.assertEqual("fake", result) + + def test_set_key(self): + t = cs.qos_types.get(1) + t.api_version = api_versions.APIVersion(constants.QOS_TYPE_VERSION) + t.set_keys({'k': 'v'}) + cs.assert_called('POST', '/qos-types/1/specs', {'specs': {'k': 'v'}}) + + def test_unset_keys(self): + t = cs.qos_types.get(1) + t.api_version = api_versions.APIVersion(constants.QOS_TYPE_VERSION) + t.unset_keys(['k']) + cs.assert_called('DELETE', '/qos-types/1/specs/k') + + def test_update(self): + self.mock_object( + self.manager, '_update', mock.Mock(return_value="fake") + ) + qos_type = 1234 + body = dict(description="updated test description") + expected_body = { + "qos_type": dict(description="updated test description") + } + result = self.manager.update(qos_type, **body) + self.manager._update.assert_called_once_with( + f"/qos-types/{qos_type}", expected_body, "qos_type" + ) + self.assertEqual("fake", result) + + def test_delete(self): + cs.qos_types.delete(1) + cs.assert_called('DELETE', '/qos-types/1') + + def test_get_keys_from_resource_data(self): + version = api_versions.APIVersion(constants.QOS_TYPE_VERSION) + manager = mock.Mock() + manager.api = mock.Mock() + manager.api.client = mock.Mock(return_value=None) + manager.api.client.get = mock.Mock(return_value=(200, {})) + + valid_specs = {'test': 'test'} + qos_type = qos_types.QosType( + manager, + {'specs': valid_specs, 'name': 'test'}, + loaded=True, + ) + qos_type.api_version = version + + actual_result = qos_type.get_keys() + + self.assertEqual(actual_result, valid_specs) + self.assertEqual(manager.api.client.get.call_count, 0) + + @ddt.data( + {'prefer_resource_data': True, 'resource_specs': {}}, + { + 'prefer_resource_data': False, + 'resource_specs': {'fake': 'fake'}, + }, + {'prefer_resource_data': False, 'resource_specs': {}}, + ) + @ddt.unpack + def test_get_keys_from_api(self, prefer_resource_data, resource_specs): + version = api_versions.APIVersion(constants.QOS_TYPE_VERSION) + manager = mock.Mock() + manager.api = mock.Mock() + manager.api.client = mock.Mock(return_value=None) + + valid_specs = {'test': 'test'} + manager.api.client.get = mock.Mock( + return_value=(200, {'specs': valid_specs}) + ) + + info = { + 'name': 'test', + 'uuid': 'fake', + 'specs': resource_specs, + } + qos_type = qos_types.QosType(manager, info, loaded=True) + qos_type.api_version = version + + actual_result = qos_type.get_keys(prefer_resource_data) + + self.assertEqual(actual_result, valid_specs) + self.assertEqual(manager.api.client.get.call_count, 1) diff --git a/manilaclient/v2/client.py b/manilaclient/v2/client.py index 6fc214e4..92d1f7a6 100644 --- a/manilaclient/v2/client.py +++ b/manilaclient/v2/client.py @@ -21,6 +21,7 @@ from manilaclient.v2 import availability_zones from manilaclient.v2 import limits from manilaclient.v2 import messages +from manilaclient.v2 import qos_types from manilaclient.v2 import quota_classes from manilaclient.v2 import quotas from manilaclient.v2 import resource_locks @@ -224,6 +225,7 @@ def __init__( self.limits = limits.LimitsManager(self) self.transfers = share_transfers.ShareTransferManager(self) self.messages = messages.MessageManager(self) + self.qos_types = qos_types.QosTypeManager(self) self.services = services.ServiceManager(self) self.security_services = security_services.SecurityServiceManager(self) self.share_networks = share_networks.ShareNetworkManager(self) diff --git a/manilaclient/v2/qos_types.py b/manilaclient/v2/qos_types.py new file mode 100644 index 00000000..d64d2364 --- /dev/null +++ b/manilaclient/v2/qos_types.py @@ -0,0 +1,185 @@ +# Copyright (c) 2025 Cloudification GmbH. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +""" +Qos Type interface. +""" + +from manilaclient import api_versions +from manilaclient import base +from manilaclient.common import constants + + +class QosType(base.Resource): + """A Qos Type represents Quality of service of Manila resource.""" + + def __init__(self, manager, info, loaded=False): + super().__init__(manager, info, loaded) + self._specs = info.get('specs', {}) + + def __repr__(self): + return f"" + + def get_keys(self, prefer_resource_data=True): + """Get specs from a qos type. + + :param prefer_resource_data: By default specs are retrieved from + resource data, but user can force this method to make API call. + :return: dict with specs + """ + specs = getattr(self, 'specs', None) + + if prefer_resource_data and specs: + return specs + + qos_type_id = base.getid(self) + _resp, body = self.manager.api.client.get( + f"/qos-types/{qos_type_id}/specs" + ) + + self.specs = body["specs"] + + return body["specs"] + + def set_keys(self, metadata): + """Set specs on a qos type. + + :param metadata: A dict of key/value pairs to be set + """ + body = {'specs': metadata} + qos_type_id = base.getid(self) + return self.manager._create( + f"/qos-types/{qos_type_id}/specs", + body, + "specs", + return_raw=True, + ) + + def unset_keys(self, keys): + """Unset specs on a qos type. + + :param keys: A list of keys to be unset + """ + qos_type_id = base.getid(self) + for k in keys: + self.manager._delete(f"/qos-types/{qos_type_id}/specs/{k}") + + def update(self, **kwargs): + """Update this qos type.""" + return self.manager.update(self, **kwargs) + + def delete(self): + """Delete this qos type.""" + return self.manager.delete(self) + + +class QosTypeManager(base.ManagerWithFind): + """Manage :class:`QosType` resources.""" + + resource_class = QosType + + @api_versions.wraps(constants.QOS_TYPE_VERSION) + def list(self, search_opts=None, sort_key=None, sort_dir=None): + """Get a list of all qos types. + + :param search_opts: Search options to filter out qos types. + :param sort_key: Key to be sorted. + :param sort_dir: Sort direction, should be 'desc' or 'asc'. + :rtype: list of :class:`QosType`. + """ + search_opts = search_opts or {} + + if sort_key is not None: + if sort_key in constants.QOS_TYPE_SORT_KEY_VALUES: + search_opts['sort_key'] = sort_key + else: + raise ValueError( + 'sort_key must be one of the following: {}.'.format( + ', '.join(constants.QOS_TYPE_SORT_KEY_VALUES) + ) + ) + + if sort_dir is not None: + if sort_dir in constants.SORT_DIR_VALUES: + search_opts['sort_dir'] = sort_dir + else: + raise ValueError( + 'sort_dir must be one of the following: {}.'.format( + ', '.join(constants.SORT_DIR_VALUES) + ) + ) + + query_string = self._build_query_string(search_opts) + return self._list(f"/qos-types{query_string}", "qos_types") + + @api_versions.wraps(constants.QOS_TYPE_VERSION) + def get(self, qos_type): + """Get a specific qos type. + + :param qos_type: The ID of the :class:`QosType` to get. + :rtype: :class:`QosType` + """ + qos_type_id = base.getid(qos_type) + return self._get(f"/qos-types/{qos_type_id}", "qos_type") + + @api_versions.wraps(constants.QOS_TYPE_VERSION) + def delete(self, qos_type): + """Delete a specific qos_type. + + :param qos_type: The name or ID of the :class:`QosType` to get. + """ + qos_type_id = base.getid(qos_type) + self._delete(f"/qos-types/{qos_type_id}") + + @api_versions.wraps(constants.QOS_TYPE_VERSION) + def create(self, name, description=None, specs=None): + """Create a qos type. + + :param name: Descriptive name of the qos type + :param specs: Specs of the qos type + :rtype: :class:`QosType` + """ + if specs is None: + specs = {} + + body = { + "qos_type": { + "name": name, + "specs": specs, + } + } + + if description: + body["qos_type"]["description"] = description + return self._create("/qos-types", body, "qos_type") + + @api_versions.wraps(constants.QOS_TYPE_VERSION) + def update(self, qos_type, **kwargs): + """Update the description for a qos type. + + :param qos_type: the ID of the :class: `QosType` to update. + :param description: Description of the qos type. + :rtype: :class:`QosType` + """ + + if not kwargs: + return + + body = { + 'qos_type': kwargs, + } + qos_type_id = base.getid(qos_type) + return self._update(f"/qos-types/{qos_type_id}", body, "qos_type") diff --git a/pyproject.toml b/pyproject.toml index 7b114c9b..cad75338 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -187,6 +187,12 @@ share_lock_show = "manilaclient.osc.v2.resource_locks:ShowResourceLock" share_lock_set = " manilaclient.osc.v2.resource_locks:SetResourceLock" share_lock_unset = "manilaclient.osc.v2.resource_locks:UnsetResourceLock" share_lock_delete = "manilaclient.osc.v2.resource_locks:DeleteResourceLock" +share_qos_type_create = "manilaclient.osc.v2.qos_types:CreateQosType" +share_qos_type_list = "manilaclient.osc.v2.qos_types:ListQosType" +share_qos_type_show = "manilaclient.osc.v2.qos_types:ShowQosType" +share_qos_type_set = "manilaclient.osc.v2.qos_types:SetQosType" +share_qos_type_unset = "manilaclient.osc.v2.qos_types:UnsetQosType" +share_qos_type_delete = "manilaclient.osc.v2.qos_types:DeleteQosType" [tool.setuptools] packages = [ diff --git a/releasenotes/notes/add-support-for-qos-type-and-specs-2b5ce0002721cdb3.yaml b/releasenotes/notes/add-support-for-qos-type-and-specs-2b5ce0002721cdb3.yaml new file mode 100644 index 00000000..7bec9025 --- /dev/null +++ b/releasenotes/notes/add-support-for-qos-type-and-specs-2b5ce0002721cdb3.yaml @@ -0,0 +1,6 @@ +--- +features: + - | + Added support for QoS types and specs via the Python SDK and the + ``openstack share qos type`` CLI commands (create, delete, list, show, + set, unset). Available from microversion 2.94 and above. From 2b3100bd4856e3c425b4b2f3bbe1a8ed0ec2684e Mon Sep 17 00:00:00 2001 From: Saikumar Pulluri Date: Tue, 20 Jan 2026 06:06:15 -0500 Subject: [PATCH 39/52] Metadata for Share Replica Extend these into OSC capabilities where appropriate. Added metadata for create/show/set commands and implemented unset operation for unified CLI. Bumps max microversion to 2.95. Partially-implements: bp metadata-for-share-resources Depends-On: https://review.opendev.org/c/openstack/manila/+/973777 Change-Id: I29bd79340698c407be3113d76b4d05b31643c194 Signed-off-by: Saikumar Pulluri --- manilaclient/api_versions.py | 2 +- manilaclient/osc/v2/share_replicas.py | 168 ++++++++++++++++- manilaclient/tests/unit/osc/v2/fakes.py | 1 + .../tests/unit/osc/v2/test_share_replicas.py | 174 +++++++++++++++++- .../tests/unit/v2/test_share_replicas.py | 23 +++ manilaclient/v2/share_replicas.py | 46 ++++- pyproject.toml | 1 + ...are-replica-metadata-e6c1c2e00295d2dd.yaml | 5 + 8 files changed, 405 insertions(+), 15 deletions(-) create mode 100644 releasenotes/notes/add-share-replica-metadata-e6c1c2e00295d2dd.yaml diff --git a/manilaclient/api_versions.py b/manilaclient/api_versions.py index 62148791..f4b4bbdc 100644 --- a/manilaclient/api_versions.py +++ b/manilaclient/api_versions.py @@ -27,7 +27,7 @@ LOG = logging.getLogger(__name__) -MAX_VERSION = '2.94' +MAX_VERSION = '2.95' MIN_VERSION = '2.0' DEPRECATED_VERSION = '1.0' _VERSIONED_METHOD_MAP = {} diff --git a/manilaclient/osc/v2/share_replicas.py b/manilaclient/osc/v2/share_replicas.py index 1bbbbd61..4bab9e3b 100644 --- a/manilaclient/osc/v2/share_replicas.py +++ b/manilaclient/osc/v2/share_replicas.py @@ -11,6 +11,7 @@ # under the License. import logging +from osc_lib.cli import format_columns from osc_lib.cli import parseractions from osc_lib.command import command from osc_lib import exceptions @@ -70,6 +71,17 @@ def get_parser(self, prog_name): 'microversion >= 2.72' ), ) + parser.add_argument( + "--property", + metavar="", + default={}, + action=parseractions.KeyValueAction, + help=_( + "Set a property to this replica " + "(repeat option to set multiple properties). " + "Available only for microversion >= 2.95" + ), + ) return parser def take_action(self, parsed_args): @@ -98,6 +110,21 @@ def take_action(self, parsed_args): 'share': share, 'availability_zone': parsed_args.availability_zone, } + + metadata = {} + if parsed_args.property: + if share_client.api_version < api_versions.APIVersion("2.95"): + raise exceptions.CommandError( + _( + "arg '--property' is available only starting " + "with API microversion '2.95'." + ) + ) + metadata = parsed_args.property + + if metadata: + body['metadata'] = metadata + if scheduler_hints: body['scheduler_hints'] = scheduler_hints @@ -213,6 +240,16 @@ def get_parser(self, prog_name): default=None, help=_("Name or ID of the share to list replicas for."), ) + parser.add_argument( + '--property', + metavar='', + action=parseractions.KeyValueAction, + help=_( + 'Filter replicas having a given metadata key=value ' + 'property. (repeat option to filter by multiple ' + 'properties)' + ), + ) return parser def take_action(self, parsed_args): @@ -224,7 +261,32 @@ def take_action(self, parsed_args): share_client.shares, parsed_args.share ) - replicas = share_client.share_replicas.list(share=share) + properties = parsed_args.property or {} + if properties: + if share_client.api_version < api_versions.APIVersion("2.95"): + raise exceptions.CommandError( + "Property based filtering is only available " + "with manila API version >= 2.95" + ) + + search_opts = {} + if properties: + meta_str = ",".join(f"{k}:{v}" for k, v in properties.items()) + search_opts['metadata'] = meta_str + + replicas = share_client.share_replicas.list( + share=share, search_opts=search_opts + ) + + if properties: + replicas = [ + r + for r in replicas + if all( + r._info.get('metadata', {}).get(k) == v + for k, v in properties.items() + ) + ] columns = [ 'id', @@ -235,7 +297,6 @@ def take_action(self, parsed_args): 'availability_zone', 'updated_at', ] - column_headers = utils.format_column_headers(columns) data = ( osc_utils.get_dict_properties(replica._info, columns) @@ -284,6 +345,15 @@ def take_action(self, parsed_args): replica._info['export_locations'] ) ) + # Special mapping for columns to make the output easier to read: + # 'metadata' --> 'properties' + replica._info.update( + { + 'properties': format_columns.DictColumn( + replica._info.pop('metadata', {}) + ), + }, + ) replica._info.pop('links', None) @@ -294,7 +364,8 @@ class SetShareReplica(command.Command): """Set share replica""" _description = _( - "Explicitly set share replica status and/or replica-state" + "Explicitly set share replica status and/or replica-state " + "and/or property" ) def get_parser(self, prog_name): @@ -329,6 +400,17 @@ def get_parser(self, prog_name): "error_deleting." ), ) + parser.add_argument( + "--property", + metavar="", + default={}, + action=parseractions.KeyValueAction, + help=_( + "Set a property to this replica " + "(repeat option to set multiple properties). " + "Available only for microversion >= 2.95" + ), + ) return parser def take_action(self, parsed_args): @@ -369,11 +451,35 @@ def take_action(self, parsed_args): {'status': parsed_args.status, 'exception': e}, ) - if not parsed_args.replica_state and not parsed_args.status: + if parsed_args.property: + if share_client.api_version < api_versions.APIVersion("2.95"): + raise exceptions.CommandError( + _( + "Setting properties in share replicas is available " + "only starting with API microversion '2.95'." + ) + ) + try: + replica.set_metadata(parsed_args.property) + except Exception as e: + LOG.error( + _( + "Failed to set share replica properties " + "'%(properties)s': %(exception)s" + ), + {'properties': parsed_args.property, 'exception': e}, + ) + result += 1 + + if ( + not parsed_args.replica_state + and not parsed_args.status + and not parsed_args.property + ): raise exceptions.CommandError( _( "Nothing to set. Please define " - "either '--replica_state' or '--status'." + "either '--replica_state' or '--status' or '--property'." ) ) if result > 0: @@ -382,6 +488,58 @@ def take_action(self, parsed_args): ) +class UnsetShareReplica(command.Command): + """Unset a share replica property.""" + + _description = _("Unset a share replica property") + + def get_parser(self, prog_name): + parser = super().get_parser(prog_name) + parser.add_argument( + "replica", + metavar="", + help=_("Unset a property for"), + ) + parser.add_argument( + '--property', + metavar='', + action='append', + help=_( + 'Remove a property from replica ' + '(repeat option to remove multiple properties)' + ), + ) + return parser + + def take_action(self, parsed_args): + share_client = self.app.client_manager.share + + replica = osc_utils.find_resource( + share_client.share_replicas, parsed_args.replica + ) + + if parsed_args.property: + if share_client.api_version < api_versions.APIVersion("2.95"): + raise exceptions.CommandError( + _( + "arg '--property' is available only starting " + "with API microversion '2.95'." + ) + ) + for key in parsed_args.property: + try: + replica.delete_metadata([key]) + except Exception as e: + msg = _( + "Failed to unset replica property '%(key)s': %(e)s" + ) + raise exceptions.CommandError(msg % {'key': key, 'e': e}) + else: + raise exceptions.CommandError( + "Please specify '--property ' to unset a property." + ) + + class PromoteShareReplica(command.Command): """Promote share replica""" diff --git a/manilaclient/tests/unit/osc/v2/fakes.py b/manilaclient/tests/unit/osc/v2/fakes.py index 5e5cdd83..d8e0ad57 100644 --- a/manilaclient/tests/unit/osc/v2/fakes.py +++ b/manilaclient/tests/unit/osc/v2/fakes.py @@ -821,6 +821,7 @@ def create_one_replica(attrs=None, methods=None): 'share_server_id': None, 'status': None, 'updated_at': None, + "properties": format_columns.DictColumn({}), } share_replica.update(attrs) diff --git a/manilaclient/tests/unit/osc/v2/test_share_replicas.py b/manilaclient/tests/unit/osc/v2/test_share_replicas.py index d1592abd..06372baa 100644 --- a/manilaclient/tests/unit/osc/v2/test_share_replicas.py +++ b/manilaclient/tests/unit/osc/v2/test_share_replicas.py @@ -216,6 +216,61 @@ def test_share_replica_create_share_network(self): self.assertCountEqual(self.columns, columns) self.assertCountEqual(self.data, data) + def test_share_replica_create_with_metadata(self): + self.app.client_manager.share.api_version = api_versions.APIVersion( + "2.95" + ) + + arglist = [ + self.share.id, + '--availability-zone', + self.share.availability_zone, + '--property', + 'fake_key1=fake_value1', + '--property', + 'fake_key2=fake_value2', + ] + verifylist = [ + ('share', self.share.id), + ('availability_zone', self.share.availability_zone), + ( + 'property', + {'fake_key1': 'fake_value1', 'fake_key2': 'fake_value2'}, + ), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + + self.replicas_mock.create.assert_called_with( + share=self.share, + availability_zone=self.share.availability_zone, + metadata={'fake_key1': 'fake_value1', 'fake_key2': 'fake_value2'}, + ) + + self.assertCountEqual(self.columns, columns) + self.assertCountEqual(self.data, data) + + def test_share_replica_create_metadata_api_version_exception(self): + self.app.client_manager.share.api_version = api_versions.APIVersion( + '2.91' + ) + arglist = [ + self.share.id, + '--property', + 'fake_key=fake_value', + ] + verifylist = [ + ('share', self.share.id), + ('property', {'fake_key': 'fake_value'}), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + self.assertRaises( + exceptions.CommandError, self.cmd.take_action, parsed_args + ) + def test_share_replica_create_wait(self): arglist = [self.share.id, '--wait'] verifylist = [('share', self.share.id), ('wait', True)] @@ -396,7 +451,7 @@ def test_share_replica_list(self): columns, data = self.cmd.take_action(parsed_args) - self.replicas_mock.list.assert_called_with(share=None) + self.replicas_mock.list.assert_called_with(share=None, search_opts={}) self.assertEqual(self.column_headers, columns) self.assertEqual(list(self.values), list(data)) @@ -409,7 +464,9 @@ def test_share_replica_list_for_share(self): columns, data = self.cmd.take_action(parsed_args) - self.replicas_mock.list.assert_called_with(share=self.share) + self.replicas_mock.list.assert_called_with( + share=self.share, search_opts={} + ) self.assertEqual(self.column_headers, columns) self.assertEqual(list(self.values), list(data)) @@ -469,7 +526,9 @@ class TestShareReplicaSet(TestShareReplica): def setUp(self): super().setUp() - self.share_replica = manila_fakes.FakeShareReplica.create_one_replica() + self.share_replica = manila_fakes.FakeShareReplica.create_one_replica( + methods={"set_metadata": None} + ) self.replicas_mock.get.return_value = self.share_replica self.cmd = osc_share_replicas.SetShareReplica(self.app, None) @@ -549,6 +608,115 @@ def test_share_replica_set_nothing_defined(self): exceptions.CommandError, self.cmd.take_action, parsed_args ) + def test_share_replica_set_property(self): + self.app.client_manager.share.api_version = api_versions.APIVersion( + '2.95' + ) + arglist = [ + self.share_replica.id, + '--property', + 'fake_key=fake_value', + ] + verifylist = [ + ('replica', self.share_replica.id), + ('property', {'fake_key': 'fake_value'}), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + self.cmd.take_action(parsed_args) + + self.share_replica.set_metadata.assert_called_once_with( + {'fake_key': 'fake_value'}, + ) + + def test_share_replica_set_property_exception(self): + self.app.client_manager.share.api_version = api_versions.APIVersion( + '2.95' + ) + arglist = [ + self.share_replica.id, + '--property', + 'fake_key=fake_value', + ] + verifylist = [ + ('replica', self.share_replica.id), + ('property', {'fake_key': 'fake_value'}), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + self.cmd.take_action(parsed_args) + + self.share_replica.set_metadata.assert_called_once_with( + {'fake_key': 'fake_value'}, + ) + + self.share_replica.set_metadata.side_effect = exceptions.BadRequest + self.assertRaises( + exceptions.CommandError, self.cmd.take_action, parsed_args + ) + + +class TestShareReplicaUnset(TestShareReplica): + def setUp(self): + super().setUp() + + self.share_replica = manila_fakes.FakeShareReplica.create_one_replica( + methods={"delete_metadata": None} + ) + self.replicas_mock.get.return_value = self.share_replica + + self.cmd = osc_share_replicas.UnsetShareReplica(self.app, None) + + def test_share_replica_unset_property(self): + self.app.client_manager.share.api_version = api_versions.APIVersion( + '2.95' + ) + arglist = [ + '--property', + 'test_key', + self.share_replica.id, + ] + verifylist = [ + ('property', ['test_key']), + ('replica', self.share_replica.id), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + self.cmd.take_action(parsed_args) + + self.share_replica.delete_metadata.assert_called_once_with( + parsed_args.property + ) + + def test_share_replica_unset_property_exception(self): + self.app.client_manager.share.api_version = api_versions.APIVersion( + '2.95' + ) + arglist = [ + self.share_replica.id, + '--property', + 'test_key', + ] + verifylist = [ + ('replica', self.share_replica.id), + ('property', ['test_key']), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + self.cmd.take_action(parsed_args) + + self.share_replica.delete_metadata.assert_called_once_with( + parsed_args.property + ) + + # 404 Not Found would be raised, if property 'test_key' doesn't exist. + self.share_replica.delete_metadata.side_effect = exceptions.NotFound + self.assertRaises( + exceptions.CommandError, self.cmd.take_action, parsed_args + ) + class TestShareReplicaPromote(TestShareReplica): def setUp(self): diff --git a/manilaclient/tests/unit/v2/test_share_replicas.py b/manilaclient/tests/unit/v2/test_share_replicas.py index 52ce16c5..f7174f36 100644 --- a/manilaclient/tests/unit/v2/test_share_replicas.py +++ b/manilaclient/tests/unit/v2/test_share_replicas.py @@ -84,6 +84,29 @@ def test_create_with_share_network(self, microversion): self.assertEqual(share_replicas.RESOURCE_NAME, result['resp_key']) self.assertEqual(body_expected, result['body']) + @ddt.data("2.95") + def test_create_with_metadata(self, microversion): + api_version = api_versions.APIVersion(microversion) + values = { + 'availability_zone': 'az1', + 'share': 's1', + 'share_network': 'sn1', + 'metadata': {"fake_key": "fake_value"}, + } + + manager = share_replicas.ShareReplicaManager( + fakes.FakeClient(api_version=api_version) + ) + with mock.patch.object(manager, '_create', fakes.fake_create): + result = manager.create(**values) + + values['share_id'] = values.pop('share') + values['share_network_id'] = values.pop('share_network') + body_expected = {share_replicas.RESOURCE_NAME: values} + self.assertEqual(share_replicas.RESOURCES_PATH, result['url']) + self.assertEqual(share_replicas.RESOURCE_NAME, result['resp_key']) + self.assertEqual(body_expected, result['body']) + def test_delete_str(self): with mock.patch.object(self.manager, '_delete', mock.Mock()): self.manager.delete(FAKE_REPLICA) diff --git a/manilaclient/v2/share_replicas.py b/manilaclient/v2/share_replicas.py index 158c5fe2..430d4921 100644 --- a/manilaclient/v2/share_replicas.py +++ b/manilaclient/v2/share_replicas.py @@ -24,7 +24,7 @@ RESOURCE_NAME = 'share_replica' -class ShareReplica(base.Resource): +class ShareReplica(base.MetadataCapableResource): """A replica is 'mirror' instance of a share at some point in time.""" def __repr__(self): @@ -47,10 +47,11 @@ def reset_replica_state(self, replica_state): self.manager.reset_replica_state(self, replica_state) -class ShareReplicaManager(base.ManagerWithFind): +class ShareReplicaManager(base.MetadataCapableManager): """Manage :class:`ShareReplica` resources.""" resource_class = ShareReplica + resource_path = '/share-replicas' @api_versions.wraps("2.11", constants.REPLICA_PRE_GRADUATION_VERSION) @api_versions.experimental_api @@ -83,16 +84,26 @@ def _list_share_replicas(self, share=None, search_opts=None): """List all share replicas or list replicas belonging to a share. :param share: either share object or its UUID. - :param search_opts: default None + :param search_opts: dict of search options (e.g., metadata filters) :rtype: list of :class:`ShareReplica` """ + search_opts = search_opts or {} + + # This will turn {'metadata': {'foo': 'bar', 'baz': 'qux'}} + # into ?metadata=foo:bar,baz:qux + query_string = self._build_query_string(search_opts) if share: share_id = '?share_id=' + base.getid(share) url = RESOURCES_PATH + '/detail' + share_id + if query_string: + url += '&' + query_string.lstrip('?') return self._list(url, RESOURCES_NAME) else: - return self._list(RESOURCES_PATH + '/detail', RESOURCES_NAME) + url = RESOURCES_PATH + '/detail' + if query_string: + url += query_string + return self._list(url, RESOURCES_NAME) @api_versions.wraps("2.11", constants.REPLICA_PRE_GRADUATION_VERSION) @api_versions.experimental_api @@ -144,7 +155,7 @@ def create(self, share, availability_zone=None, scheduler_hints=None): # noqa F scheduler_hints=scheduler_hints, ) - @api_versions.wraps("2.72") # noqa + @api_versions.wraps("2.72", "2.94") # noqa def create( # noqa self, share, # pylint: disable=function-redefined # noqa F811 @@ -159,12 +170,30 @@ def create( # noqa share_network=share_network, ) + @api_versions.wraps("2.95") # noqa + def create( # noqa + self, + share, # pylint: disable=function-redefined # noqa F811 + availability_zone=None, + scheduler_hints=None, + share_network=None, + metadata=None, + ): + return self._create_share_replica( + share, + availability_zone=availability_zone, + scheduler_hints=scheduler_hints, + share_network=share_network, + metadata=metadata, + ) + def _create_share_replica( self, share, availability_zone=None, scheduler_hints=None, share_network=None, + metadata=None, ): """Create a replica for a share. @@ -174,11 +203,13 @@ def _create_share_replica( :param scheduler_hints: The scheduler_hints as key=value pair. Only supported key is 'only_host'. :param share_network: either share network object or its UUID. + :param metadata: dict - optional metadata to set on share replica + creation """ share_id = base.getid(share) - body = {'share_id': share_id} + body = {'share_id': share_id} if availability_zone: body['availability_zone'] = base.getid(availability_zone) @@ -188,6 +219,9 @@ def _create_share_replica( if share_network: body['share_network_id'] = base.getid(share_network) + if metadata: + body['metadata'] = metadata + return self._create( RESOURCES_PATH, {RESOURCE_NAME: body}, RESOURCE_NAME ) diff --git a/pyproject.toml b/pyproject.toml index a8f81b04..99dd0cb3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -108,6 +108,7 @@ share_replica_delete = "manilaclient.osc.v2.share_replicas:DeleteShareReplica" share_replica_list = "manilaclient.osc.v2.share_replicas:ListShareReplica" share_replica_show = "manilaclient.osc.v2.share_replicas:ShowShareReplica" share_replica_set = "manilaclient.osc.v2.share_replicas:SetShareReplica" +share_replica_unset = "manilaclient.osc.v2.share_replicas:UnsetShareReplica" share_replica_promote = "manilaclient.osc.v2.share_replicas:PromoteShareReplica" share_replica_resync = "manilaclient.osc.v2.share_replicas:ResyncShareReplica" share_replica_export_location_list = "manilaclient.osc.v2.share_replica_export_locations:ShareReplicaListExportLocation" diff --git a/releasenotes/notes/add-share-replica-metadata-e6c1c2e00295d2dd.yaml b/releasenotes/notes/add-share-replica-metadata-e6c1c2e00295d2dd.yaml new file mode 100644 index 00000000..e06e41df --- /dev/null +++ b/releasenotes/notes/add-share-replica-metadata-e6c1c2e00295d2dd.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + Adds support to create/update/delete replica metadata (properties) + with set and unset command. From 8a25cfa720e6fbc559d40dd095f819b0ba914823 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Fri, 12 Dec 2025 11:32:51 +0000 Subject: [PATCH 40/52] Handle single digit versions This matches the behavior of novaclient [1], cinderclient [2] etc. We also fix a typo. [1] https://github.com/openstack/python-novaclient/blob/3e2dd5bd638352ac453d975ec2194315d4daea8f/novaclient/api_versions.py#L233-L234 [2] https://github.com/openstack/python-cinderclient/blob/1d8c7becaf2c1363afe843d2a5a86b1707a8e3ff/cinderclient/api_versions.py#L227-L228 Change-Id: I91b46474366248ae34df27fe35f63281602ae377 Signed-off-by: Stephen Finucane --- manilaclient/api_versions.py | 4 ++++ manilaclient/osc/plugin.py | 2 +- manilaclient/tests/unit/test_api_versions.py | 5 ----- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/manilaclient/api_versions.py b/manilaclient/api_versions.py index 62148791..e4b094a4 100644 --- a/manilaclient/api_versions.py +++ b/manilaclient/api_versions.py @@ -18,6 +18,8 @@ import re import warnings +from oslo_utils import strutils + import manilaclient from manilaclient.common._i18n import _ from manilaclient.common import cliutils @@ -231,6 +233,8 @@ def check_version_deprecated(api_version): def get_api_version(version_string): """Returns checked APIVersion object.""" version_string = str(version_string) + if strutils.is_int_like(version_string): + version_string = f"{version_string}.0" api_version = APIVersion(version_string) check_version_supported(api_version) diff --git a/manilaclient/osc/plugin.py b/manilaclient/osc/plugin.py index 65acb761..63495ded 100644 --- a/manilaclient/osc/plugin.py +++ b/manilaclient/osc/plugin.py @@ -121,7 +121,7 @@ def build_option_parser(parser): ), help='Shared File System API version, default=' + default_api_version - + 'version supported by both the client and the server). ' + + ' (version supported by both the client and the server) ' '(Env: OS_SHARE_API_VERSION)', ) parser.add_argument( diff --git a/manilaclient/tests/unit/test_api_versions.py b/manilaclient/tests/unit/test_api_versions.py index f71cfaa2..2a1ce4bc 100644 --- a/manilaclient/tests/unit/test_api_versions.py +++ b/manilaclient/tests/unit/test_api_versions.py @@ -144,11 +144,6 @@ def test_wrong_format(self): "something_wrong", ) - def test_wrong_major_version(self): - self.assertRaises( - exceptions.UnsupportedVersion, api_versions.get_api_version, "1" - ) - @mock.patch("manilaclient.api_versions.APIVersion") def test_major_and_minor_parts_is_presented(self, mock_apiversion): version = "2.7" From 3996ff3e6aba50d8b7a4c705857f3a0401210660 Mon Sep 17 00:00:00 2001 From: OpenStack Release Bot Date: Fri, 6 Mar 2026 13:14:01 +0000 Subject: [PATCH 41/52] Update master for stable/2026.1 Add file to the reno documentation build to show release notes for stable/2026.1. Use pbr instruction to increment the minor version number automatically so that master versions are higher than the versions on stable/2026.1. Sem-Ver: feature Change-Id: Icddd583bf42e0a8e94745448fbf321e455b4c111 Signed-off-by: OpenStack Release Bot Generated-By: openstack/project-config:roles/copy-release-tools-scripts/files/release-tools/add_release_note_page.sh --- releasenotes/source/2026.1.rst | 6 ++++++ releasenotes/source/index.rst | 1 + 2 files changed, 7 insertions(+) create mode 100644 releasenotes/source/2026.1.rst diff --git a/releasenotes/source/2026.1.rst b/releasenotes/source/2026.1.rst new file mode 100644 index 00000000..3d286158 --- /dev/null +++ b/releasenotes/source/2026.1.rst @@ -0,0 +1,6 @@ +=========================== +2026.1 Series Release Notes +=========================== + +.. release-notes:: + :branch: stable/2026.1 diff --git a/releasenotes/source/index.rst b/releasenotes/source/index.rst index 9ad580fc..9233d8d2 100644 --- a/releasenotes/source/index.rst +++ b/releasenotes/source/index.rst @@ -7,6 +7,7 @@ python-manilaclient Release Notes :maxdepth: 1 unreleased + 2026.1 2025.2 2025.1 2024.2 From df6f2dd4729f41244a3cdeae33202255038170dd Mon Sep 17 00:00:00 2001 From: Kiran Pawar Date: Fri, 27 Feb 2026 10:32:35 +0000 Subject: [PATCH 42/52] Fix option to override API endpoint Provide an option to override API endpoint to address multiple manila deployments on same cloud. Usage as following: "openstack --os-endpoint-override share list". Closes-bug: #2111331 Co-authored-by: Chuan Miao Signed-off-by: Kiran Pawar Change-Id: I7951055b4528908bafbe98f0707d9d89ed436862 --- doc/source/cli/osc_plugin_cli.rst | 2 +- manilaclient/osc/plugin.py | 15 ++++++++++++--- ...or-api-endpoint-override-c00ea54e1670cb90.yaml | 7 +++++++ 3 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 releasenotes/notes/add-export-variable-for-api-endpoint-override-c00ea54e1670cb90.yaml diff --git a/doc/source/cli/osc_plugin_cli.rst b/doc/source/cli/osc_plugin_cli.rst index 88e30318..33ba0c10 100644 --- a/doc/source/cli/osc_plugin_cli.rst +++ b/doc/source/cli/osc_plugin_cli.rst @@ -36,7 +36,7 @@ Client. In this case, you can use configuration option ``--os-endpoint-override`` or set the corresponding environment variable:: - export OS_ENDPOINT_OVERRIDE=http://... + export OS_SHARED_FILE_SYSTEM_ENDPOINT_OVERRIDE=http://... Getting help diff --git a/manilaclient/osc/plugin.py b/manilaclient/osc/plugin.py index 63495ded..2009b874 100644 --- a/manilaclient/osc/plugin.py +++ b/manilaclient/osc/plugin.py @@ -64,9 +64,17 @@ def make_client(instance): """Returns a shared file system service client.""" requested_api_version = instance._api_version[API_NAME] - service_type, manila_endpoint_url = _get_manila_url_from_service_catalog( - instance + endpoint_override = getattr( + instance._cli_options, 'os_endpoint_override', None ) + if endpoint_override: + manila_endpoint_url = endpoint_override + service_type = constants.SFS_SERVICE_TYPE + else: + service_type, manila_endpoint_url = ( + _get_manila_url_from_service_catalog(instance) + ) + instance.setup_auth() debugging_enabled = instance._cli_options.debug @@ -128,13 +136,14 @@ def build_option_parser(parser): "--os-endpoint-override", metavar="", default=utils.env( + "OS_SHARED_FILE_SYSTEM_ENDPOINT_OVERRIDE", "OS_ENDPOINT_OVERRIDE", "OS_MANILA_BYPASS_URL", "MANILACLIENT_BYPASS_URL", ), help=( "Use this API endpoint instead of the Service Catalog. " - "Defaults to env[OS_ENDPOINT_OVERRIDE]." + "Defaults to env[OS_SHARED_FILE_SYSTEM_ENDPOINT_OVERRIDE]." ), ) return parser diff --git a/releasenotes/notes/add-export-variable-for-api-endpoint-override-c00ea54e1670cb90.yaml b/releasenotes/notes/add-export-variable-for-api-endpoint-override-c00ea54e1670cb90.yaml new file mode 100644 index 00000000..a426db72 --- /dev/null +++ b/releasenotes/notes/add-export-variable-for-api-endpoint-override-c00ea54e1670cb90.yaml @@ -0,0 +1,7 @@ +--- +fixes: + - | + In addition to existing "--os-endpoint-override" option to override API + endpoint, user can also use export variable. For example, use + "export OS_SHARED_FILE_SYSTEM_ENDPOINT_OVERRIDE=" and then + use "openstack share list" command to refer different Manila API endpoint. From 6c2b5c808530bf2c8eb467adfd272ba010224f10 Mon Sep 17 00:00:00 2001 From: Sally Karimi Date: Wed, 25 Mar 2026 12:16:16 +0300 Subject: [PATCH 43/52] Fix typo 'occured' should be 'occurred' Closes-Bug: #2146280 Closes-Bug: #2146288 Change-Id: Ia6e7d8e2794cb3c349082a27dba3b6bd692c146b Signed-off-by: Sally Karimi --- manilaclient/exceptions.py | 2 +- .../bug-2051394-fix-validate-neutron-info-ebe679675111eec9.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/manilaclient/exceptions.py b/manilaclient/exceptions.py index 3a1d8ebb..daeb3a05 100644 --- a/manilaclient/exceptions.py +++ b/manilaclient/exceptions.py @@ -24,7 +24,7 @@ class ManilaclientException(Exception): """A generic client error.""" - message = _("An unexpected error occured.") + message = _("An unexpected error occurred.") def __init__(self, message): self.message = message or self.message diff --git a/releasenotes/notes/bug-2051394-fix-validate-neutron-info-ebe679675111eec9.yaml b/releasenotes/notes/bug-2051394-fix-validate-neutron-info-ebe679675111eec9.yaml index 81e6f871..f1e47c58 100644 --- a/releasenotes/notes/bug-2051394-fix-validate-neutron-info-ebe679675111eec9.yaml +++ b/releasenotes/notes/bug-2051394-fix-validate-neutron-info-ebe679675111eec9.yaml @@ -5,7 +5,7 @@ fixes: now validate Neutron network information provided before sending the request. - Previously, validation only occured in the Manila service + Previously, validation only occurred in the Manila service which could result in client-side errors when invalid network or subnet IDs were supplied. The client now performs proper validation and handles missing or invalid From e4a56ac5fc2d206e4b44356603386d688a7616e5 Mon Sep 17 00:00:00 2001 From: Denver Baraka Date: Wed, 25 Mar 2026 22:51:08 +0300 Subject: [PATCH 44/52] doc: Update OS_TENANT_NAME to OS_PROJECT_NAME The OpenStack Client plugin documentation in osc_plugin_cli.rst incorrectly uses OS_TENANT_NAME as an example for environment variable. This patch updates it to OS_PROJECT_NAME to match current OpenStack conventions and ensure consistency. Closes-Bug: #2146286 Change-Id: Ie49a5ee798225357223de55c4fa2dddec85a7acf Signed-off-by: Denver Baraka --- doc/source/cli/osc_plugin_cli.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/cli/osc_plugin_cli.rst b/doc/source/cli/osc_plugin_cli.rst index 88e30318..879ac569 100644 --- a/doc/source/cli/osc_plugin_cli.rst +++ b/doc/source/cli/osc_plugin_cli.rst @@ -27,7 +27,7 @@ environment variables:: export OS_USERNAME=foo export OS_PASSWORD=bar - export OS_TENANT_NAME=foobarproject + export OS_PROJECT_NAME=foobarproject export OS_AUTH_URL=http://... export OS_SHARE_API_VERSION=2.51 From 87e0e6792015d24f26a4329f409c6ba066080b73 Mon Sep 17 00:00:00 2001 From: Denver Baraka Date: Wed, 25 Mar 2026 23:08:50 +0300 Subject: [PATCH 45/52] doc: Fix wrong class references in manager docstrings Some manager classes had errors in their docstring referencing wrong resource classes. This patch updates them to reference correct classes. - ShareReplicaExportLocationManager: ShareInstanceExportLocation > ShareReplicaExportLocation - AvailabilityZoneManager: Service > AvailabilityZone - ShareInstanceManager: ShareInstances > ShareInstance Closes-bug: #2146282 Change-Id: I7960eec25f5db9c5c6405bee0706752c1d1dc9fa Signed-off-by: Denver Baraka --- manilaclient/v2/availability_zones.py | 2 +- manilaclient/v2/share_instances.py | 2 +- manilaclient/v2/share_replica_export_locations.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/manilaclient/v2/availability_zones.py b/manilaclient/v2/availability_zones.py index ccb1cbf5..e8ee08fe 100644 --- a/manilaclient/v2/availability_zones.py +++ b/manilaclient/v2/availability_zones.py @@ -27,7 +27,7 @@ def __repr__(self): class AvailabilityZoneManager(base.Manager): - """Manage :class:`Service` resources.""" + """Manage :class:`AvailabilityZone` resources.""" resource_class = AvailabilityZone diff --git a/manilaclient/v2/share_instances.py b/manilaclient/v2/share_instances.py index 92f6dc0e..2509bf02 100644 --- a/manilaclient/v2/share_instances.py +++ b/manilaclient/v2/share_instances.py @@ -35,7 +35,7 @@ def reset_state(self, state): class ShareInstanceManager(base.ManagerWithFind): - """Manage :class:`ShareInstances` resources.""" + """Manage :class:`ShareInstance` resources.""" resource_class = ShareInstance diff --git a/manilaclient/v2/share_replica_export_locations.py b/manilaclient/v2/share_replica_export_locations.py index d5ab4178..510809ca 100644 --- a/manilaclient/v2/share_replica_export_locations.py +++ b/manilaclient/v2/share_replica_export_locations.py @@ -28,7 +28,7 @@ def __getitem__(self, key): class ShareReplicaExportLocationManager(base.ManagerWithFind): - """Manage :class:`ShareInstanceExportLocation` resources.""" + """Manage :class:`ShareReplicaExportLocation` resources.""" resource_class = ShareReplicaExportLocation From d4d5d1964ddc80d8a7adc9581802de9e69fc1ea6 Mon Sep 17 00:00:00 2001 From: Denver Baraka Date: Wed, 25 Mar 2026 23:57:58 +0300 Subject: [PATCH 46/52] doc: fix share network docstrings fix copy-paste errors in share_networks.py and share_network_subnets.py manager classes by updating incorrect parameter names and return types. - policy > share_network / share_network_subnet - NetworkInfo > ShareNetwork - NetworkSubnetInfo > ShareNetworkSubnet Closes-bug: #2146281 Change-Id: I7aac0a31966667cc59d2da58d9edbc8250fabaea Signed-off-by: Denver Baraka --- manilaclient/v2/share_network_subnets.py | 4 ++-- manilaclient/v2/share_networks.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/manilaclient/v2/share_network_subnets.py b/manilaclient/v2/share_network_subnets.py index 1acb1b9c..c00161e0 100644 --- a/manilaclient/v2/share_network_subnets.py +++ b/manilaclient/v2/share_network_subnets.py @@ -108,8 +108,8 @@ def create( # noqa def get(self, share_network, share_network_subnet): """Get a share network subnet. - :param policy: share network subnet to get. - :rtype: :class:`NetworkSubnetInfo` + :param share_network_subnet: share network subnet to get. + :rtype: :class:`ShareNetworkSubnet` """ share_network_id = base.getid(share_network) share_network_subnet_id = base.getid(share_network_subnet) diff --git a/manilaclient/v2/share_networks.py b/manilaclient/v2/share_networks.py index cc858679..e1a738a3 100644 --- a/manilaclient/v2/share_networks.py +++ b/manilaclient/v2/share_networks.py @@ -155,8 +155,8 @@ def remove_security_service(self, share_network, security_service): def get(self, share_network): """Get a share network. - :param policy: share network to get. - :rtype: :class:`NetworkInfo` + :param share_network: share network to get. + :rtype: :class:`ShareNetwork` """ return self._get( RESOURCE_PATH % base.getid(share_network), RESOURCE_NAME @@ -249,7 +249,7 @@ def delete(self, share_network): def list(self, detailed=True, search_opts=None): """Get a list of all share network. - :rtype: list of :class:`NetworkInfo` + :rtype: list of :class:`ShareNetwork` """ query_string = self._build_query_string(search_opts) From ed3a69b14452a8205396e4ed68a43fdc29c2df85 Mon Sep 17 00:00:00 2001 From: Denver Baraka Date: Thu, 26 Mar 2026 19:33:27 +0300 Subject: [PATCH 47/52] fix formatting errors in pyproject.toml there were three minor formatting issues. Specifically, - 'share_delete' and 'share_lock_set' had leading spaces which could affect plugin loading. - 'share_group_snapshot_show' was missing a space before equal sign so not consistent with style. This change removes the leading spaces and adds the missing space for style consistency. Test Plan: PASS: tox -e pep8 Closes-Bug: #2146283 Change-Id: Id5948ac61f6b171b152de5a11aac4d7e99c901f1 Signed-off-by: Denver Baraka --- pyproject.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 99dd0cb3..69068e91 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,7 +39,7 @@ share = "manilaclient.osc.plugin" [project.entry-points."openstack.share.v2"] share_list = "manilaclient.osc.v2.share:ListShare" share_create = "manilaclient.osc.v2.share:CreateShare" -share_delete = " manilaclient.osc.v2.share:DeleteShare" +share_delete = "manilaclient.osc.v2.share:DeleteShare" share_show = "manilaclient.osc.v2.share:ShowShare" share_set = "manilaclient.osc.v2.share:SetShare" share_unset = "manilaclient.osc.v2.share:UnsetShare" @@ -159,7 +159,7 @@ share_group_type_access_list = "manilaclient.osc.v2.share_group_type_access:List share_group_type_access_delete = "manilaclient.osc.v2.share_group_type_access:ShareGroupTypeAccessDeny" share_group_snapshot_create = "manilaclient.osc.v2.share_group_snapshots:CreateShareGroupSnapshot" share_group_snapshot_delete = "manilaclient.osc.v2.share_group_snapshots:DeleteShareGroupSnapshot" -share_group_snapshot_show= "manilaclient.osc.v2.share_group_snapshots:ShowShareGroupSnapshot" +share_group_snapshot_show = "manilaclient.osc.v2.share_group_snapshots:ShowShareGroupSnapshot" share_group_snapshot_list = "manilaclient.osc.v2.share_group_snapshots:ListShareGroupSnapshot" share_group_snapshot_set = "manilaclient.osc.v2.share_group_snapshots:SetShareGroupSnapshot" share_group_snapshot_unset = "manilaclient.osc.v2.share_group_snapshots:UnsetShareGroupSnapshot" @@ -182,7 +182,7 @@ share_transfer_accept = "manilaclient.osc.v2.share_transfers:AcceptShareTransfer share_lock_create = "manilaclient.osc.v2.resource_locks:CreateResourceLock" share_lock_list = "manilaclient.osc.v2.resource_locks:ListResourceLock" share_lock_show = "manilaclient.osc.v2.resource_locks:ShowResourceLock" -share_lock_set = " manilaclient.osc.v2.resource_locks:SetResourceLock" +share_lock_set = "manilaclient.osc.v2.resource_locks:SetResourceLock" share_lock_unset = "manilaclient.osc.v2.resource_locks:UnsetResourceLock" share_lock_delete = "manilaclient.osc.v2.resource_locks:DeleteResourceLock" share_qos_type_create = "manilaclient.osc.v2.qos_types:CreateQosType" From c3402be1d9f50700f1b88266b0276de3f4350189 Mon Sep 17 00:00:00 2001 From: Denver Baraka Date: Thu, 26 Mar 2026 19:48:37 +0300 Subject: [PATCH 48/52] update stale OpenStack references in README.rst The python-manila client README had some outdated references that didn't allign with current conventions. Specifically, this patch: - updates wording to explicitly mention "OpenStack Manila API" instead of "Rackspace compatible API" - replaces keystone v2 'tenant' with '--os-project-name' and 'OS_PROJECT_NAME' - updates keystone authentication URL examples from 'v2.0' to 'v3' - updatesthe python API quickstart snippet to import and use 'manilaclient.v2' and 'PROJECT' credentials. Closes-Bug: #2146284 Change-Id: Ibdf2601f70fb94274747a78e47708edc62cbd65c Signed-off-by: Denver Baraka --- README.rst | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.rst b/README.rst index 53ae74a6..b3ea62df 100644 --- a/README.rst +++ b/README.rst @@ -52,20 +52,20 @@ Command-line API ---------------- Installing this package gets you a shell command, ``manila``, that you -can use to interact with any Rackspace compatible API (including OpenStack). +can use to interact with the OpenStack Manila API. You'll need to provide your OpenStack username and password. You can do this -with the ``--os-username``, ``--os-password`` and ``--os-tenant-name`` +with the ``--os-username``, ``--os-password`` and ``--os-project-name`` params, but it's easier to just set them as environment variables:: export OS_USERNAME=foouser export OS_PASSWORD=barpass - export OS_TENANT_NAME=fooproject + export OS_PROJECT_NAME=fooproject You will also need to define the authentication url either with param ``--os-auth-url`` or as an environment variable:: - export OS_AUTH_URL=http://example.com:5000/v2.0/ + export OS_AUTH_URL=http://example.com:5000/v3/ Since Keystone can return multiple regions in the Service Catalog, you can specify the one you want with ``--os-region-name`` (or @@ -81,9 +81,9 @@ There's also a complete Python API, but it has not yet been documented. Quick-start using keystone:: - # use v2.0 auth with http://example.com:5000/v2.0/ - >>> from manilaclient.v1 import client - >>> nt = client.Client(USER, PASS, TENANT, AUTH_URL, service_type="share") + # use v3 auth with http://example.com:5000/v3/ + >>> from manilaclient.v2 import client + >>> nt = client.Client("2", USER, PASS, PROJECT, AUTH_URL, service_type="share") >>> nt.shares.list() [...] From a960e55e11bd683609bfb11684e645997eadc449 Mon Sep 17 00:00:00 2001 From: Denver Baraka Date: Thu, 26 Mar 2026 22:57:45 +0300 Subject: [PATCH 49/52] fix stale API examble and typo in user/api.rst this change replaces the deprecated v1 client and '$OS_TENANT_NAME' with current standard of using v2 client and the '$OS_PROJECT_NAME' this change also corrects a minorr spelling error "assuumes" to "assumes" Closes-Bug: #2146285 Change-Id: I1314abb3476466df05093cc87775f5ac96fcefa9 Signed-off-by: Denver Baraka --- doc/source/user/api.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/source/user/api.rst b/doc/source/user/api.rst index 8c67f998..49f9e39c 100644 --- a/doc/source/user/api.rst +++ b/doc/source/user/api.rst @@ -14,7 +14,7 @@ token and identify which endpoint you wish to speak to. Once you have done so, you can use the API like so:: >>> from manilaclient import client - >>> manila = client.Client('1', $OS_USER_NAME, $OS_PASSWORD, $OS_TENANT_NAME, $OS_AUTH_URL) + >>> manila = client.Client('2', $OS_USER_NAME, $OS_PASSWORD, $OS_PROJECT_NAME, $OS_AUTH_URL) >>> manila.shares.list() [] >>> share = manila.shares.create(share_proto="nfs", size=1, share_network_id="some_share_network_id") @@ -26,7 +26,7 @@ done so, you can use the API like so:: In addition to creating and deleting shares, the manilaclient can manage share-types, access controls, and more! Using CephFS with Ganesha for NFS -support as an example (assuumes this continues from the above initialization):: +support as an example (assumes this continues from the above initialization):: >>> share_type = client.share_types.create( >>> name="cephfsnfstype", spec_driver_handles_share_servers=False, From 0b7d33037f7c35456bbcfc4d11f1f2ff7e94ac07 Mon Sep 17 00:00:00 2001 From: Medha Chaturvedi Date: Mon, 13 Apr 2026 08:15:25 -0400 Subject: [PATCH 50/52] Follow up on share replica metadata changes Addressed comments from 973923 patch. Added functional and unit tests Patch link: https://review.opendev.org/c/openstack/python-manilaclient/+/973923 Change-Id: I10c5d23b698f6f3e8e20b911cd8a65b6e8585afb Co-authored-by: medhac1403 Signed-off-by: Medha Choudhary --- manilaclient/osc/v2/share_replicas.py | 17 +++-- manilaclient/tests/functional/osc/base.py | 19 ++++- .../functional/osc/test_share_replicas.py | 71 ++++++++++++++++++- .../tests/unit/osc/v2/test_share_replicas.py | 33 +++++++-- manilaclient/v2/share_replicas.py | 4 ++ 5 files changed, 131 insertions(+), 13 deletions(-) diff --git a/manilaclient/osc/v2/share_replicas.py b/manilaclient/osc/v2/share_replicas.py index 4bab9e3b..cfe92d3f 100644 --- a/manilaclient/osc/v2/share_replicas.py +++ b/manilaclient/osc/v2/share_replicas.py @@ -498,7 +498,7 @@ def get_parser(self, prog_name): parser.add_argument( "replica", metavar="", - help=_("Unset a property for"), + help=_("ID of the share replica to unset property from"), ) parser.add_argument( '--property', @@ -526,14 +526,23 @@ def take_action(self, parsed_args): "with API microversion '2.95'." ) ) + result = 0 for key in parsed_args.property: try: replica.delete_metadata([key]) except Exception as e: - msg = _( - "Failed to unset replica property '%(key)s': %(e)s" + result += 1 + LOG.error( + _( + "Failed to unset replica property " + "'%(key)s': %(exception)s" + ), + {'key': key, 'exception': e}, ) - raise exceptions.CommandError(msg % {'key': key, 'e': e}) + if result > 0: + raise exceptions.CommandError( + _("One or more of the unset operations failed") + ) else: raise exceptions.CommandError( "Please specify '--property ' to unset a property." diff --git a/manilaclient/tests/functional/osc/base.py b/manilaclient/tests/functional/osc/base.py index 8bee30e4..92c34a1a 100644 --- a/manilaclient/tests/functional/osc/base.py +++ b/manilaclient/tests/functional/osc/base.py @@ -417,6 +417,7 @@ def create_share_replica( availability_zone=None, share_network=None, wait=None, + properties=None, add_cleanup=True, ): cmd = f'replica create {share}' @@ -427,6 +428,9 @@ def create_share_replica( cmd = cmd + ' --wait' if share_network: cmd = cmd + f' --share-network {share_network}' + if properties: + for key, value in properties.items(): + cmd = cmd + f' --property {key}={value}' replica_object = self.dict_result('share', cmd) self._wait_for_object_status( @@ -435,11 +439,22 @@ def create_share_replica( if add_cleanup: self.addCleanup( - self.openstack, - f'share replica delete {replica_object["id"]} --wait', + self._delete_share_replica_and_wait, replica_object['id'] ) return replica_object + def _delete_share_replica_and_wait(self, replica_id): + """Delete a share replica and wait for it to be gone. + + Uses check_object_deleted (respects CONF.build_timeout) instead of + the CLI --wait flag which is limited to osc_lib's hardcoded 300s. + """ + self.openstack( + f'share replica delete {replica_id}', + fail_ok=True, + ) + self.check_object_deleted('share replica', replica_id) + def get_share_replica_export_locations(self, replica): cmd = f'replica export location list {replica}' export_locations = self.listing_result('share', cmd) diff --git a/manilaclient/tests/functional/osc/test_share_replicas.py b/manilaclient/tests/functional/osc/test_share_replicas.py index 4eb84604..c56066dc 100644 --- a/manilaclient/tests/functional/osc/test_share_replicas.py +++ b/manilaclient/tests/functional/osc/test_share_replicas.py @@ -18,7 +18,7 @@ class ShareReplicasCLITest(base.OSCClientTestBase): - def _create_share_and_replica(self, add_cleanup=True): + def _create_share_and_replica(self, add_cleanup=True, properties=None): replication_type = CONF.replication_type share_type = self.create_share_type( data_utils.rand_name('test_share_type'), @@ -33,6 +33,7 @@ def _create_share_and_replica(self, add_cleanup=True): share['id'], share_network=share_network['id'], wait=True, + properties=properties, add_cleanup=add_cleanup, ) return replica @@ -56,3 +57,71 @@ def test_share_replica_delete(self): share_replica = self._create_share_and_replica(add_cleanup=False) self.openstack(f'share replica delete {share_replica["id"]}') self.check_object_deleted('share replica', share_replica["id"]) + + def test_share_replica_create_with_metadata(self): + """Create a replica with --property and verify it appears in show.""" + share_replica = self._create_share_and_replica( + properties={'test_key': 'test_value'} + ) + show_result = self.dict_result( + 'share', f'replica show {share_replica["id"]}' + ) + self.assertEqual(share_replica['id'], show_result['id']) + self.assertIn('test_key', show_result['properties']) + self.assertIn('test_value', show_result['properties']) + + def test_share_replica_set_property(self): + """Set a property on a replica and verify it appears in show.""" + share_replica = self._create_share_and_replica() + + self.openstack( + f'share replica set {share_replica["id"]}' + ' --property custom_role=secondary' + ) + + show_result = self.dict_result( + 'share', f'replica show {share_replica["id"]}' + ) + self.assertEqual(share_replica['id'], show_result['id']) + self.assertIn('custom_role', show_result['properties']) + self.assertIn('secondary', show_result['properties']) + + def test_share_replica_unset_property(self): + """Unset a property from a replica and verify it is removed.""" + share_replica = self._create_share_and_replica( + properties={ + 'custom_role': 'secondary', + 'custom_policy': 'async', + } + ) + + self.openstack( + f'share replica unset {share_replica["id"]} --property custom_role' + ) + + show_result = self.dict_result( + 'share', f'replica show {share_replica["id"]}' + ) + self.assertEqual(share_replica['id'], show_result['id']) + self.assertNotIn('custom_role', show_result['properties']) + self.assertIn('custom_policy', show_result['properties']) + self.assertIn('async', show_result['properties']) + + def test_share_replica_list_with_property_filter(self): + """List replicas filtered by property and verify correct results.""" + share_replica = self._create_share_and_replica( + properties={'filter_key': 'filter_value'} + ) + share_id = self.dict_result( + 'share', f'replica show {share_replica["id"]}' + )['share_id'] + + # List filtered by property; the replica should appear + filtered_list = self.listing_result( + 'share', + f'replica list --share {share_id}' + ' --property filter_key=filter_value', + ) + filtered_ids = [item['ID'] for item in filtered_list] + + self.assertIn(share_replica['id'], filtered_ids) diff --git a/manilaclient/tests/unit/osc/v2/test_share_replicas.py b/manilaclient/tests/unit/osc/v2/test_share_replicas.py index 06372baa..b29beddd 100644 --- a/manilaclient/tests/unit/osc/v2/test_share_replicas.py +++ b/manilaclient/tests/unit/osc/v2/test_share_replicas.py @@ -689,27 +689,48 @@ def test_share_replica_unset_property(self): parsed_args.property ) - def test_share_replica_unset_property_exception(self): + def test_share_replica_unset_multiple_properties(self): self.app.client_manager.share.api_version = api_versions.APIVersion( '2.95' ) arglist = [ - self.share_replica.id, '--property', - 'test_key', + 'key1', + '--property', + 'key2', + self.share_replica.id, ] verifylist = [ + ('property', ['key1', 'key2']), ('replica', self.share_replica.id), - ('property', ['test_key']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) - self.share_replica.delete_metadata.assert_called_once_with( - parsed_args.property + # Assert delete_metadata was called for each key + expected_calls = [mock.call(['key1']), mock.call(['key2'])] + self.share_replica.delete_metadata.assert_has_calls( + expected_calls, any_order=False + ) + self.assertEqual(self.share_replica.delete_metadata.call_count, 2) + + def test_share_replica_unset_property_exception(self): + self.app.client_manager.share.api_version = api_versions.APIVersion( + '2.95' ) + arglist = [ + self.share_replica.id, + '--property', + 'test_key', + ] + verifylist = [ + ('replica', self.share_replica.id), + ('property', ['test_key']), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) # 404 Not Found would be raised, if property 'test_key' doesn't exist. self.share_replica.delete_metadata.side_effect = exceptions.NotFound diff --git a/manilaclient/v2/share_replicas.py b/manilaclient/v2/share_replicas.py index 430d4921..e4c0ac5e 100644 --- a/manilaclient/v2/share_replicas.py +++ b/manilaclient/v2/share_replicas.py @@ -85,12 +85,16 @@ def _list_share_replicas(self, share=None, search_opts=None): :param share: either share object or its UUID. :param search_opts: dict of search options (e.g., metadata filters) + :rtype: list of :class:`ShareReplica` """ search_opts = search_opts or {} # This will turn {'metadata': {'foo': 'bar', 'baz': 'qux'}} # into ?metadata=foo:bar,baz:qux + # For nested search options like metadata, + # stringified inner dict is expected. + # e.g., {'metadata': 'foo:bar,baz:qux'} query_string = self._build_query_string(search_opts) if share: From e1f84b736c0d71d0215fee3e488ced34fd3f13b6 Mon Sep 17 00:00:00 2001 From: medhac1403 Date: Thu, 30 Apr 2026 07:07:42 -0400 Subject: [PATCH 51/52] Graduate share migration feature From this patch, share migration feature is no longer considered experimental. The experimental headers were removed from the share migration client commands. DocImpact Partially-implements: bp graduate-share-migration-feature Change-Id: Ia0f9b7adadc27c94737d53a5304b276f4c9b0b9f Signed-off-by: medhac1403 --- manilaclient/api_versions.py | 2 +- manilaclient/common/constants.py | 2 + manilaclient/v2/shares.py | 105 +++++++++++++++++- ...re-migration-feature-3b8fa72d4e91a517.yaml | 11 ++ 4 files changed, 114 insertions(+), 6 deletions(-) create mode 100644 releasenotes/notes/graduate-share-migration-feature-3b8fa72d4e91a517.yaml diff --git a/manilaclient/api_versions.py b/manilaclient/api_versions.py index 9c944373..d0c8c719 100644 --- a/manilaclient/api_versions.py +++ b/manilaclient/api_versions.py @@ -29,7 +29,7 @@ LOG = logging.getLogger(__name__) -MAX_VERSION = '2.95' +MAX_VERSION = '2.96' MIN_VERSION = '2.0' DEPRECATED_VERSION = '1.0' _VERSIONED_METHOD_MAP = {} diff --git a/manilaclient/common/constants.py b/manilaclient/common/constants.py index f148ae79..bb57f52a 100644 --- a/manilaclient/common/constants.py +++ b/manilaclient/common/constants.py @@ -181,3 +181,5 @@ SHARE_TRANSFER_VERSION = '2.77' RESOURCE_LOCK_VERSION = '2.81' QOS_TYPE_VERSION = '2.94' +SHARE_MIGRATION_GRADUATION_VERSION = '2.96' +SHARE_MIGRATION_PRE_GRADUATION_VERSION = '2.95' diff --git a/manilaclient/v2/shares.py b/manilaclient/v2/shares.py index a48fce68..805282ef 100644 --- a/manilaclient/v2/shares.py +++ b/manilaclient/v2/shares.py @@ -208,7 +208,9 @@ def create( '/shares', {'share': body}, 'share', return_raw=return_raw ) - @api_versions.wraps("2.29") + @api_versions.wraps( + "2.29", constants.SHARE_MIGRATION_PRE_GRADUATION_VERSION + ) @api_versions.experimental_api def migration_start( self, @@ -221,6 +223,55 @@ def migration_start( preserve_snapshots, new_share_network_id=None, new_share_type_id=None, + ): + return self._migration_start( + share, + host, + force_host_assisted_migration, + preserve_metadata, + writable, + nondisruptive, + preserve_snapshots, + new_share_network_id, + new_share_type_id, + ) + + @api_versions.wraps(constants.SHARE_MIGRATION_GRADUATION_VERSION) # noqa + def migration_start( # noqa F811 + self, + share, + host, + force_host_assisted_migration, + preserve_metadata, + writable, + nondisruptive, + preserve_snapshots, + new_share_network_id=None, + new_share_type_id=None, + ): + return self._migration_start( + share, + host, + force_host_assisted_migration, + preserve_metadata, + writable, + nondisruptive, + preserve_snapshots, + new_share_network_id, + new_share_type_id, + ) + + def _migration_start( + self, + share, + host, + force_host_assisted_migration, + preserve_metadata, + writable, + nondisruptive, + preserve_snapshots, + new_share_network_id=None, + new_share_type_id=None, ): return self._action( "migration_start", @@ -237,7 +288,9 @@ def migration_start( }, ) - @api_versions.wraps("2.22") + @api_versions.wraps( + "2.22", constants.SHARE_MIGRATION_PRE_GRADUATION_VERSION + ) @api_versions.experimental_api def reset_task_state(self, share, task_state): """Update the provided share with the provided task state. @@ -245,11 +298,25 @@ def reset_task_state(self, share, task_state): :param share: either share object or text with its ID. :param task_state: text with new task state to set for share. """ + return self._reset_task_state(share, task_state) + + @api_versions.wraps(constants.SHARE_MIGRATION_GRADUATION_VERSION) # noqa + def reset_task_state(self, share, task_state): # noqa F811 + """Update the provided share with the provided task state. + + :param share: either share object or text with its ID. + :param task_state: text with new task state to set for share. + """ + return self._reset_task_state(share, task_state) + + def _reset_task_state(self, share, task_state): return self._action( 'reset_task_state', share, {"task_state": task_state} ) - @api_versions.wraps("2.22") + @api_versions.wraps( + "2.22", constants.SHARE_MIGRATION_PRE_GRADUATION_VERSION + ) @api_versions.experimental_api def migration_complete(self, share): """Completes migration for a given share. @@ -258,7 +325,17 @@ def migration_complete(self, share): """ return self._action('migration_complete', share) - @api_versions.wraps("2.22") + @api_versions.wraps(constants.SHARE_MIGRATION_GRADUATION_VERSION) # noqa + def migration_complete(self, share): # noqa F811 + """Completes migration for a given share. + + :param share: The :class:'share' to complete migration + """ + return self._action('migration_complete', share) + + @api_versions.wraps( + "2.22", constants.SHARE_MIGRATION_PRE_GRADUATION_VERSION + ) @api_versions.experimental_api def migration_cancel(self, share): """Attempts to cancel migration for a given share. @@ -267,7 +344,17 @@ def migration_cancel(self, share): """ return self._action('migration_cancel', share) - @api_versions.wraps("2.22") + @api_versions.wraps(constants.SHARE_MIGRATION_GRADUATION_VERSION) # noqa + def migration_cancel(self, share): # noqa F811 + """Attempts to cancel migration for a given share. + + :param share: The :class:'share' to cancel migration + """ + return self._action('migration_cancel', share) + + @api_versions.wraps( + "2.22", constants.SHARE_MIGRATION_PRE_GRADUATION_VERSION + ) @api_versions.experimental_api def migration_get_progress(self, share): """Obtains progress of share migration for a given share. @@ -276,6 +363,14 @@ def migration_get_progress(self, share): """ return self._action('migration_get_progress', share) + @api_versions.wraps(constants.SHARE_MIGRATION_GRADUATION_VERSION) # noqa + def migration_get_progress(self, share): # noqa F811 + """Obtains progress of share migration for a given share. + + :param share: The :class:'share' to obtain migration progress + """ + return self._action('migration_get_progress', share) + def _do_manage( self, service_host, diff --git a/releasenotes/notes/graduate-share-migration-feature-3b8fa72d4e91a517.yaml b/releasenotes/notes/graduate-share-migration-feature-3b8fa72d4e91a517.yaml new file mode 100644 index 00000000..fd04a103 --- /dev/null +++ b/releasenotes/notes/graduate-share-migration-feature-3b8fa72d4e91a517.yaml @@ -0,0 +1,11 @@ +--- +prelude: > + - | + Share migration APIs have graduated from their `experimental feature + state `_ + from API version ``2.96``. The share migration actions + (``migration_start``, ``migration_complete``, ``migration_cancel``, + ``migration_get_progress`` and ``reset_task_state``) no longer require + the inclusion of the ``X-OpenStack-Manila-API-Experimental`` header in + API requests starting at version ``2.96``. Older microversions continue + to send the experimental header for backward compatibility. From 397105a5379966f63a1584b227226099cff1e9ea Mon Sep 17 00:00:00 2001 From: Takashi Kajinami Date: Sun, 3 May 2026 14:35:24 +0900 Subject: [PATCH 52/52] Replace OVN Metadata agent with OVN agent ... following the change in devstack[1]. [1] 6180e73702cfef2011c32f315cde97128a4b7eec Change-Id: Ia4a055a1aae4452abd712315b526aafdea51beff Signed-off-by: Takashi Kajinami --- zuul.d/python-manilaclient-jobs.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zuul.d/python-manilaclient-jobs.yaml b/zuul.d/python-manilaclient-jobs.yaml index a6477da7..4013638c 100644 --- a/zuul.d/python-manilaclient-jobs.yaml +++ b/zuul.d/python-manilaclient-jobs.yaml @@ -80,7 +80,7 @@ ovsdb-server: true # Neutron services q-svc: true - q-ovn-metadata-agent: true + q-ovn-agent: true # openstack-cli-server causes problem with credential switch in ansible # task openstack-cli-server: false