python-openstackclient 6.3.0__py3-none-any.whl → 6.5.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 +4 -4
- openstackclient/common/pagination.py +82 -0
- openstackclient/compute/v2/flavor.py +2 -16
- openstackclient/compute/v2/hypervisor.py +2 -21
- openstackclient/compute/v2/keypair.py +2 -9
- openstackclient/compute/v2/server.py +220 -131
- openstackclient/compute/v2/server_event.py +30 -19
- openstackclient/compute/v2/server_group.py +2 -23
- openstackclient/compute/v2/server_migration.py +2 -22
- openstackclient/compute/v2/usage.py +4 -6
- openstackclient/identity/v3/mapping.py +25 -3
- openstackclient/identity/v3/policy.py +3 -1
- openstackclient/image/v2/cache.py +218 -0
- openstackclient/image/v2/image.py +40 -17
- openstackclient/image/v2/metadef_namespaces.py +25 -21
- openstackclient/image/v2/metadef_objects.py +189 -0
- openstackclient/image/v2/metadef_properties.py +284 -0
- openstackclient/network/utils.py +100 -0
- openstackclient/network/v2/default_security_group_rule.py +418 -0
- openstackclient/network/v2/local_ip_association.py +1 -1
- openstackclient/network/v2/ndp_proxy.py +7 -3
- openstackclient/network/v2/network.py +2 -2
- openstackclient/network/v2/port.py +65 -19
- openstackclient/network/v2/security_group_rule.py +18 -111
- openstackclient/network/v2/subnet.py +1 -0
- openstackclient/object/v1/container.py +2 -12
- openstackclient/object/v1/object.py +2 -11
- openstackclient/tests/functional/base.py +13 -6
- openstackclient/tests/functional/identity/v3/test_role.py +11 -3
- openstackclient/tests/functional/network/v2/common.py +7 -1
- openstackclient/tests/functional/network/v2/test_address_group.py +2 -4
- openstackclient/tests/functional/network/v2/test_address_scope.py +0 -6
- openstackclient/tests/functional/network/v2/test_default_security_group_rule.py +67 -0
- openstackclient/tests/functional/network/v2/test_floating_ip.py +3 -6
- openstackclient/tests/functional/network/v2/test_ip_availability.py +3 -8
- openstackclient/tests/functional/network/v2/test_l3_conntrack_helper.py +3 -4
- openstackclient/tests/functional/network/v2/test_local_ip.py +2 -4
- openstackclient/tests/functional/network/v2/test_network.py +18 -17
- openstackclient/tests/functional/network/v2/test_network_agent.py +24 -21
- openstackclient/tests/functional/network/v2/test_network_flavor.py +0 -6
- openstackclient/tests/functional/network/v2/test_network_flavor_profile.py +0 -6
- openstackclient/tests/functional/network/v2/test_network_meter.py +6 -6
- openstackclient/tests/functional/network/v2/test_network_meter_rule.py +7 -8
- openstackclient/tests/functional/network/v2/test_network_ndp_proxy.py +1 -3
- openstackclient/tests/functional/network/v2/test_network_qos_policy.py +4 -4
- openstackclient/tests/functional/network/v2/test_network_qos_rule.py +16 -20
- openstackclient/tests/functional/network/v2/test_network_qos_rule_type.py +4 -4
- openstackclient/tests/functional/network/v2/test_network_rbac.py +1 -4
- openstackclient/tests/functional/network/v2/test_network_segment.py +7 -12
- openstackclient/tests/functional/network/v2/test_network_segment_range.py +3 -4
- openstackclient/tests/functional/network/v2/test_network_service_provider.py +2 -4
- openstackclient/tests/functional/network/v2/test_network_trunk.py +3 -3
- openstackclient/tests/functional/network/v2/test_port.py +2 -8
- openstackclient/tests/functional/network/v2/test_router.py +0 -6
- openstackclient/tests/functional/network/v2/test_security_group.py +1 -4
- openstackclient/tests/functional/network/v2/test_security_group_rule.py +1 -4
- openstackclient/tests/functional/network/v2/test_subnet.py +4 -22
- openstackclient/tests/functional/network/v2/test_subnet_pool.py +0 -6
- openstackclient/tests/unit/common/test_availability_zone.py +28 -30
- openstackclient/tests/unit/common/test_extension.py +1 -4
- openstackclient/tests/unit/common/test_limits.py +2 -4
- openstackclient/tests/unit/common/test_project_cleanup.py +3 -10
- openstackclient/tests/unit/common/test_quota.py +18 -24
- openstackclient/tests/unit/compute/v2/fakes.py +24 -11
- openstackclient/tests/unit/compute/v2/test_agent.py +1 -1
- openstackclient/tests/unit/compute/v2/test_aggregate.py +62 -72
- openstackclient/tests/unit/compute/v2/test_console.py +18 -30
- openstackclient/tests/unit/compute/v2/test_flavor.py +85 -89
- openstackclient/tests/unit/compute/v2/test_host.py +12 -19
- openstackclient/tests/unit/compute/v2/test_hypervisor.py +23 -25
- openstackclient/tests/unit/compute/v2/test_hypervisor_stats.py +2 -6
- openstackclient/tests/unit/compute/v2/test_keypair.py +25 -39
- openstackclient/tests/unit/compute/v2/test_server.py +316 -365
- openstackclient/tests/unit/compute/v2/test_server_backup.py +5 -17
- openstackclient/tests/unit/compute/v2/test_server_event.py +23 -25
- openstackclient/tests/unit/compute/v2/test_server_group.py +41 -33
- openstackclient/tests/unit/compute/v2/test_server_image.py +6 -18
- openstackclient/tests/unit/compute/v2/test_server_migration.py +45 -45
- openstackclient/tests/unit/compute/v2/test_server_volume.py +15 -31
- openstackclient/tests/unit/compute/v2/test_service.py +51 -56
- openstackclient/tests/unit/compute/v2/test_usage.py +10 -13
- openstackclient/tests/unit/fakes.py +4 -0
- openstackclient/tests/unit/identity/v3/test_mappings.py +9 -4
- openstackclient/tests/unit/identity/v3/test_trust.py +0 -2
- openstackclient/tests/unit/image/v1/fakes.py +2 -1
- openstackclient/tests/unit/image/v1/test_image.py +1 -1
- openstackclient/tests/unit/image/v2/fakes.py +82 -0
- openstackclient/tests/unit/image/v2/test_cache.py +214 -0
- openstackclient/tests/unit/image/v2/test_image.py +62 -4
- openstackclient/tests/unit/image/v2/test_metadef_namespaces.py +5 -19
- openstackclient/tests/unit/image/v2/test_metadef_objects.py +162 -0
- openstackclient/tests/unit/image/v2/test_metadef_properties.py +227 -0
- openstackclient/tests/unit/integ/cli/test_shell.py +0 -2
- openstackclient/tests/unit/network/test_common.py +3 -3
- openstackclient/tests/unit/network/v2/fakes.py +1 -0
- openstackclient/tests/unit/network/v2/test_default_security_group_rule.py +1133 -0
- openstackclient/tests/unit/network/v2/test_floating_ip_compute.py +5 -13
- openstackclient/tests/unit/network/v2/test_floating_ip_pool_compute.py +1 -9
- openstackclient/tests/unit/network/v2/test_network.py +33 -0
- openstackclient/tests/unit/network/v2/test_network_compute.py +5 -11
- openstackclient/tests/unit/network/v2/test_network_trunk.py +6 -8
- openstackclient/tests/unit/network/v2/test_port.py +83 -38
- openstackclient/tests/unit/network/v2/test_security_group_compute.py +7 -15
- openstackclient/tests/unit/network/v2/test_security_group_rule_compute.py +19 -27
- openstackclient/tests/unit/network/v2/test_security_group_rule_network.py +3 -6
- openstackclient/tests/unit/network/v2/test_subnet.py +92 -0
- openstackclient/tests/unit/network/v2/test_subnet_pool.py +11 -13
- openstackclient/tests/unit/test_shell.py +1 -7
- openstackclient/tests/unit/utils.py +10 -4
- openstackclient/tests/unit/volume/v1/fakes.py +7 -1
- openstackclient/tests/unit/volume/v1/test_qos_specs.py +2 -2
- openstackclient/tests/unit/volume/v1/test_service.py +1 -1
- openstackclient/tests/unit/volume/v1/test_transfer_request.py +2 -2
- openstackclient/tests/unit/volume/v1/test_type.py +2 -4
- openstackclient/tests/unit/volume/v1/test_volume.py +5 -7
- openstackclient/tests/unit/volume/v1/test_volume_backup.py +4 -4
- openstackclient/tests/unit/volume/v2/fakes.py +32 -12
- openstackclient/tests/unit/volume/v2/test_backup_record.py +1 -1
- openstackclient/tests/unit/volume/v2/test_consistency_group.py +4 -6
- openstackclient/tests/unit/volume/v2/test_consistency_group_snapshot.py +2 -4
- openstackclient/tests/unit/volume/v2/test_qos_specs.py +2 -2
- openstackclient/tests/unit/volume/v2/test_service.py +1 -1
- openstackclient/tests/unit/volume/v2/test_volume.py +78 -16
- openstackclient/tests/unit/volume/v2/test_volume_backend.py +10 -22
- openstackclient/tests/unit/volume/v2/test_volume_backup.py +76 -89
- openstackclient/tests/unit/volume/v2/test_volume_host.py +1 -1
- openstackclient/tests/unit/volume/v2/test_volume_snapshot.py +5 -7
- openstackclient/tests/unit/volume/v2/test_volume_transfer_request.py +4 -8
- openstackclient/tests/unit/volume/v2/test_volume_type.py +164 -24
- openstackclient/tests/unit/volume/v3/fakes.py +91 -15
- openstackclient/tests/unit/volume/v3/test_block_storage_cleanup.py +3 -7
- openstackclient/tests/unit/volume/v3/test_block_storage_cluster.py +11 -31
- openstackclient/tests/unit/volume/v3/test_block_storage_log_level.py +6 -16
- openstackclient/tests/unit/volume/v3/test_block_storage_manage.py +219 -157
- openstackclient/tests/unit/volume/v3/test_block_storage_resource_filter.py +32 -23
- openstackclient/tests/unit/volume/v3/test_volume.py +50 -48
- openstackclient/tests/unit/volume/v3/test_volume_attachment.py +17 -47
- openstackclient/tests/unit/volume/v3/test_volume_group.py +23 -65
- openstackclient/tests/unit/volume/v3/test_volume_group_snapshot.py +88 -77
- openstackclient/tests/unit/volume/v3/test_volume_group_type.py +14 -42
- openstackclient/tests/unit/volume/v3/test_volume_message.py +10 -28
- openstackclient/volume/v1/volume.py +2 -14
- openstackclient/volume/v2/volume.py +30 -15
- openstackclient/volume/v2/volume_backend.py +10 -18
- openstackclient/volume/v2/volume_backup.py +18 -15
- openstackclient/volume/v2/volume_snapshot.py +2 -12
- openstackclient/volume/v2/volume_type.py +211 -14
- openstackclient/volume/v3/block_storage_manage.py +72 -11
- openstackclient/volume/v3/block_storage_resource_filter.py +33 -11
- openstackclient/volume/v3/volume_attachment.py +2 -14
- openstackclient/volume/v3/volume_group_snapshot.py +27 -27
- openstackclient/volume/v3/volume_message.py +2 -13
- {python_openstackclient-6.3.0.dist-info → python_openstackclient-6.5.0.dist-info}/AUTHORS +11 -0
- {python_openstackclient-6.3.0.dist-info → python_openstackclient-6.5.0.dist-info}/METADATA +6 -5
- {python_openstackclient-6.3.0.dist-info → python_openstackclient-6.5.0.dist-info}/RECORD +160 -151
- {python_openstackclient-6.3.0.dist-info → python_openstackclient-6.5.0.dist-info}/entry_points.txt +23 -5
- python_openstackclient-6.5.0.dist-info/pbr.json +1 -0
- openstackclient/tests/unit/common/test_parseractions.py +0 -233
- python_openstackclient-6.3.0.dist-info/pbr.json +0 -1
- {python_openstackclient-6.3.0.dist-info → python_openstackclient-6.5.0.dist-info}/LICENSE +0 -0
- {python_openstackclient-6.3.0.dist-info → python_openstackclient-6.5.0.dist-info}/WHEEL +0 -0
- {python_openstackclient-6.3.0.dist-info → python_openstackclient-6.5.0.dist-info}/top_level.txt +0 -0
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
import functools
|
|
18
18
|
import logging
|
|
19
19
|
|
|
20
|
+
from cinderclient import api_versions
|
|
20
21
|
from cliff import columns as cliff_columns
|
|
21
22
|
from osc_lib.cli import format_columns
|
|
22
23
|
from osc_lib.cli import parseractions
|
|
@@ -139,19 +140,61 @@ class CreateVolumeType(command.ShowOne):
|
|
|
139
140
|
'--property',
|
|
140
141
|
metavar='<key=value>',
|
|
141
142
|
action=parseractions.KeyValueAction,
|
|
143
|
+
dest='properties',
|
|
142
144
|
help=_(
|
|
143
145
|
'Set a property on this volume type '
|
|
144
146
|
'(repeat option to set multiple properties)'
|
|
145
147
|
),
|
|
146
148
|
)
|
|
149
|
+
parser.add_argument(
|
|
150
|
+
'--multiattach',
|
|
151
|
+
action='store_true',
|
|
152
|
+
default=False,
|
|
153
|
+
help=_(
|
|
154
|
+
"Enable multi-attach for this volume type "
|
|
155
|
+
"(this is an alias for '--property multiattach=<is> True') "
|
|
156
|
+
"(requires driver support)"
|
|
157
|
+
),
|
|
158
|
+
)
|
|
159
|
+
parser.add_argument(
|
|
160
|
+
'--cacheable',
|
|
161
|
+
action='store_true',
|
|
162
|
+
default=False,
|
|
163
|
+
help=_(
|
|
164
|
+
"Enable caching for this volume type "
|
|
165
|
+
"(this is an alias for '--property cacheable=<is> True') "
|
|
166
|
+
"(requires driver support)"
|
|
167
|
+
),
|
|
168
|
+
)
|
|
169
|
+
parser.add_argument(
|
|
170
|
+
'--replicated',
|
|
171
|
+
action='store_true',
|
|
172
|
+
default=False,
|
|
173
|
+
help=_(
|
|
174
|
+
"Enabled replication for this volume type "
|
|
175
|
+
"(this is an alias for '--property replication_enabled=<is> True') " # noqa: E501
|
|
176
|
+
"(requires driver support)"
|
|
177
|
+
),
|
|
178
|
+
)
|
|
179
|
+
parser.add_argument(
|
|
180
|
+
'--availability-zone',
|
|
181
|
+
action='append',
|
|
182
|
+
dest='availability_zones',
|
|
183
|
+
help=_(
|
|
184
|
+
"Set an availability zone for this volume type "
|
|
185
|
+
"(this is an alias for '--property RESKEY:availability_zones:<az>') " # noqa: E501
|
|
186
|
+
"(repeat option to set multiple availability zones)"
|
|
187
|
+
),
|
|
188
|
+
)
|
|
147
189
|
parser.add_argument(
|
|
148
190
|
'--project',
|
|
149
191
|
metavar='<project>',
|
|
150
192
|
help=_(
|
|
151
193
|
"Allow <project> to access private type (name or ID) "
|
|
152
|
-
"(
|
|
194
|
+
"(must be used with --private option)"
|
|
153
195
|
),
|
|
154
196
|
)
|
|
197
|
+
identity_common.add_project_domain_option_to_parser(parser)
|
|
155
198
|
# TODO(Huanxuan Ao): Add choices for each "--encryption-*" option.
|
|
156
199
|
parser.add_argument(
|
|
157
200
|
'--encryption-provider',
|
|
@@ -159,8 +202,8 @@ class CreateVolumeType(command.ShowOne):
|
|
|
159
202
|
help=_(
|
|
160
203
|
'Set the encryption provider format for '
|
|
161
204
|
'this volume type (e.g "luks" or "plain") (admin only) '
|
|
162
|
-
'(
|
|
163
|
-
'of a volume
|
|
205
|
+
'(this option is required when setting encryption type '
|
|
206
|
+
'of a volume; consider using other encryption options '
|
|
164
207
|
'such as: "--encryption-cipher", "--encryption-key-size" '
|
|
165
208
|
'and "--encryption-control-location")'
|
|
166
209
|
),
|
|
@@ -196,7 +239,6 @@ class CreateVolumeType(command.ShowOne):
|
|
|
196
239
|
'"--encryption-provider")'
|
|
197
240
|
),
|
|
198
241
|
)
|
|
199
|
-
identity_common.add_project_domain_option_to_parser(parser)
|
|
200
242
|
return parser
|
|
201
243
|
|
|
202
244
|
def take_action(self, parsed_args):
|
|
@@ -208,11 +250,14 @@ class CreateVolumeType(command.ShowOne):
|
|
|
208
250
|
raise exceptions.CommandError(msg)
|
|
209
251
|
|
|
210
252
|
kwargs = {}
|
|
253
|
+
|
|
211
254
|
if parsed_args.is_public is not None:
|
|
212
255
|
kwargs['is_public'] = parsed_args.is_public
|
|
213
256
|
|
|
214
257
|
volume_type = volume_client.volume_types.create(
|
|
215
|
-
parsed_args.name,
|
|
258
|
+
parsed_args.name,
|
|
259
|
+
description=parsed_args.description,
|
|
260
|
+
**kwargs,
|
|
216
261
|
)
|
|
217
262
|
volume_type._info.pop('extra_specs')
|
|
218
263
|
|
|
@@ -232,11 +277,26 @@ class CreateVolumeType(command.ShowOne):
|
|
|
232
277
|
"type: %(e)s"
|
|
233
278
|
)
|
|
234
279
|
LOG.error(msg % {'project': parsed_args.project, 'e': e})
|
|
235
|
-
|
|
236
|
-
|
|
280
|
+
|
|
281
|
+
properties = {}
|
|
282
|
+
if parsed_args.properties:
|
|
283
|
+
properties.update(parsed_args.properties)
|
|
284
|
+
if parsed_args.multiattach:
|
|
285
|
+
properties['multiattach'] = '<is> True'
|
|
286
|
+
if parsed_args.cacheable:
|
|
287
|
+
properties['cacheable'] = '<is> True'
|
|
288
|
+
if parsed_args.replicated:
|
|
289
|
+
properties['replication_enabled'] = '<is> True'
|
|
290
|
+
if parsed_args.availability_zones:
|
|
291
|
+
properties['RESKEY:availability_zones'] = ','.join(
|
|
292
|
+
parsed_args.availability_zones
|
|
293
|
+
)
|
|
294
|
+
if properties:
|
|
295
|
+
result = volume_type.set_keys(properties)
|
|
237
296
|
volume_type._info.update(
|
|
238
297
|
{'properties': format_columns.DictColumn(result)}
|
|
239
298
|
)
|
|
299
|
+
|
|
240
300
|
if (
|
|
241
301
|
parsed_args.encryption_provider
|
|
242
302
|
or parsed_args.encryption_cipher
|
|
@@ -261,6 +321,7 @@ class CreateVolumeType(command.ShowOne):
|
|
|
261
321
|
volume_type._info.update(
|
|
262
322
|
{'encryption': format_columns.DictColumn(encryption._info)}
|
|
263
323
|
)
|
|
324
|
+
|
|
264
325
|
volume_type._info.pop("os-volume-type-access:is_public", None)
|
|
265
326
|
|
|
266
327
|
return zip(*sorted(volume_type._info.items()))
|
|
@@ -348,6 +409,59 @@ class ListVolumeType(command.Lister):
|
|
|
348
409
|
"(admin only)"
|
|
349
410
|
),
|
|
350
411
|
)
|
|
412
|
+
parser.add_argument(
|
|
413
|
+
'--property',
|
|
414
|
+
metavar='<key=value>',
|
|
415
|
+
action=parseractions.KeyValueAction,
|
|
416
|
+
dest='properties',
|
|
417
|
+
help=_(
|
|
418
|
+
'Filter by a property on the volume types '
|
|
419
|
+
'(repeat option to filter by multiple properties) '
|
|
420
|
+
'(admin only except for user-visible extra specs) '
|
|
421
|
+
'(supported by --os-volume-api-version 3.52 or above)'
|
|
422
|
+
),
|
|
423
|
+
)
|
|
424
|
+
parser.add_argument(
|
|
425
|
+
'--multiattach',
|
|
426
|
+
action='store_true',
|
|
427
|
+
default=False,
|
|
428
|
+
help=_(
|
|
429
|
+
"List only volume types with multi-attach enabled "
|
|
430
|
+
"(this is an alias for '--property multiattach=<is> True') "
|
|
431
|
+
"(supported by --os-volume-api-version 3.52 or above)"
|
|
432
|
+
),
|
|
433
|
+
)
|
|
434
|
+
parser.add_argument(
|
|
435
|
+
'--cacheable',
|
|
436
|
+
action='store_true',
|
|
437
|
+
default=False,
|
|
438
|
+
help=_(
|
|
439
|
+
"List only volume types with caching enabled "
|
|
440
|
+
"(this is an alias for '--property cacheable=<is> True') "
|
|
441
|
+
"(admin only) "
|
|
442
|
+
"(supported by --os-volume-api-version 3.52 or above)"
|
|
443
|
+
),
|
|
444
|
+
)
|
|
445
|
+
parser.add_argument(
|
|
446
|
+
'--replicated',
|
|
447
|
+
action='store_true',
|
|
448
|
+
default=False,
|
|
449
|
+
help=_(
|
|
450
|
+
"List only volume types with replication enabled "
|
|
451
|
+
"(this is an alias for '--property replication_enabled=<is> True') " # noqa: E501
|
|
452
|
+
"(supported by --os-volume-api-version 3.52 or above)"
|
|
453
|
+
),
|
|
454
|
+
)
|
|
455
|
+
parser.add_argument(
|
|
456
|
+
'--availability-zone',
|
|
457
|
+
action='append',
|
|
458
|
+
dest='availability_zones',
|
|
459
|
+
help=_(
|
|
460
|
+
"List only volume types with this availability configured "
|
|
461
|
+
"(this is an alias for '--property RESKEY:availability_zones:<az>') " # noqa: E501
|
|
462
|
+
"(repeat option to filter on multiple availability zones)"
|
|
463
|
+
),
|
|
464
|
+
)
|
|
351
465
|
return parser
|
|
352
466
|
|
|
353
467
|
def take_action(self, parsed_args):
|
|
@@ -375,8 +489,34 @@ class ListVolumeType(command.Lister):
|
|
|
375
489
|
if parsed_args.default:
|
|
376
490
|
data = [volume_client.volume_types.default()]
|
|
377
491
|
else:
|
|
492
|
+
search_opts = {}
|
|
493
|
+
properties = {}
|
|
494
|
+
if parsed_args.properties:
|
|
495
|
+
properties.update(parsed_args.properties)
|
|
496
|
+
if parsed_args.multiattach:
|
|
497
|
+
properties['multiattach'] = '<is> True'
|
|
498
|
+
if parsed_args.cacheable:
|
|
499
|
+
properties['cacheable'] = '<is> True'
|
|
500
|
+
if parsed_args.replicated:
|
|
501
|
+
properties['replication_enabled'] = '<is> True'
|
|
502
|
+
if parsed_args.availability_zones:
|
|
503
|
+
properties['RESKEY:availability_zones'] = ','.join(
|
|
504
|
+
parsed_args.availability_zones
|
|
505
|
+
)
|
|
506
|
+
if properties:
|
|
507
|
+
if volume_client.api_version < api_versions.APIVersion('3.52'):
|
|
508
|
+
msg = _(
|
|
509
|
+
"--os-volume-api-version 3.52 or greater is required "
|
|
510
|
+
"to use the '--property' option or any of the alias "
|
|
511
|
+
"options"
|
|
512
|
+
)
|
|
513
|
+
raise exceptions.CommandError(msg)
|
|
514
|
+
|
|
515
|
+
search_opts['extra_specs'] = properties
|
|
516
|
+
|
|
378
517
|
data = volume_client.volume_types.list(
|
|
379
|
-
|
|
518
|
+
search_opts=search_opts,
|
|
519
|
+
is_public=parsed_args.is_public,
|
|
380
520
|
)
|
|
381
521
|
|
|
382
522
|
formatters = {'Extra Specs': format_columns.DictColumn}
|
|
@@ -445,11 +585,52 @@ class SetVolumeType(command.Command):
|
|
|
445
585
|
'--property',
|
|
446
586
|
metavar='<key=value>',
|
|
447
587
|
action=parseractions.KeyValueAction,
|
|
588
|
+
dest='properties',
|
|
448
589
|
help=_(
|
|
449
590
|
'Set a property on this volume type '
|
|
450
591
|
'(repeat option to set multiple properties)'
|
|
451
592
|
),
|
|
452
593
|
)
|
|
594
|
+
parser.add_argument(
|
|
595
|
+
'--multiattach',
|
|
596
|
+
action='store_true',
|
|
597
|
+
default=False,
|
|
598
|
+
help=_(
|
|
599
|
+
"Enable multi-attach for this volume type "
|
|
600
|
+
"(this is an alias for '--property multiattach=<is> True') "
|
|
601
|
+
"(requires driver support)"
|
|
602
|
+
),
|
|
603
|
+
)
|
|
604
|
+
parser.add_argument(
|
|
605
|
+
'--cacheable',
|
|
606
|
+
action='store_true',
|
|
607
|
+
default=False,
|
|
608
|
+
help=_(
|
|
609
|
+
"Enable caching for this volume type "
|
|
610
|
+
"(this is an alias for '--property cacheable=<is> True') "
|
|
611
|
+
"(requires driver support)"
|
|
612
|
+
),
|
|
613
|
+
)
|
|
614
|
+
parser.add_argument(
|
|
615
|
+
'--replicated',
|
|
616
|
+
action='store_true',
|
|
617
|
+
default=False,
|
|
618
|
+
help=_(
|
|
619
|
+
"Enabled replication for this volume type "
|
|
620
|
+
"(this is an alias for '--property replication_enabled=<is> True') " # noqa: E501
|
|
621
|
+
"(requires driver support)"
|
|
622
|
+
),
|
|
623
|
+
)
|
|
624
|
+
parser.add_argument(
|
|
625
|
+
'--availability-zone',
|
|
626
|
+
action='append',
|
|
627
|
+
dest='availability_zones',
|
|
628
|
+
help=_(
|
|
629
|
+
"Set an availability zone for this volume type "
|
|
630
|
+
"(this is an alias for '--property RESKEY:availability_zones:<az>') " # noqa: E501
|
|
631
|
+
"(repeat option to set multiple availability zones)"
|
|
632
|
+
),
|
|
633
|
+
)
|
|
453
634
|
parser.add_argument(
|
|
454
635
|
'--project',
|
|
455
636
|
metavar='<project>',
|
|
@@ -555,11 +736,26 @@ class SetVolumeType(command.Command):
|
|
|
555
736
|
)
|
|
556
737
|
result += 1
|
|
557
738
|
|
|
558
|
-
|
|
739
|
+
properties = {}
|
|
740
|
+
|
|
741
|
+
properties = {}
|
|
742
|
+
if parsed_args.properties:
|
|
743
|
+
properties.update(parsed_args.properties)
|
|
744
|
+
if parsed_args.multiattach:
|
|
745
|
+
properties['multiattach'] = '<is> True'
|
|
746
|
+
if parsed_args.cacheable:
|
|
747
|
+
properties['cacheable'] = '<is> True'
|
|
748
|
+
if parsed_args.replicated:
|
|
749
|
+
properties['replication_enabled'] = '<is> True'
|
|
750
|
+
if parsed_args.availability_zones:
|
|
751
|
+
properties['RESKEY:availability_zones'] = ','.join(
|
|
752
|
+
parsed_args.availability_zones
|
|
753
|
+
)
|
|
754
|
+
if properties:
|
|
559
755
|
try:
|
|
560
|
-
volume_type.set_keys(
|
|
756
|
+
volume_type.set_keys(properties)
|
|
561
757
|
except Exception as e:
|
|
562
|
-
LOG.error(_("Failed to set volume type
|
|
758
|
+
LOG.error(_("Failed to set volume type properties: %s"), e)
|
|
563
759
|
result += 1
|
|
564
760
|
|
|
565
761
|
if parsed_args.project:
|
|
@@ -689,6 +885,7 @@ class UnsetVolumeType(command.Command):
|
|
|
689
885
|
'--property',
|
|
690
886
|
metavar='<key>',
|
|
691
887
|
action='append',
|
|
888
|
+
dest='properties',
|
|
692
889
|
help=_(
|
|
693
890
|
'Remove a property from this volume type '
|
|
694
891
|
'(repeat option to remove multiple properties)'
|
|
@@ -723,11 +920,11 @@ class UnsetVolumeType(command.Command):
|
|
|
723
920
|
)
|
|
724
921
|
|
|
725
922
|
result = 0
|
|
726
|
-
if parsed_args.
|
|
923
|
+
if parsed_args.properties:
|
|
727
924
|
try:
|
|
728
|
-
volume_type.unset_keys(parsed_args.
|
|
925
|
+
volume_type.unset_keys(parsed_args.properties)
|
|
729
926
|
except Exception as e:
|
|
730
|
-
LOG.error(_("Failed to unset volume type
|
|
927
|
+
LOG.error(_("Failed to unset volume type properties: %s"), e)
|
|
731
928
|
result += 1
|
|
732
929
|
|
|
733
930
|
if parsed_args.project:
|
|
@@ -13,11 +13,12 @@
|
|
|
13
13
|
|
|
14
14
|
"""Block Storage Volume/Snapshot Management implementations"""
|
|
15
15
|
|
|
16
|
+
import argparse
|
|
17
|
+
|
|
16
18
|
from cinderclient import api_versions
|
|
17
19
|
from osc_lib.command import command
|
|
18
20
|
from osc_lib import exceptions
|
|
19
21
|
from osc_lib import utils
|
|
20
|
-
from oslo_utils import strutils
|
|
21
22
|
|
|
22
23
|
from openstackclient.i18n import _
|
|
23
24
|
|
|
@@ -52,11 +53,18 @@ class BlockStorageManageVolumes(command.Lister):
|
|
|
52
53
|
'(supported by --os-volume-api-version 3.17 or later)'
|
|
53
54
|
),
|
|
54
55
|
)
|
|
56
|
+
parser.add_argument(
|
|
57
|
+
'--long',
|
|
58
|
+
action='store_true',
|
|
59
|
+
default=False,
|
|
60
|
+
help=_('List additional fields in output'),
|
|
61
|
+
)
|
|
62
|
+
# TODO(stephenfin): Remove this in a future major version bump
|
|
55
63
|
parser.add_argument(
|
|
56
64
|
'--detailed',
|
|
57
65
|
metavar='<detailed>',
|
|
58
|
-
default=
|
|
59
|
-
help=
|
|
66
|
+
default=None,
|
|
67
|
+
help=argparse.SUPPRESS,
|
|
60
68
|
)
|
|
61
69
|
parser.add_argument(
|
|
62
70
|
'--marker',
|
|
@@ -121,8 +129,30 @@ class BlockStorageManageVolumes(command.Lister):
|
|
|
121
129
|
)
|
|
122
130
|
raise exceptions.CommandError(msg)
|
|
123
131
|
|
|
124
|
-
detailed =
|
|
125
|
-
|
|
132
|
+
detailed = parsed_args.long
|
|
133
|
+
if parsed_args.detailed is not None:
|
|
134
|
+
detailed = parsed_args.detailed.lower().strip() in {
|
|
135
|
+
'1',
|
|
136
|
+
't',
|
|
137
|
+
'true',
|
|
138
|
+
'on',
|
|
139
|
+
'y',
|
|
140
|
+
'yes',
|
|
141
|
+
}
|
|
142
|
+
if detailed:
|
|
143
|
+
# if the user requested e.g. '--detailed true' then they should
|
|
144
|
+
# not request '--long'
|
|
145
|
+
msg = _(
|
|
146
|
+
"The --detailed option has been deprecated. "
|
|
147
|
+
"Use --long instead."
|
|
148
|
+
)
|
|
149
|
+
self.log.warning(msg)
|
|
150
|
+
else:
|
|
151
|
+
# if the user requested e.g. '--detailed false' then they
|
|
152
|
+
# should simply stop requesting this since the default has
|
|
153
|
+
# changed
|
|
154
|
+
msg = _("The --detailed option has been deprecated. Unset it.")
|
|
155
|
+
self.log.warning(msg)
|
|
126
156
|
|
|
127
157
|
columns = [
|
|
128
158
|
'reference',
|
|
@@ -145,7 +175,7 @@ class BlockStorageManageVolumes(command.Lister):
|
|
|
145
175
|
limit=parsed_args.limit,
|
|
146
176
|
offset=parsed_args.offset,
|
|
147
177
|
sort=parsed_args.sort,
|
|
148
|
-
cluster=cluster,
|
|
178
|
+
cluster=parsed_args.cluster,
|
|
149
179
|
)
|
|
150
180
|
|
|
151
181
|
return (
|
|
@@ -187,11 +217,18 @@ class BlockStorageManageSnapshots(command.Lister):
|
|
|
187
217
|
'(supported by --os-volume-api-version 3.17 or later)'
|
|
188
218
|
),
|
|
189
219
|
)
|
|
220
|
+
parser.add_argument(
|
|
221
|
+
'--long',
|
|
222
|
+
action='store_true',
|
|
223
|
+
default=False,
|
|
224
|
+
help=_('List additional fields in output'),
|
|
225
|
+
)
|
|
226
|
+
# TODO(stephenfin): Remove this in a future major version bump
|
|
190
227
|
parser.add_argument(
|
|
191
228
|
'--detailed',
|
|
192
229
|
metavar='<detailed>',
|
|
193
|
-
default=
|
|
194
|
-
help=
|
|
230
|
+
default=None,
|
|
231
|
+
help=argparse.SUPPRESS,
|
|
195
232
|
)
|
|
196
233
|
parser.add_argument(
|
|
197
234
|
'--marker',
|
|
@@ -258,8 +295,32 @@ class BlockStorageManageSnapshots(command.Lister):
|
|
|
258
295
|
)
|
|
259
296
|
raise exceptions.CommandError(msg)
|
|
260
297
|
|
|
261
|
-
detailed =
|
|
262
|
-
|
|
298
|
+
detailed = parsed_args.long
|
|
299
|
+
if parsed_args.detailed is not None:
|
|
300
|
+
detailed = parsed_args.detailed.lower().strip() in {
|
|
301
|
+
'1',
|
|
302
|
+
't',
|
|
303
|
+
'true',
|
|
304
|
+
'on',
|
|
305
|
+
'y',
|
|
306
|
+
'yes',
|
|
307
|
+
}
|
|
308
|
+
if detailed:
|
|
309
|
+
# if the user requested e.g. '--detailed true' then they should
|
|
310
|
+
# not request '--long'
|
|
311
|
+
msg = _(
|
|
312
|
+
"The --detailed option has been deprecated. "
|
|
313
|
+
"Use --long instead."
|
|
314
|
+
)
|
|
315
|
+
self.log.warning(msg)
|
|
316
|
+
else:
|
|
317
|
+
# if the user requested e.g. '--detailed false' then they
|
|
318
|
+
# should simply stop requesting this since the default has
|
|
319
|
+
# changed
|
|
320
|
+
msg = _(
|
|
321
|
+
"The --detailed option has been deprecated. " "Unset it."
|
|
322
|
+
)
|
|
323
|
+
self.log.warning(msg)
|
|
263
324
|
|
|
264
325
|
columns = [
|
|
265
326
|
'reference',
|
|
@@ -283,7 +344,7 @@ class BlockStorageManageSnapshots(command.Lister):
|
|
|
283
344
|
limit=parsed_args.limit,
|
|
284
345
|
offset=parsed_args.offset,
|
|
285
346
|
sort=parsed_args.sort,
|
|
286
|
-
cluster=cluster,
|
|
347
|
+
cluster=parsed_args.cluster,
|
|
287
348
|
)
|
|
288
349
|
|
|
289
350
|
return (
|
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
|
|
13
13
|
"""Volume V3 Resource Filters implementations"""
|
|
14
14
|
|
|
15
|
-
from
|
|
15
|
+
from openstack import utils as sdk_utils
|
|
16
|
+
from osc_lib.cli import format_columns
|
|
16
17
|
from osc_lib.command import command
|
|
17
18
|
from osc_lib import exceptions
|
|
18
19
|
from osc_lib import utils
|
|
@@ -24,9 +25,9 @@ class ListBlockStorageResourceFilter(command.Lister):
|
|
|
24
25
|
_description = _('List block storage resource filters')
|
|
25
26
|
|
|
26
27
|
def take_action(self, parsed_args):
|
|
27
|
-
volume_client = self.app.client_manager.volume
|
|
28
|
+
volume_client = self.app.client_manager.sdk_connection.volume
|
|
28
29
|
|
|
29
|
-
if
|
|
30
|
+
if not sdk_utils.supports_microversion(volume_client, '3.33'):
|
|
30
31
|
msg = _(
|
|
31
32
|
"--os-volume-api-version 3.33 or greater is required to "
|
|
32
33
|
"support the 'block storage resource filter list' command"
|
|
@@ -37,12 +38,20 @@ class ListBlockStorageResourceFilter(command.Lister):
|
|
|
37
38
|
'Resource',
|
|
38
39
|
'Filters',
|
|
39
40
|
)
|
|
41
|
+
columns = (
|
|
42
|
+
'resource',
|
|
43
|
+
'filters',
|
|
44
|
+
)
|
|
40
45
|
|
|
41
|
-
data = volume_client.resource_filters
|
|
46
|
+
data = volume_client.resource_filters()
|
|
47
|
+
formatters = {'filters': format_columns.ListColumn}
|
|
42
48
|
|
|
43
49
|
return (
|
|
44
50
|
column_headers,
|
|
45
|
-
(
|
|
51
|
+
(
|
|
52
|
+
utils.get_item_properties(s, columns, formatters=formatters)
|
|
53
|
+
for s in data
|
|
54
|
+
),
|
|
46
55
|
)
|
|
47
56
|
|
|
48
57
|
|
|
@@ -60,18 +69,16 @@ class ShowBlockStorageResourceFilter(command.ShowOne):
|
|
|
60
69
|
return parser
|
|
61
70
|
|
|
62
71
|
def take_action(self, parsed_args):
|
|
63
|
-
volume_client = self.app.client_manager.volume
|
|
72
|
+
volume_client = self.app.client_manager.sdk_connection.volume
|
|
64
73
|
|
|
65
|
-
if
|
|
74
|
+
if not sdk_utils.supports_microversion(volume_client, '3.33'):
|
|
66
75
|
msg = _(
|
|
67
76
|
"--os-volume-api-version 3.33 or greater is required to "
|
|
68
77
|
"support the 'block storage resource filter show' command"
|
|
69
78
|
)
|
|
70
79
|
raise exceptions.CommandError(msg)
|
|
71
80
|
|
|
72
|
-
data = volume_client.resource_filters.
|
|
73
|
-
resource=parsed_args.resource
|
|
74
|
-
)
|
|
81
|
+
data = volume_client.resource_filters(resource=parsed_args.resource)
|
|
75
82
|
if not data:
|
|
76
83
|
msg = _(
|
|
77
84
|
"No resource filter with a name of {parsed_args.resource}' "
|
|
@@ -80,4 +87,19 @@ class ShowBlockStorageResourceFilter(command.ShowOne):
|
|
|
80
87
|
raise exceptions.CommandError(msg)
|
|
81
88
|
resource_filter = next(data)
|
|
82
89
|
|
|
83
|
-
|
|
90
|
+
column_headers = (
|
|
91
|
+
'Resource',
|
|
92
|
+
'Filters',
|
|
93
|
+
)
|
|
94
|
+
columns = (
|
|
95
|
+
'resource',
|
|
96
|
+
'filters',
|
|
97
|
+
)
|
|
98
|
+
formatters = {'filters': format_columns.ListColumn}
|
|
99
|
+
|
|
100
|
+
return (
|
|
101
|
+
column_headers,
|
|
102
|
+
utils.get_dict_properties(
|
|
103
|
+
resource_filter, columns, formatters=formatters
|
|
104
|
+
),
|
|
105
|
+
)
|
|
@@ -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 pagination
|
|
21
22
|
from openstackclient.i18n import _
|
|
22
23
|
from openstackclient.identity import common as identity_common
|
|
23
24
|
|
|
@@ -410,20 +411,7 @@ class ListVolumeAttachment(command.Lister):
|
|
|
410
411
|
metavar='<status>',
|
|
411
412
|
help=_('Filters results by a status. ') + _FILTER_DEPRECATED,
|
|
412
413
|
)
|
|
413
|
-
|
|
414
|
-
'--marker',
|
|
415
|
-
metavar='<marker>',
|
|
416
|
-
help=_(
|
|
417
|
-
'Begin returning volume attachments that appear later in '
|
|
418
|
-
'volume attachment list than that represented by this ID.'
|
|
419
|
-
),
|
|
420
|
-
)
|
|
421
|
-
parser.add_argument(
|
|
422
|
-
'--limit',
|
|
423
|
-
type=int,
|
|
424
|
-
metavar='<limit>',
|
|
425
|
-
help=_('Maximum number of volume attachments to return.'),
|
|
426
|
-
)
|
|
414
|
+
pagination.add_marker_pagination_option_to_parser(parser)
|
|
427
415
|
# TODO(stephenfin): Add once we have an equivalent command for
|
|
428
416
|
# 'cinder list-filters'
|
|
429
417
|
# parser.add_argument(
|