python-openstackclient 8.0.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.
Files changed (85) hide show
  1. openstackclient/compute/client.py +5 -0
  2. openstackclient/compute/v2/console.py +7 -0
  3. openstackclient/compute/v2/console_connection.py +48 -0
  4. openstackclient/compute/v2/keypair.py +10 -3
  5. openstackclient/compute/v2/server.py +75 -10
  6. openstackclient/compute/v2/server_event.py +1 -1
  7. openstackclient/identity/common.py +79 -0
  8. openstackclient/identity/v3/application_credential.py +2 -2
  9. openstackclient/identity/v3/domain.py +62 -43
  10. openstackclient/identity/v3/group.py +113 -68
  11. openstackclient/identity/v3/project.py +17 -0
  12. openstackclient/identity/v3/user.py +38 -5
  13. openstackclient/image/client.py +5 -0
  14. openstackclient/image/v2/image.py +11 -11
  15. openstackclient/network/client.py +0 -6
  16. openstackclient/network/v2/floating_ip.py +58 -29
  17. openstackclient/network/v2/network_qos_rule.py +3 -11
  18. openstackclient/network/v2/router.py +1 -1
  19. openstackclient/network/v2/security_group.py +5 -4
  20. openstackclient/network/v2/security_group_rule.py +1 -1
  21. openstackclient/shell.py +1 -1
  22. openstackclient/tests/functional/base.py +5 -1
  23. openstackclient/tests/functional/compute/v2/test_keypair.py +41 -5
  24. openstackclient/tests/unit/compute/v2/fakes.py +81 -305
  25. openstackclient/tests/unit/compute/v2/test_console.py +18 -1
  26. openstackclient/tests/unit/compute/v2/test_console_connection.py +72 -0
  27. openstackclient/tests/unit/compute/v2/test_flavor.py +1 -1
  28. openstackclient/tests/unit/compute/v2/test_keypair.py +12 -5
  29. openstackclient/tests/unit/compute/v2/test_server.py +169 -46
  30. openstackclient/tests/unit/compute/v2/test_server_backup.py +32 -71
  31. openstackclient/tests/unit/compute/v2/test_server_event.py +2 -2
  32. openstackclient/tests/unit/compute/v2/test_server_image.py +33 -72
  33. openstackclient/tests/unit/compute/v2/test_server_migration.py +4 -4
  34. openstackclient/tests/unit/identity/v3/test_application_credential.py +47 -25
  35. openstackclient/tests/unit/identity/v3/test_domain.py +115 -105
  36. openstackclient/tests/unit/identity/v3/test_group.py +353 -202
  37. openstackclient/tests/unit/identity/v3/test_project.py +16 -0
  38. openstackclient/tests/unit/identity/v3/test_user.py +86 -6
  39. openstackclient/tests/unit/image/v1/test_image.py +8 -9
  40. openstackclient/tests/unit/image/v2/test_image.py +49 -49
  41. openstackclient/tests/unit/network/v2/fakes.py +405 -485
  42. openstackclient/tests/unit/network/v2/test_floating_ip_network.py +13 -19
  43. openstackclient/tests/unit/network/v2/test_l3_conntrack_helper.py +2 -2
  44. openstackclient/tests/unit/network/v2/test_ndp_proxy.py +1 -3
  45. openstackclient/tests/unit/network/v2/test_network.py +4 -4
  46. openstackclient/tests/unit/network/v2/test_network_agent.py +15 -29
  47. openstackclient/tests/unit/network/v2/test_network_qos_policy.py +16 -19
  48. openstackclient/tests/unit/network/v2/test_network_qos_rule.py +79 -152
  49. openstackclient/tests/unit/network/v2/test_network_qos_rule_type.py +4 -6
  50. openstackclient/tests/unit/network/v2/test_network_rbac.py +2 -2
  51. openstackclient/tests/unit/network/v2/test_port.py +17 -17
  52. openstackclient/tests/unit/network/v2/test_router.py +73 -57
  53. openstackclient/tests/unit/network/v2/test_security_group_network.py +25 -27
  54. openstackclient/tests/unit/network/v2/test_security_group_rule_compute.py +1 -3
  55. openstackclient/tests/unit/network/v2/test_security_group_rule_network.py +33 -39
  56. openstackclient/tests/unit/volume/v2/fakes.py +1 -2
  57. openstackclient/tests/unit/volume/v2/test_service.py +57 -91
  58. openstackclient/tests/unit/volume/v2/test_volume.py +108 -105
  59. openstackclient/tests/unit/volume/v2/test_volume_backup.py +141 -148
  60. openstackclient/tests/unit/volume/v2/test_volume_snapshot.py +293 -283
  61. openstackclient/tests/unit/volume/v3/test_block_storage_log_level.py +61 -71
  62. openstackclient/tests/unit/volume/v3/test_service.py +221 -141
  63. openstackclient/tests/unit/volume/v3/test_volume.py +130 -119
  64. openstackclient/tests/unit/volume/v3/test_volume_attachment.py +1 -1
  65. openstackclient/tests/unit/volume/v3/test_volume_backup.py +198 -203
  66. openstackclient/tests/unit/volume/v3/test_volume_snapshot.py +682 -47
  67. openstackclient/volume/v2/service.py +41 -38
  68. openstackclient/volume/v2/volume.py +63 -37
  69. openstackclient/volume/v2/volume_backup.py +9 -3
  70. openstackclient/volume/v2/volume_snapshot.py +121 -84
  71. openstackclient/volume/v3/block_storage_log_level.py +22 -28
  72. openstackclient/volume/v3/service.py +105 -14
  73. openstackclient/volume/v3/volume.py +200 -39
  74. openstackclient/volume/v3/volume_backup.py +24 -19
  75. openstackclient/volume/v3/volume_snapshot.py +485 -10
  76. {python_openstackclient-8.0.0.dist-info → python_openstackclient-8.1.0.dist-info}/AUTHORS +8 -0
  77. python_openstackclient-8.1.0.dist-info/METADATA +264 -0
  78. {python_openstackclient-8.0.0.dist-info → python_openstackclient-8.1.0.dist-info}/RECORD +83 -81
  79. {python_openstackclient-8.0.0.dist-info → python_openstackclient-8.1.0.dist-info}/entry_points.txt +7 -6
  80. python_openstackclient-8.1.0.dist-info/pbr.json +1 -0
  81. python_openstackclient-8.0.0.dist-info/METADATA +0 -166
  82. python_openstackclient-8.0.0.dist-info/pbr.json +0 -1
  83. {python_openstackclient-8.0.0.dist-info → python_openstackclient-8.1.0.dist-info}/LICENSE +0 -0
  84. {python_openstackclient-8.0.0.dist-info → python_openstackclient-8.1.0.dist-info}/WHEEL +0 -0
  85. {python_openstackclient-8.0.0.dist-info → python_openstackclient-8.1.0.dist-info}/top_level.txt +0 -0
