python-openstackclient 9.0.0__py3-none-any.whl → 10.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- openstackclient/__init__.py +2 -6
- openstackclient/api/api.py +41 -23
- openstackclient/api/compute_v2.py +44 -25
- openstackclient/api/object_store_v1.py +75 -97
- openstackclient/api/volume_v2.py +2 -1
- openstackclient/api/volume_v3.py +2 -1
- openstackclient/common/availability_zone.py +58 -42
- openstackclient/common/clientmanager.py +56 -29
- openstackclient/common/configuration.py +10 -3
- openstackclient/common/envvars.py +2 -2
- openstackclient/common/extension.py +14 -5
- openstackclient/common/limits.py +10 -5
- openstackclient/common/module.py +14 -6
- openstackclient/common/pagination.py +8 -2
- openstackclient/common/progressbar.py +7 -6
- openstackclient/common/project_cleanup.py +13 -7
- openstackclient/common/quota.py +97 -99
- openstackclient/common/versions.py +8 -2
- openstackclient/compute/client.py +7 -3
- openstackclient/compute/v2/agent.py +17 -10
- openstackclient/compute/v2/aggregate.py +36 -22
- openstackclient/compute/v2/console.py +14 -8
- openstackclient/compute/v2/console_connection.py +11 -3
- openstackclient/compute/v2/flavor.py +39 -21
- openstackclient/compute/v2/host.py +14 -6
- openstackclient/compute/v2/hypervisor.py +14 -5
- openstackclient/compute/v2/hypervisor_stats.py +10 -2
- openstackclient/compute/v2/keypair.py +29 -14
- openstackclient/compute/v2/server.py +249 -169
- openstackclient/compute/v2/server_backup.py +10 -4
- openstackclient/compute/v2/server_event.py +21 -12
- openstackclient/compute/v2/server_group.py +21 -11
- openstackclient/compute/v2/server_image.py +19 -10
- openstackclient/compute/v2/server_migration.py +24 -10
- openstackclient/compute/v2/server_share.py +274 -0
- openstackclient/compute/v2/server_volume.py +10 -4
- openstackclient/compute/v2/service.py +14 -7
- openstackclient/compute/v2/usage.py +26 -21
- openstackclient/identity/client.py +8 -3
- openstackclient/identity/common.py +78 -47
- openstackclient/identity/v2_0/catalog.py +14 -7
- openstackclient/identity/v2_0/ec2creds.py +21 -10
- openstackclient/identity/v2_0/endpoint.py +23 -11
- openstackclient/identity/v2_0/project.py +25 -14
- openstackclient/identity/v2_0/role.py +28 -14
- openstackclient/identity/v2_0/role_assignment.py +9 -3
- openstackclient/identity/v2_0/service.py +23 -11
- openstackclient/identity/v2_0/token.py +12 -5
- openstackclient/identity/v2_0/user.py +26 -15
- openstackclient/identity/v3/access_rule.py +26 -12
- openstackclient/identity/v3/application_credential.py +59 -24
- openstackclient/identity/v3/catalog.py +14 -7
- openstackclient/identity/v3/consumer.py +22 -11
- openstackclient/identity/v3/credential.py +36 -16
- openstackclient/identity/v3/domain.py +37 -18
- openstackclient/identity/v3/ec2creds.py +25 -12
- openstackclient/identity/v3/endpoint.py +42 -20
- openstackclient/identity/v3/endpoint_group.py +28 -17
- openstackclient/identity/v3/federation_protocol.py +38 -16
- openstackclient/identity/v3/group.py +55 -32
- openstackclient/identity/v3/identity_provider.py +92 -57
- openstackclient/identity/v3/implied_role.py +21 -9
- openstackclient/identity/v3/limit.py +38 -16
- openstackclient/identity/v3/mapping.py +26 -13
- openstackclient/identity/v3/policy.py +23 -12
- openstackclient/identity/v3/project.py +43 -23
- openstackclient/identity/v3/region.py +36 -16
- openstackclient/identity/v3/registered_limit.py +40 -16
- openstackclient/identity/v3/role.py +61 -31
- openstackclient/identity/v3/role_assignment.py +23 -6
- openstackclient/identity/v3/service.py +36 -16
- openstackclient/identity/v3/service_provider.py +37 -15
- openstackclient/identity/v3/tag.py +23 -6
- openstackclient/identity/v3/token.py +30 -14
- openstackclient/identity/v3/trust.py +32 -14
- openstackclient/identity/v3/unscoped_saml.py +10 -2
- openstackclient/identity/v3/user.py +49 -26
- openstackclient/image/client.py +7 -3
- openstackclient/image/v1/image.py +33 -26
- openstackclient/image/v2/cache.py +14 -9
- openstackclient/image/v2/image.py +74 -48
- openstackclient/image/v2/info.py +7 -1
- openstackclient/image/v2/metadef_namespaces.py +109 -13
- openstackclient/image/v2/metadef_objects.py +28 -15
- openstackclient/image/v2/metadef_properties.py +24 -13
- openstackclient/image/v2/metadef_resource_type_association.py +14 -7
- openstackclient/image/v2/metadef_resource_types.py +7 -1
- openstackclient/image/v2/task.py +15 -6
- openstackclient/locale/tr_TR/LC_MESSAGES/openstackclient.po +7 -192
- openstackclient/network/client.py +7 -2
- openstackclient/network/common.py +16 -241
- openstackclient/network/utils.py +36 -22
- openstackclient/network/v2/address_group.py +27 -16
- openstackclient/network/v2/address_scope.py +24 -13
- openstackclient/network/v2/bgpvpn/bgpvpn.py +463 -0
- openstackclient/network/v2/bgpvpn/constants.py +30 -0
- openstackclient/network/v2/bgpvpn/network_association.py +214 -0
- openstackclient/network/v2/bgpvpn/port_association.py +490 -0
- openstackclient/network/v2/bgpvpn/router_association.py +288 -0
- openstackclient/network/v2/default_security_group_rule.py +19 -10
- openstackclient/network/v2/floating_ip.py +110 -159
- openstackclient/network/v2/floating_ip_port_forwarding.py +30 -18
- openstackclient/network/v2/fwaas/__init__.py +0 -0
- openstackclient/network/v2/fwaas/group.py +466 -0
- openstackclient/network/v2/fwaas/policy.py +518 -0
- openstackclient/network/v2/fwaas/rule.py +574 -0
- openstackclient/network/v2/ip_availability.py +13 -5
- openstackclient/network/v2/l3_conntrack_helper.py +22 -13
- openstackclient/network/v2/local_ip.py +24 -13
- openstackclient/network/v2/local_ip_association.py +14 -7
- openstackclient/network/v2/ndp_proxy.py +20 -11
- openstackclient/network/v2/network.py +129 -196
- openstackclient/network/v2/network_agent.py +46 -25
- openstackclient/network/v2/network_auto_allocated_topology.py +22 -11
- openstackclient/network/v2/network_flavor.py +27 -16
- openstackclient/network/v2/network_flavor_profile.py +23 -12
- openstackclient/network/v2/network_meter.py +21 -10
- openstackclient/network/v2/network_meter_rule.py +21 -11
- openstackclient/network/v2/network_qos_policy.py +25 -15
- openstackclient/network/v2/network_qos_rule.py +32 -17
- openstackclient/network/v2/network_qos_rule_type.py +13 -5
- openstackclient/network/v2/network_rbac.py +23 -12
- openstackclient/network/v2/network_segment.py +20 -11
- openstackclient/network/v2/network_segment_range.py +56 -29
- openstackclient/network/v2/network_service_provider.py +7 -1
- openstackclient/network/v2/network_trunk.py +38 -22
- openstackclient/network/v2/port.py +54 -29
- openstackclient/network/v2/router.py +75 -52
- openstackclient/network/v2/security_group.py +87 -157
- openstackclient/network/v2/security_group_rule.py +100 -280
- openstackclient/network/v2/subnet.py +49 -28
- openstackclient/network/v2/subnet_pool.py +30 -17
- openstackclient/network/v2/taas/tap_flow.py +22 -11
- openstackclient/network/v2/taas/tap_mirror.py +22 -11
- openstackclient/network/v2/taas/tap_service.py +23 -12
- openstackclient/object/client.py +7 -2
- openstackclient/object/v1/account.py +13 -6
- openstackclient/object/v1/container.py +25 -15
- openstackclient/object/v1/object.py +25 -15
- openstackclient/py.typed +0 -0
- openstackclient/shell.py +46 -10
- openstackclient/tests/functional/base.py +55 -20
- openstackclient/tests/functional/common/test_extension.py +4 -0
- openstackclient/tests/functional/common/test_quota.py +3 -1
- openstackclient/tests/functional/compute/v2/common.py +14 -13
- openstackclient/tests/functional/compute/v2/test_flavor.py +3 -1
- openstackclient/tests/functional/compute/v2/test_server.py +3 -0
- openstackclient/tests/functional/identity/v2/common.py +10 -6
- openstackclient/tests/functional/identity/v2/test_role.py +4 -4
- openstackclient/tests/functional/identity/v3/common.py +25 -19
- openstackclient/tests/functional/identity/v3/test_group.py +20 -20
- openstackclient/tests/functional/identity/v3/test_idp.py +3 -1
- openstackclient/tests/functional/identity/v3/test_project.py +10 -10
- openstackclient/tests/functional/identity/v3/test_role.py +18 -18
- openstackclient/tests/functional/identity/v3/test_role_assignment.py +12 -12
- openstackclient/tests/functional/identity/v3/test_user.py +8 -8
- openstackclient/tests/functional/image/base.py +1 -6
- openstackclient/tests/functional/network/v2/common.py +5 -2
- openstackclient/tests/functional/network/v2/test_floating_ip.py +10 -4
- openstackclient/tests/functional/network/v2/test_ip_availability.py +4 -0
- openstackclient/tests/functional/network/v2/test_network_meter_rule.py +3 -2
- openstackclient/tests/functional/network/v2/test_network_segment.py +5 -0
- openstackclient/tests/functional/network/v2/test_subnet.py +13 -9
- openstackclient/tests/functional/object/v1/common.py +4 -0
- openstackclient/tests/functional/volume/v2/common.py +4 -0
- openstackclient/tests/functional/volume/v2/test_volume_snapshot.py +27 -11
- openstackclient/tests/functional/volume/v2/test_volume_type.py +2 -2
- openstackclient/tests/functional/volume/v3/common.py +4 -0
- openstackclient/tests/functional/volume/v3/test_volume_snapshot.py +11 -7
- openstackclient/tests/functional/volume/v3/test_volume_type.py +2 -2
- openstackclient/tests/unit/common/test_availability_zone.py +35 -49
- openstackclient/tests/unit/common/test_extension.py +2 -2
- openstackclient/tests/unit/common/test_module.py +12 -7
- openstackclient/tests/unit/common/test_project_cleanup.py +3 -1
- openstackclient/tests/unit/common/test_quota.py +6 -26
- openstackclient/tests/unit/compute/v2/fakes.py +25 -0
- openstackclient/tests/unit/compute/v2/test_flavor.py +28 -2
- openstackclient/tests/unit/compute/v2/test_keypair.py +6 -6
- openstackclient/tests/unit/compute/v2/test_server.py +11 -96
- openstackclient/tests/unit/compute/v2/test_server_share.py +287 -0
- openstackclient/tests/unit/identity/v3/fakes.py +3 -0
- openstackclient/tests/unit/identity/v3/test_group.py +4 -14
- openstackclient/tests/unit/identity/v3/test_identity_provider.py +303 -299
- openstackclient/tests/unit/identity/v3/test_user.py +4 -4
- openstackclient/tests/unit/image/v2/test_image.py +11 -11
- openstackclient/tests/unit/image/v2/test_metadef_namespaces.py +105 -6
- openstackclient/tests/unit/network/test_common.py +0 -155
- openstackclient/tests/unit/network/v2/bgpvpn/__init__.py +0 -0
- openstackclient/tests/unit/network/v2/bgpvpn/fakes.py +179 -0
- openstackclient/tests/unit/network/v2/bgpvpn/test_bgpvpn.py +584 -0
- openstackclient/tests/unit/network/v2/bgpvpn/test_network_association.py +285 -0
- openstackclient/tests/unit/network/v2/bgpvpn/test_port_association.py +384 -0
- openstackclient/tests/unit/network/v2/bgpvpn/test_router_association.py +297 -0
- openstackclient/tests/unit/network/v2/fwaas/__init__.py +0 -0
- openstackclient/tests/unit/network/v2/fwaas/test_group.py +897 -0
- openstackclient/tests/unit/network/v2/fwaas/test_policy.py +869 -0
- openstackclient/tests/unit/network/v2/fwaas/test_rule.py +980 -0
- openstackclient/tests/unit/network/v2/taas/{test_osc_tap_flow.py → test_tap_flow.py} +18 -25
- openstackclient/tests/unit/network/v2/taas/{test_osc_tap_mirror.py → test_tap_mirror.py} +19 -29
- openstackclient/tests/unit/network/v2/taas/{test_osc_tap_service.py → test_tap_service.py} +19 -29
- openstackclient/tests/unit/network/v2/test_address_group.py +2 -2
- openstackclient/tests/unit/network/v2/{test_floating_ip_network.py → test_floating_ip.py} +3 -2
- openstackclient/tests/unit/network/v2/test_floating_ip_port_forwarding.py +13 -13
- openstackclient/tests/unit/network/v2/test_network_agent.py +8 -4
- openstackclient/tests/unit/network/v2/test_network_auto_allocated_topology.py +3 -3
- openstackclient/tests/unit/network/v2/test_network_flavor.py +2 -2
- openstackclient/tests/unit/network/v2/test_network_qos_policy.py +1 -1
- openstackclient/tests/unit/network/v2/test_network_qos_rule.py +2 -2
- openstackclient/tests/unit/network/v2/test_network_rbac.py +1 -1
- openstackclient/tests/unit/network/v2/test_network_segment.py +1 -1
- openstackclient/tests/unit/network/v2/test_network_segment_range.py +7 -10
- openstackclient/tests/unit/network/v2/test_network_trunk.py +1 -1
- openstackclient/tests/unit/network/v2/test_router.py +8 -9
- openstackclient/tests/unit/network/v2/{test_security_group_network.py → test_security_group.py} +1 -20
- openstackclient/tests/unit/network/v2/{test_security_group_rule_network.py → test_security_group_rule.py} +7 -41
- openstackclient/tests/unit/network/v2/test_subnet.py +2 -1
- openstackclient/tests/unit/network/v2/test_subnet_pool.py +2 -1
- openstackclient/tests/unit/object/v1/fakes.py +8 -7
- openstackclient/tests/unit/object/v1/test_container.py +65 -101
- openstackclient/tests/unit/object/v1/test_container_all.py +8 -1
- openstackclient/tests/unit/object/v1/test_object.py +44 -84
- openstackclient/tests/unit/object/v1/test_object_all.py +8 -1
- openstackclient/tests/unit/test_hacking.py +108 -0
- openstackclient/tests/unit/volume/v2/fakes.py +1 -0
- openstackclient/tests/unit/volume/v2/test_volume_backup.py +1 -5
- openstackclient/tests/unit/volume/v2/test_volume_snapshot.py +2 -1
- openstackclient/tests/unit/volume/v2/test_volume_type.py +2 -4
- openstackclient/tests/unit/volume/v3/fakes.py +1 -0
- openstackclient/tests/unit/volume/v3/test_volume.py +60 -3
- openstackclient/tests/unit/volume/v3/test_volume_attachment.py +1 -1
- openstackclient/tests/unit/volume/v3/test_volume_backup.py +1 -5
- openstackclient/tests/unit/volume/v3/test_volume_snapshot.py +55 -1
- openstackclient/tests/unit/volume/v3/test_volume_type.py +2 -4
- openstackclient/volume/client.py +7 -3
- openstackclient/volume/v2/backup_record.py +15 -6
- openstackclient/volume/v2/consistency_group.py +29 -17
- openstackclient/volume/v2/consistency_group_snapshot.py +25 -10
- openstackclient/volume/v2/qos_specs.py +28 -17
- openstackclient/volume/v2/service.py +17 -6
- openstackclient/volume/v2/volume.py +57 -29
- openstackclient/volume/v2/volume_backend.py +19 -6
- openstackclient/volume/v2/volume_backup.py +46 -20
- openstackclient/volume/v2/volume_host.py +6 -4
- openstackclient/volume/v2/volume_snapshot.py +50 -24
- openstackclient/volume/v2/volume_transfer_request.py +31 -13
- openstackclient/volume/v2/volume_type.py +43 -24
- openstackclient/volume/v3/block_storage_cleanup.py +11 -3
- openstackclient/volume/v3/block_storage_cluster.py +19 -7
- openstackclient/volume/v3/block_storage_log_level.py +15 -6
- openstackclient/volume/v3/block_storage_manage.py +10 -4
- openstackclient/volume/v3/block_storage_resource_filter.py +17 -5
- openstackclient/volume/v3/service.py +16 -6
- openstackclient/volume/v3/volume.py +89 -39
- openstackclient/volume/v3/volume_attachment.py +43 -21
- openstackclient/volume/v3/volume_backup.py +53 -24
- openstackclient/volume/v3/volume_group.py +23 -13
- openstackclient/volume/v3/volume_group_snapshot.py +32 -13
- openstackclient/volume/v3/volume_group_type.py +26 -13
- openstackclient/volume/v3/volume_message.py +15 -7
- openstackclient/volume/v3/volume_snapshot.py +69 -32
- openstackclient/volume/v3/volume_transfer_request.py +31 -13
- openstackclient/volume/v3/volume_type.py +42 -24
- {python_openstackclient-9.0.0.dist-info → python_openstackclient-10.0.0.dist-info}/METADATA +6 -6
- {python_openstackclient-9.0.0.dist-info → python_openstackclient-10.0.0.dist-info}/RECORD +271 -260
- {python_openstackclient-9.0.0.dist-info → python_openstackclient-10.0.0.dist-info}/WHEEL +1 -1
- {python_openstackclient-9.0.0.dist-info → python_openstackclient-10.0.0.dist-info}/entry_points.txt +53 -1
- {python_openstackclient-9.0.0.dist-info → python_openstackclient-10.0.0.dist-info}/licenses/AUTHORS +4 -0
- python_openstackclient-10.0.0.dist-info/pbr.json +1 -0
- openstackclient/api/image_v1.py +0 -69
- openstackclient/api/image_v2.py +0 -79
- openstackclient/network/v2/floating_ip_pool.py +0 -38
- openstackclient/tests/functional/image/v1/test_image.py +0 -97
- openstackclient/tests/unit/api/test_image_v1.py +0 -96
- openstackclient/tests/unit/api/test_image_v2.py +0 -96
- openstackclient/tests/unit/network/v2/test_floating_ip_compute.py +0 -248
- openstackclient/tests/unit/network/v2/test_floating_ip_pool_compute.py +0 -49
- openstackclient/tests/unit/network/v2/test_floating_ip_pool_network.py +0 -39
- openstackclient/tests/unit/network/v2/test_network_compute.py +0 -404
- openstackclient/tests/unit/network/v2/test_security_group_compute.py +0 -392
- openstackclient/tests/unit/network/v2/test_security_group_rule_compute.py +0 -555
- python_openstackclient-9.0.0.dist-info/pbr.json +0 -1
- /openstackclient/{tests/functional/image/v1 → network/v2/bgpvpn}/__init__.py +0 -0
- {python_openstackclient-9.0.0.dist-info → python_openstackclient-10.0.0.dist-info}/licenses/LICENSE +0 -0
- {python_openstackclient-9.0.0.dist-info → python_openstackclient-10.0.0.dist-info}/top_level.txt +0 -0
|
@@ -14,6 +14,9 @@
|
|
|
14
14
|
|
|
15
15
|
"""Block Storage Service action implementations"""
|
|
16
16
|
|
|
17
|
+
import argparse
|
|
18
|
+
from typing import Any
|
|
19
|
+
|
|
17
20
|
from openstack import utils as sdk_utils
|
|
18
21
|
from osc_lib import exceptions
|
|
19
22
|
|
|
@@ -27,7 +30,7 @@ class BlockStorageLogLevelList(command.Lister):
|
|
|
27
30
|
Supported by --os-volume-api-version 3.32 or greater.
|
|
28
31
|
"""
|
|
29
32
|
|
|
30
|
-
def get_parser(self, prog_name):
|
|
33
|
+
def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
|
|
31
34
|
parser = super().get_parser(prog_name)
|
|
32
35
|
parser.add_argument(
|
|
33
36
|
"--host",
|
|
@@ -63,8 +66,12 @@ class BlockStorageLogLevelList(command.Lister):
|
|
|
63
66
|
)
|
|
64
67
|
return parser
|
|
65
68
|
|
|
66
|
-
def take_action(
|
|
67
|
-
|
|
69
|
+
def take_action(
|
|
70
|
+
self, parsed_args: argparse.Namespace
|
|
71
|
+
) -> tuple[list[str], list[tuple[Any, ...]]]:
|
|
72
|
+
volume_client = sdk_utils.ensure_service_version(
|
|
73
|
+
self.app.client_manager.sdk_connection.volume, '3'
|
|
74
|
+
)
|
|
68
75
|
columns = [
|
|
69
76
|
"Binary",
|
|
70
77
|
"Host",
|
|
@@ -98,7 +105,7 @@ class BlockStorageLogLevelSet(command.Command):
|
|
|
98
105
|
Supported by --os-volume-api-version 3.32 or greater.
|
|
99
106
|
"""
|
|
100
107
|
|
|
101
|
-
def get_parser(self, prog_name):
|
|
108
|
+
def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
|
|
102
109
|
parser = super().get_parser(prog_name)
|
|
103
110
|
parser.add_argument(
|
|
104
111
|
"level",
|
|
@@ -141,8 +148,10 @@ class BlockStorageLogLevelSet(command.Command):
|
|
|
141
148
|
)
|
|
142
149
|
return parser
|
|
143
150
|
|
|
144
|
-
def take_action(self, parsed_args):
|
|
145
|
-
volume_client =
|
|
151
|
+
def take_action(self, parsed_args: argparse.Namespace) -> None:
|
|
152
|
+
volume_client = sdk_utils.ensure_service_version(
|
|
153
|
+
self.app.client_manager.sdk_connection.volume, '3'
|
|
154
|
+
)
|
|
146
155
|
|
|
147
156
|
if not sdk_utils.supports_microversion(volume_client, '3.32'):
|
|
148
157
|
msg = _(
|
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
"""Block Storage Volume/Snapshot Management implementations"""
|
|
15
15
|
|
|
16
16
|
import argparse
|
|
17
|
+
from collections.abc import Iterable
|
|
18
|
+
from typing import Any
|
|
17
19
|
|
|
18
20
|
from cinderclient import api_versions
|
|
19
21
|
from osc_lib import exceptions
|
|
@@ -32,7 +34,7 @@ class BlockStorageManageVolumes(command.Lister):
|
|
|
32
34
|
Supported by --os-volume-api-version 3.8 or greater.
|
|
33
35
|
"""
|
|
34
36
|
|
|
35
|
-
def get_parser(self, prog_name):
|
|
37
|
+
def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
|
|
36
38
|
parser = super().get_parser(prog_name)
|
|
37
39
|
host_group = parser.add_mutually_exclusive_group()
|
|
38
40
|
host_group.add_argument(
|
|
@@ -104,7 +106,9 @@ class BlockStorageManageVolumes(command.Lister):
|
|
|
104
106
|
)
|
|
105
107
|
return parser
|
|
106
108
|
|
|
107
|
-
def take_action(
|
|
109
|
+
def take_action(
|
|
110
|
+
self, parsed_args: argparse.Namespace
|
|
111
|
+
) -> tuple[list[str], Iterable[tuple[Any, ...]]]:
|
|
108
112
|
volume_client = self.app.client_manager.volume
|
|
109
113
|
|
|
110
114
|
if parsed_args.host is None and parsed_args.cluster is None:
|
|
@@ -196,7 +200,7 @@ class BlockStorageManageSnapshots(command.Lister):
|
|
|
196
200
|
Supported by --os-volume-api-version 3.8 or greater.
|
|
197
201
|
"""
|
|
198
202
|
|
|
199
|
-
def get_parser(self, prog_name):
|
|
203
|
+
def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
|
|
200
204
|
parser = super().get_parser(prog_name)
|
|
201
205
|
host_group = parser.add_mutually_exclusive_group()
|
|
202
206
|
host_group.add_argument(
|
|
@@ -268,7 +272,9 @@ class BlockStorageManageSnapshots(command.Lister):
|
|
|
268
272
|
)
|
|
269
273
|
return parser
|
|
270
274
|
|
|
271
|
-
def take_action(
|
|
275
|
+
def take_action(
|
|
276
|
+
self, parsed_args: argparse.Namespace
|
|
277
|
+
) -> tuple[list[str], Iterable[tuple[Any, ...]]]:
|
|
272
278
|
volume_client = self.app.client_manager.volume
|
|
273
279
|
|
|
274
280
|
if parsed_args.host is None and parsed_args.cluster is None:
|
|
@@ -12,6 +12,10 @@
|
|
|
12
12
|
|
|
13
13
|
"""Volume V3 Resource Filters implementations"""
|
|
14
14
|
|
|
15
|
+
import argparse
|
|
16
|
+
from collections.abc import Iterable, Sequence
|
|
17
|
+
from typing import Any
|
|
18
|
+
|
|
15
19
|
from openstack import utils as sdk_utils
|
|
16
20
|
from osc_lib.cli import format_columns
|
|
17
21
|
from osc_lib import exceptions
|
|
@@ -24,8 +28,12 @@ from openstackclient.i18n import _
|
|
|
24
28
|
class ListBlockStorageResourceFilter(command.Lister):
|
|
25
29
|
_description = _('List block storage resource filters')
|
|
26
30
|
|
|
27
|
-
def take_action(
|
|
28
|
-
|
|
31
|
+
def take_action(
|
|
32
|
+
self, parsed_args: argparse.Namespace
|
|
33
|
+
) -> tuple[tuple[str, ...], Iterable[tuple[Any, ...]]]:
|
|
34
|
+
volume_client = sdk_utils.ensure_service_version(
|
|
35
|
+
self.app.client_manager.sdk_connection.volume, '3'
|
|
36
|
+
)
|
|
29
37
|
|
|
30
38
|
if not sdk_utils.supports_microversion(volume_client, '3.33'):
|
|
31
39
|
msg = _(
|
|
@@ -58,7 +66,7 @@ class ListBlockStorageResourceFilter(command.Lister):
|
|
|
58
66
|
class ShowBlockStorageResourceFilter(command.ShowOne):
|
|
59
67
|
_description = _('Show filters for a block storage resource type')
|
|
60
68
|
|
|
61
|
-
def get_parser(self, prog_name):
|
|
69
|
+
def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
|
|
62
70
|
parser = super().get_parser(prog_name)
|
|
63
71
|
parser.add_argument(
|
|
64
72
|
'resource',
|
|
@@ -68,8 +76,12 @@ class ShowBlockStorageResourceFilter(command.ShowOne):
|
|
|
68
76
|
|
|
69
77
|
return parser
|
|
70
78
|
|
|
71
|
-
def take_action(
|
|
72
|
-
|
|
79
|
+
def take_action(
|
|
80
|
+
self, parsed_args: argparse.Namespace
|
|
81
|
+
) -> tuple[Sequence[str], Iterable[Any]]:
|
|
82
|
+
volume_client = sdk_utils.ensure_service_version(
|
|
83
|
+
self.app.client_manager.sdk_connection.volume, '3'
|
|
84
|
+
)
|
|
73
85
|
|
|
74
86
|
if not sdk_utils.supports_microversion(volume_client, '3.33'):
|
|
75
87
|
msg = _(
|
|
@@ -14,6 +14,10 @@
|
|
|
14
14
|
|
|
15
15
|
"""Service action implementations"""
|
|
16
16
|
|
|
17
|
+
import argparse
|
|
18
|
+
from collections.abc import Iterable
|
|
19
|
+
from typing import Any
|
|
20
|
+
|
|
17
21
|
from openstack import utils as sdk_utils
|
|
18
22
|
from osc_lib import exceptions
|
|
19
23
|
from osc_lib import utils
|
|
@@ -25,7 +29,7 @@ from openstackclient.i18n import _
|
|
|
25
29
|
class ListService(command.Lister):
|
|
26
30
|
_description = _("List service command")
|
|
27
31
|
|
|
28
|
-
def get_parser(self, prog_name):
|
|
32
|
+
def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
|
|
29
33
|
parser = super().get_parser(prog_name)
|
|
30
34
|
parser.add_argument(
|
|
31
35
|
"--host",
|
|
@@ -45,8 +49,12 @@ class ListService(command.Lister):
|
|
|
45
49
|
)
|
|
46
50
|
return parser
|
|
47
51
|
|
|
48
|
-
def take_action(
|
|
49
|
-
|
|
52
|
+
def take_action(
|
|
53
|
+
self, parsed_args: argparse.Namespace
|
|
54
|
+
) -> tuple[tuple[str, ...], Iterable[tuple[Any, ...]]]:
|
|
55
|
+
volume_client = sdk_utils.ensure_service_version(
|
|
56
|
+
self.app.client_manager.sdk_connection.volume, '3'
|
|
57
|
+
)
|
|
50
58
|
|
|
51
59
|
columns: tuple[str, ...] = (
|
|
52
60
|
"binary",
|
|
@@ -93,7 +101,7 @@ class ListService(command.Lister):
|
|
|
93
101
|
class SetService(command.Command):
|
|
94
102
|
_description = _("Set volume service properties")
|
|
95
103
|
|
|
96
|
-
def get_parser(self, prog_name):
|
|
104
|
+
def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
|
|
97
105
|
parser = super().get_parser(prog_name)
|
|
98
106
|
parser.add_argument(
|
|
99
107
|
"host",
|
|
@@ -122,7 +130,7 @@ class SetService(command.Command):
|
|
|
122
130
|
)
|
|
123
131
|
return parser
|
|
124
132
|
|
|
125
|
-
def take_action(self, parsed_args):
|
|
133
|
+
def take_action(self, parsed_args: argparse.Namespace) -> None:
|
|
126
134
|
if parsed_args.disable_reason and not parsed_args.disable:
|
|
127
135
|
msg = _(
|
|
128
136
|
"Cannot specify option --disable-reason without "
|
|
@@ -130,7 +138,9 @@ class SetService(command.Command):
|
|
|
130
138
|
)
|
|
131
139
|
raise exceptions.CommandError(msg)
|
|
132
140
|
|
|
133
|
-
volume_client =
|
|
141
|
+
volume_client = sdk_utils.ensure_service_version(
|
|
142
|
+
self.app.client_manager.sdk_connection.volume, '3'
|
|
143
|
+
)
|
|
134
144
|
|
|
135
145
|
service = volume_client.find_service(
|
|
136
146
|
parsed_args.service, ignore_missing=False, host=parsed_args.host
|
|
@@ -15,10 +15,11 @@
|
|
|
15
15
|
"""Volume V3 Volume action implementations"""
|
|
16
16
|
|
|
17
17
|
import argparse
|
|
18
|
+
from collections.abc import Iterable, Sequence
|
|
18
19
|
import copy
|
|
19
20
|
import functools
|
|
20
21
|
import logging
|
|
21
|
-
|
|
22
|
+
from typing import Any
|
|
22
23
|
|
|
23
24
|
from cliff import columns as cliff_columns
|
|
24
25
|
from openstack.block_storage.v3 import volume as _volume
|
|
@@ -44,14 +45,20 @@ class KeyValueHintAction(argparse.Action):
|
|
|
44
45
|
|
|
45
46
|
APPEND_KEYS = ('same_host', 'different_host')
|
|
46
47
|
|
|
47
|
-
def __init__(self, *args, **kwargs):
|
|
48
|
+
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
|
48
49
|
self._key_value_action = parseractions.KeyValueAction(*args, **kwargs)
|
|
49
50
|
self._key_value_append_action = parseractions.KeyValueAppendAction(
|
|
50
51
|
*args, **kwargs
|
|
51
52
|
)
|
|
52
53
|
super().__init__(*args, **kwargs)
|
|
53
54
|
|
|
54
|
-
def __call__(
|
|
55
|
+
def __call__(
|
|
56
|
+
self,
|
|
57
|
+
parser: argparse.ArgumentParser,
|
|
58
|
+
namespace: argparse.Namespace,
|
|
59
|
+
values: Any,
|
|
60
|
+
option_string: str | None = None,
|
|
61
|
+
) -> None:
|
|
55
62
|
if values.startswith(self.APPEND_KEYS):
|
|
56
63
|
self._key_value_append_action(
|
|
57
64
|
parser, namespace, values, option_string=option_string
|
|
@@ -62,7 +69,7 @@ class KeyValueHintAction(argparse.Action):
|
|
|
62
69
|
)
|
|
63
70
|
|
|
64
71
|
|
|
65
|
-
class AttachmentsColumn(cliff_columns.FormattableColumn[list[
|
|
72
|
+
class AttachmentsColumn(cliff_columns.FormattableColumn[list[Any]]):
|
|
66
73
|
"""Formattable column for attachments column.
|
|
67
74
|
|
|
68
75
|
Unlike the parent FormattableColumn class, the initializer of the
|
|
@@ -73,11 +80,13 @@ class AttachmentsColumn(cliff_columns.FormattableColumn[list[ty.Any]]):
|
|
|
73
80
|
``functools.partial(AttachmentsColumn, server_cache)``.
|
|
74
81
|
"""
|
|
75
82
|
|
|
76
|
-
def __init__(
|
|
83
|
+
def __init__(
|
|
84
|
+
self, value: list[Any], server_cache: dict[str, Any] | None = None
|
|
85
|
+
) -> None:
|
|
77
86
|
super().__init__(value)
|
|
78
87
|
self._server_cache = server_cache or {}
|
|
79
88
|
|
|
80
|
-
def human_readable(self):
|
|
89
|
+
def human_readable(self) -> str:
|
|
81
90
|
"""Return a formatted string of a volume's attached instances
|
|
82
91
|
|
|
83
92
|
:rtype: a string of formatted instances
|
|
@@ -93,7 +102,7 @@ class AttachmentsColumn(cliff_columns.FormattableColumn[list[ty.Any]]):
|
|
|
93
102
|
return msg
|
|
94
103
|
|
|
95
104
|
|
|
96
|
-
def _format_volume(volume: _volume.Volume) -> dict[str,
|
|
105
|
+
def _format_volume(volume: _volume.Volume) -> dict[str, Any]:
|
|
97
106
|
# Some columns returned by openstacksdk should not be shown because they're
|
|
98
107
|
# either irrelevant or duplicates
|
|
99
108
|
ignored_columns = {
|
|
@@ -143,7 +152,7 @@ class CreateVolume(command.ShowOne):
|
|
|
143
152
|
_description = _("Create new volume")
|
|
144
153
|
|
|
145
154
|
@staticmethod
|
|
146
|
-
def _check_size_arg(args):
|
|
155
|
+
def _check_size_arg(args: argparse.Namespace) -> None:
|
|
147
156
|
"""Check whether --size option is required or not.
|
|
148
157
|
|
|
149
158
|
Require size parameter in case if any of the following is not
|
|
@@ -164,7 +173,7 @@ class CreateVolume(command.ShowOne):
|
|
|
164
173
|
)
|
|
165
174
|
raise exceptions.CommandError(msg)
|
|
166
175
|
|
|
167
|
-
def get_parser(self, prog_name):
|
|
176
|
+
def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
|
|
168
177
|
parser = super().get_parser(prog_name)
|
|
169
178
|
parser.add_argument(
|
|
170
179
|
"name",
|
|
@@ -313,7 +322,9 @@ class CreateVolume(command.ShowOne):
|
|
|
313
322
|
)
|
|
314
323
|
return parser
|
|
315
324
|
|
|
316
|
-
def take_action(
|
|
325
|
+
def take_action(
|
|
326
|
+
self, parsed_args: argparse.Namespace
|
|
327
|
+
) -> tuple[Sequence[str], Iterable[Any]]:
|
|
317
328
|
self._check_size_arg(parsed_args)
|
|
318
329
|
# size is validated in the above call to
|
|
319
330
|
# _check_size_arg where we check that size
|
|
@@ -321,7 +332,9 @@ class CreateVolume(command.ShowOne):
|
|
|
321
332
|
# volume from snapshot, backup or source volume
|
|
322
333
|
size = parsed_args.size
|
|
323
334
|
|
|
324
|
-
volume_client =
|
|
335
|
+
volume_client = sdk_utils.ensure_service_version(
|
|
336
|
+
self.app.client_manager.sdk_connection.volume, '3'
|
|
337
|
+
)
|
|
325
338
|
image_client = self.app.client_manager.image
|
|
326
339
|
|
|
327
340
|
if (
|
|
@@ -386,7 +399,8 @@ class CreateVolume(command.ShowOne):
|
|
|
386
399
|
bootable=parsed_args.bootable,
|
|
387
400
|
)
|
|
388
401
|
data = _format_volume(volume)
|
|
389
|
-
|
|
402
|
+
col_headers, col_data = zip(*sorted(data.items()))
|
|
403
|
+
return col_headers, col_data
|
|
390
404
|
|
|
391
405
|
source_volume = None
|
|
392
406
|
if parsed_args.source:
|
|
@@ -491,13 +505,14 @@ class CreateVolume(command.ShowOne):
|
|
|
491
505
|
)
|
|
492
506
|
|
|
493
507
|
data = _format_volume(volume)
|
|
494
|
-
|
|
508
|
+
col_headers, col_data = zip(*sorted(data.items()))
|
|
509
|
+
return col_headers, col_data
|
|
495
510
|
|
|
496
511
|
|
|
497
512
|
class DeleteVolume(command.Command):
|
|
498
513
|
_description = _("Delete volume(s)")
|
|
499
514
|
|
|
500
|
-
def get_parser(self, prog_name):
|
|
515
|
+
def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
|
|
501
516
|
parser = super().get_parser(prog_name)
|
|
502
517
|
parser.add_argument(
|
|
503
518
|
"volumes",
|
|
@@ -535,8 +550,10 @@ class DeleteVolume(command.Command):
|
|
|
535
550
|
)
|
|
536
551
|
return parser
|
|
537
552
|
|
|
538
|
-
def take_action(self, parsed_args):
|
|
539
|
-
volume_client =
|
|
553
|
+
def take_action(self, parsed_args: argparse.Namespace) -> None:
|
|
554
|
+
volume_client = sdk_utils.ensure_service_version(
|
|
555
|
+
self.app.client_manager.sdk_connection.volume, '3'
|
|
556
|
+
)
|
|
540
557
|
result = 0
|
|
541
558
|
|
|
542
559
|
if parsed_args.remote and (parsed_args.force or parsed_args.cascade):
|
|
@@ -581,7 +598,7 @@ class DeleteVolume(command.Command):
|
|
|
581
598
|
class ListVolume(command.Lister):
|
|
582
599
|
_description = _("List volumes")
|
|
583
600
|
|
|
584
|
-
def get_parser(self, prog_name):
|
|
601
|
+
def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
|
|
585
602
|
parser = super().get_parser(prog_name)
|
|
586
603
|
parser.add_argument(
|
|
587
604
|
'--project',
|
|
@@ -630,7 +647,9 @@ class ListVolume(command.Lister):
|
|
|
630
647
|
pagination.add_marker_pagination_option_to_parser(parser)
|
|
631
648
|
return parser
|
|
632
649
|
|
|
633
|
-
def take_action(
|
|
650
|
+
def take_action(
|
|
651
|
+
self, parsed_args: argparse.Namespace
|
|
652
|
+
) -> tuple[Sequence[str], Iterable[tuple[Any, ...]]]:
|
|
634
653
|
volume_client = self.app.client_manager.volume
|
|
635
654
|
identity_client = self.app.client_manager.identity
|
|
636
655
|
|
|
@@ -706,7 +725,7 @@ class ListVolume(command.Lister):
|
|
|
706
725
|
compute_client = self.app.client_manager.compute
|
|
707
726
|
for s in compute_client.servers():
|
|
708
727
|
server_cache[s.id] = s
|
|
709
|
-
except sdk_exceptions.SDKException:
|
|
728
|
+
except sdk_exceptions.SDKException:
|
|
710
729
|
# Just forget it if there's any trouble
|
|
711
730
|
pass
|
|
712
731
|
AttachmentsColumnWithCache = functools.partial(
|
|
@@ -736,21 +755,29 @@ class ListVolume(command.Lister):
|
|
|
736
755
|
class MigrateVolume(command.Command):
|
|
737
756
|
_description = _("Migrate volume to a new host")
|
|
738
757
|
|
|
739
|
-
def get_parser(self, prog_name):
|
|
758
|
+
def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
|
|
740
759
|
parser = super().get_parser(prog_name)
|
|
741
760
|
parser.add_argument(
|
|
742
761
|
'volume',
|
|
743
762
|
metavar="<volume>",
|
|
744
763
|
help=_("Volume to migrate (name or ID)"),
|
|
745
764
|
)
|
|
746
|
-
parser.
|
|
765
|
+
destination_group = parser.add_mutually_exclusive_group(required=True)
|
|
766
|
+
destination_group.add_argument(
|
|
747
767
|
'--host',
|
|
748
768
|
metavar="<host>",
|
|
749
|
-
required=True,
|
|
750
769
|
help=_(
|
|
751
770
|
"Destination host (takes the form: host@backend-name#pool)"
|
|
752
771
|
),
|
|
753
772
|
)
|
|
773
|
+
destination_group.add_argument(
|
|
774
|
+
'--cluster',
|
|
775
|
+
metavar="<cluster>",
|
|
776
|
+
help=_(
|
|
777
|
+
"Destination cluster to migrate the volume to "
|
|
778
|
+
"(requires --os-volume-api-version 3.16 or higher)"
|
|
779
|
+
),
|
|
780
|
+
)
|
|
754
781
|
parser.add_argument(
|
|
755
782
|
'--force-host-copy',
|
|
756
783
|
action="store_true",
|
|
@@ -768,26 +795,38 @@ class MigrateVolume(command.Command):
|
|
|
768
795
|
"(possibly by another operation)"
|
|
769
796
|
),
|
|
770
797
|
)
|
|
771
|
-
# TODO(stephenfin): Add --cluster argument
|
|
772
798
|
return parser
|
|
773
799
|
|
|
774
|
-
def take_action(self, parsed_args):
|
|
775
|
-
volume_client =
|
|
800
|
+
def take_action(self, parsed_args: argparse.Namespace) -> None:
|
|
801
|
+
volume_client = sdk_utils.ensure_service_version(
|
|
802
|
+
self.app.client_manager.sdk_connection.volume, '3'
|
|
803
|
+
)
|
|
776
804
|
volume = volume_client.find_volume(
|
|
777
805
|
parsed_args.volume, ignore_missing=False
|
|
778
806
|
)
|
|
807
|
+
|
|
808
|
+
if parsed_args.cluster and not sdk_utils.supports_microversion(
|
|
809
|
+
volume_client, '3.16'
|
|
810
|
+
):
|
|
811
|
+
msg = _(
|
|
812
|
+
"--os-volume-api-version 3.16 or greater is required to "
|
|
813
|
+
"support the volume migration with cluster"
|
|
814
|
+
)
|
|
815
|
+
raise exceptions.CommandError(msg)
|
|
816
|
+
|
|
779
817
|
volume_client.migrate_volume(
|
|
780
818
|
volume.id,
|
|
781
819
|
host=parsed_args.host,
|
|
782
820
|
force_host_copy=parsed_args.force_host_copy,
|
|
783
821
|
lock_volume=parsed_args.lock_volume,
|
|
822
|
+
cluster=parsed_args.cluster,
|
|
784
823
|
)
|
|
785
824
|
|
|
786
825
|
|
|
787
826
|
class SetVolume(command.Command):
|
|
788
827
|
_description = _("Set volume properties")
|
|
789
828
|
|
|
790
|
-
def get_parser(self, prog_name):
|
|
829
|
+
def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
|
|
791
830
|
parser = super().get_parser(prog_name)
|
|
792
831
|
parser.add_argument(
|
|
793
832
|
'volume',
|
|
@@ -940,7 +979,7 @@ class SetVolume(command.Command):
|
|
|
940
979
|
)
|
|
941
980
|
return parser
|
|
942
981
|
|
|
943
|
-
def take_action(self, parsed_args):
|
|
982
|
+
def take_action(self, parsed_args: argparse.Namespace) -> None:
|
|
944
983
|
volume_client = self.app.client_manager.volume
|
|
945
984
|
volume = utils.find_resource(volume_client.volumes, parsed_args.volume)
|
|
946
985
|
|
|
@@ -1113,7 +1152,7 @@ class SetVolume(command.Command):
|
|
|
1113
1152
|
class ShowVolume(command.ShowOne):
|
|
1114
1153
|
_description = _("Display volume details")
|
|
1115
1154
|
|
|
1116
|
-
def get_parser(self, prog_name):
|
|
1155
|
+
def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
|
|
1117
1156
|
parser = super().get_parser(prog_name)
|
|
1118
1157
|
parser.add_argument(
|
|
1119
1158
|
'volume',
|
|
@@ -1122,20 +1161,25 @@ class ShowVolume(command.ShowOne):
|
|
|
1122
1161
|
)
|
|
1123
1162
|
return parser
|
|
1124
1163
|
|
|
1125
|
-
def take_action(
|
|
1126
|
-
|
|
1164
|
+
def take_action(
|
|
1165
|
+
self, parsed_args: argparse.Namespace
|
|
1166
|
+
) -> tuple[Sequence[str], Iterable[Any]]:
|
|
1167
|
+
volume_client = sdk_utils.ensure_service_version(
|
|
1168
|
+
self.app.client_manager.sdk_connection.volume, '3'
|
|
1169
|
+
)
|
|
1127
1170
|
volume = volume_client.find_volume(
|
|
1128
1171
|
parsed_args.volume, ignore_missing=False
|
|
1129
1172
|
)
|
|
1130
1173
|
|
|
1131
1174
|
data = _format_volume(volume)
|
|
1132
|
-
|
|
1175
|
+
col_headers, col_data = zip(*sorted(data.items()))
|
|
1176
|
+
return col_headers, col_data
|
|
1133
1177
|
|
|
1134
1178
|
|
|
1135
1179
|
class UnsetVolume(command.Command):
|
|
1136
1180
|
_description = _("Unset volume properties")
|
|
1137
1181
|
|
|
1138
|
-
def get_parser(self, prog_name):
|
|
1182
|
+
def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
|
|
1139
1183
|
parser = super().get_parser(prog_name)
|
|
1140
1184
|
parser.add_argument(
|
|
1141
1185
|
'volume',
|
|
@@ -1164,7 +1208,7 @@ class UnsetVolume(command.Command):
|
|
|
1164
1208
|
)
|
|
1165
1209
|
return parser
|
|
1166
1210
|
|
|
1167
|
-
def take_action(self, parsed_args):
|
|
1211
|
+
def take_action(self, parsed_args: argparse.Namespace) -> None:
|
|
1168
1212
|
volume_client = self.app.client_manager.volume
|
|
1169
1213
|
volume = utils.find_resource(volume_client.volumes, parsed_args.volume)
|
|
1170
1214
|
|
|
@@ -1196,7 +1240,7 @@ class UnsetVolume(command.Command):
|
|
|
1196
1240
|
class VolumeSummary(command.ShowOne):
|
|
1197
1241
|
_description = _("Show a summary of all volumes in this deployment.")
|
|
1198
1242
|
|
|
1199
|
-
def get_parser(self, prog_name):
|
|
1243
|
+
def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
|
|
1200
1244
|
parser = super().get_parser(prog_name)
|
|
1201
1245
|
parser.add_argument(
|
|
1202
1246
|
'--all-projects',
|
|
@@ -1206,8 +1250,12 @@ class VolumeSummary(command.ShowOne):
|
|
|
1206
1250
|
)
|
|
1207
1251
|
return parser
|
|
1208
1252
|
|
|
1209
|
-
def take_action(
|
|
1210
|
-
|
|
1253
|
+
def take_action(
|
|
1254
|
+
self, parsed_args: argparse.Namespace
|
|
1255
|
+
) -> tuple[Sequence[str], Iterable[Any]]:
|
|
1256
|
+
volume_client = sdk_utils.ensure_service_version(
|
|
1257
|
+
self.app.client_manager.sdk_connection.volume, '3'
|
|
1258
|
+
)
|
|
1211
1259
|
|
|
1212
1260
|
if not sdk_utils.supports_microversion(volume_client, '3.12'):
|
|
1213
1261
|
msg = _(
|
|
@@ -1246,7 +1294,7 @@ class VolumeSummary(command.ShowOne):
|
|
|
1246
1294
|
class VolumeRevertToSnapshot(command.Command):
|
|
1247
1295
|
_description = _("Revert a volume to a snapshot.")
|
|
1248
1296
|
|
|
1249
|
-
def get_parser(self, prog_name):
|
|
1297
|
+
def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
|
|
1250
1298
|
parser = super().get_parser(prog_name)
|
|
1251
1299
|
parser.add_argument(
|
|
1252
1300
|
'snapshot',
|
|
@@ -1258,8 +1306,10 @@ class VolumeRevertToSnapshot(command.Command):
|
|
|
1258
1306
|
)
|
|
1259
1307
|
return parser
|
|
1260
1308
|
|
|
1261
|
-
def take_action(self, parsed_args):
|
|
1262
|
-
volume_client =
|
|
1309
|
+
def take_action(self, parsed_args: argparse.Namespace) -> None:
|
|
1310
|
+
volume_client = sdk_utils.ensure_service_version(
|
|
1311
|
+
self.app.client_manager.sdk_connection.volume, '3'
|
|
1312
|
+
)
|
|
1263
1313
|
|
|
1264
1314
|
if not sdk_utils.supports_microversion(volume_client, '3.40'):
|
|
1265
1315
|
msg = _(
|