python-openstackclient 7.4.0__py3-none-any.whl → 8.1.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/common/availability_zone.py +3 -6
- openstackclient/common/clientmanager.py +2 -1
- openstackclient/common/envvars.py +57 -0
- openstackclient/common/extension.py +3 -11
- openstackclient/common/limits.py +1 -1
- openstackclient/common/project_cleanup.py +3 -2
- openstackclient/common/quota.py +54 -28
- openstackclient/compute/client.py +7 -5
- openstackclient/compute/v2/agent.py +5 -5
- openstackclient/compute/v2/aggregate.py +17 -15
- openstackclient/compute/v2/console.py +10 -4
- openstackclient/compute/v2/console_connection.py +48 -0
- openstackclient/compute/v2/flavor.py +14 -18
- openstackclient/compute/v2/host.py +3 -3
- openstackclient/compute/v2/hypervisor.py +10 -4
- openstackclient/compute/v2/hypervisor_stats.py +1 -1
- openstackclient/compute/v2/keypair.py +18 -13
- openstackclient/compute/v2/server.py +144 -121
- openstackclient/compute/v2/server_backup.py +1 -1
- openstackclient/compute/v2/server_event.py +8 -17
- openstackclient/compute/v2/server_group.py +6 -6
- openstackclient/compute/v2/server_image.py +1 -1
- openstackclient/compute/v2/server_migration.py +6 -6
- openstackclient/compute/v2/server_volume.py +4 -4
- openstackclient/compute/v2/service.py +9 -13
- openstackclient/compute/v2/usage.py +4 -6
- openstackclient/identity/client.py +2 -4
- openstackclient/identity/common.py +95 -17
- openstackclient/identity/v2_0/ec2creds.py +4 -3
- openstackclient/identity/v2_0/endpoint.py +12 -10
- openstackclient/identity/v2_0/project.py +6 -6
- openstackclient/identity/v2_0/role.py +1 -1
- openstackclient/identity/v2_0/service.py +7 -7
- openstackclient/identity/v2_0/user.py +6 -21
- openstackclient/identity/v3/access_rule.py +2 -5
- openstackclient/identity/v3/application_credential.py +2 -2
- openstackclient/identity/v3/consumer.py +4 -3
- openstackclient/identity/v3/credential.py +6 -7
- openstackclient/identity/v3/domain.py +63 -44
- openstackclient/identity/v3/ec2creds.py +4 -3
- openstackclient/identity/v3/endpoint.py +104 -88
- openstackclient/identity/v3/endpoint_group.py +1 -1
- openstackclient/identity/v3/group.py +116 -72
- openstackclient/identity/v3/identity_provider.py +1 -2
- openstackclient/identity/v3/limit.py +4 -9
- openstackclient/identity/v3/mapping.py +4 -3
- openstackclient/identity/v3/policy.py +5 -8
- openstackclient/identity/v3/project.py +23 -6
- openstackclient/identity/v3/region.py +2 -5
- openstackclient/identity/v3/registered_limit.py +4 -8
- openstackclient/identity/v3/role.py +15 -16
- openstackclient/identity/v3/service.py +8 -8
- openstackclient/identity/v3/service_provider.py +3 -6
- openstackclient/identity/v3/tag.py +2 -2
- openstackclient/identity/v3/token.py +1 -2
- openstackclient/identity/v3/trust.py +74 -25
- openstackclient/identity/v3/user.py +47 -11
- openstackclient/image/client.py +7 -5
- openstackclient/image/v1/image.py +11 -15
- openstackclient/image/v2/cache.py +2 -4
- openstackclient/image/v2/image.py +41 -48
- openstackclient/image/v2/metadef_namespaces.py +4 -3
- openstackclient/image/v2/metadef_resource_type_association.py +1 -2
- openstackclient/image/v2/metadef_resource_types.py +1 -2
- openstackclient/locale/tr_TR/LC_MESSAGES/openstackclient.po +9 -1370
- openstackclient/network/client.py +4 -16
- openstackclient/network/common.py +16 -12
- openstackclient/network/utils.py +3 -3
- openstackclient/network/v2/address_group.py +5 -9
- openstackclient/network/v2/address_scope.py +2 -3
- openstackclient/network/v2/default_security_group_rule.py +1 -2
- openstackclient/network/v2/floating_ip.py +69 -47
- openstackclient/network/v2/floating_ip_port_forwarding.py +7 -7
- openstackclient/network/v2/ip_availability.py +1 -2
- openstackclient/network/v2/l3_conntrack_helper.py +8 -12
- openstackclient/network/v2/local_ip.py +24 -26
- openstackclient/network/v2/local_ip_association.py +4 -5
- openstackclient/network/v2/ndp_proxy.py +9 -10
- openstackclient/network/v2/network.py +12 -16
- openstackclient/network/v2/network_agent.py +29 -37
- openstackclient/network/v2/network_auto_allocated_topology.py +4 -5
- openstackclient/network/v2/network_flavor.py +1 -1
- openstackclient/network/v2/network_flavor_profile.py +5 -5
- openstackclient/network/v2/network_meter.py +3 -3
- openstackclient/network/v2/network_meter_rule.py +5 -8
- openstackclient/network/v2/network_qos_policy.py +4 -4
- openstackclient/network/v2/network_qos_rule.py +7 -16
- openstackclient/network/v2/network_rbac.py +4 -4
- openstackclient/network/v2/network_segment.py +6 -7
- openstackclient/network/v2/network_segment_range.py +16 -20
- openstackclient/network/v2/network_trunk.py +24 -16
- openstackclient/network/v2/port.py +28 -29
- openstackclient/network/v2/router.py +53 -42
- openstackclient/network/v2/security_group.py +13 -19
- openstackclient/network/v2/security_group_rule.py +10 -11
- openstackclient/network/v2/subnet.py +31 -30
- openstackclient/network/v2/subnet_pool.py +4 -4
- openstackclient/object/client.py +2 -3
- openstackclient/object/v1/container.py +2 -3
- openstackclient/object/v1/object.py +2 -9
- openstackclient/shell.py +22 -5
- openstackclient/tests/functional/base.py +7 -3
- openstackclient/tests/functional/common/test_quota.py +3 -1
- openstackclient/tests/functional/compute/v2/common.py +12 -6
- openstackclient/tests/functional/compute/v2/test_keypair.py +41 -5
- openstackclient/tests/functional/compute/v2/test_server.py +2 -3
- openstackclient/tests/functional/compute/v2/test_server_event.py +1 -1
- openstackclient/tests/functional/identity/v2/test_user.py +1 -1
- openstackclient/tests/functional/identity/v3/common.py +3 -8
- openstackclient/tests/functional/identity/v3/test_application_credential.py +10 -10
- openstackclient/tests/functional/identity/v3/test_endpoint.py +3 -3
- openstackclient/tests/functional/identity/v3/test_group.py +3 -3
- openstackclient/tests/functional/identity/v3/test_idp.py +3 -7
- openstackclient/tests/functional/identity/v3/test_limit.py +4 -4
- openstackclient/tests/functional/identity/v3/test_project.py +5 -14
- openstackclient/tests/functional/identity/v3/test_region.py +1 -3
- openstackclient/tests/functional/identity/v3/test_registered_limit.py +3 -3
- openstackclient/tests/functional/identity/v3/test_role.py +1 -1
- openstackclient/tests/functional/identity/v3/test_role_assignment.py +13 -31
- openstackclient/tests/functional/identity/v3/test_service_provider.py +3 -7
- openstackclient/tests/functional/identity/v3/test_user.py +8 -8
- openstackclient/tests/functional/network/v2/common.py +7 -3
- openstackclient/tests/functional/network/v2/test_address_group.py +4 -0
- openstackclient/tests/functional/network/v2/test_l3_conntrack_helper.py +15 -11
- openstackclient/tests/functional/network/v2/test_local_ip.py +4 -0
- openstackclient/tests/functional/network/v2/test_network_meter_rule.py +2 -2
- openstackclient/tests/functional/network/v2/test_network_ndp_proxy.py +2 -3
- openstackclient/tests/functional/network/v2/test_network_rbac.py +2 -2
- openstackclient/tests/functional/network/v2/test_network_trunk.py +1 -1
- openstackclient/tests/functional/network/v2/test_port.py +17 -7
- openstackclient/tests/functional/network/v2/test_router.py +42 -0
- openstackclient/tests/functional/network/v2/test_subnet_pool.py +4 -0
- openstackclient/tests/unit/api/test_compute_v2.py +67 -87
- openstackclient/tests/unit/common/test_availability_zone.py +6 -14
- openstackclient/tests/unit/common/test_command.py +1 -1
- openstackclient/tests/unit/common/test_extension.py +5 -7
- openstackclient/tests/unit/common/test_limits.py +1 -1
- openstackclient/tests/unit/common/test_project_cleanup.py +5 -6
- openstackclient/tests/unit/common/test_quota.py +51 -28
- openstackclient/tests/unit/compute/v2/fakes.py +85 -315
- openstackclient/tests/unit/compute/v2/test_agent.py +16 -16
- openstackclient/tests/unit/compute/v2/test_aggregate.py +56 -60
- openstackclient/tests/unit/compute/v2/test_console.py +34 -17
- openstackclient/tests/unit/compute/v2/test_console_connection.py +72 -0
- openstackclient/tests/unit/compute/v2/test_flavor.py +72 -72
- openstackclient/tests/unit/compute/v2/test_host.py +8 -8
- openstackclient/tests/unit/compute/v2/test_hypervisor.py +22 -30
- openstackclient/tests/unit/compute/v2/test_hypervisor_stats.py +2 -2
- openstackclient/tests/unit/compute/v2/test_keypair.py +36 -29
- openstackclient/tests/unit/compute/v2/test_server.py +693 -606
- openstackclient/tests/unit/compute/v2/test_server_backup.py +36 -77
- openstackclient/tests/unit/compute/v2/test_server_event.py +18 -20
- openstackclient/tests/unit/compute/v2/test_server_group.py +25 -31
- openstackclient/tests/unit/compute/v2/test_server_image.py +37 -78
- openstackclient/tests/unit/compute/v2/test_server_migration.py +41 -41
- openstackclient/tests/unit/compute/v2/test_server_volume.py +12 -12
- openstackclient/tests/unit/compute/v2/test_service.py +39 -45
- openstackclient/tests/unit/compute/v2/test_usage.py +5 -5
- openstackclient/tests/unit/identity/v2_0/fakes.py +1 -1
- openstackclient/tests/unit/identity/v3/test_access_rule.py +1 -3
- openstackclient/tests/unit/identity/v3/test_application_credential.py +48 -26
- openstackclient/tests/unit/identity/v3/test_domain.py +115 -105
- openstackclient/tests/unit/identity/v3/test_endpoint.py +167 -172
- openstackclient/tests/unit/identity/v3/test_group.py +353 -202
- openstackclient/tests/unit/identity/v3/test_mappings.py +2 -2
- openstackclient/tests/unit/identity/v3/test_project.py +16 -0
- openstackclient/tests/unit/identity/v3/test_trust.py +5 -2
- openstackclient/tests/unit/identity/v3/test_user.py +102 -6
- openstackclient/tests/unit/image/v1/fakes.py +2 -2
- openstackclient/tests/unit/image/v1/test_image.py +8 -9
- openstackclient/tests/unit/image/v2/test_image.py +84 -46
- openstackclient/tests/unit/integ/cli/test_shell.py +1 -2
- openstackclient/tests/unit/network/test_common.py +2 -2
- openstackclient/tests/unit/network/v2/fakes.py +405 -485
- openstackclient/tests/unit/network/v2/test_floating_ip_compute.py +8 -14
- openstackclient/tests/unit/network/v2/test_floating_ip_network.py +62 -54
- openstackclient/tests/unit/network/v2/test_floating_ip_pool_compute.py +1 -1
- openstackclient/tests/unit/network/v2/test_l3_conntrack_helper.py +2 -2
- openstackclient/tests/unit/network/v2/test_ndp_proxy.py +1 -3
- openstackclient/tests/unit/network/v2/test_network.py +4 -4
- openstackclient/tests/unit/network/v2/test_network_agent.py +15 -29
- openstackclient/tests/unit/network/v2/test_network_compute.py +11 -11
- openstackclient/tests/unit/network/v2/test_network_qos_policy.py +16 -19
- openstackclient/tests/unit/network/v2/test_network_qos_rule.py +79 -152
- openstackclient/tests/unit/network/v2/test_network_qos_rule_type.py +4 -6
- openstackclient/tests/unit/network/v2/test_network_rbac.py +2 -2
- openstackclient/tests/unit/network/v2/test_network_trunk.py +2 -2
- openstackclient/tests/unit/network/v2/test_port.py +21 -22
- openstackclient/tests/unit/network/v2/test_router.py +130 -51
- openstackclient/tests/unit/network/v2/test_security_group_compute.py +11 -19
- openstackclient/tests/unit/network/v2/test_security_group_network.py +25 -27
- openstackclient/tests/unit/network/v2/test_security_group_rule_compute.py +15 -17
- openstackclient/tests/unit/network/v2/test_security_group_rule_network.py +33 -39
- openstackclient/tests/unit/object/v1/test_object_all.py +4 -3
- openstackclient/tests/unit/test_shell.py +16 -13
- openstackclient/tests/unit/volume/v2/fakes.py +1 -2
- openstackclient/tests/unit/volume/v2/test_service.py +57 -91
- openstackclient/tests/unit/volume/v2/test_volume.py +109 -106
- openstackclient/tests/unit/volume/v2/test_volume_backup.py +141 -148
- openstackclient/tests/unit/volume/v2/test_volume_snapshot.py +293 -283
- openstackclient/tests/unit/volume/v2/test_volume_transfer_request.py +1 -1
- openstackclient/tests/unit/volume/v3/fakes.py +2 -8
- openstackclient/tests/unit/volume/v3/test_block_storage_log_level.py +61 -71
- openstackclient/tests/unit/volume/v3/test_service.py +221 -141
- openstackclient/tests/unit/volume/v3/test_volume.py +131 -120
- openstackclient/tests/unit/volume/v3/test_volume_attachment.py +4 -4
- openstackclient/tests/unit/volume/v3/test_volume_backup.py +198 -203
- openstackclient/tests/unit/volume/v3/test_volume_snapshot.py +683 -49
- openstackclient/tests/unit/volume/v3/test_volume_transfer_request.py +1 -1
- openstackclient/volume/client.py +1 -3
- openstackclient/volume/v2/consistency_group.py +4 -8
- openstackclient/volume/v2/consistency_group_snapshot.py +1 -2
- openstackclient/volume/v2/qos_specs.py +1 -2
- openstackclient/volume/v2/service.py +41 -38
- openstackclient/volume/v2/volume.py +71 -53
- openstackclient/volume/v2/volume_backup.py +15 -10
- openstackclient/volume/v2/volume_snapshot.py +129 -93
- openstackclient/volume/v2/volume_transfer_request.py +0 -3
- openstackclient/volume/v2/volume_type.py +10 -21
- openstackclient/volume/v3/block_storage_cluster.py +3 -3
- openstackclient/volume/v3/block_storage_log_level.py +22 -28
- openstackclient/volume/v3/block_storage_manage.py +1 -3
- openstackclient/volume/v3/service.py +105 -14
- openstackclient/volume/v3/volume.py +218 -58
- openstackclient/volume/v3/volume_attachment.py +3 -2
- openstackclient/volume/v3/volume_backup.py +31 -27
- openstackclient/volume/v3/volume_group.py +2 -1
- openstackclient/volume/v3/volume_group_snapshot.py +2 -1
- openstackclient/volume/v3/volume_snapshot.py +489 -13
- openstackclient/volume/v3/volume_type.py +10 -21
- {python_openstackclient-7.4.0.dist-info → python_openstackclient-8.1.0.dist-info}/AUTHORS +11 -0
- python_openstackclient-8.1.0.dist-info/METADATA +264 -0
- {python_openstackclient-7.4.0.dist-info → python_openstackclient-8.1.0.dist-info}/RECORD +238 -259
- {python_openstackclient-7.4.0.dist-info → python_openstackclient-8.1.0.dist-info}/WHEEL +1 -1
- {python_openstackclient-7.4.0.dist-info → python_openstackclient-8.1.0.dist-info}/entry_points.txt +7 -47
- python_openstackclient-8.1.0.dist-info/pbr.json +1 -0
- openstackclient/tests/functional/volume/v1/__init__.py +0 -0
- openstackclient/tests/functional/volume/v1/common.py +0 -35
- openstackclient/tests/functional/volume/v1/test_qos.py +0 -100
- openstackclient/tests/functional/volume/v1/test_service.py +0 -76
- openstackclient/tests/functional/volume/v1/test_snapshot.py +0 -232
- openstackclient/tests/functional/volume/v1/test_transfer_request.py +0 -111
- openstackclient/tests/functional/volume/v1/test_volume.py +0 -228
- openstackclient/tests/functional/volume/v1/test_volume_type.py +0 -213
- openstackclient/tests/unit/volume/v1/__init__.py +0 -0
- openstackclient/tests/unit/volume/v1/fakes.py +0 -615
- openstackclient/tests/unit/volume/v1/test_qos_specs.py +0 -471
- openstackclient/tests/unit/volume/v1/test_service.py +0 -295
- openstackclient/tests/unit/volume/v1/test_transfer_request.py +0 -380
- openstackclient/tests/unit/volume/v1/test_type.py +0 -633
- openstackclient/tests/unit/volume/v1/test_volume.py +0 -1447
- openstackclient/tests/unit/volume/v1/test_volume_backup.py +0 -435
- openstackclient/volume/v1/__init__.py +0 -0
- openstackclient/volume/v1/qos_specs.py +0 -377
- openstackclient/volume/v1/service.py +0 -136
- openstackclient/volume/v1/volume.py +0 -734
- openstackclient/volume/v1/volume_backup.py +0 -302
- openstackclient/volume/v1/volume_snapshot.py +0 -433
- openstackclient/volume/v1/volume_transfer_request.py +0 -200
- openstackclient/volume/v1/volume_type.py +0 -520
- python_openstackclient-7.4.0.dist-info/METADATA +0 -172
- python_openstackclient-7.4.0.dist-info/pbr.json +0 -1
- {python_openstackclient-7.4.0.dist-info → python_openstackclient-8.1.0.dist-info}/LICENSE +0 -0
- {python_openstackclient-7.4.0.dist-info → python_openstackclient-8.1.0.dist-info}/top_level.txt +0 -0
|
@@ -14,11 +14,12 @@
|
|
|
14
14
|
|
|
15
15
|
"""Volume v2 snapshot action implementations"""
|
|
16
16
|
|
|
17
|
-
import copy
|
|
18
17
|
import functools
|
|
19
18
|
import logging
|
|
19
|
+
import typing as ty
|
|
20
20
|
|
|
21
21
|
from cliff import columns as cliff_columns
|
|
22
|
+
from openstack.block_storage.v2 import snapshot as _snapshot
|
|
22
23
|
from osc_lib.cli import format_columns
|
|
23
24
|
from osc_lib.cli import parseractions
|
|
24
25
|
from osc_lib.command import command
|
|
@@ -60,6 +61,42 @@ class VolumeIdColumn(cliff_columns.FormattableColumn):
|
|
|
60
61
|
return volume
|
|
61
62
|
|
|
62
63
|
|
|
64
|
+
def _format_snapshot(snapshot: _snapshot.Snapshot) -> dict[str, ty.Any]:
|
|
65
|
+
# Some columns returned by openstacksdk should not be shown because they're
|
|
66
|
+
# either irrelevant or duplicates
|
|
67
|
+
ignored_columns = {
|
|
68
|
+
# computed columns
|
|
69
|
+
'location',
|
|
70
|
+
# create-only columns
|
|
71
|
+
'consumes_quota',
|
|
72
|
+
'force',
|
|
73
|
+
'group_snapshot_id',
|
|
74
|
+
# ignored columns
|
|
75
|
+
'os-extended-snapshot-attributes:progress',
|
|
76
|
+
'os-extended-snapshot-attributes:project_id',
|
|
77
|
+
'updated_at',
|
|
78
|
+
'user_id',
|
|
79
|
+
# unnecessary columns
|
|
80
|
+
'links',
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
info = snapshot.to_dict(original_names=True)
|
|
84
|
+
data = {}
|
|
85
|
+
for key, value in info.items():
|
|
86
|
+
if key in ignored_columns:
|
|
87
|
+
continue
|
|
88
|
+
|
|
89
|
+
data[key] = value
|
|
90
|
+
|
|
91
|
+
data.update(
|
|
92
|
+
{
|
|
93
|
+
'properties': format_columns.DictColumn(data.pop('metadata')),
|
|
94
|
+
}
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
return data
|
|
98
|
+
|
|
99
|
+
|
|
63
100
|
class CreateVolumeSnapshot(command.ShowOne):
|
|
64
101
|
_description = _("Create new volume snapshot")
|
|
65
102
|
|
|
@@ -74,8 +111,7 @@ class CreateVolumeSnapshot(command.ShowOne):
|
|
|
74
111
|
"--volume",
|
|
75
112
|
metavar="<volume>",
|
|
76
113
|
help=_(
|
|
77
|
-
"Volume to snapshot (name or ID) "
|
|
78
|
-
"(default is <snapshot-name>)"
|
|
114
|
+
"Volume to snapshot (name or ID) (default is <snapshot-name>)"
|
|
79
115
|
),
|
|
80
116
|
)
|
|
81
117
|
parser.add_argument(
|
|
@@ -88,14 +124,14 @@ class CreateVolumeSnapshot(command.ShowOne):
|
|
|
88
124
|
action="store_true",
|
|
89
125
|
default=False,
|
|
90
126
|
help=_(
|
|
91
|
-
"Create a snapshot attached to an instance. "
|
|
92
|
-
"Default is False"
|
|
127
|
+
"Create a snapshot attached to an instance. Default is False"
|
|
93
128
|
),
|
|
94
129
|
)
|
|
95
130
|
parser.add_argument(
|
|
96
131
|
"--property",
|
|
97
132
|
metavar="<key=value>",
|
|
98
133
|
action=parseractions.KeyValueAction,
|
|
134
|
+
dest="properties",
|
|
99
135
|
help=_(
|
|
100
136
|
"Set a property to this snapshot "
|
|
101
137
|
"(repeat option to set multiple properties)"
|
|
@@ -115,11 +151,13 @@ class CreateVolumeSnapshot(command.ShowOne):
|
|
|
115
151
|
return parser
|
|
116
152
|
|
|
117
153
|
def take_action(self, parsed_args):
|
|
118
|
-
volume_client = self.app.client_manager.volume
|
|
154
|
+
volume_client = self.app.client_manager.sdk_connection.volume
|
|
155
|
+
|
|
119
156
|
volume = parsed_args.volume
|
|
120
157
|
if not parsed_args.volume:
|
|
121
158
|
volume = parsed_args.snapshot_name
|
|
122
|
-
volume_id =
|
|
159
|
+
volume_id = volume_client.find_volume(volume, ignore_missing=False).id
|
|
160
|
+
|
|
123
161
|
if parsed_args.remote_source:
|
|
124
162
|
# Create a new snapshot from an existing remote snapshot source
|
|
125
163
|
if parsed_args.force:
|
|
@@ -129,30 +167,26 @@ class CreateVolumeSnapshot(command.ShowOne):
|
|
|
129
167
|
"volume snapshot"
|
|
130
168
|
)
|
|
131
169
|
LOG.warning(msg)
|
|
132
|
-
|
|
170
|
+
|
|
171
|
+
snapshot = volume_client.manage_snapshot(
|
|
133
172
|
volume_id=volume_id,
|
|
134
173
|
ref=parsed_args.remote_source,
|
|
135
174
|
name=parsed_args.snapshot_name,
|
|
136
175
|
description=parsed_args.description,
|
|
137
|
-
metadata=parsed_args.
|
|
176
|
+
metadata=parsed_args.properties,
|
|
138
177
|
)
|
|
139
178
|
else:
|
|
140
179
|
# create a new snapshot from scratch
|
|
141
|
-
snapshot = volume_client.
|
|
142
|
-
volume_id,
|
|
180
|
+
snapshot = volume_client.create_snapshot(
|
|
181
|
+
volume_id=volume_id,
|
|
143
182
|
force=parsed_args.force,
|
|
144
183
|
name=parsed_args.snapshot_name,
|
|
145
184
|
description=parsed_args.description,
|
|
146
|
-
metadata=parsed_args.
|
|
185
|
+
metadata=parsed_args.properties,
|
|
147
186
|
)
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
snapshot._info.pop('metadata')
|
|
152
|
-
)
|
|
153
|
-
}
|
|
154
|
-
)
|
|
155
|
-
return zip(*sorted(snapshot._info.items()))
|
|
187
|
+
|
|
188
|
+
data = _format_snapshot(snapshot)
|
|
189
|
+
return zip(*sorted(data.items()))
|
|
156
190
|
|
|
157
191
|
|
|
158
192
|
class DeleteVolumeSnapshot(command.Command):
|
|
@@ -177,16 +211,16 @@ class DeleteVolumeSnapshot(command.Command):
|
|
|
177
211
|
return parser
|
|
178
212
|
|
|
179
213
|
def take_action(self, parsed_args):
|
|
180
|
-
volume_client = self.app.client_manager.volume
|
|
214
|
+
volume_client = self.app.client_manager.sdk_connection.volume
|
|
181
215
|
result = 0
|
|
182
216
|
|
|
183
|
-
for
|
|
217
|
+
for snapshot in parsed_args.snapshots:
|
|
184
218
|
try:
|
|
185
|
-
snapshot_id =
|
|
186
|
-
|
|
219
|
+
snapshot_id = volume_client.find_snapshot(
|
|
220
|
+
snapshot, ignore_missing=False
|
|
187
221
|
).id
|
|
188
|
-
volume_client.
|
|
189
|
-
snapshot_id, parsed_args.force
|
|
222
|
+
volume_client.delete_snapshot(
|
|
223
|
+
snapshot_id, force=parsed_args.force
|
|
190
224
|
)
|
|
191
225
|
except Exception as e:
|
|
192
226
|
result += 1
|
|
@@ -195,14 +229,15 @@ class DeleteVolumeSnapshot(command.Command):
|
|
|
195
229
|
"Failed to delete snapshot with "
|
|
196
230
|
"name or ID '%(snapshot)s': %(e)s"
|
|
197
231
|
)
|
|
198
|
-
% {'snapshot':
|
|
232
|
+
% {'snapshot': snapshot, 'e': e}
|
|
199
233
|
)
|
|
200
234
|
|
|
201
235
|
if result > 0:
|
|
202
236
|
total = len(parsed_args.snapshots)
|
|
203
|
-
msg = _(
|
|
204
|
-
|
|
205
|
-
|
|
237
|
+
msg = _("%(result)s of %(total)s snapshots failed to delete.") % {
|
|
238
|
+
'result': result,
|
|
239
|
+
'total': total,
|
|
240
|
+
}
|
|
206
241
|
raise exceptions.CommandError(msg)
|
|
207
242
|
|
|
208
243
|
|
|
@@ -261,31 +296,39 @@ class ListVolumeSnapshot(command.Lister):
|
|
|
261
296
|
return parser
|
|
262
297
|
|
|
263
298
|
def take_action(self, parsed_args):
|
|
264
|
-
volume_client = self.app.client_manager.volume
|
|
299
|
+
volume_client = self.app.client_manager.sdk_connection.volume
|
|
265
300
|
identity_client = self.app.client_manager.identity
|
|
266
301
|
|
|
302
|
+
columns: tuple[str, ...] = (
|
|
303
|
+
'id',
|
|
304
|
+
'name',
|
|
305
|
+
'description',
|
|
306
|
+
'status',
|
|
307
|
+
'size',
|
|
308
|
+
)
|
|
309
|
+
column_headers: tuple[str, ...] = (
|
|
310
|
+
'ID',
|
|
311
|
+
'Name',
|
|
312
|
+
'Description',
|
|
313
|
+
'Status',
|
|
314
|
+
'Size',
|
|
315
|
+
)
|
|
267
316
|
if parsed_args.long:
|
|
268
|
-
columns
|
|
269
|
-
'
|
|
270
|
-
'
|
|
271
|
-
'
|
|
272
|
-
|
|
273
|
-
|
|
317
|
+
columns += (
|
|
318
|
+
'created_at',
|
|
319
|
+
'volume_id',
|
|
320
|
+
'metadata',
|
|
321
|
+
)
|
|
322
|
+
column_headers += (
|
|
274
323
|
'Created At',
|
|
275
|
-
'Volume
|
|
276
|
-
'
|
|
277
|
-
|
|
278
|
-
column_headers = copy.deepcopy(columns)
|
|
279
|
-
column_headers[6] = 'Volume'
|
|
280
|
-
column_headers[7] = 'Properties'
|
|
281
|
-
else:
|
|
282
|
-
columns = ['ID', 'Name', 'Description', 'Status', 'Size']
|
|
283
|
-
column_headers = copy.deepcopy(columns)
|
|
324
|
+
'Volume',
|
|
325
|
+
'Properties',
|
|
326
|
+
)
|
|
284
327
|
|
|
285
328
|
# Cache the volume list
|
|
286
329
|
volume_cache = {}
|
|
287
330
|
try:
|
|
288
|
-
for s in volume_client.volumes
|
|
331
|
+
for s in volume_client.volumes():
|
|
289
332
|
volume_cache[s.id] = s
|
|
290
333
|
except Exception: # noqa: S110
|
|
291
334
|
# Just forget it if there's any trouble
|
|
@@ -296,8 +339,8 @@ class ListVolumeSnapshot(command.Lister):
|
|
|
296
339
|
|
|
297
340
|
volume_id = None
|
|
298
341
|
if parsed_args.volume:
|
|
299
|
-
volume_id =
|
|
300
|
-
|
|
342
|
+
volume_id = volume_client.find_volume(
|
|
343
|
+
parsed_args.volume, ignore_missing=False
|
|
301
344
|
).id
|
|
302
345
|
|
|
303
346
|
project_id = None
|
|
@@ -313,18 +356,14 @@ class ListVolumeSnapshot(command.Lister):
|
|
|
313
356
|
True if parsed_args.project else parsed_args.all_projects
|
|
314
357
|
)
|
|
315
358
|
|
|
316
|
-
|
|
317
|
-
'all_tenants': all_projects,
|
|
318
|
-
'project_id': project_id,
|
|
319
|
-
'name': parsed_args.name,
|
|
320
|
-
'status': parsed_args.status,
|
|
321
|
-
'volume_id': volume_id,
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
data = volume_client.volume_snapshots.list(
|
|
325
|
-
search_opts=search_opts,
|
|
359
|
+
data = volume_client.snapshots(
|
|
326
360
|
marker=parsed_args.marker,
|
|
327
361
|
limit=parsed_args.limit,
|
|
362
|
+
all_projects=all_projects,
|
|
363
|
+
project_id=project_id,
|
|
364
|
+
name=parsed_args.name,
|
|
365
|
+
status=parsed_args.status,
|
|
366
|
+
volume_id=volume_id,
|
|
328
367
|
)
|
|
329
368
|
return (
|
|
330
369
|
column_headers,
|
|
@@ -333,8 +372,8 @@ class ListVolumeSnapshot(command.Lister):
|
|
|
333
372
|
s,
|
|
334
373
|
columns,
|
|
335
374
|
formatters={
|
|
336
|
-
'
|
|
337
|
-
'
|
|
375
|
+
'metadata': format_columns.DictColumn,
|
|
376
|
+
'volume_id': _VolumeIdColumn,
|
|
338
377
|
},
|
|
339
378
|
)
|
|
340
379
|
for s in data
|
|
@@ -375,6 +414,7 @@ class SetVolumeSnapshot(command.Command):
|
|
|
375
414
|
'--property',
|
|
376
415
|
metavar='<key=value>',
|
|
377
416
|
action=parseractions.KeyValueAction,
|
|
417
|
+
dest='properties',
|
|
378
418
|
help=_(
|
|
379
419
|
'Property to add/change for this snapshot '
|
|
380
420
|
'(repeat option to set multiple properties)'
|
|
@@ -401,27 +441,26 @@ class SetVolumeSnapshot(command.Command):
|
|
|
401
441
|
return parser
|
|
402
442
|
|
|
403
443
|
def take_action(self, parsed_args):
|
|
404
|
-
volume_client = self.app.client_manager.volume
|
|
405
|
-
|
|
406
|
-
|
|
444
|
+
volume_client = self.app.client_manager.sdk_connection.volume
|
|
445
|
+
|
|
446
|
+
snapshot = volume_client.find_snapshot(
|
|
447
|
+
parsed_args.snapshot, ignore_missing=False
|
|
407
448
|
)
|
|
408
449
|
|
|
409
450
|
result = 0
|
|
410
451
|
if parsed_args.no_property:
|
|
411
452
|
try:
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
snapshot.id,
|
|
415
|
-
list(key_list),
|
|
453
|
+
volume_client.delete_snapshot_metadata(
|
|
454
|
+
snapshot.id, keys=list(snapshot.metadata)
|
|
416
455
|
)
|
|
417
456
|
except Exception as e:
|
|
418
457
|
LOG.error(_("Failed to clean snapshot properties: %s"), e)
|
|
419
458
|
result += 1
|
|
420
459
|
|
|
421
|
-
if parsed_args.
|
|
460
|
+
if parsed_args.properties:
|
|
422
461
|
try:
|
|
423
|
-
volume_client.
|
|
424
|
-
snapshot.id, parsed_args.
|
|
462
|
+
volume_client.set_snapshot_metadata(
|
|
463
|
+
snapshot.id, **parsed_args.properties
|
|
425
464
|
)
|
|
426
465
|
except Exception as e:
|
|
427
466
|
LOG.error(_("Failed to set snapshot property: %s"), e)
|
|
@@ -429,7 +468,7 @@ class SetVolumeSnapshot(command.Command):
|
|
|
429
468
|
|
|
430
469
|
if parsed_args.state:
|
|
431
470
|
try:
|
|
432
|
-
volume_client.
|
|
471
|
+
volume_client.reset_snapshot_status(
|
|
433
472
|
snapshot.id, parsed_args.state
|
|
434
473
|
)
|
|
435
474
|
except Exception as e:
|
|
@@ -443,17 +482,17 @@ class SetVolumeSnapshot(command.Command):
|
|
|
443
482
|
kwargs['description'] = parsed_args.description
|
|
444
483
|
if kwargs:
|
|
445
484
|
try:
|
|
446
|
-
volume_client.
|
|
485
|
+
volume_client.update_snapshot(snapshot.id, **kwargs)
|
|
447
486
|
except Exception as e:
|
|
448
487
|
LOG.error(
|
|
449
|
-
_("Failed to update snapshot name
|
|
488
|
+
_("Failed to update snapshot name or description: %s"),
|
|
450
489
|
e,
|
|
451
490
|
)
|
|
452
491
|
result += 1
|
|
453
492
|
|
|
454
493
|
if result > 0:
|
|
455
494
|
raise exceptions.CommandError(
|
|
456
|
-
_("One or more of the
|
|
495
|
+
_("One or more of the set operations failed")
|
|
457
496
|
)
|
|
458
497
|
|
|
459
498
|
|
|
@@ -470,18 +509,14 @@ class ShowVolumeSnapshot(command.ShowOne):
|
|
|
470
509
|
return parser
|
|
471
510
|
|
|
472
511
|
def take_action(self, parsed_args):
|
|
473
|
-
volume_client = self.app.client_manager.volume
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
snapshot._info.update(
|
|
478
|
-
{
|
|
479
|
-
'properties': format_columns.DictColumn(
|
|
480
|
-
snapshot._info.pop('metadata')
|
|
481
|
-
)
|
|
482
|
-
}
|
|
512
|
+
volume_client = self.app.client_manager.sdk_connection.volume
|
|
513
|
+
|
|
514
|
+
snapshot = volume_client.find_snapshot(
|
|
515
|
+
parsed_args.snapshot, ignore_missing=False
|
|
483
516
|
)
|
|
484
|
-
|
|
517
|
+
|
|
518
|
+
data = _format_snapshot(snapshot)
|
|
519
|
+
return zip(*sorted(data.items()))
|
|
485
520
|
|
|
486
521
|
|
|
487
522
|
class UnsetVolumeSnapshot(command.Command):
|
|
@@ -499,6 +534,7 @@ class UnsetVolumeSnapshot(command.Command):
|
|
|
499
534
|
metavar='<key>',
|
|
500
535
|
action='append',
|
|
501
536
|
default=[],
|
|
537
|
+
dest='properties',
|
|
502
538
|
help=_(
|
|
503
539
|
'Property to remove from snapshot '
|
|
504
540
|
'(repeat option to remove multiple properties)'
|
|
@@ -507,13 +543,13 @@ class UnsetVolumeSnapshot(command.Command):
|
|
|
507
543
|
return parser
|
|
508
544
|
|
|
509
545
|
def take_action(self, parsed_args):
|
|
510
|
-
volume_client = self.app.client_manager.volume
|
|
511
|
-
|
|
512
|
-
|
|
546
|
+
volume_client = self.app.client_manager.sdk_connection.volume
|
|
547
|
+
|
|
548
|
+
snapshot = volume_client.find_snapshot(
|
|
549
|
+
parsed_args.snapshot, ignore_missing=False
|
|
513
550
|
)
|
|
514
551
|
|
|
515
|
-
if parsed_args.
|
|
516
|
-
volume_client.
|
|
517
|
-
snapshot.id,
|
|
518
|
-
parsed_args.property,
|
|
552
|
+
if parsed_args.properties:
|
|
553
|
+
volume_client.delete_snapshot_metadata(
|
|
554
|
+
snapshot.id, keys=parsed_args.properties
|
|
519
555
|
)
|
|
@@ -85,8 +85,6 @@ class CreateTransferRequest(command.ShowOne):
|
|
|
85
85
|
def take_action(self, parsed_args):
|
|
86
86
|
volume_client = self.app.client_manager.volume
|
|
87
87
|
|
|
88
|
-
kwargs = {}
|
|
89
|
-
|
|
90
88
|
volume_id = utils.find_resource(
|
|
91
89
|
volume_client.volumes,
|
|
92
90
|
parsed_args.volume,
|
|
@@ -94,7 +92,6 @@ class CreateTransferRequest(command.ShowOne):
|
|
|
94
92
|
volume_transfer_request = volume_client.transfers.create(
|
|
95
93
|
volume_id,
|
|
96
94
|
parsed_args.name,
|
|
97
|
-
**kwargs,
|
|
98
95
|
)
|
|
99
96
|
volume_transfer_request._info.pop("links", None)
|
|
100
97
|
|
|
@@ -272,8 +272,7 @@ class CreateVolumeType(command.ShowOne):
|
|
|
272
272
|
)
|
|
273
273
|
except Exception as e:
|
|
274
274
|
msg = _(
|
|
275
|
-
"Failed to add project %(project)s access to "
|
|
276
|
-
"type: %(e)s"
|
|
275
|
+
"Failed to add project %(project)s access to type: %(e)s"
|
|
277
276
|
)
|
|
278
277
|
LOG.error(msg % {'project': parsed_args.project, 'e': e})
|
|
279
278
|
|
|
@@ -363,7 +362,7 @@ class DeleteVolumeType(command.Command):
|
|
|
363
362
|
if result > 0:
|
|
364
363
|
total = len(parsed_args.volume_types)
|
|
365
364
|
msg = _(
|
|
366
|
-
"%(result)s of %(total)s volume types failed
|
|
365
|
+
"%(result)s of %(total)s volume types failed to delete."
|
|
367
366
|
) % {'result': result, 'total': total}
|
|
368
367
|
raise exceptions.CommandError(msg)
|
|
369
368
|
|
|
@@ -553,8 +552,7 @@ class SetVolumeType(command.Command):
|
|
|
553
552
|
'--project',
|
|
554
553
|
metavar='<project>',
|
|
555
554
|
help=_(
|
|
556
|
-
'Set volume type access to project (name or ID) '
|
|
557
|
-
'(admin only)'
|
|
555
|
+
'Set volume type access to project (name or ID) (admin only)'
|
|
558
556
|
),
|
|
559
557
|
)
|
|
560
558
|
public_group = parser.add_mutually_exclusive_group()
|
|
@@ -646,17 +644,12 @@ class SetVolumeType(command.Command):
|
|
|
646
644
|
volume_client.volume_types.update(volume_type.id, **kwargs)
|
|
647
645
|
except Exception as e:
|
|
648
646
|
LOG.error(
|
|
649
|
-
_(
|
|
650
|
-
"Failed to update volume type name or"
|
|
651
|
-
" description: %s"
|
|
652
|
-
),
|
|
647
|
+
_("Failed to update volume type name or description: %s"),
|
|
653
648
|
e,
|
|
654
649
|
)
|
|
655
650
|
result += 1
|
|
656
651
|
|
|
657
|
-
properties = {}
|
|
658
|
-
|
|
659
|
-
properties = {}
|
|
652
|
+
properties: dict[str, str] = {}
|
|
660
653
|
if parsed_args.properties:
|
|
661
654
|
properties.update(parsed_args.properties)
|
|
662
655
|
if parsed_args.multiattach:
|
|
@@ -690,7 +683,7 @@ class SetVolumeType(command.Command):
|
|
|
690
683
|
)
|
|
691
684
|
except Exception as e:
|
|
692
685
|
LOG.error(
|
|
693
|
-
_("Failed to set volume type access to
|
|
686
|
+
_("Failed to set volume type access to project: %s"), e
|
|
694
687
|
)
|
|
695
688
|
result += 1
|
|
696
689
|
|
|
@@ -714,7 +707,7 @@ class SetVolumeType(command.Command):
|
|
|
714
707
|
|
|
715
708
|
if result > 0:
|
|
716
709
|
raise exceptions.CommandError(
|
|
717
|
-
_("Command Failed: One or more of
|
|
710
|
+
_("Command Failed: One or more of the operations failed")
|
|
718
711
|
)
|
|
719
712
|
|
|
720
713
|
|
|
@@ -822,8 +815,7 @@ class UnsetVolumeType(command.Command):
|
|
|
822
815
|
"--encryption-type",
|
|
823
816
|
action="store_true",
|
|
824
817
|
help=_(
|
|
825
|
-
"Remove the encryption type for this volume type "
|
|
826
|
-
"(admin only)"
|
|
818
|
+
"Remove the encryption type for this volume type (admin only)"
|
|
827
819
|
),
|
|
828
820
|
)
|
|
829
821
|
return parser
|
|
@@ -859,10 +851,7 @@ class UnsetVolumeType(command.Command):
|
|
|
859
851
|
)
|
|
860
852
|
except Exception as e:
|
|
861
853
|
LOG.error(
|
|
862
|
-
_(
|
|
863
|
-
"Failed to remove volume type access from "
|
|
864
|
-
"project: %s"
|
|
865
|
-
),
|
|
854
|
+
_("Failed to remove volume type access from project: %s"),
|
|
866
855
|
e,
|
|
867
856
|
)
|
|
868
857
|
result += 1
|
|
@@ -881,5 +870,5 @@ class UnsetVolumeType(command.Command):
|
|
|
881
870
|
|
|
882
871
|
if result > 0:
|
|
883
872
|
raise exceptions.CommandError(
|
|
884
|
-
_("Command Failed: One or more of
|
|
873
|
+
_("Command Failed: One or more of the operations failed")
|
|
885
874
|
)
|
|
@@ -19,13 +19,13 @@ from openstackclient.i18n import _
|
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
def _format_cluster(cluster, detailed=False):
|
|
22
|
-
columns = (
|
|
22
|
+
columns: tuple[str, ...] = (
|
|
23
23
|
'name',
|
|
24
24
|
'binary',
|
|
25
25
|
'state',
|
|
26
26
|
'status',
|
|
27
27
|
)
|
|
28
|
-
column_headers = (
|
|
28
|
+
column_headers: tuple[str, ...] = (
|
|
29
29
|
'Name',
|
|
30
30
|
'Binary',
|
|
31
31
|
'State',
|
|
@@ -147,7 +147,7 @@ class ListBlockStorageCluster(command.Lister):
|
|
|
147
147
|
)
|
|
148
148
|
raise exceptions.CommandError(msg)
|
|
149
149
|
|
|
150
|
-
columns = ('Name', 'Binary', 'State', 'Status')
|
|
150
|
+
columns: tuple[str, ...] = ('Name', 'Binary', 'State', 'Status')
|
|
151
151
|
if parsed_args.long:
|
|
152
152
|
columns += (
|
|
153
153
|
'Num Hosts',
|
|
@@ -14,10 +14,9 @@
|
|
|
14
14
|
|
|
15
15
|
"""Block Storage Service action implementations"""
|
|
16
16
|
|
|
17
|
-
from
|
|
17
|
+
from openstack import utils as sdk_utils
|
|
18
18
|
from osc_lib.command import command
|
|
19
19
|
from osc_lib import exceptions
|
|
20
|
-
from osc_lib import utils
|
|
21
20
|
|
|
22
21
|
from openstackclient.i18n import _
|
|
23
22
|
|
|
@@ -33,7 +32,7 @@ class BlockStorageLogLevelList(command.Lister):
|
|
|
33
32
|
parser.add_argument(
|
|
34
33
|
"--host",
|
|
35
34
|
metavar="<host>",
|
|
36
|
-
default=
|
|
35
|
+
default=None,
|
|
37
36
|
help=_(
|
|
38
37
|
"List block storage service log level of specified host "
|
|
39
38
|
"(name only)"
|
|
@@ -42,9 +41,9 @@ class BlockStorageLogLevelList(command.Lister):
|
|
|
42
41
|
parser.add_argument(
|
|
43
42
|
"--service",
|
|
44
43
|
metavar="<service>",
|
|
45
|
-
default=
|
|
44
|
+
default=None,
|
|
46
45
|
choices=(
|
|
47
|
-
|
|
46
|
+
None,
|
|
48
47
|
'*',
|
|
49
48
|
'cinder-api',
|
|
50
49
|
'cinder-volume',
|
|
@@ -59,13 +58,13 @@ class BlockStorageLogLevelList(command.Lister):
|
|
|
59
58
|
parser.add_argument(
|
|
60
59
|
"--log-prefix",
|
|
61
60
|
metavar="<log-prefix>",
|
|
62
|
-
default=
|
|
61
|
+
default=None,
|
|
63
62
|
help="Prefix for the log, e.g. 'sqlalchemy'",
|
|
64
63
|
)
|
|
65
64
|
return parser
|
|
66
65
|
|
|
67
66
|
def take_action(self, parsed_args):
|
|
68
|
-
|
|
67
|
+
volume_client = self.app.client_manager.sdk_connection.volume
|
|
69
68
|
columns = [
|
|
70
69
|
"Binary",
|
|
71
70
|
"Host",
|
|
@@ -73,29 +72,24 @@ class BlockStorageLogLevelList(command.Lister):
|
|
|
73
72
|
"Level",
|
|
74
73
|
]
|
|
75
74
|
|
|
76
|
-
if
|
|
75
|
+
if not sdk_utils.supports_microversion(volume_client, '3.32'):
|
|
77
76
|
msg = _(
|
|
78
77
|
"--os-volume-api-version 3.32 or greater is required to "
|
|
79
78
|
"support the 'block storage log level list' command"
|
|
80
79
|
)
|
|
81
80
|
raise exceptions.CommandError(msg)
|
|
82
81
|
|
|
83
|
-
data =
|
|
82
|
+
data = []
|
|
83
|
+
for entry in volume_client.get_service_log_levels(
|
|
84
84
|
binary=parsed_args.service,
|
|
85
85
|
server=parsed_args.host,
|
|
86
86
|
prefix=parsed_args.log_prefix,
|
|
87
|
-
)
|
|
87
|
+
):
|
|
88
|
+
entry_levels = sorted(entry.levels.items(), key=lambda x: x[0])
|
|
89
|
+
for prefix, level in entry_levels:
|
|
90
|
+
data.append((entry.binary, entry.host, prefix, level))
|
|
88
91
|
|
|
89
|
-
return (
|
|
90
|
-
columns,
|
|
91
|
-
(
|
|
92
|
-
utils.get_item_properties(
|
|
93
|
-
s,
|
|
94
|
-
columns,
|
|
95
|
-
)
|
|
96
|
-
for s in data
|
|
97
|
-
),
|
|
98
|
-
)
|
|
92
|
+
return (columns, data)
|
|
99
93
|
|
|
100
94
|
|
|
101
95
|
class BlockStorageLogLevelSet(command.Command):
|
|
@@ -111,12 +105,12 @@ class BlockStorageLogLevelSet(command.Command):
|
|
|
111
105
|
metavar="<log-level>",
|
|
112
106
|
choices=('INFO', 'WARNING', 'ERROR', 'DEBUG'),
|
|
113
107
|
type=str.upper,
|
|
114
|
-
help=_("Desired log level
|
|
108
|
+
help=_("Desired log level"),
|
|
115
109
|
)
|
|
116
110
|
parser.add_argument(
|
|
117
111
|
"--host",
|
|
118
112
|
metavar="<host>",
|
|
119
|
-
default=
|
|
113
|
+
default=None,
|
|
120
114
|
help=_(
|
|
121
115
|
"Set block storage service log level of specified host "
|
|
122
116
|
"(name only)"
|
|
@@ -125,9 +119,9 @@ class BlockStorageLogLevelSet(command.Command):
|
|
|
125
119
|
parser.add_argument(
|
|
126
120
|
"--service",
|
|
127
121
|
metavar="<service>",
|
|
128
|
-
default=
|
|
122
|
+
default=None,
|
|
129
123
|
choices=(
|
|
130
|
-
|
|
124
|
+
None,
|
|
131
125
|
'*',
|
|
132
126
|
'cinder-api',
|
|
133
127
|
'cinder-volume',
|
|
@@ -142,22 +136,22 @@ class BlockStorageLogLevelSet(command.Command):
|
|
|
142
136
|
parser.add_argument(
|
|
143
137
|
"--log-prefix",
|
|
144
138
|
metavar="<log-prefix>",
|
|
145
|
-
default=
|
|
139
|
+
default=None,
|
|
146
140
|
help="Prefix for the log, e.g. 'sqlalchemy'",
|
|
147
141
|
)
|
|
148
142
|
return parser
|
|
149
143
|
|
|
150
144
|
def take_action(self, parsed_args):
|
|
151
|
-
|
|
145
|
+
volume_client = self.app.client_manager.sdk_connection.volume
|
|
152
146
|
|
|
153
|
-
if
|
|
147
|
+
if not sdk_utils.supports_microversion(volume_client, '3.32'):
|
|
154
148
|
msg = _(
|
|
155
149
|
"--os-volume-api-version 3.32 or greater is required to "
|
|
156
150
|
"support the 'block storage log level set' command"
|
|
157
151
|
)
|
|
158
152
|
raise exceptions.CommandError(msg)
|
|
159
153
|
|
|
160
|
-
|
|
154
|
+
volume_client.set_service_log_levels(
|
|
161
155
|
level=parsed_args.level,
|
|
162
156
|
binary=parsed_args.service,
|
|
163
157
|
server=parsed_args.host,
|