python-openstackclient 8.3.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 +126 -114
- 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 +251 -171
- 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 +103 -41
- 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 +26 -12
- 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 +71 -50
- 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 +115 -92
- openstackclient/identity/v3/mapping.py +26 -13
- openstackclient/identity/v3/policy.py +23 -12
- openstackclient/identity/v3/project.py +211 -122
- openstackclient/identity/v3/region.py +36 -16
- openstackclient/identity/v3/registered_limit.py +116 -109
- 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 -17
- 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 +76 -49
- 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_limit.py +47 -0
- 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/image/v2/test_metadef_objects.py +69 -0
- 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 +56 -138
- 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 +62 -23
- 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 +17 -104
- 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_limit.py +197 -145
- openstackclient/tests/unit/identity/v3/test_project.py +831 -512
- openstackclient/tests/unit/identity/v3/test_protocol.py +97 -88
- openstackclient/tests/unit/identity/v3/test_registered_limit.py +355 -220
- openstackclient/tests/unit/identity/v3/test_user.py +4 -4
- openstackclient/tests/unit/image/v2/test_image.py +16 -16
- 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_consistency_group.py +8 -2
- openstackclient/tests/unit/volume/v2/test_volume.py +7 -6
- 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 +94 -15
- 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 +37 -25
- openstackclient/volume/v2/consistency_group_snapshot.py +27 -12
- openstackclient/volume/v2/qos_specs.py +30 -19
- openstackclient/volume/v2/service.py +17 -6
- openstackclient/volume/v2/volume.py +69 -34
- openstackclient/volume/v2/volume_backend.py +19 -6
- openstackclient/volume/v2/volume_backup.py +48 -22
- openstackclient/volume/v2/volume_host.py +6 -4
- openstackclient/volume/v2/volume_snapshot.py +52 -26
- openstackclient/volume/v2/volume_transfer_request.py +33 -15
- openstackclient/volume/v2/volume_type.py +46 -27
- 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 +103 -46
- openstackclient/volume/v3/volume_attachment.py +43 -21
- openstackclient/volume/v3/volume_backup.py +55 -26
- 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 +71 -34
- openstackclient/volume/v3/volume_transfer_request.py +33 -15
- openstackclient/volume/v3/volume_type.py +45 -27
- {python_openstackclient-8.3.0.dist-info → python_openstackclient-10.0.0.dist-info}/METADATA +6 -6
- {python_openstackclient-8.3.0.dist-info → python_openstackclient-10.0.0.dist-info}/RECORD +279 -267
- {python_openstackclient-8.3.0.dist-info → python_openstackclient-10.0.0.dist-info}/WHEEL +1 -1
- {python_openstackclient-8.3.0.dist-info → python_openstackclient-10.0.0.dist-info}/entry_points.txt +53 -1
- {python_openstackclient-8.3.0.dist-info → python_openstackclient-10.0.0.dist-info}/licenses/AUTHORS +9 -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-8.3.0.dist-info/pbr.json +0 -1
- /openstackclient/{tests/functional/image/v1 → network/v2/bgpvpn}/__init__.py +0 -0
- {python_openstackclient-8.3.0.dist-info → python_openstackclient-10.0.0.dist-info}/licenses/LICENSE +0 -0
- {python_openstackclient-8.3.0.dist-info → python_openstackclient-10.0.0.dist-info}/top_level.txt +0 -0
|
@@ -16,7 +16,8 @@
|
|
|
16
16
|
import logging
|
|
17
17
|
import os
|
|
18
18
|
import sys
|
|
19
|
-
import
|
|
19
|
+
from typing import Any
|
|
20
|
+
import urllib.parse
|
|
20
21
|
|
|
21
22
|
from osc_lib import utils
|
|
22
23
|
|
|
@@ -31,12 +32,15 @@ PUBLIC_CONTAINER_ACLS = [GLOBAL_READ_ACL, LIST_CONTENTS_ACL]
|
|
|
31
32
|
class APIv1(api.BaseAPI):
|
|
32
33
|
"""Object Store v1 API"""
|
|
33
34
|
|
|
34
|
-
def __init__(self, **kwargs):
|
|
35
|
+
def __init__(self, **kwargs: Any) -> None:
|
|
35
36
|
super().__init__(**kwargs)
|
|
36
37
|
|
|
37
38
|
def container_create(
|
|
38
|
-
self,
|
|
39
|
-
|
|
39
|
+
self,
|
|
40
|
+
container: str,
|
|
41
|
+
public: bool = False,
|
|
42
|
+
storage_policy: str | None = None,
|
|
43
|
+
) -> dict[str, Any | None]:
|
|
40
44
|
"""Create a container
|
|
41
45
|
|
|
42
46
|
:param string container:
|
|
@@ -58,7 +62,9 @@ class APIv1(api.BaseAPI):
|
|
|
58
62
|
headers['x-storage-policy'] = storage_policy
|
|
59
63
|
|
|
60
64
|
response = self.create(
|
|
61
|
-
urllib.parse.quote(container),
|
|
65
|
+
urllib.parse.quote(container),
|
|
66
|
+
method='PUT',
|
|
67
|
+
headers=headers,
|
|
62
68
|
)
|
|
63
69
|
|
|
64
70
|
data = {
|
|
@@ -69,10 +75,7 @@ class APIv1(api.BaseAPI):
|
|
|
69
75
|
|
|
70
76
|
return data
|
|
71
77
|
|
|
72
|
-
def container_delete(
|
|
73
|
-
self,
|
|
74
|
-
container=None,
|
|
75
|
-
):
|
|
78
|
+
def container_delete(self, container: str) -> None:
|
|
76
79
|
"""Delete a container
|
|
77
80
|
|
|
78
81
|
:param string container:
|
|
@@ -84,13 +87,13 @@ class APIv1(api.BaseAPI):
|
|
|
84
87
|
|
|
85
88
|
def container_list(
|
|
86
89
|
self,
|
|
87
|
-
full_listing=False,
|
|
88
|
-
limit=None,
|
|
89
|
-
marker=None,
|
|
90
|
-
end_marker=None,
|
|
91
|
-
prefix=None,
|
|
92
|
-
**params,
|
|
93
|
-
):
|
|
90
|
+
full_listing: bool = False,
|
|
91
|
+
limit: int | None = None,
|
|
92
|
+
marker: str | None = None,
|
|
93
|
+
end_marker: str | None = None,
|
|
94
|
+
prefix: str | None = None,
|
|
95
|
+
**params: Any,
|
|
96
|
+
) -> Any:
|
|
94
97
|
"""Get containers in an account
|
|
95
98
|
|
|
96
99
|
:param boolean full_listing:
|
|
@@ -142,10 +145,7 @@ class APIv1(api.BaseAPI):
|
|
|
142
145
|
|
|
143
146
|
return self.list('', **params)
|
|
144
147
|
|
|
145
|
-
def container_save(
|
|
146
|
-
self,
|
|
147
|
-
container=None,
|
|
148
|
-
):
|
|
148
|
+
def container_save(self, container: str) -> None:
|
|
149
149
|
"""Save all the content from a container
|
|
150
150
|
|
|
151
151
|
:param string container:
|
|
@@ -158,9 +158,9 @@ class APIv1(api.BaseAPI):
|
|
|
158
158
|
|
|
159
159
|
def container_set(
|
|
160
160
|
self,
|
|
161
|
-
container,
|
|
162
|
-
properties,
|
|
163
|
-
):
|
|
161
|
+
container: str,
|
|
162
|
+
properties: dict[str, str],
|
|
163
|
+
) -> None:
|
|
164
164
|
"""Set container properties
|
|
165
165
|
|
|
166
166
|
:param string container:
|
|
@@ -173,10 +173,7 @@ class APIv1(api.BaseAPI):
|
|
|
173
173
|
if headers:
|
|
174
174
|
self.create(urllib.parse.quote(container), headers=headers)
|
|
175
175
|
|
|
176
|
-
def container_show(
|
|
177
|
-
self,
|
|
178
|
-
container=None,
|
|
179
|
-
):
|
|
176
|
+
def container_show(self, container: str) -> dict[str, Any]:
|
|
180
177
|
"""Get container details
|
|
181
178
|
|
|
182
179
|
:param string container:
|
|
@@ -213,9 +210,9 @@ class APIv1(api.BaseAPI):
|
|
|
213
210
|
|
|
214
211
|
def container_unset(
|
|
215
212
|
self,
|
|
216
|
-
container,
|
|
217
|
-
properties,
|
|
218
|
-
):
|
|
213
|
+
container: str,
|
|
214
|
+
properties: dict[str, str],
|
|
215
|
+
) -> None:
|
|
219
216
|
"""Unset container properties
|
|
220
217
|
|
|
221
218
|
:param string container:
|
|
@@ -231,11 +228,8 @@ class APIv1(api.BaseAPI):
|
|
|
231
228
|
self.create(urllib.parse.quote(container), headers=headers)
|
|
232
229
|
|
|
233
230
|
def object_create(
|
|
234
|
-
self,
|
|
235
|
-
|
|
236
|
-
object=None,
|
|
237
|
-
name=None,
|
|
238
|
-
):
|
|
231
|
+
self, container: str, object: str, name: str | None = None
|
|
232
|
+
) -> dict[str, Any]:
|
|
239
233
|
"""Create an object inside a container
|
|
240
234
|
|
|
241
235
|
:param string container:
|
|
@@ -254,33 +248,25 @@ class APIv1(api.BaseAPI):
|
|
|
254
248
|
|
|
255
249
|
# For uploading a file, if name is provided then set it as the
|
|
256
250
|
# object's name in the container.
|
|
257
|
-
|
|
251
|
+
name = name if name else object
|
|
258
252
|
|
|
259
|
-
full_url = (
|
|
260
|
-
f"{urllib.parse.quote(container)}/"
|
|
261
|
-
f"{urllib.parse.quote(object_name_str)}"
|
|
262
|
-
)
|
|
263
253
|
with open(object, 'rb') as f:
|
|
264
254
|
response = self.create(
|
|
265
|
-
|
|
255
|
+
f"{urllib.parse.quote(container)}/{urllib.parse.quote(name)}",
|
|
266
256
|
method='PUT',
|
|
267
257
|
data=f,
|
|
268
258
|
)
|
|
269
259
|
data = {
|
|
270
260
|
'account': self._find_account_id(),
|
|
271
261
|
'container': container,
|
|
272
|
-
'object':
|
|
262
|
+
'object': name,
|
|
273
263
|
'x-trans-id': response.headers.get('X-Trans-Id'),
|
|
274
264
|
'etag': response.headers.get('Etag'),
|
|
275
265
|
}
|
|
276
266
|
|
|
277
267
|
return data
|
|
278
268
|
|
|
279
|
-
def object_delete(
|
|
280
|
-
self,
|
|
281
|
-
container=None,
|
|
282
|
-
object=None,
|
|
283
|
-
):
|
|
269
|
+
def object_delete(self, container: str, object: str) -> None:
|
|
284
270
|
"""Delete an object from a container
|
|
285
271
|
|
|
286
272
|
:param string container:
|
|
@@ -298,15 +284,15 @@ class APIv1(api.BaseAPI):
|
|
|
298
284
|
|
|
299
285
|
def object_list(
|
|
300
286
|
self,
|
|
301
|
-
container
|
|
302
|
-
full_listing=False,
|
|
303
|
-
limit=None,
|
|
304
|
-
marker=None,
|
|
305
|
-
end_marker=None,
|
|
306
|
-
delimiter=None,
|
|
307
|
-
prefix=None,
|
|
308
|
-
**params,
|
|
309
|
-
):
|
|
287
|
+
container: str,
|
|
288
|
+
full_listing: bool = False,
|
|
289
|
+
limit: int | None = None,
|
|
290
|
+
marker: str | None = None,
|
|
291
|
+
end_marker: str | None = None,
|
|
292
|
+
delimiter: str | None = None,
|
|
293
|
+
prefix: str | None = None,
|
|
294
|
+
**params: Any,
|
|
295
|
+
) -> Any:
|
|
310
296
|
"""List objects in a container
|
|
311
297
|
|
|
312
298
|
:param string container:
|
|
@@ -374,11 +360,8 @@ class APIv1(api.BaseAPI):
|
|
|
374
360
|
return self.list(urllib.parse.quote(container), **params)
|
|
375
361
|
|
|
376
362
|
def object_save(
|
|
377
|
-
self,
|
|
378
|
-
|
|
379
|
-
object=None,
|
|
380
|
-
file=None,
|
|
381
|
-
):
|
|
363
|
+
self, container: str, object: str, file: str | None = None
|
|
364
|
+
) -> None:
|
|
382
365
|
"""Save an object stored in a container
|
|
383
366
|
|
|
384
367
|
:param string container:
|
|
@@ -394,7 +377,7 @@ class APIv1(api.BaseAPI):
|
|
|
394
377
|
|
|
395
378
|
response = self._request(
|
|
396
379
|
'GET',
|
|
397
|
-
f
|
|
380
|
+
f'{urllib.parse.quote(container)}/{urllib.parse.quote(object)}',
|
|
398
381
|
stream=True,
|
|
399
382
|
)
|
|
400
383
|
if response.status_code == 200:
|
|
@@ -403,19 +386,20 @@ class APIv1(api.BaseAPI):
|
|
|
403
386
|
for chunk in response.iter_content(64 * 1024):
|
|
404
387
|
f.write(chunk)
|
|
405
388
|
else:
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
389
|
+
file_path = file or ''
|
|
390
|
+
if not os.path.exists(os.path.dirname(file_path)):
|
|
391
|
+
if len(os.path.dirname(file_path)) > 0:
|
|
392
|
+
os.makedirs(os.path.dirname(file_path))
|
|
393
|
+
with open(file_path, 'wb') as f:
|
|
410
394
|
for chunk in response.iter_content(64 * 1024):
|
|
411
395
|
f.write(chunk)
|
|
412
396
|
|
|
413
397
|
def object_set(
|
|
414
398
|
self,
|
|
415
|
-
container,
|
|
416
|
-
object,
|
|
417
|
-
properties,
|
|
418
|
-
):
|
|
399
|
+
container: str,
|
|
400
|
+
object: str,
|
|
401
|
+
properties: dict[str, str],
|
|
402
|
+
) -> None:
|
|
419
403
|
"""Set object properties
|
|
420
404
|
|
|
421
405
|
:param string container:
|
|
@@ -434,11 +418,8 @@ class APIv1(api.BaseAPI):
|
|
|
434
418
|
)
|
|
435
419
|
|
|
436
420
|
def object_unset(
|
|
437
|
-
self,
|
|
438
|
-
|
|
439
|
-
object,
|
|
440
|
-
properties,
|
|
441
|
-
):
|
|
421
|
+
self, container: str, object: str, properties: dict[str, str]
|
|
422
|
+
) -> None:
|
|
442
423
|
"""Unset object properties
|
|
443
424
|
|
|
444
425
|
:param string container:
|
|
@@ -456,11 +437,7 @@ class APIv1(api.BaseAPI):
|
|
|
456
437
|
headers=headers,
|
|
457
438
|
)
|
|
458
439
|
|
|
459
|
-
def object_show(
|
|
460
|
-
self,
|
|
461
|
-
container=None,
|
|
462
|
-
object=None,
|
|
463
|
-
):
|
|
440
|
+
def object_show(self, container: str, object: str) -> dict[str, Any]:
|
|
464
441
|
"""Get object details
|
|
465
442
|
|
|
466
443
|
:param string container:
|
|
@@ -502,10 +479,7 @@ class APIv1(api.BaseAPI):
|
|
|
502
479
|
|
|
503
480
|
return data
|
|
504
481
|
|
|
505
|
-
def account_set(
|
|
506
|
-
self,
|
|
507
|
-
properties,
|
|
508
|
-
):
|
|
482
|
+
def account_set(self, properties: dict[str, str]) -> None:
|
|
509
483
|
"""Set account properties
|
|
510
484
|
|
|
511
485
|
:param dict properties:
|
|
@@ -519,13 +493,13 @@ class APIv1(api.BaseAPI):
|
|
|
519
493
|
# registered in the catalog
|
|
520
494
|
self.create("", headers=headers)
|
|
521
495
|
|
|
522
|
-
def account_show(self):
|
|
496
|
+
def account_show(self) -> dict[str, Any]:
|
|
523
497
|
"""Show account details"""
|
|
524
498
|
|
|
525
499
|
# NOTE(stevemar): Just a HEAD request to the endpoint already in the
|
|
526
500
|
# catalog should be enough.
|
|
527
501
|
response = self._request("HEAD", "")
|
|
528
|
-
data = {}
|
|
502
|
+
data: dict[str, Any] = {}
|
|
529
503
|
|
|
530
504
|
properties = self._get_properties(response.headers, 'x-account-meta-')
|
|
531
505
|
if properties:
|
|
@@ -541,8 +515,8 @@ class APIv1(api.BaseAPI):
|
|
|
541
515
|
|
|
542
516
|
def account_unset(
|
|
543
517
|
self,
|
|
544
|
-
properties,
|
|
545
|
-
):
|
|
518
|
+
properties: dict[str, str],
|
|
519
|
+
) -> None:
|
|
546
520
|
"""Unset account properties
|
|
547
521
|
|
|
548
522
|
:param dict properties:
|
|
@@ -555,11 +529,13 @@ class APIv1(api.BaseAPI):
|
|
|
555
529
|
if headers:
|
|
556
530
|
self.create("", headers=headers)
|
|
557
531
|
|
|
558
|
-
def _find_account_id(self):
|
|
559
|
-
url_parts = urllib.parse.urlparse(self.endpoint)
|
|
560
|
-
return url_parts.path.split('/')[-1]
|
|
532
|
+
def _find_account_id(self) -> str:
|
|
533
|
+
url_parts = urllib.parse.urlparse(self.endpoint or '')
|
|
534
|
+
return str(url_parts.path).split('/')[-1]
|
|
561
535
|
|
|
562
|
-
def _unset_properties(
|
|
536
|
+
def _unset_properties(
|
|
537
|
+
self, properties: dict[str, str], header_tag: str
|
|
538
|
+
) -> dict[str, str]:
|
|
563
539
|
# NOTE(stevemar): As per the API, the headers have to be in the form
|
|
564
540
|
# of "X-Remove-Account-Meta-Book: x". In the case where metadata is
|
|
565
541
|
# removed, we can set the value of the header to anything, so it's
|
|
@@ -567,13 +543,15 @@ class APIv1(api.BaseAPI):
|
|
|
567
543
|
# "X-Remove-Container-Meta-Book: x", and the same logic applies for
|
|
568
544
|
# Object properties
|
|
569
545
|
|
|
570
|
-
headers = {}
|
|
546
|
+
headers: dict[str, str] = {}
|
|
571
547
|
for k in properties:
|
|
572
548
|
header_name = header_tag % k
|
|
573
549
|
headers[header_name] = 'x'
|
|
574
550
|
return headers
|
|
575
551
|
|
|
576
|
-
def _set_properties(
|
|
552
|
+
def _set_properties(
|
|
553
|
+
self, properties: dict[str, str], header_tag: str
|
|
554
|
+
) -> dict[str, str]:
|
|
577
555
|
# NOTE(stevemar): As per the API, the headers have to be in the form
|
|
578
556
|
# of "X-Account-Meta-Book: MobyDick". In the case of a Container
|
|
579
557
|
# property we use: "X-Add-Container-Meta-Book: MobyDick", and the same
|
|
@@ -581,7 +559,7 @@ class APIv1(api.BaseAPI):
|
|
|
581
559
|
|
|
582
560
|
log = logging.getLogger(__name__ + '._set_properties')
|
|
583
561
|
|
|
584
|
-
headers = {}
|
|
562
|
+
headers: dict[str, str] = {}
|
|
585
563
|
for k, v in properties.items():
|
|
586
564
|
if not utils.is_ascii(k) or not utils.is_ascii(v):
|
|
587
565
|
log.error('Cannot set property %s to non-ascii value', k)
|
|
@@ -591,10 +569,10 @@ class APIv1(api.BaseAPI):
|
|
|
591
569
|
headers[header_name] = v
|
|
592
570
|
return headers
|
|
593
571
|
|
|
594
|
-
def _get_properties(self, headers, header_tag):
|
|
572
|
+
def _get_properties(self, headers: Any, header_tag: str) -> dict[str, Any]:
|
|
595
573
|
# Add in properties as a top level key, this is consistent with other
|
|
596
574
|
# OSC commands
|
|
597
|
-
properties = {}
|
|
575
|
+
properties: dict[str, Any] = {}
|
|
598
576
|
for k, v in headers.items():
|
|
599
577
|
if k.lower().startswith(header_tag):
|
|
600
578
|
properties[k[len(header_tag) :]] = v
|
openstackclient/api/volume_v2.py
CHANGED
|
@@ -17,6 +17,7 @@ intentionally supported by SDK.
|
|
|
17
17
|
"""
|
|
18
18
|
|
|
19
19
|
import http
|
|
20
|
+
from typing import Any
|
|
20
21
|
|
|
21
22
|
from openstack import exceptions as sdk_exceptions
|
|
22
23
|
from osc_lib import exceptions
|
|
@@ -25,7 +26,7 @@ from osc_lib import exceptions
|
|
|
25
26
|
# consistency groups
|
|
26
27
|
|
|
27
28
|
|
|
28
|
-
def find_consistency_group(compute_client, name_or_id):
|
|
29
|
+
def find_consistency_group(compute_client: Any, name_or_id: str) -> Any:
|
|
29
30
|
"""Find the consistency group for a given name or ID
|
|
30
31
|
|
|
31
32
|
https://docs.openstack.org/api-ref/block-storage/v3/#show-a-consistency-group-s-details
|
openstackclient/api/volume_v3.py
CHANGED
|
@@ -17,6 +17,7 @@ intentionally supported by SDK.
|
|
|
17
17
|
"""
|
|
18
18
|
|
|
19
19
|
import http
|
|
20
|
+
from typing import Any
|
|
20
21
|
|
|
21
22
|
from openstack import exceptions as sdk_exceptions
|
|
22
23
|
from osc_lib import exceptions
|
|
@@ -25,7 +26,7 @@ from osc_lib import exceptions
|
|
|
25
26
|
# consistency groups
|
|
26
27
|
|
|
27
28
|
|
|
28
|
-
def find_consistency_group(compute_client, name_or_id):
|
|
29
|
+
def find_consistency_group(compute_client: Any, name_or_id: str) -> Any:
|
|
29
30
|
"""Find the consistency group for a given name or ID
|
|
30
31
|
|
|
31
32
|
https://docs.openstack.org/api-ref/block-storage/v3/#show-a-consistency-group-s-details
|
|
@@ -13,10 +13,14 @@
|
|
|
13
13
|
|
|
14
14
|
"""Availability Zone action implementations"""
|
|
15
15
|
|
|
16
|
+
import argparse
|
|
16
17
|
import copy
|
|
17
18
|
import logging
|
|
19
|
+
from collections.abc import Iterable, Sequence
|
|
20
|
+
from typing import Any
|
|
18
21
|
|
|
19
22
|
from openstack import exceptions as sdk_exceptions
|
|
23
|
+
from openstack import utils as sdk_utils
|
|
20
24
|
from osc_lib import utils
|
|
21
25
|
|
|
22
26
|
from openstackclient import command
|
|
@@ -26,8 +30,10 @@ from openstackclient.i18n import _
|
|
|
26
30
|
LOG = logging.getLogger(__name__)
|
|
27
31
|
|
|
28
32
|
|
|
29
|
-
def _xform_compute_availability_zone(
|
|
30
|
-
|
|
33
|
+
def _xform_compute_availability_zone(
|
|
34
|
+
az: Any, include_extra: bool
|
|
35
|
+
) -> list[dict[str, str]]:
|
|
36
|
+
result: list[dict[str, str]] = []
|
|
31
37
|
zone_info = {
|
|
32
38
|
'zone_name': az.name,
|
|
33
39
|
'zone_status': (
|
|
@@ -61,20 +67,8 @@ def _xform_compute_availability_zone(az, include_extra):
|
|
|
61
67
|
return result
|
|
62
68
|
|
|
63
69
|
|
|
64
|
-
def
|
|
65
|
-
result = []
|
|
66
|
-
zone_info = {
|
|
67
|
-
'zone_name': az.name,
|
|
68
|
-
'zone_status': (
|
|
69
|
-
'available' if az.state['available'] else 'not available'
|
|
70
|
-
),
|
|
71
|
-
}
|
|
72
|
-
result.append(zone_info)
|
|
73
|
-
return result
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
def _xform_network_availability_zone(az):
|
|
77
|
-
result = []
|
|
70
|
+
def _xform_network_availability_zone(az: Any) -> list[dict[str, str]]:
|
|
71
|
+
result: list[dict[str, str]] = []
|
|
78
72
|
zone_info = {}
|
|
79
73
|
zone_info['zone_name'] = az.name
|
|
80
74
|
zone_info['zone_status'] = az.state
|
|
@@ -85,10 +79,22 @@ def _xform_network_availability_zone(az):
|
|
|
85
79
|
return result
|
|
86
80
|
|
|
87
81
|
|
|
82
|
+
def _xform_volume_availability_zone(az: Any) -> list[dict[str, str]]:
|
|
83
|
+
result: list[dict[str, str]] = []
|
|
84
|
+
zone_info = {
|
|
85
|
+
'zone_name': az.name,
|
|
86
|
+
'zone_status': (
|
|
87
|
+
'available' if az.state['available'] else 'not available'
|
|
88
|
+
),
|
|
89
|
+
}
|
|
90
|
+
result.append(zone_info)
|
|
91
|
+
return result
|
|
92
|
+
|
|
93
|
+
|
|
88
94
|
class ListAvailabilityZone(command.Lister):
|
|
89
95
|
_description = _("List availability zones and their status")
|
|
90
96
|
|
|
91
|
-
def get_parser(self, prog_name):
|
|
97
|
+
def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
|
|
92
98
|
parser = super().get_parser(prog_name)
|
|
93
99
|
parser.add_argument(
|
|
94
100
|
'--compute',
|
|
@@ -116,7 +122,9 @@ class ListAvailabilityZone(command.Lister):
|
|
|
116
122
|
)
|
|
117
123
|
return parser
|
|
118
124
|
|
|
119
|
-
def _get_compute_availability_zones(
|
|
125
|
+
def _get_compute_availability_zones(
|
|
126
|
+
self, parsed_args: argparse.Namespace
|
|
127
|
+
) -> list[dict[str, str]]:
|
|
120
128
|
compute_client = self.app.client_manager.compute
|
|
121
129
|
try:
|
|
122
130
|
data = list(compute_client.availability_zones(details=True))
|
|
@@ -131,26 +139,9 @@ class ListAvailabilityZone(command.Lister):
|
|
|
131
139
|
result += _xform_compute_availability_zone(zone, parsed_args.long)
|
|
132
140
|
return result
|
|
133
141
|
|
|
134
|
-
def
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
try:
|
|
138
|
-
data = list(volume_client.availability_zones())
|
|
139
|
-
except Exception as e:
|
|
140
|
-
LOG.debug('Volume availability zone exception: %s', e)
|
|
141
|
-
if parsed_args.volume:
|
|
142
|
-
message = _(
|
|
143
|
-
"Availability zones list not supported by "
|
|
144
|
-
"Block Storage API"
|
|
145
|
-
)
|
|
146
|
-
LOG.warning(message)
|
|
147
|
-
|
|
148
|
-
result = []
|
|
149
|
-
for zone in data:
|
|
150
|
-
result += _xform_volume_availability_zone(zone)
|
|
151
|
-
return result
|
|
152
|
-
|
|
153
|
-
def _get_network_availability_zones(self, parsed_args):
|
|
142
|
+
def _get_network_availability_zones(
|
|
143
|
+
self, parsed_args: argparse.Namespace
|
|
144
|
+
) -> list[dict[str, str]]:
|
|
154
145
|
network_client = self.app.client_manager.network
|
|
155
146
|
try:
|
|
156
147
|
# Verify that the extension exists.
|
|
@@ -171,7 +162,32 @@ class ListAvailabilityZone(command.Lister):
|
|
|
171
162
|
result += _xform_network_availability_zone(zone)
|
|
172
163
|
return result
|
|
173
164
|
|
|
174
|
-
def
|
|
165
|
+
def _get_volume_availability_zones(
|
|
166
|
+
self, parsed_args: argparse.Namespace
|
|
167
|
+
) -> list[dict[str, str]]:
|
|
168
|
+
volume_client = sdk_utils.ensure_service_version(
|
|
169
|
+
self.app.client_manager.sdk_connection.volume, '3'
|
|
170
|
+
)
|
|
171
|
+
data = []
|
|
172
|
+
try:
|
|
173
|
+
data = list(volume_client.availability_zones())
|
|
174
|
+
except Exception as e:
|
|
175
|
+
LOG.debug('Volume availability zone exception: %s', e)
|
|
176
|
+
if parsed_args.volume:
|
|
177
|
+
message = _(
|
|
178
|
+
"Availability zones list not supported by "
|
|
179
|
+
"Block Storage API"
|
|
180
|
+
)
|
|
181
|
+
LOG.warning(message)
|
|
182
|
+
|
|
183
|
+
result = []
|
|
184
|
+
for zone in data:
|
|
185
|
+
result += _xform_volume_availability_zone(zone)
|
|
186
|
+
return result
|
|
187
|
+
|
|
188
|
+
def take_action(
|
|
189
|
+
self, parsed_args: argparse.Namespace
|
|
190
|
+
) -> tuple[Sequence[str], Iterable[tuple[Any, ...]]]:
|
|
175
191
|
columns: tuple[str, ...] = ('Zone Name', 'Zone Status')
|
|
176
192
|
if parsed_args.long:
|
|
177
193
|
columns += (
|
|
@@ -184,17 +200,17 @@ class ListAvailabilityZone(command.Lister):
|
|
|
184
200
|
# Show everything by default.
|
|
185
201
|
show_all = (
|
|
186
202
|
not parsed_args.compute
|
|
187
|
-
and not parsed_args.volume
|
|
188
203
|
and not parsed_args.network
|
|
204
|
+
and not parsed_args.volume
|
|
189
205
|
)
|
|
190
206
|
|
|
191
207
|
result = []
|
|
192
208
|
if parsed_args.compute or show_all:
|
|
193
209
|
result += self._get_compute_availability_zones(parsed_args)
|
|
194
|
-
if parsed_args.volume or show_all:
|
|
195
|
-
result += self._get_volume_availability_zones(parsed_args)
|
|
196
210
|
if parsed_args.network or show_all:
|
|
197
211
|
result += self._get_network_availability_zones(parsed_args)
|
|
212
|
+
if parsed_args.volume or show_all:
|
|
213
|
+
result += self._get_volume_availability_zones(parsed_args)
|
|
198
214
|
|
|
199
215
|
return (
|
|
200
216
|
columns,
|