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