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
|
@@ -31,7 +31,6 @@ from osc_lib import utils
|
|
|
31
31
|
from openstackclient.common import pagination
|
|
32
32
|
from openstackclient.i18n import _
|
|
33
33
|
from openstackclient.identity import common as identity_common
|
|
34
|
-
from openstackclient.volume.v2 import volume as volume_v2
|
|
35
34
|
|
|
36
35
|
|
|
37
36
|
LOG = logging.getLogger(__name__)
|
|
@@ -91,7 +90,7 @@ class AttachmentsColumn(cliff_columns.FormattableColumn):
|
|
|
91
90
|
return msg
|
|
92
91
|
|
|
93
92
|
|
|
94
|
-
class CreateVolume(
|
|
93
|
+
class CreateVolume(command.ShowOne):
|
|
95
94
|
_description = _("Create new volume")
|
|
96
95
|
|
|
97
96
|
@staticmethod
|
|
@@ -117,8 +116,48 @@ class CreateVolume(volume_v2.CreateVolume):
|
|
|
117
116
|
raise exceptions.CommandError(msg)
|
|
118
117
|
|
|
119
118
|
def get_parser(self, prog_name):
|
|
120
|
-
parser
|
|
121
|
-
|
|
119
|
+
parser = super().get_parser(prog_name)
|
|
120
|
+
parser.add_argument(
|
|
121
|
+
"name",
|
|
122
|
+
metavar="<name>",
|
|
123
|
+
nargs="?",
|
|
124
|
+
help=_("Volume name"),
|
|
125
|
+
)
|
|
126
|
+
parser.add_argument(
|
|
127
|
+
"--size",
|
|
128
|
+
metavar="<size>",
|
|
129
|
+
type=int,
|
|
130
|
+
help=_(
|
|
131
|
+
"Volume size in GB (required unless --snapshot or "
|
|
132
|
+
"--source specified)"
|
|
133
|
+
),
|
|
134
|
+
)
|
|
135
|
+
parser.add_argument(
|
|
136
|
+
"--type",
|
|
137
|
+
metavar="<volume-type>",
|
|
138
|
+
help=_("Set the type of volume"),
|
|
139
|
+
)
|
|
140
|
+
source_group = parser.add_mutually_exclusive_group()
|
|
141
|
+
source_group.add_argument(
|
|
142
|
+
"--image",
|
|
143
|
+
metavar="<image>",
|
|
144
|
+
help=_("Use <image> as source of volume (name or ID)"),
|
|
145
|
+
)
|
|
146
|
+
source_group.add_argument(
|
|
147
|
+
"--snapshot",
|
|
148
|
+
metavar="<snapshot>",
|
|
149
|
+
help=_("Use <snapshot> as source of volume (name or ID)"),
|
|
150
|
+
)
|
|
151
|
+
source_group.add_argument(
|
|
152
|
+
"--source",
|
|
153
|
+
metavar="<volume>",
|
|
154
|
+
help=_("Volume to clone (name or ID)"),
|
|
155
|
+
)
|
|
156
|
+
source_group.add_argument(
|
|
157
|
+
"--source-replicated",
|
|
158
|
+
metavar="<replicated-volume>",
|
|
159
|
+
help=argparse.SUPPRESS,
|
|
160
|
+
)
|
|
122
161
|
source_group.add_argument(
|
|
123
162
|
"--backup",
|
|
124
163
|
metavar="<backup>",
|
|
@@ -138,6 +177,72 @@ class CreateVolume(volume_v2.CreateVolume):
|
|
|
138
177
|
"--remote-source source-id=test_id')"
|
|
139
178
|
),
|
|
140
179
|
)
|
|
180
|
+
parser.add_argument(
|
|
181
|
+
"--description",
|
|
182
|
+
metavar="<description>",
|
|
183
|
+
help=_("Volume description"),
|
|
184
|
+
)
|
|
185
|
+
parser.add_argument(
|
|
186
|
+
"--availability-zone",
|
|
187
|
+
metavar="<availability-zone>",
|
|
188
|
+
help=_("Create volume in <availability-zone>"),
|
|
189
|
+
)
|
|
190
|
+
parser.add_argument(
|
|
191
|
+
"--consistency-group",
|
|
192
|
+
metavar="consistency-group>",
|
|
193
|
+
help=_("Consistency group where the new volume belongs to"),
|
|
194
|
+
)
|
|
195
|
+
parser.add_argument(
|
|
196
|
+
"--property",
|
|
197
|
+
metavar="<key=value>",
|
|
198
|
+
action=parseractions.KeyValueAction,
|
|
199
|
+
dest="properties",
|
|
200
|
+
help=_(
|
|
201
|
+
"Set a property to this volume "
|
|
202
|
+
"(repeat option to set multiple properties)"
|
|
203
|
+
),
|
|
204
|
+
)
|
|
205
|
+
parser.add_argument(
|
|
206
|
+
"--hint",
|
|
207
|
+
metavar="<key=value>",
|
|
208
|
+
action=KeyValueHintAction,
|
|
209
|
+
help=_(
|
|
210
|
+
"Arbitrary scheduler hint key-value pairs to help creating "
|
|
211
|
+
"a volume. Repeat the option to set multiple hints. "
|
|
212
|
+
"'same_host' and 'different_host' get values appended when "
|
|
213
|
+
"repeated, all other keys take the last given value"
|
|
214
|
+
),
|
|
215
|
+
)
|
|
216
|
+
bootable_group = parser.add_mutually_exclusive_group()
|
|
217
|
+
bootable_group.add_argument(
|
|
218
|
+
"--bootable",
|
|
219
|
+
action="store_true",
|
|
220
|
+
dest="bootable",
|
|
221
|
+
default=None,
|
|
222
|
+
help=_("Mark volume as bootable"),
|
|
223
|
+
)
|
|
224
|
+
bootable_group.add_argument(
|
|
225
|
+
"--non-bootable",
|
|
226
|
+
action="store_false",
|
|
227
|
+
dest="bootable",
|
|
228
|
+
default=None,
|
|
229
|
+
help=_("Mark volume as non-bootable (default)"),
|
|
230
|
+
)
|
|
231
|
+
readonly_group = parser.add_mutually_exclusive_group()
|
|
232
|
+
readonly_group.add_argument(
|
|
233
|
+
"--read-only",
|
|
234
|
+
action="store_true",
|
|
235
|
+
dest="read_only",
|
|
236
|
+
default=None,
|
|
237
|
+
help=_("Set volume to read-only access mode"),
|
|
238
|
+
)
|
|
239
|
+
readonly_group.add_argument(
|
|
240
|
+
"--read-write",
|
|
241
|
+
action="store_false",
|
|
242
|
+
dest="read_only",
|
|
243
|
+
default=None,
|
|
244
|
+
help=_("Set volume to read-write access mode (default)"),
|
|
245
|
+
)
|
|
141
246
|
parser.add_argument(
|
|
142
247
|
"--host",
|
|
143
248
|
metavar="<host>",
|
|
@@ -160,7 +265,7 @@ class CreateVolume(volume_v2.CreateVolume):
|
|
|
160
265
|
return parser
|
|
161
266
|
|
|
162
267
|
def take_action(self, parsed_args):
|
|
163
|
-
|
|
268
|
+
self._check_size_arg(parsed_args)
|
|
164
269
|
# size is validated in the above call to
|
|
165
270
|
# _check_size_arg where we check that size
|
|
166
271
|
# should be passed if we are not creating a
|
|
@@ -194,8 +299,7 @@ class CreateVolume(volume_v2.CreateVolume):
|
|
|
194
299
|
parsed_args.size
|
|
195
300
|
or parsed_args.consistency_group
|
|
196
301
|
or parsed_args.hint
|
|
197
|
-
or parsed_args.read_only
|
|
198
|
-
or parsed_args.read_write
|
|
302
|
+
or parsed_args.read_only is not None
|
|
199
303
|
):
|
|
200
304
|
msg = _(
|
|
201
305
|
"The --size, --consistency-group, --hint, --read-only "
|
|
@@ -232,10 +336,24 @@ class CreateVolume(volume_v2.CreateVolume):
|
|
|
232
336
|
description=parsed_args.description,
|
|
233
337
|
volume_type=parsed_args.type,
|
|
234
338
|
availability_zone=parsed_args.availability_zone,
|
|
235
|
-
metadata=parsed_args.
|
|
339
|
+
metadata=parsed_args.properties,
|
|
236
340
|
bootable=parsed_args.bootable,
|
|
237
341
|
)
|
|
238
|
-
|
|
342
|
+
data = {}
|
|
343
|
+
for key, value in volume.to_dict().items():
|
|
344
|
+
# FIXME(stephenfin): Stop ignoring these once we bump SDK
|
|
345
|
+
# https://review.opendev.org/c/openstack/openstacksdk/+/945836/
|
|
346
|
+
if key in (
|
|
347
|
+
'cluster_name',
|
|
348
|
+
'consumes_quota',
|
|
349
|
+
'encryption_key_id',
|
|
350
|
+
'service_uuid',
|
|
351
|
+
'shared_targets',
|
|
352
|
+
'volume_type_id',
|
|
353
|
+
):
|
|
354
|
+
continue
|
|
355
|
+
data[key] = value
|
|
356
|
+
return zip(*sorted(data.items()))
|
|
239
357
|
|
|
240
358
|
source_volume = None
|
|
241
359
|
if parsed_args.source:
|
|
@@ -287,7 +405,7 @@ class CreateVolume(volume_v2.CreateVolume):
|
|
|
287
405
|
description=parsed_args.description,
|
|
288
406
|
volume_type=parsed_args.type,
|
|
289
407
|
availability_zone=parsed_args.availability_zone,
|
|
290
|
-
metadata=parsed_args.
|
|
408
|
+
metadata=parsed_args.properties,
|
|
291
409
|
imageRef=image,
|
|
292
410
|
source_volid=source_volume,
|
|
293
411
|
consistencygroup_id=consistency_group,
|
|
@@ -295,7 +413,7 @@ class CreateVolume(volume_v2.CreateVolume):
|
|
|
295
413
|
backup_id=backup,
|
|
296
414
|
)
|
|
297
415
|
|
|
298
|
-
if parsed_args.bootable
|
|
416
|
+
if parsed_args.bootable is not None:
|
|
299
417
|
try:
|
|
300
418
|
if utils.wait_for_status(
|
|
301
419
|
volume_client.volumes.get,
|
|
@@ -309,13 +427,13 @@ class CreateVolume(volume_v2.CreateVolume):
|
|
|
309
427
|
)
|
|
310
428
|
else:
|
|
311
429
|
msg = _(
|
|
312
|
-
"Volume status is not available for setting boot "
|
|
313
|
-
"state"
|
|
430
|
+
"Volume status is not available for setting boot state"
|
|
314
431
|
)
|
|
315
432
|
raise exceptions.CommandError(msg)
|
|
316
433
|
except Exception as e:
|
|
317
434
|
LOG.error(_("Failed to set volume bootable property: %s"), e)
|
|
318
|
-
|
|
435
|
+
|
|
436
|
+
if parsed_args.read_only is not None:
|
|
319
437
|
try:
|
|
320
438
|
if utils.wait_for_status(
|
|
321
439
|
volume_client.volumes.get,
|
|
@@ -335,10 +453,7 @@ class CreateVolume(volume_v2.CreateVolume):
|
|
|
335
453
|
raise exceptions.CommandError(msg)
|
|
336
454
|
except Exception as e:
|
|
337
455
|
LOG.error(
|
|
338
|
-
_(
|
|
339
|
-
"Failed to set volume read-only access "
|
|
340
|
-
"mode flag: %s"
|
|
341
|
-
),
|
|
456
|
+
_("Failed to set volume read-only access mode flag: %s"),
|
|
342
457
|
e,
|
|
343
458
|
)
|
|
344
459
|
|
|
@@ -355,11 +470,33 @@ class CreateVolume(volume_v2.CreateVolume):
|
|
|
355
470
|
return zip(*sorted(volume._info.items()))
|
|
356
471
|
|
|
357
472
|
|
|
358
|
-
class DeleteVolume(
|
|
473
|
+
class DeleteVolume(command.Command):
|
|
359
474
|
_description = _("Delete volume(s)")
|
|
360
475
|
|
|
361
476
|
def get_parser(self, prog_name):
|
|
362
477
|
parser = super().get_parser(prog_name)
|
|
478
|
+
parser.add_argument(
|
|
479
|
+
"volumes",
|
|
480
|
+
metavar="<volume>",
|
|
481
|
+
nargs="+",
|
|
482
|
+
help=_("Volume(s) to delete (name or ID)"),
|
|
483
|
+
)
|
|
484
|
+
group = parser.add_mutually_exclusive_group()
|
|
485
|
+
group.add_argument(
|
|
486
|
+
"--force",
|
|
487
|
+
action="store_true",
|
|
488
|
+
help=_(
|
|
489
|
+
"Attempt forced removal of volume(s), regardless of state "
|
|
490
|
+
"(defaults to False)"
|
|
491
|
+
),
|
|
492
|
+
)
|
|
493
|
+
group.add_argument(
|
|
494
|
+
"--purge",
|
|
495
|
+
action="store_true",
|
|
496
|
+
help=_(
|
|
497
|
+
"Remove any snapshots along with volume(s) (defaults to False)"
|
|
498
|
+
),
|
|
499
|
+
)
|
|
363
500
|
parser.add_argument(
|
|
364
501
|
'--remote',
|
|
365
502
|
action='store_true',
|
|
@@ -368,8 +505,7 @@ class DeleteVolume(volume_v2.DeleteVolume):
|
|
|
368
505
|
return parser
|
|
369
506
|
|
|
370
507
|
def take_action(self, parsed_args):
|
|
371
|
-
volume_client = self.app.client_manager.volume
|
|
372
|
-
volume_client_sdk = self.app.client_manager.sdk_connection.volume
|
|
508
|
+
volume_client = self.app.client_manager.sdk_connection.volume
|
|
373
509
|
result = 0
|
|
374
510
|
|
|
375
511
|
if parsed_args.remote and (parsed_args.force or parsed_args.purge):
|
|
@@ -379,16 +515,18 @@ class DeleteVolume(volume_v2.DeleteVolume):
|
|
|
379
515
|
)
|
|
380
516
|
raise exceptions.CommandError(msg)
|
|
381
517
|
|
|
382
|
-
for
|
|
518
|
+
for volume in parsed_args.volumes:
|
|
383
519
|
try:
|
|
384
|
-
volume_obj =
|
|
520
|
+
volume_obj = volume_client.find_volume(
|
|
521
|
+
volume, ignore_missing=False
|
|
522
|
+
)
|
|
385
523
|
if parsed_args.remote:
|
|
386
|
-
|
|
387
|
-
elif parsed_args.force:
|
|
388
|
-
volume_client.volumes.force_delete(volume_obj.id)
|
|
524
|
+
volume_client.unmanage_volume(volume_obj.id)
|
|
389
525
|
else:
|
|
390
|
-
volume_client.
|
|
391
|
-
volume_obj.id,
|
|
526
|
+
volume_client.delete_volume(
|
|
527
|
+
volume_obj.id,
|
|
528
|
+
force=parsed_args.force,
|
|
529
|
+
cascade=parsed_args.purge,
|
|
392
530
|
)
|
|
393
531
|
except Exception as e:
|
|
394
532
|
result += 1
|
|
@@ -397,12 +535,12 @@ class DeleteVolume(volume_v2.DeleteVolume):
|
|
|
397
535
|
"Failed to delete volume with "
|
|
398
536
|
"name or ID '%(volume)s': %(e)s"
|
|
399
537
|
),
|
|
400
|
-
{'volume':
|
|
538
|
+
{'volume': volume, 'e': e},
|
|
401
539
|
)
|
|
402
540
|
|
|
403
541
|
if result > 0:
|
|
404
542
|
total = len(parsed_args.volumes)
|
|
405
|
-
msg = _("%(result)s of %(total)s volumes failed
|
|
543
|
+
msg = _("%(result)s of %(total)s volumes failed to delete.") % {
|
|
406
544
|
'result': result,
|
|
407
545
|
'total': total,
|
|
408
546
|
}
|
|
@@ -523,7 +661,7 @@ class ListVolume(command.Lister):
|
|
|
523
661
|
server_cache = {}
|
|
524
662
|
if do_server_list:
|
|
525
663
|
try:
|
|
526
|
-
compute_client = self.app.client_manager.
|
|
664
|
+
compute_client = self.app.client_manager.compute
|
|
527
665
|
for s in compute_client.servers():
|
|
528
666
|
server_cache[s.id] = s
|
|
529
667
|
except sdk_exceptions.SDKException: # noqa: S110
|
|
@@ -642,6 +780,7 @@ class SetVolume(command.Command):
|
|
|
642
780
|
'--property',
|
|
643
781
|
metavar='<key=value>',
|
|
644
782
|
action=parseractions.KeyValueAction,
|
|
783
|
+
dest='properties',
|
|
645
784
|
help=_(
|
|
646
785
|
'Set a property on this volume '
|
|
647
786
|
'(repeat option to set multiple properties)'
|
|
@@ -651,6 +790,7 @@ class SetVolume(command.Command):
|
|
|
651
790
|
'--image-property',
|
|
652
791
|
metavar='<key=value>',
|
|
653
792
|
action=parseractions.KeyValueAction,
|
|
793
|
+
dest='image_properties',
|
|
654
794
|
help=_(
|
|
655
795
|
'Set an image property on this volume '
|
|
656
796
|
'(repeat option to set multiple image properties)'
|
|
@@ -727,22 +867,30 @@ class SetVolume(command.Command):
|
|
|
727
867
|
bootable_group.add_argument(
|
|
728
868
|
"--bootable",
|
|
729
869
|
action="store_true",
|
|
870
|
+
dest="bootable",
|
|
871
|
+
default=None,
|
|
730
872
|
help=_("Mark volume as bootable"),
|
|
731
873
|
)
|
|
732
874
|
bootable_group.add_argument(
|
|
733
875
|
"--non-bootable",
|
|
734
|
-
action="
|
|
876
|
+
action="store_false",
|
|
877
|
+
dest="bootable",
|
|
878
|
+
default=None,
|
|
735
879
|
help=_("Mark volume as non-bootable"),
|
|
736
880
|
)
|
|
737
881
|
readonly_group = parser.add_mutually_exclusive_group()
|
|
738
882
|
readonly_group.add_argument(
|
|
739
883
|
"--read-only",
|
|
740
884
|
action="store_true",
|
|
885
|
+
dest="read_only",
|
|
886
|
+
default=None,
|
|
741
887
|
help=_("Set volume to read-only access mode"),
|
|
742
888
|
)
|
|
743
889
|
readonly_group.add_argument(
|
|
744
890
|
"--read-write",
|
|
745
|
-
action="
|
|
891
|
+
action="store_false",
|
|
892
|
+
dest="read_only",
|
|
893
|
+
default=None,
|
|
746
894
|
help=_("Set volume to read-write access mode"),
|
|
747
895
|
)
|
|
748
896
|
return parser
|
|
@@ -768,18 +916,24 @@ class SetVolume(command.Command):
|
|
|
768
916
|
_("New size must be greater than %s GB") % volume.size
|
|
769
917
|
)
|
|
770
918
|
raise exceptions.CommandError(msg)
|
|
771
|
-
if (
|
|
772
|
-
volume.status != 'available'
|
|
773
|
-
and not volume_client.api_version.matches('3.42')
|
|
774
|
-
):
|
|
919
|
+
if volume.status not in ('available', 'in-use'):
|
|
775
920
|
msg = (
|
|
776
921
|
_(
|
|
777
922
|
"Volume is in %s state, it must be available "
|
|
778
|
-
"before size can be extended"
|
|
923
|
+
"or in-use before size can be extended."
|
|
779
924
|
)
|
|
780
925
|
% volume.status
|
|
781
926
|
)
|
|
782
927
|
raise exceptions.CommandError(msg)
|
|
928
|
+
if (
|
|
929
|
+
volume.status == 'in-use'
|
|
930
|
+
and not volume_client.api_version.matches('3.42')
|
|
931
|
+
):
|
|
932
|
+
msg = _(
|
|
933
|
+
"--os-volume-api-version 3.42 or greater is "
|
|
934
|
+
"required to extend in-use volumes."
|
|
935
|
+
)
|
|
936
|
+
raise exceptions.CommandError(msg)
|
|
783
937
|
volume_client.volumes.extend(volume.id, parsed_args.size)
|
|
784
938
|
except Exception as e:
|
|
785
939
|
LOG.error(_("Failed to set volume size: %s"), e)
|
|
@@ -794,28 +948,31 @@ class SetVolume(command.Command):
|
|
|
794
948
|
LOG.error(_("Failed to clean volume properties: %s"), e)
|
|
795
949
|
result += 1
|
|
796
950
|
|
|
797
|
-
if parsed_args.
|
|
951
|
+
if parsed_args.properties:
|
|
798
952
|
try:
|
|
799
953
|
volume_client.volumes.set_metadata(
|
|
800
|
-
volume.id, parsed_args.
|
|
954
|
+
volume.id, parsed_args.properties
|
|
801
955
|
)
|
|
802
956
|
except Exception as e:
|
|
803
|
-
LOG.error(_("Failed to set volume
|
|
957
|
+
LOG.error(_("Failed to set volume properties: %s"), e)
|
|
804
958
|
result += 1
|
|
805
|
-
|
|
959
|
+
|
|
960
|
+
if parsed_args.image_properties:
|
|
806
961
|
try:
|
|
807
962
|
volume_client.volumes.set_image_metadata(
|
|
808
|
-
volume.id, parsed_args.
|
|
963
|
+
volume.id, parsed_args.image_properties
|
|
809
964
|
)
|
|
810
965
|
except Exception as e:
|
|
811
|
-
LOG.error(_("Failed to set image
|
|
966
|
+
LOG.error(_("Failed to set image properties: %s"), e)
|
|
812
967
|
result += 1
|
|
968
|
+
|
|
813
969
|
if parsed_args.state:
|
|
814
970
|
try:
|
|
815
971
|
volume_client.volumes.reset_state(volume.id, parsed_args.state)
|
|
816
972
|
except Exception as e:
|
|
817
973
|
LOG.error(_("Failed to set volume state: %s"), e)
|
|
818
974
|
result += 1
|
|
975
|
+
|
|
819
976
|
if parsed_args.attached:
|
|
820
977
|
try:
|
|
821
978
|
volume_client.volumes.reset_state(
|
|
@@ -824,6 +981,7 @@ class SetVolume(command.Command):
|
|
|
824
981
|
except Exception as e:
|
|
825
982
|
LOG.error(_("Failed to set volume attach-status: %s"), e)
|
|
826
983
|
result += 1
|
|
984
|
+
|
|
827
985
|
if parsed_args.detached:
|
|
828
986
|
try:
|
|
829
987
|
volume_client.volumes.reset_state(
|
|
@@ -832,7 +990,8 @@ class SetVolume(command.Command):
|
|
|
832
990
|
except Exception as e:
|
|
833
991
|
LOG.error(_("Failed to set volume attach-status: %s"), e)
|
|
834
992
|
result += 1
|
|
835
|
-
|
|
993
|
+
|
|
994
|
+
if parsed_args.bootable is not None:
|
|
836
995
|
try:
|
|
837
996
|
volume_client.volumes.set_bootable(
|
|
838
997
|
volume.id, parsed_args.bootable
|
|
@@ -840,20 +999,19 @@ class SetVolume(command.Command):
|
|
|
840
999
|
except Exception as e:
|
|
841
1000
|
LOG.error(_("Failed to set volume bootable property: %s"), e)
|
|
842
1001
|
result += 1
|
|
843
|
-
|
|
1002
|
+
|
|
1003
|
+
if parsed_args.read_only is not None:
|
|
844
1004
|
try:
|
|
845
1005
|
volume_client.volumes.update_readonly_flag(
|
|
846
1006
|
volume.id, parsed_args.read_only
|
|
847
1007
|
)
|
|
848
1008
|
except Exception as e:
|
|
849
1009
|
LOG.error(
|
|
850
|
-
_(
|
|
851
|
-
"Failed to set volume read-only access "
|
|
852
|
-
"mode flag: %s"
|
|
853
|
-
),
|
|
1010
|
+
_("Failed to set volume read-only access mode flag: %s"),
|
|
854
1011
|
e,
|
|
855
1012
|
)
|
|
856
1013
|
result += 1
|
|
1014
|
+
|
|
857
1015
|
policy = parsed_args.migration_policy or parsed_args.retype_policy
|
|
858
1016
|
if parsed_args.type:
|
|
859
1017
|
# get the migration policy
|
|
@@ -903,7 +1061,7 @@ class SetVolume(command.Command):
|
|
|
903
1061
|
|
|
904
1062
|
if result > 0:
|
|
905
1063
|
raise exceptions.CommandError(
|
|
906
|
-
_("One or more of the
|
|
1064
|
+
_("One or more of the set operations failed")
|
|
907
1065
|
)
|
|
908
1066
|
|
|
909
1067
|
|
|
@@ -954,6 +1112,7 @@ class UnsetVolume(command.Command):
|
|
|
954
1112
|
'--property',
|
|
955
1113
|
metavar='<key>',
|
|
956
1114
|
action='append',
|
|
1115
|
+
dest='properties',
|
|
957
1116
|
help=_(
|
|
958
1117
|
'Remove a property from volume '
|
|
959
1118
|
'(repeat option to remove multiple properties)'
|
|
@@ -963,6 +1122,7 @@ class UnsetVolume(command.Command):
|
|
|
963
1122
|
'--image-property',
|
|
964
1123
|
metavar='<key>',
|
|
965
1124
|
action='append',
|
|
1125
|
+
dest='image_properties',
|
|
966
1126
|
help=_(
|
|
967
1127
|
'Remove an image property from volume '
|
|
968
1128
|
'(repeat option to remove multiple image properties)'
|
|
@@ -975,27 +1135,27 @@ class UnsetVolume(command.Command):
|
|
|
975
1135
|
volume = utils.find_resource(volume_client.volumes, parsed_args.volume)
|
|
976
1136
|
|
|
977
1137
|
result = 0
|
|
978
|
-
if parsed_args.
|
|
1138
|
+
if parsed_args.properties:
|
|
979
1139
|
try:
|
|
980
1140
|
volume_client.volumes.delete_metadata(
|
|
981
|
-
volume.id, parsed_args.
|
|
1141
|
+
volume.id, parsed_args.properties
|
|
982
1142
|
)
|
|
983
1143
|
except Exception as e:
|
|
984
|
-
LOG.error(_("Failed to unset volume
|
|
1144
|
+
LOG.error(_("Failed to unset volume properties: %s"), e)
|
|
985
1145
|
result += 1
|
|
986
1146
|
|
|
987
|
-
if parsed_args.
|
|
1147
|
+
if parsed_args.image_properties:
|
|
988
1148
|
try:
|
|
989
1149
|
volume_client.volumes.delete_image_metadata(
|
|
990
|
-
volume.id, parsed_args.
|
|
1150
|
+
volume.id, parsed_args.image_properties
|
|
991
1151
|
)
|
|
992
1152
|
except Exception as e:
|
|
993
|
-
LOG.error(_("Failed to unset image
|
|
1153
|
+
LOG.error(_("Failed to unset image properties: %s"), e)
|
|
994
1154
|
result += 1
|
|
995
1155
|
|
|
996
1156
|
if result > 0:
|
|
997
1157
|
raise exceptions.CommandError(
|
|
998
|
-
_("One or more of the
|
|
1158
|
+
_("One or more of the unset operations failed")
|
|
999
1159
|
)
|
|
1000
1160
|
|
|
1001
1161
|
|
|
@@ -18,6 +18,7 @@ from osc_lib.command import command
|
|
|
18
18
|
from osc_lib import exceptions
|
|
19
19
|
from osc_lib import utils
|
|
20
20
|
|
|
21
|
+
from openstackclient.common import envvars
|
|
21
22
|
from openstackclient.common import pagination
|
|
22
23
|
from openstackclient.i18n import _
|
|
23
24
|
from openstackclient.identity import common as identity_common
|
|
@@ -171,7 +172,7 @@ class CreateVolumeAttachment(command.ShowOne):
|
|
|
171
172
|
|
|
172
173
|
def take_action(self, parsed_args):
|
|
173
174
|
volume_client = self.app.client_manager.sdk_connection.volume
|
|
174
|
-
compute_client = self.app.client_manager.
|
|
175
|
+
compute_client = self.app.client_manager.compute
|
|
175
176
|
|
|
176
177
|
if not sdk_utils.supports_microversion(volume_client, '3.27'):
|
|
177
178
|
msg = _(
|
|
@@ -399,7 +400,7 @@ class ListVolumeAttachment(command.Lister):
|
|
|
399
400
|
'--all-projects',
|
|
400
401
|
dest='all_projects',
|
|
401
402
|
action='store_true',
|
|
402
|
-
default=
|
|
403
|
+
default=envvars.boolenv('ALL_PROJECTS'),
|
|
403
404
|
help=_('Shows details for all projects (admin only).'),
|
|
404
405
|
)
|
|
405
406
|
parser.add_argument(
|