@@ -45,33 +45,34 @@ class ListService(command.Lister):
45
45
  return parser
46
46
 
47
47
  def take_action(self, parsed_args):
48
- service_client = self.app.client_manager.volume
48
+ volume_client = self.app.client_manager.sdk_connection.volume
49
+
50
+ columns: tuple[str, ...] = (
51
+ "binary",
52
+ "host",
53
+ "availability_zone",
54
+ "status",
55
+ "state",
56
+ "updated_at",
57
+ )
58
+ column_names: tuple[str, ...] = (
59
+ "Binary",
60
+ "Host",
61
+ "Zone",
62
+ "Status",
63
+ "State",
64
+ "Updated At",
65
+ )
49
66
 
50
67
  if parsed_args.long:
51
- columns = [
52
- "Binary",
53
- "Host",
54
- "Zone",
55
- "Status",
56
- "State",
57
- "Updated At",
58
- "Disabled Reason",
59
- ]
60
- else:
61
- columns = [
62
- "Binary",
63
- "Host",
64
- "Zone",
65
- "Status",
66
- "State",
67
- "Updated At",
68
- ]
69
-
70
- data = service_client.services.list(
71
- parsed_args.host, parsed_args.service
68
+ columns += ("disabled_reason",)
69
+ column_names += ("Disabled Reason",)
70
+
71
+ data = volume_client.services(
72
+ host=parsed_args.host, binary=parsed_args.service
72
73
  )
73
74
  return (
74
- columns,
75
+ column_names,
75
76
  (
76
77
  utils.get_item_properties(
77
78
  s,
@@ -87,7 +88,11 @@ class SetService(command.Command):
87
88
 
88
89
  def get_parser(self, prog_name):
89
90
  parser = super().get_parser(prog_name)
90
- parser.add_argument("host", metavar="<host>", help=_("Name of host"))
91
+ parser.add_argument(
92
+ "host",
93
+ metavar="<host>",
94
+ help=_("Name of host"),
95
+ )
91
96
  parser.add_argument(
92
97
  "service",
93
98
  metavar="<service>",
@@ -118,19 +123,17 @@ class SetService(command.Command):
118
123
  )
119
124
  raise exceptions.CommandError(msg)
120
125
 
121
- service_client = self.app.client_manager.volume
126
+ volume_client = self.app.client_manager.sdk_connection.volume
127
+
128
+ service = volume_client.find_service(
129
+ host=parsed_args.host, service=parsed_args.service
130
+ )
131
+
122
132
  if parsed_args.enable:
123
- service_client.services.enable(
124
- parsed_args.host, parsed_args.service
125
- )
133
+ service.enable(volume_client)
134
+
126
135
  if parsed_args.disable:
127
- if parsed_args.disable_reason:
128
- service_client.services.disable_log_reason(
129
- parsed_args.host,
130
- parsed_args.service,
131
- parsed_args.disable_reason,
132
- )
133
- else:
134
- service_client.services.disable(
135
- parsed_args.host, parsed_args.service
136
- )
136
+ service.disable(
137
+ volume_client,
138
+ reason=parsed_args.disable_reason,
139
+ )
@@ -107,7 +107,7 @@ class CreateVolume(command.ShowOne):
107
107
  )
108
108
  raise exceptions.CommandError(msg)
109
109
 
110
- def _get_parser(self, prog_name):
110
+ def get_parser(self, prog_name):
111
111
  parser = super().get_parser(prog_name)
112
112
  parser.add_argument(
113
113
  "name",
@@ -169,6 +169,7 @@ class CreateVolume(command.ShowOne):
169
169
  "--property",
170
170
  metavar="<key=value>",
171
171
  action=parseractions.KeyValueAction,
172
+ dest="properties",
172
173
  help=_(
173
174
  "Set a property to this volume "
174
175
  "(repeat option to set multiple properties)"
@@ -189,32 +190,36 @@ class CreateVolume(command.ShowOne):
189
190
  bootable_group.add_argument(
190
191
  "--bootable",
191
192
  action="store_true",
193
+ dest="bootable",
194
+ default=None,
192
195
  help=_("Mark volume as bootable"),
193
196
  )
194
197
  bootable_group.add_argument(
195
198
  "--non-bootable",
196
- action="store_true",
199
+ action="store_false",
200
+ dest="bootable",
201
+ default=None,
197
202
  help=_("Mark volume as non-bootable (default)"),
198
203
  )
199
204
  readonly_group = parser.add_mutually_exclusive_group()
200
205
  readonly_group.add_argument(
201
206
  "--read-only",
202
207
  action="store_true",
208
+ dest="read_only",
209
+ default=None,
203
210
  help=_("Set volume to read-only access mode"),
204
211
  )
205
212
  readonly_group.add_argument(
206
213
  "--read-write",
207
- action="store_true",
214
+ action="store_false",
215
+ dest="read_only",
216
+ default=None,
208
217
  help=_("Set volume to read-write access mode (default)"),
209
218
  )
210
- return parser, source_group
211
-
212
- def get_parser(self, prog_name):
213
- parser, _ = self._get_parser(prog_name)
214
219
  return parser
215
220
 
216
221
  def take_action(self, parsed_args):
217
- CreateVolume._check_size_arg(parsed_args)
222
+ self._check_size_arg(parsed_args)
218
223
  # size is validated in the above call to
219
224
  # _check_size_arg where we check that size
220
225
  # should be passed if we are not creating a
@@ -265,14 +270,14 @@ class CreateVolume(command.ShowOne):
265
270
  description=parsed_args.description,
266
271
  volume_type=parsed_args.type,
267
272
  availability_zone=parsed_args.availability_zone,
268
- metadata=parsed_args.property,
273
+ metadata=parsed_args.properties,
269
274
  imageRef=image,
270
275
  source_volid=source_volume,
271
276
  consistencygroup_id=consistency_group,
272
277
  scheduler_hints=parsed_args.hint,
273
278
  )
274
279
 
275
- if parsed_args.bootable or parsed_args.non_bootable:
280
+ if parsed_args.bootable is not None:
276
281
  try:
277
282
  if utils.wait_for_status(
278
283
  volume_client.volumes.get,
@@ -291,7 +296,8 @@ class CreateVolume(command.ShowOne):
291
296
  raise exceptions.CommandError(msg)
292
297
  except Exception as e:
293
298
  LOG.error(_("Failed to set volume bootable property: %s"), e)
294
- if parsed_args.read_only or parsed_args.read_write:
299
+
300
+ if parsed_args.read_only is not None:
295
301
  try:
296
302
  if utils.wait_for_status(
297
303
  volume_client.volumes.get,
@@ -358,18 +364,19 @@ class DeleteVolume(command.Command):
358
364
  return parser
359
365
 
360
366
  def take_action(self, parsed_args):
361
- volume_client = self.app.client_manager.volume
367
+ volume_client = self.app.client_manager.sdk_connection.volume
362
368
  result = 0
363
369
 
364
- for i in parsed_args.volumes:
370
+ for volume in parsed_args.volumes:
365
371
  try:
366
- volume_obj = utils.find_resource(volume_client.volumes, i)
367
- if parsed_args.force:
368
- volume_client.volumes.force_delete(volume_obj.id)
369
- else:
370
- volume_client.volumes.delete(
371
- volume_obj.id, cascade=parsed_args.purge
372
- )
372
+ volume_obj = volume_client.find_volume(
373
+ volume, ignore_missing=False
374
+ )
375
+ volume_client.delete_volume(
376
+ volume_obj.id,
377
+ force=parsed_args.force,
378
+ cascade=parsed_args.purge,
379
+ )
373
380
  except Exception as e:
374
381
  result += 1
375
382
  LOG.error(
@@ -377,7 +384,7 @@ class DeleteVolume(command.Command):
377
384
  "Failed to delete volume with "
378
385
  "name or ID '%(volume)s': %(e)s"
379
386
  ),
380
- {'volume': i, 'e': e},
387
+ {'volume': volume, 'e': e},
381
388
  )
382
389
 
383
390
  if result > 0:
@@ -622,6 +629,7 @@ class SetVolume(command.Command):
622
629
  '--property',
623
630
  metavar='<key=value>',
624
631
  action=parseractions.KeyValueAction,
632
+ dest="properties",
625
633
  help=_(
626
634
  'Set a property on this volume '
627
635
  '(repeat option to set multiple properties)'
@@ -631,6 +639,7 @@ class SetVolume(command.Command):
631
639
  '--image-property',
632
640
  metavar='<key=value>',
633
641
  action=parseractions.KeyValueAction,
642
+ dest="image_properties",
634
643
  help=_(
635
644
  'Set an image property on this volume '
636
645
  '(repeat option to set multiple image properties)'
@@ -707,22 +716,30 @@ class SetVolume(command.Command):
707
716
  bootable_group.add_argument(
708
717
  "--bootable",
709
718
  action="store_true",
719
+ dest="bootable",
720
+ default=None,
710
721
  help=_("Mark volume as bootable"),
711
722
  )
712
723
  bootable_group.add_argument(
713
724
  "--non-bootable",
714
- action="store_true",
725
+ action="store_false",
726
+ dest="bootable",
727
+ default=None,
715
728
  help=_("Mark volume as non-bootable"),
716
729
  )
717
730
  readonly_group = parser.add_mutually_exclusive_group()
718
731
  readonly_group.add_argument(
719
732
  "--read-only",
720
733
  action="store_true",
734
+ dest="read_only",
735
+ default=None,
721
736
  help=_("Set volume to read-only access mode"),
722
737
  )
723
738
  readonly_group.add_argument(
724
739
  "--read-write",
725
- action="store_true",
740
+ action="store_false",
741
+ dest="read_only",
742
+ default=None,
726
743
  help=_("Set volume to read-write access mode"),
727
744
  )
728
745
  return parser
@@ -771,28 +788,31 @@ class SetVolume(command.Command):
771
788
  LOG.error(_("Failed to clean volume properties: %s"), e)
772
789
  result += 1
773
790
 
774
- if parsed_args.property:
791
+ if parsed_args.properties:
775
792
  try:
776
793
  volume_client.volumes.set_metadata(
777
- volume.id, parsed_args.property
794
+ volume.id, parsed_args.properties
778
795
  )
779
796
  except Exception as e:
780
- LOG.error(_("Failed to set volume property: %s"), e)
797
+ LOG.error(_("Failed to set volume properties: %s"), e)
781
798
  result += 1
782
- if parsed_args.image_property:
799
+
800
+ if parsed_args.image_properties:
783
801
  try:
784
802
  volume_client.volumes.set_image_metadata(
785
- volume.id, parsed_args.image_property
803
+ volume.id, parsed_args.image_properties
786
804
  )
787
805
  except Exception as e:
788
- LOG.error(_("Failed to set image property: %s"), e)
806
+ LOG.error(_("Failed to set image properties: %s"), e)
789
807
  result += 1
808
+
790
809
  if parsed_args.state:
791
810
  try:
792
811
  volume_client.volumes.reset_state(volume.id, parsed_args.state)
793
812
  except Exception as e:
794
813
  LOG.error(_("Failed to set volume state: %s"), e)
795
814
  result += 1
815
+
796
816
  if parsed_args.attached:
797
817
  try:
798
818
  volume_client.volumes.reset_state(
@@ -801,6 +821,7 @@ class SetVolume(command.Command):
801
821
  except Exception as e:
802
822
  LOG.error(_("Failed to set volume attach-status: %s"), e)
803
823
  result += 1
824
+
804
825
  if parsed_args.detached:
805
826
  try:
806
827
  volume_client.volumes.reset_state(
@@ -809,7 +830,8 @@ class SetVolume(command.Command):
809
830
  except Exception as e:
810
831
  LOG.error(_("Failed to set volume attach-status: %s"), e)
811
832
  result += 1
812
- if parsed_args.bootable or parsed_args.non_bootable:
833
+
834
+ if parsed_args.bootable is not None:
813
835
  try:
814
836
  volume_client.volumes.set_bootable(
815
837
  volume.id, parsed_args.bootable
@@ -817,7 +839,8 @@ class SetVolume(command.Command):
817
839
  except Exception as e:
818
840
  LOG.error(_("Failed to set volume bootable property: %s"), e)
819
841
  result += 1
820
- if parsed_args.read_only or parsed_args.read_write:
842
+
843
+ if parsed_args.read_only is not None:
821
844
  try:
822
845
  volume_client.volumes.update_readonly_flag(
823
846
  volume.id, parsed_args.read_only
@@ -828,6 +851,7 @@ class SetVolume(command.Command):
828
851
  e,
829
852
  )
830
853
  result += 1
854
+
831
855
  policy = parsed_args.migration_policy or parsed_args.retype_policy
832
856
  if parsed_args.type:
833
857
  # get the migration policy
@@ -928,6 +952,7 @@ class UnsetVolume(command.Command):
928
952
  '--property',
929
953
  metavar='<key>',
930
954
  action='append',
955
+ dest='properties',
931
956
  help=_(
932
957
  'Remove a property from volume '
933
958
  '(repeat option to remove multiple properties)'
@@ -937,6 +962,7 @@ class UnsetVolume(command.Command):
937
962
  '--image-property',
938
963
  metavar='<key>',
939
964
  action='append',
965
+ dest='image_properties',
940
966
  help=_(
941
967
  'Remove an image property from volume '
942
968
  '(repeat option to remove multiple image properties)'
@@ -949,22 +975,22 @@ class UnsetVolume(command.Command):
949
975
  volume = utils.find_resource(volume_client.volumes, parsed_args.volume)
950
976
 
951
977
  result = 0
952
- if parsed_args.property:
978
+ if parsed_args.properties:
953
979
  try:
954
980
  volume_client.volumes.delete_metadata(
955
- volume.id, parsed_args.property
981
+ volume.id, parsed_args.properties
956
982
  )
957
983
  except Exception as e:
958
- LOG.error(_("Failed to unset volume property: %s"), e)
984
+ LOG.error(_("Failed to unset volume properties: %s"), e)
959
985
  result += 1
960
986
 
961
- if parsed_args.image_property:
987
+ if parsed_args.image_properties:
962
988
  try:
963
989
  volume_client.volumes.delete_image_metadata(
964
- volume.id, parsed_args.image_property
990
+ volume.id, parsed_args.image_properties
965
991
  )
966
992
  except Exception as e:
967
- LOG.error(_("Failed to unset image property: %s"), e)
993
+ LOG.error(_("Failed to unset image properties: %s"), e)
968
994
  result += 1
969
995
 
970
996
  if result > 0:
@@ -417,13 +417,19 @@ class SetVolumeBackup(command.Command):
417
417
  return parser
418
418
 
419
419
  def take_action(self, parsed_args):
420
- volume_client = self.app.client_manager.volume
421
- backup = utils.find_resource(volume_client.backups, parsed_args.backup)
420
+ volume_client = self.app.client_manager.sdk_connection.volume
421
+
422
+ backup = volume_client.find_backup(
423
+ parsed_args.backup,
424
+ ignore_missing=False,
425
+ )
422
426
 
423
427
  result = 0
424
428
  if parsed_args.state:
425
429
  try:
426
- volume_client.backups.reset_state(backup.id, parsed_args.state)
430
+ volume_client.reset_backup_status(
431
+ backup, status=parsed_args.state
432
+ )
427
433
  except Exception as e:
428
434
  LOG.error(_("Failed to set backup state: %s"), e)
429
435
  result += 1