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.
Files changed (162) hide show
  1. openstackclient/common/availability_zone.py +4 -4
  2. openstackclient/common/pagination.py +82 -0
  3. openstackclient/compute/v2/flavor.py +2 -16
  4. openstackclient/compute/v2/hypervisor.py +2 -21
  5. openstackclient/compute/v2/keypair.py +2 -9
  6. openstackclient/compute/v2/server.py +220 -131
  7. openstackclient/compute/v2/server_event.py +30 -19
  8. openstackclient/compute/v2/server_group.py +2 -23
  9. openstackclient/compute/v2/server_migration.py +2 -22
  10. openstackclient/compute/v2/usage.py +4 -6
  11. openstackclient/identity/v3/mapping.py +25 -3
  12. openstackclient/identity/v3/policy.py +3 -1
  13. openstackclient/image/v2/cache.py +218 -0
  14. openstackclient/image/v2/image.py +40 -17
  15. openstackclient/image/v2/metadef_namespaces.py +25 -21
  16. openstackclient/image/v2/metadef_objects.py +189 -0
  17. openstackclient/image/v2/metadef_properties.py +284 -0
  18. openstackclient/network/utils.py +100 -0
  19. openstackclient/network/v2/default_security_group_rule.py +418 -0
  20. openstackclient/network/v2/local_ip_association.py +1 -1
  21. openstackclient/network/v2/ndp_proxy.py +7 -3
  22. openstackclient/network/v2/network.py +2 -2
  23. openstackclient/network/v2/port.py +65 -19
  24. openstackclient/network/v2/security_group_rule.py +18 -111
  25. openstackclient/network/v2/subnet.py +1 -0
  26. openstackclient/object/v1/container.py +2 -12
  27. openstackclient/object/v1/object.py +2 -11
  28. openstackclient/tests/functional/base.py +13 -6
  29. openstackclient/tests/functional/identity/v3/test_role.py +11 -3
  30. openstackclient/tests/functional/network/v2/common.py +7 -1
  31. openstackclient/tests/functional/network/v2/test_address_group.py +2 -4
  32. openstackclient/tests/functional/network/v2/test_address_scope.py +0 -6
  33. openstackclient/tests/functional/network/v2/test_default_security_group_rule.py +67 -0
  34. openstackclient/tests/functional/network/v2/test_floating_ip.py +3 -6
  35. openstackclient/tests/functional/network/v2/test_ip_availability.py +3 -8
  36. openstackclient/tests/functional/network/v2/test_l3_conntrack_helper.py +3 -4
  37. openstackclient/tests/functional/network/v2/test_local_ip.py +2 -4
  38. openstackclient/tests/functional/network/v2/test_network.py +18 -17
  39. openstackclient/tests/functional/network/v2/test_network_agent.py +24 -21
  40. openstackclient/tests/functional/network/v2/test_network_flavor.py +0 -6
  41. openstackclient/tests/functional/network/v2/test_network_flavor_profile.py +0 -6
  42. openstackclient/tests/functional/network/v2/test_network_meter.py +6 -6
  43. openstackclient/tests/functional/network/v2/test_network_meter_rule.py +7 -8
  44. openstackclient/tests/functional/network/v2/test_network_ndp_proxy.py +1 -3
  45. openstackclient/tests/functional/network/v2/test_network_qos_policy.py +4 -4
  46. openstackclient/tests/functional/network/v2/test_network_qos_rule.py +16 -20
  47. openstackclient/tests/functional/network/v2/test_network_qos_rule_type.py +4 -4
  48. openstackclient/tests/functional/network/v2/test_network_rbac.py +1 -4
  49. openstackclient/tests/functional/network/v2/test_network_segment.py +7 -12
  50. openstackclient/tests/functional/network/v2/test_network_segment_range.py +3 -4
  51. openstackclient/tests/functional/network/v2/test_network_service_provider.py +2 -4
  52. openstackclient/tests/functional/network/v2/test_network_trunk.py +3 -3
  53. openstackclient/tests/functional/network/v2/test_port.py +2 -8
  54. openstackclient/tests/functional/network/v2/test_router.py +0 -6
  55. openstackclient/tests/functional/network/v2/test_security_group.py +1 -4
  56. openstackclient/tests/functional/network/v2/test_security_group_rule.py +1 -4
  57. openstackclient/tests/functional/network/v2/test_subnet.py +4 -22
  58. openstackclient/tests/functional/network/v2/test_subnet_pool.py +0 -6
  59. openstackclient/tests/unit/common/test_availability_zone.py +28 -30
  60. openstackclient/tests/unit/common/test_extension.py +1 -4
  61. openstackclient/tests/unit/common/test_limits.py +2 -4
  62. openstackclient/tests/unit/common/test_project_cleanup.py +3 -10
  63. openstackclient/tests/unit/common/test_quota.py +18 -24
  64. openstackclient/tests/unit/compute/v2/fakes.py +24 -11
  65. openstackclient/tests/unit/compute/v2/test_agent.py +1 -1
  66. openstackclient/tests/unit/compute/v2/test_aggregate.py +62 -72
  67. openstackclient/tests/unit/compute/v2/test_console.py +18 -30
  68. openstackclient/tests/unit/compute/v2/test_flavor.py +85 -89
  69. openstackclient/tests/unit/compute/v2/test_host.py +12 -19
  70. openstackclient/tests/unit/compute/v2/test_hypervisor.py +23 -25
  71. openstackclient/tests/unit/compute/v2/test_hypervisor_stats.py +2 -6
  72. openstackclient/tests/unit/compute/v2/test_keypair.py +25 -39
  73. openstackclient/tests/unit/compute/v2/test_server.py +316 -365
  74. openstackclient/tests/unit/compute/v2/test_server_backup.py +5 -17
  75. openstackclient/tests/unit/compute/v2/test_server_event.py +23 -25
  76. openstackclient/tests/unit/compute/v2/test_server_group.py +41 -33
  77. openstackclient/tests/unit/compute/v2/test_server_image.py +6 -18
  78. openstackclient/tests/unit/compute/v2/test_server_migration.py +45 -45
  79. openstackclient/tests/unit/compute/v2/test_server_volume.py +15 -31
  80. openstackclient/tests/unit/compute/v2/test_service.py +51 -56
  81. openstackclient/tests/unit/compute/v2/test_usage.py +10 -13
  82. openstackclient/tests/unit/fakes.py +4 -0
  83. openstackclient/tests/unit/identity/v3/test_mappings.py +9 -4
  84. openstackclient/tests/unit/identity/v3/test_trust.py +0 -2
  85. openstackclient/tests/unit/image/v1/fakes.py +2 -1
  86. openstackclient/tests/unit/image/v1/test_image.py +1 -1
  87. openstackclient/tests/unit/image/v2/fakes.py +82 -0
  88. openstackclient/tests/unit/image/v2/test_cache.py +214 -0
  89. openstackclient/tests/unit/image/v2/test_image.py +62 -4
  90. openstackclient/tests/unit/image/v2/test_metadef_namespaces.py +5 -19
  91. openstackclient/tests/unit/image/v2/test_metadef_objects.py +162 -0
  92. openstackclient/tests/unit/image/v2/test_metadef_properties.py +227 -0
  93. openstackclient/tests/unit/integ/cli/test_shell.py +0 -2
  94. openstackclient/tests/unit/network/test_common.py +3 -3
  95. openstackclient/tests/unit/network/v2/fakes.py +1 -0
  96. openstackclient/tests/unit/network/v2/test_default_security_group_rule.py +1133 -0
  97. openstackclient/tests/unit/network/v2/test_floating_ip_compute.py +5 -13
  98. openstackclient/tests/unit/network/v2/test_floating_ip_pool_compute.py +1 -9
  99. openstackclient/tests/unit/network/v2/test_network.py +33 -0
  100. openstackclient/tests/unit/network/v2/test_network_compute.py +5 -11
  101. openstackclient/tests/unit/network/v2/test_network_trunk.py +6 -8
  102. openstackclient/tests/unit/network/v2/test_port.py +83 -38
  103. openstackclient/tests/unit/network/v2/test_security_group_compute.py +7 -15
  104. openstackclient/tests/unit/network/v2/test_security_group_rule_compute.py +19 -27
  105. openstackclient/tests/unit/network/v2/test_security_group_rule_network.py +3 -6
  106. openstackclient/tests/unit/network/v2/test_subnet.py +92 -0
  107. openstackclient/tests/unit/network/v2/test_subnet_pool.py +11 -13
  108. openstackclient/tests/unit/test_shell.py +1 -7
  109. openstackclient/tests/unit/utils.py +10 -4
  110. openstackclient/tests/unit/volume/v1/fakes.py +7 -1
  111. openstackclient/tests/unit/volume/v1/test_qos_specs.py +2 -2
  112. openstackclient/tests/unit/volume/v1/test_service.py +1 -1
  113. openstackclient/tests/unit/volume/v1/test_transfer_request.py +2 -2
  114. openstackclient/tests/unit/volume/v1/test_type.py +2 -4
  115. openstackclient/tests/unit/volume/v1/test_volume.py +5 -7
  116. openstackclient/tests/unit/volume/v1/test_volume_backup.py +4 -4
  117. openstackclient/tests/unit/volume/v2/fakes.py +32 -12
  118. openstackclient/tests/unit/volume/v2/test_backup_record.py +1 -1
  119. openstackclient/tests/unit/volume/v2/test_consistency_group.py +4 -6
  120. openstackclient/tests/unit/volume/v2/test_consistency_group_snapshot.py +2 -4
  121. openstackclient/tests/unit/volume/v2/test_qos_specs.py +2 -2
  122. openstackclient/tests/unit/volume/v2/test_service.py +1 -1
  123. openstackclient/tests/unit/volume/v2/test_volume.py +78 -16
  124. openstackclient/tests/unit/volume/v2/test_volume_backend.py +10 -22
  125. openstackclient/tests/unit/volume/v2/test_volume_backup.py +76 -89
  126. openstackclient/tests/unit/volume/v2/test_volume_host.py +1 -1
  127. openstackclient/tests/unit/volume/v2/test_volume_snapshot.py +5 -7
  128. openstackclient/tests/unit/volume/v2/test_volume_transfer_request.py +4 -8
  129. openstackclient/tests/unit/volume/v2/test_volume_type.py +164 -24
  130. openstackclient/tests/unit/volume/v3/fakes.py +91 -15
  131. openstackclient/tests/unit/volume/v3/test_block_storage_cleanup.py +3 -7
  132. openstackclient/tests/unit/volume/v3/test_block_storage_cluster.py +11 -31
  133. openstackclient/tests/unit/volume/v3/test_block_storage_log_level.py +6 -16
  134. openstackclient/tests/unit/volume/v3/test_block_storage_manage.py +219 -157
  135. openstackclient/tests/unit/volume/v3/test_block_storage_resource_filter.py +32 -23
  136. openstackclient/tests/unit/volume/v3/test_volume.py +50 -48
  137. openstackclient/tests/unit/volume/v3/test_volume_attachment.py +17 -47
  138. openstackclient/tests/unit/volume/v3/test_volume_group.py +23 -65
  139. openstackclient/tests/unit/volume/v3/test_volume_group_snapshot.py +88 -77
  140. openstackclient/tests/unit/volume/v3/test_volume_group_type.py +14 -42
  141. openstackclient/tests/unit/volume/v3/test_volume_message.py +10 -28
  142. openstackclient/volume/v1/volume.py +2 -14
  143. openstackclient/volume/v2/volume.py +30 -15
  144. openstackclient/volume/v2/volume_backend.py +10 -18
  145. openstackclient/volume/v2/volume_backup.py +18 -15
  146. openstackclient/volume/v2/volume_snapshot.py +2 -12
  147. openstackclient/volume/v2/volume_type.py +211 -14
  148. openstackclient/volume/v3/block_storage_manage.py +72 -11
  149. openstackclient/volume/v3/block_storage_resource_filter.py +33 -11
  150. openstackclient/volume/v3/volume_attachment.py +2 -14
  151. openstackclient/volume/v3/volume_group_snapshot.py +27 -27
  152. openstackclient/volume/v3/volume_message.py +2 -13
  153. {python_openstackclient-6.3.0.dist-info → python_openstackclient-6.5.0.dist-info}/AUTHORS +11 -0
  154. {python_openstackclient-6.3.0.dist-info → python_openstackclient-6.5.0.dist-info}/METADATA +6 -5
  155. {python_openstackclient-6.3.0.dist-info → python_openstackclient-6.5.0.dist-info}/RECORD +160 -151
  156. {python_openstackclient-6.3.0.dist-info → python_openstackclient-6.5.0.dist-info}/entry_points.txt +23 -5
  157. python_openstackclient-6.5.0.dist-info/pbr.json +1 -0
  158. openstackclient/tests/unit/common/test_parseractions.py +0 -233
  159. python_openstackclient-6.3.0.dist-info/pbr.json +0 -1
  160. {python_openstackclient-6.3.0.dist-info → python_openstackclient-6.5.0.dist-info}/LICENSE +0 -0
  161. {python_openstackclient-6.3.0.dist-info → python_openstackclient-6.5.0.dist-info}/WHEEL +0 -0
  162. {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
- "(Must be used with --private option)"
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
- '(This option is required when setting encryption type '
163
- 'of a volume. Consider using other encryption options '
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, description=parsed_args.description, **kwargs
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
- if parsed_args.property:
236
- result = volume_type.set_keys(parsed_args.property)
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
- is_public=parsed_args.is_public
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
- if parsed_args.property:
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(parsed_args.property)
756
+ volume_type.set_keys(properties)
561
757
  except Exception as e:
562
- LOG.error(_("Failed to set volume type property: %s"), e)
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.property:
923
+ if parsed_args.properties:
727
924
  try:
728
- volume_type.unset_keys(parsed_args.property)
925
+ volume_type.unset_keys(parsed_args.properties)
729
926
  except Exception as e:
730
- LOG.error(_("Failed to unset volume type property: %s"), e)
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=True,
59
- help=_('Returns detailed information (Default=True).'),
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 = strutils.bool_from_string(parsed_args.detailed)
125
- cluster = getattr(parsed_args, 'cluster', None)
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=True,
194
- help=_('Returns detailed information (Default=True).'),
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 = strutils.bool_from_string(parsed_args.detailed)
262
- cluster = getattr(parsed_args, 'cluster', None)
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 cinderclient import api_versions
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 volume_client.api_version < api_versions.APIVersion('3.33'):
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.list()
46
+ data = volume_client.resource_filters()
47
+ formatters = {'filters': format_columns.ListColumn}
42
48
 
43
49
  return (
44
50
  column_headers,
45
- (utils.get_item_properties(s, column_headers) for s in data),
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 volume_client.api_version < api_versions.APIVersion('3.33'):
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.list(
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
- return zip(*sorted(resource_filter._info.items()))
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
- parser.add_argument(
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(