python-openstackclient 9.0.0__py3-none-any.whl → 10.0.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 (284) hide show
  1. openstackclient/__init__.py +2 -6
  2. openstackclient/api/api.py +41 -23
  3. openstackclient/api/compute_v2.py +44 -25
  4. openstackclient/api/object_store_v1.py +75 -97
  5. openstackclient/api/volume_v2.py +2 -1
  6. openstackclient/api/volume_v3.py +2 -1
  7. openstackclient/common/availability_zone.py +58 -42
  8. openstackclient/common/clientmanager.py +56 -29
  9. openstackclient/common/configuration.py +10 -3
  10. openstackclient/common/envvars.py +2 -2
  11. openstackclient/common/extension.py +14 -5
  12. openstackclient/common/limits.py +10 -5
  13. openstackclient/common/module.py +14 -6
  14. openstackclient/common/pagination.py +8 -2
  15. openstackclient/common/progressbar.py +7 -6
  16. openstackclient/common/project_cleanup.py +13 -7
  17. openstackclient/common/quota.py +97 -99
  18. openstackclient/common/versions.py +8 -2
  19. openstackclient/compute/client.py +7 -3
  20. openstackclient/compute/v2/agent.py +17 -10
  21. openstackclient/compute/v2/aggregate.py +36 -22
  22. openstackclient/compute/v2/console.py +14 -8
  23. openstackclient/compute/v2/console_connection.py +11 -3
  24. openstackclient/compute/v2/flavor.py +39 -21
  25. openstackclient/compute/v2/host.py +14 -6
  26. openstackclient/compute/v2/hypervisor.py +14 -5
  27. openstackclient/compute/v2/hypervisor_stats.py +10 -2
  28. openstackclient/compute/v2/keypair.py +29 -14
  29. openstackclient/compute/v2/server.py +249 -169
  30. openstackclient/compute/v2/server_backup.py +10 -4
  31. openstackclient/compute/v2/server_event.py +21 -12
  32. openstackclient/compute/v2/server_group.py +21 -11
  33. openstackclient/compute/v2/server_image.py +19 -10
  34. openstackclient/compute/v2/server_migration.py +24 -10
  35. openstackclient/compute/v2/server_share.py +274 -0
  36. openstackclient/compute/v2/server_volume.py +10 -4
  37. openstackclient/compute/v2/service.py +14 -7
  38. openstackclient/compute/v2/usage.py +26 -21
  39. openstackclient/identity/client.py +8 -3
  40. openstackclient/identity/common.py +78 -47
  41. openstackclient/identity/v2_0/catalog.py +14 -7
  42. openstackclient/identity/v2_0/ec2creds.py +21 -10
  43. openstackclient/identity/v2_0/endpoint.py +23 -11
  44. openstackclient/identity/v2_0/project.py +25 -14
  45. openstackclient/identity/v2_0/role.py +28 -14
  46. openstackclient/identity/v2_0/role_assignment.py +9 -3
  47. openstackclient/identity/v2_0/service.py +23 -11
  48. openstackclient/identity/v2_0/token.py +12 -5
  49. openstackclient/identity/v2_0/user.py +26 -15
  50. openstackclient/identity/v3/access_rule.py +26 -12
  51. openstackclient/identity/v3/application_credential.py +59 -24
  52. openstackclient/identity/v3/catalog.py +14 -7
  53. openstackclient/identity/v3/consumer.py +22 -11
  54. openstackclient/identity/v3/credential.py +36 -16
  55. openstackclient/identity/v3/domain.py +37 -18
  56. openstackclient/identity/v3/ec2creds.py +25 -12
  57. openstackclient/identity/v3/endpoint.py +42 -20
  58. openstackclient/identity/v3/endpoint_group.py +28 -17
  59. openstackclient/identity/v3/federation_protocol.py +38 -16
  60. openstackclient/identity/v3/group.py +55 -32
  61. openstackclient/identity/v3/identity_provider.py +92 -57
  62. openstackclient/identity/v3/implied_role.py +21 -9
  63. openstackclient/identity/v3/limit.py +38 -16
  64. openstackclient/identity/v3/mapping.py +26 -13
  65. openstackclient/identity/v3/policy.py +23 -12
  66. openstackclient/identity/v3/project.py +43 -23
  67. openstackclient/identity/v3/region.py +36 -16
  68. openstackclient/identity/v3/registered_limit.py +40 -16
  69. openstackclient/identity/v3/role.py +61 -31
  70. openstackclient/identity/v3/role_assignment.py +23 -6
  71. openstackclient/identity/v3/service.py +36 -16
  72. openstackclient/identity/v3/service_provider.py +37 -15
  73. openstackclient/identity/v3/tag.py +23 -6
  74. openstackclient/identity/v3/token.py +30 -14
  75. openstackclient/identity/v3/trust.py +32 -14
  76. openstackclient/identity/v3/unscoped_saml.py +10 -2
  77. openstackclient/identity/v3/user.py +49 -26
  78. openstackclient/image/client.py +7 -3
  79. openstackclient/image/v1/image.py +33 -26
  80. openstackclient/image/v2/cache.py +14 -9
  81. openstackclient/image/v2/image.py +74 -48
  82. openstackclient/image/v2/info.py +7 -1
  83. openstackclient/image/v2/metadef_namespaces.py +109 -13
  84. openstackclient/image/v2/metadef_objects.py +28 -15
  85. openstackclient/image/v2/metadef_properties.py +24 -13
  86. openstackclient/image/v2/metadef_resource_type_association.py +14 -7
  87. openstackclient/image/v2/metadef_resource_types.py +7 -1
  88. openstackclient/image/v2/task.py +15 -6
  89. openstackclient/locale/tr_TR/LC_MESSAGES/openstackclient.po +7 -192
  90. openstackclient/network/client.py +7 -2
  91. openstackclient/network/common.py +16 -241
  92. openstackclient/network/utils.py +36 -22
  93. openstackclient/network/v2/address_group.py +27 -16
  94. openstackclient/network/v2/address_scope.py +24 -13
  95. openstackclient/network/v2/bgpvpn/bgpvpn.py +463 -0
  96. openstackclient/network/v2/bgpvpn/constants.py +30 -0
  97. openstackclient/network/v2/bgpvpn/network_association.py +214 -0
  98. openstackclient/network/v2/bgpvpn/port_association.py +490 -0
  99. openstackclient/network/v2/bgpvpn/router_association.py +288 -0
  100. openstackclient/network/v2/default_security_group_rule.py +19 -10
  101. openstackclient/network/v2/floating_ip.py +110 -159
  102. openstackclient/network/v2/floating_ip_port_forwarding.py +30 -18
  103. openstackclient/network/v2/fwaas/__init__.py +0 -0
  104. openstackclient/network/v2/fwaas/group.py +466 -0
  105. openstackclient/network/v2/fwaas/policy.py +518 -0
  106. openstackclient/network/v2/fwaas/rule.py +574 -0
  107. openstackclient/network/v2/ip_availability.py +13 -5
  108. openstackclient/network/v2/l3_conntrack_helper.py +22 -13
  109. openstackclient/network/v2/local_ip.py +24 -13
  110. openstackclient/network/v2/local_ip_association.py +14 -7
  111. openstackclient/network/v2/ndp_proxy.py +20 -11
  112. openstackclient/network/v2/network.py +129 -196
  113. openstackclient/network/v2/network_agent.py +46 -25
  114. openstackclient/network/v2/network_auto_allocated_topology.py +22 -11
  115. openstackclient/network/v2/network_flavor.py +27 -16
  116. openstackclient/network/v2/network_flavor_profile.py +23 -12
  117. openstackclient/network/v2/network_meter.py +21 -10
  118. openstackclient/network/v2/network_meter_rule.py +21 -11
  119. openstackclient/network/v2/network_qos_policy.py +25 -15
  120. openstackclient/network/v2/network_qos_rule.py +32 -17
  121. openstackclient/network/v2/network_qos_rule_type.py +13 -5
  122. openstackclient/network/v2/network_rbac.py +23 -12
  123. openstackclient/network/v2/network_segment.py +20 -11
  124. openstackclient/network/v2/network_segment_range.py +56 -29
  125. openstackclient/network/v2/network_service_provider.py +7 -1
  126. openstackclient/network/v2/network_trunk.py +38 -22
  127. openstackclient/network/v2/port.py +54 -29
  128. openstackclient/network/v2/router.py +75 -52
  129. openstackclient/network/v2/security_group.py +87 -157
  130. openstackclient/network/v2/security_group_rule.py +100 -280
  131. openstackclient/network/v2/subnet.py +49 -28
  132. openstackclient/network/v2/subnet_pool.py +30 -17
  133. openstackclient/network/v2/taas/tap_flow.py +22 -11
  134. openstackclient/network/v2/taas/tap_mirror.py +22 -11
  135. openstackclient/network/v2/taas/tap_service.py +23 -12
  136. openstackclient/object/client.py +7 -2
  137. openstackclient/object/v1/account.py +13 -6
  138. openstackclient/object/v1/container.py +25 -15
  139. openstackclient/object/v1/object.py +25 -15
  140. openstackclient/py.typed +0 -0
  141. openstackclient/shell.py +46 -10
  142. openstackclient/tests/functional/base.py +55 -20
  143. openstackclient/tests/functional/common/test_extension.py +4 -0
  144. openstackclient/tests/functional/common/test_quota.py +3 -1
  145. openstackclient/tests/functional/compute/v2/common.py +14 -13
  146. openstackclient/tests/functional/compute/v2/test_flavor.py +3 -1
  147. openstackclient/tests/functional/compute/v2/test_server.py +3 -0
  148. openstackclient/tests/functional/identity/v2/common.py +10 -6
  149. openstackclient/tests/functional/identity/v2/test_role.py +4 -4
  150. openstackclient/tests/functional/identity/v3/common.py +25 -19
  151. openstackclient/tests/functional/identity/v3/test_group.py +20 -20
  152. openstackclient/tests/functional/identity/v3/test_idp.py +3 -1
  153. openstackclient/tests/functional/identity/v3/test_project.py +10 -10
  154. openstackclient/tests/functional/identity/v3/test_role.py +18 -18
  155. openstackclient/tests/functional/identity/v3/test_role_assignment.py +12 -12
  156. openstackclient/tests/functional/identity/v3/test_user.py +8 -8
  157. openstackclient/tests/functional/image/base.py +1 -6
  158. openstackclient/tests/functional/network/v2/common.py +5 -2
  159. openstackclient/tests/functional/network/v2/test_floating_ip.py +10 -4
  160. openstackclient/tests/functional/network/v2/test_ip_availability.py +4 -0
  161. openstackclient/tests/functional/network/v2/test_network_meter_rule.py +3 -2
  162. openstackclient/tests/functional/network/v2/test_network_segment.py +5 -0
  163. openstackclient/tests/functional/network/v2/test_subnet.py +13 -9
  164. openstackclient/tests/functional/object/v1/common.py +4 -0
  165. openstackclient/tests/functional/volume/v2/common.py +4 -0
  166. openstackclient/tests/functional/volume/v2/test_volume_snapshot.py +27 -11
  167. openstackclient/tests/functional/volume/v2/test_volume_type.py +2 -2
  168. openstackclient/tests/functional/volume/v3/common.py +4 -0
  169. openstackclient/tests/functional/volume/v3/test_volume_snapshot.py +11 -7
  170. openstackclient/tests/functional/volume/v3/test_volume_type.py +2 -2
  171. openstackclient/tests/unit/common/test_availability_zone.py +35 -49
  172. openstackclient/tests/unit/common/test_extension.py +2 -2
  173. openstackclient/tests/unit/common/test_module.py +12 -7
  174. openstackclient/tests/unit/common/test_project_cleanup.py +3 -1
  175. openstackclient/tests/unit/common/test_quota.py +6 -26
  176. openstackclient/tests/unit/compute/v2/fakes.py +25 -0
  177. openstackclient/tests/unit/compute/v2/test_flavor.py +28 -2
  178. openstackclient/tests/unit/compute/v2/test_keypair.py +6 -6
  179. openstackclient/tests/unit/compute/v2/test_server.py +11 -96
  180. openstackclient/tests/unit/compute/v2/test_server_share.py +287 -0
  181. openstackclient/tests/unit/identity/v3/fakes.py +3 -0
  182. openstackclient/tests/unit/identity/v3/test_group.py +4 -14
  183. openstackclient/tests/unit/identity/v3/test_identity_provider.py +303 -299
  184. openstackclient/tests/unit/identity/v3/test_user.py +4 -4
  185. openstackclient/tests/unit/image/v2/test_image.py +11 -11
  186. openstackclient/tests/unit/image/v2/test_metadef_namespaces.py +105 -6
  187. openstackclient/tests/unit/network/test_common.py +0 -155
  188. openstackclient/tests/unit/network/v2/bgpvpn/__init__.py +0 -0
  189. openstackclient/tests/unit/network/v2/bgpvpn/fakes.py +179 -0
  190. openstackclient/tests/unit/network/v2/bgpvpn/test_bgpvpn.py +584 -0
  191. openstackclient/tests/unit/network/v2/bgpvpn/test_network_association.py +285 -0
  192. openstackclient/tests/unit/network/v2/bgpvpn/test_port_association.py +384 -0
  193. openstackclient/tests/unit/network/v2/bgpvpn/test_router_association.py +297 -0
  194. openstackclient/tests/unit/network/v2/fwaas/__init__.py +0 -0
  195. openstackclient/tests/unit/network/v2/fwaas/test_group.py +897 -0
  196. openstackclient/tests/unit/network/v2/fwaas/test_policy.py +869 -0
  197. openstackclient/tests/unit/network/v2/fwaas/test_rule.py +980 -0
  198. openstackclient/tests/unit/network/v2/taas/{test_osc_tap_flow.py → test_tap_flow.py} +18 -25
  199. openstackclient/tests/unit/network/v2/taas/{test_osc_tap_mirror.py → test_tap_mirror.py} +19 -29
  200. openstackclient/tests/unit/network/v2/taas/{test_osc_tap_service.py → test_tap_service.py} +19 -29
  201. openstackclient/tests/unit/network/v2/test_address_group.py +2 -2
  202. openstackclient/tests/unit/network/v2/{test_floating_ip_network.py → test_floating_ip.py} +3 -2
  203. openstackclient/tests/unit/network/v2/test_floating_ip_port_forwarding.py +13 -13
  204. openstackclient/tests/unit/network/v2/test_network_agent.py +8 -4
  205. openstackclient/tests/unit/network/v2/test_network_auto_allocated_topology.py +3 -3
  206. openstackclient/tests/unit/network/v2/test_network_flavor.py +2 -2
  207. openstackclient/tests/unit/network/v2/test_network_qos_policy.py +1 -1
  208. openstackclient/tests/unit/network/v2/test_network_qos_rule.py +2 -2
  209. openstackclient/tests/unit/network/v2/test_network_rbac.py +1 -1
  210. openstackclient/tests/unit/network/v2/test_network_segment.py +1 -1
  211. openstackclient/tests/unit/network/v2/test_network_segment_range.py +7 -10
  212. openstackclient/tests/unit/network/v2/test_network_trunk.py +1 -1
  213. openstackclient/tests/unit/network/v2/test_router.py +8 -9
  214. openstackclient/tests/unit/network/v2/{test_security_group_network.py → test_security_group.py} +1 -20
  215. openstackclient/tests/unit/network/v2/{test_security_group_rule_network.py → test_security_group_rule.py} +7 -41
  216. openstackclient/tests/unit/network/v2/test_subnet.py +2 -1
  217. openstackclient/tests/unit/network/v2/test_subnet_pool.py +2 -1
  218. openstackclient/tests/unit/object/v1/fakes.py +8 -7
  219. openstackclient/tests/unit/object/v1/test_container.py +65 -101
  220. openstackclient/tests/unit/object/v1/test_container_all.py +8 -1
  221. openstackclient/tests/unit/object/v1/test_object.py +44 -84
  222. openstackclient/tests/unit/object/v1/test_object_all.py +8 -1
  223. openstackclient/tests/unit/test_hacking.py +108 -0
  224. openstackclient/tests/unit/volume/v2/fakes.py +1 -0
  225. openstackclient/tests/unit/volume/v2/test_volume_backup.py +1 -5
  226. openstackclient/tests/unit/volume/v2/test_volume_snapshot.py +2 -1
  227. openstackclient/tests/unit/volume/v2/test_volume_type.py +2 -4
  228. openstackclient/tests/unit/volume/v3/fakes.py +1 -0
  229. openstackclient/tests/unit/volume/v3/test_volume.py +60 -3
  230. openstackclient/tests/unit/volume/v3/test_volume_attachment.py +1 -1
  231. openstackclient/tests/unit/volume/v3/test_volume_backup.py +1 -5
  232. openstackclient/tests/unit/volume/v3/test_volume_snapshot.py +55 -1
  233. openstackclient/tests/unit/volume/v3/test_volume_type.py +2 -4
  234. openstackclient/volume/client.py +7 -3
  235. openstackclient/volume/v2/backup_record.py +15 -6
  236. openstackclient/volume/v2/consistency_group.py +29 -17
  237. openstackclient/volume/v2/consistency_group_snapshot.py +25 -10
  238. openstackclient/volume/v2/qos_specs.py +28 -17
  239. openstackclient/volume/v2/service.py +17 -6
  240. openstackclient/volume/v2/volume.py +57 -29
  241. openstackclient/volume/v2/volume_backend.py +19 -6
  242. openstackclient/volume/v2/volume_backup.py +46 -20
  243. openstackclient/volume/v2/volume_host.py +6 -4
  244. openstackclient/volume/v2/volume_snapshot.py +50 -24
  245. openstackclient/volume/v2/volume_transfer_request.py +31 -13
  246. openstackclient/volume/v2/volume_type.py +43 -24
  247. openstackclient/volume/v3/block_storage_cleanup.py +11 -3
  248. openstackclient/volume/v3/block_storage_cluster.py +19 -7
  249. openstackclient/volume/v3/block_storage_log_level.py +15 -6
  250. openstackclient/volume/v3/block_storage_manage.py +10 -4
  251. openstackclient/volume/v3/block_storage_resource_filter.py +17 -5
  252. openstackclient/volume/v3/service.py +16 -6
  253. openstackclient/volume/v3/volume.py +89 -39
  254. openstackclient/volume/v3/volume_attachment.py +43 -21
  255. openstackclient/volume/v3/volume_backup.py +53 -24
  256. openstackclient/volume/v3/volume_group.py +23 -13
  257. openstackclient/volume/v3/volume_group_snapshot.py +32 -13
  258. openstackclient/volume/v3/volume_group_type.py +26 -13
  259. openstackclient/volume/v3/volume_message.py +15 -7
  260. openstackclient/volume/v3/volume_snapshot.py +69 -32
  261. openstackclient/volume/v3/volume_transfer_request.py +31 -13
  262. openstackclient/volume/v3/volume_type.py +42 -24
  263. {python_openstackclient-9.0.0.dist-info → python_openstackclient-10.0.0.dist-info}/METADATA +6 -6
  264. {python_openstackclient-9.0.0.dist-info → python_openstackclient-10.0.0.dist-info}/RECORD +271 -260
  265. {python_openstackclient-9.0.0.dist-info → python_openstackclient-10.0.0.dist-info}/WHEEL +1 -1
  266. {python_openstackclient-9.0.0.dist-info → python_openstackclient-10.0.0.dist-info}/entry_points.txt +53 -1
  267. {python_openstackclient-9.0.0.dist-info → python_openstackclient-10.0.0.dist-info}/licenses/AUTHORS +4 -0
  268. python_openstackclient-10.0.0.dist-info/pbr.json +1 -0
  269. openstackclient/api/image_v1.py +0 -69
  270. openstackclient/api/image_v2.py +0 -79
  271. openstackclient/network/v2/floating_ip_pool.py +0 -38
  272. openstackclient/tests/functional/image/v1/test_image.py +0 -97
  273. openstackclient/tests/unit/api/test_image_v1.py +0 -96
  274. openstackclient/tests/unit/api/test_image_v2.py +0 -96
  275. openstackclient/tests/unit/network/v2/test_floating_ip_compute.py +0 -248
  276. openstackclient/tests/unit/network/v2/test_floating_ip_pool_compute.py +0 -49
  277. openstackclient/tests/unit/network/v2/test_floating_ip_pool_network.py +0 -39
  278. openstackclient/tests/unit/network/v2/test_network_compute.py +0 -404
  279. openstackclient/tests/unit/network/v2/test_security_group_compute.py +0 -392
  280. openstackclient/tests/unit/network/v2/test_security_group_rule_compute.py +0 -555
  281. python_openstackclient-9.0.0.dist-info/pbr.json +0 -1
  282. /openstackclient/{tests/functional/image/v1 → network/v2/bgpvpn}/__init__.py +0 -0
  283. {python_openstackclient-9.0.0.dist-info → python_openstackclient-10.0.0.dist-info}/licenses/LICENSE +0 -0
  284. {python_openstackclient-9.0.0.dist-info → python_openstackclient-10.0.0.dist-info}/top_level.txt +0 -0
@@ -17,11 +17,12 @@
17
17
 
18
18
  import argparse
19
19
  import base64
20
+ from collections.abc import Iterable, Sequence
20
21
  import getpass
21
22
  import json
22
23
  import logging
23
24
  import os
24
- import typing as ty
25
+ from typing import Any
25
26
 
26
27
  from cliff import columns as cliff_columns
27
28
  import iso8601
@@ -38,7 +39,6 @@ from openstackclient.common import envvars
38
39
  from openstackclient.common import pagination
39
40
  from openstackclient.i18n import _
40
41
  from openstackclient.identity import common as identity_common
41
- from openstackclient.network import common as network_common
42
42
 
43
43
  LOG = logging.getLogger(__name__)
44
44
 
@@ -59,28 +59,31 @@ class PowerStateColumn(cliff_columns.FormattableColumn[int]):
59
59
  'Suspended', # 0x07
60
60
  ]
61
61
 
62
- def human_readable(self):
62
+ def human_readable(self) -> str:
63
63
  try:
64
64
  return self.power_states[self._value]
65
65
  except Exception:
66
66
  return 'N/A'
67
67
 
68
68
 
69
- class AddressesColumn(cliff_columns.FormattableColumn[ty.Any]):
69
+ class AddressesColumn(cliff_columns.FormattableColumn[Any]):
70
70
  """Generate a formatted string of a server's addresses."""
71
71
 
72
- def human_readable(self):
72
+ def human_readable(self) -> str:
73
73
  try:
74
- return utils.format_dict_of_list(
75
- {
76
- k: [i['addr'] for i in v if 'addr' in i]
77
- for k, v in self._value.items()
78
- }
74
+ return (
75
+ utils.format_dict_of_list(
76
+ {
77
+ k: [i['addr'] for i in v if 'addr' in i]
78
+ for k, v in self._value.items()
79
+ }
80
+ )
81
+ or ''
79
82
  )
80
83
  except Exception:
81
84
  return 'N/A'
82
85
 
83
- def machine_readable(self):
86
+ def machine_readable(self) -> Any:
84
87
  return {
85
88
  k: [i['addr'] for i in v if 'addr' in i]
86
89
  for k, v in (self._value.items() if self._value else [])
@@ -90,14 +93,16 @@ class AddressesColumn(cliff_columns.FormattableColumn[ty.Any]):
90
93
  class HostColumn(cliff_columns.FormattableColumn[str | None]):
91
94
  """Generate a formatted string of a hostname."""
92
95
 
93
- def human_readable(self):
96
+ def human_readable(self) -> str:
94
97
  if self._value is None:
95
98
  return ''
96
99
 
97
100
  return self._value
98
101
 
99
102
 
100
- def _get_ip_address(addresses, address_type, ip_address_family):
103
+ def _get_ip_address(
104
+ addresses: Any, address_type: str, ip_address_family: list[int]
105
+ ) -> Any:
101
106
  # Old style addresses
102
107
  if address_type in addresses:
103
108
  for addy in addresses[address_type]:
@@ -130,7 +135,13 @@ def _get_ip_address(addresses, address_type, ip_address_family):
130
135
  )
131
136
 
132
137
 
133
- def _prep_server_detail(compute_client, image_client, server, *, refresh=True):
138
+ def _prep_server_detail(
139
+ compute_client: Any,
140
+ image_client: Any,
141
+ server: Any,
142
+ *,
143
+ refresh: bool = True,
144
+ ) -> dict[str, Any]:
134
145
  """Prepare the detailed server dict for printing
135
146
 
136
147
  :param compute_client: a compute client instance
@@ -352,7 +363,7 @@ def _prep_server_detail(compute_client, image_client, server, *, refresh=True):
352
363
  class AddFixedIP(command.ShowOne):
353
364
  _description = _("Add fixed IP address to server")
354
365
 
355
- def get_parser(self, prog_name):
366
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
356
367
  parser = super().get_parser(prog_name)
357
368
  parser.add_argument(
358
369
  "server",
@@ -381,7 +392,9 @@ class AddFixedIP(command.ShowOne):
381
392
  )
382
393
  return parser
383
394
 
384
- def take_action(self, parsed_args):
395
+ def take_action(
396
+ self, parsed_args: argparse.Namespace
397
+ ) -> tuple[Sequence[str], Iterable[Any]]:
385
398
  compute_client = self.app.client_manager.compute
386
399
  server = compute_client.find_server(
387
400
  parsed_args.server, ignore_missing=False
@@ -403,7 +416,7 @@ class AddFixedIP(command.ShowOne):
403
416
  else:
404
417
  net_id = parsed_args.network
405
418
 
406
- kwargs = {'net_id': net_id}
419
+ kwargs: dict[str, Any] = {'net_id': net_id}
407
420
  if parsed_args.fixed_ip_address:
408
421
  kwargs['fixed_ips'] = [
409
422
  {"ip_address": parsed_args.fixed_ip_address}
@@ -447,10 +460,11 @@ class AddFixedIP(command.ShowOne):
447
460
  )
448
461
 
449
462
 
450
- class AddFloatingIP(network_common.NetworkAndComputeCommand):
463
+ class AddFloatingIP(command.Command):
451
464
  _description = _("Add floating IP address to server")
452
465
 
453
- def update_parser_common(self, parser):
466
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
467
+ parser = super().get_parser(prog_name)
454
468
  parser.add_argument(
455
469
  "server",
456
470
  metavar="<server>",
@@ -475,7 +489,8 @@ class AddFloatingIP(network_common.NetworkAndComputeCommand):
475
489
  )
476
490
  return parser
477
491
 
478
- def take_action_network(self, client, parsed_args):
492
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
493
+ client = self.app.client_manager.network
479
494
  compute_client = self.app.client_manager.compute
480
495
 
481
496
  attrs = {}
@@ -534,19 +549,11 @@ class AddFloatingIP(network_common.NetworkAndComputeCommand):
534
549
  if error:
535
550
  raise error
536
551
 
537
- def take_action_compute(self, client, parsed_args):
538
- server = client.find_server(parsed_args.server, ignore_missing=False)
539
- client.add_floating_ip_to_server(
540
- server,
541
- parsed_args.ip_address,
542
- fixed_address=parsed_args.fixed_ip_address,
543
- )
544
-
545
552
 
546
553
  class AddPort(command.Command):
547
554
  _description = _("Add port to server")
548
555
 
549
- def get_parser(self, prog_name):
556
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
550
557
  parser = super().get_parser(prog_name)
551
558
  parser.add_argument(
552
559
  "server",
@@ -568,7 +575,7 @@ class AddPort(command.Command):
568
575
  )
569
576
  return parser
570
577
 
571
- def take_action(self, parsed_args):
578
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
572
579
  compute_client = self.app.client_manager.compute
573
580
 
574
581
  server = compute_client.find_server(
@@ -600,7 +607,7 @@ class AddPort(command.Command):
600
607
  class AddNetwork(command.Command):
601
608
  _description = _("Add network to server")
602
609
 
603
- def get_parser(self, prog_name):
610
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
604
611
  parser = super().get_parser(prog_name)
605
612
  parser.add_argument(
606
613
  "server",
@@ -622,7 +629,7 @@ class AddNetwork(command.Command):
622
629
  )
623
630
  return parser
624
631
 
625
- def take_action(self, parsed_args):
632
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
626
633
  compute_client = self.app.client_manager.compute
627
634
 
628
635
  server = compute_client.find_server(
@@ -655,7 +662,7 @@ class AddNetwork(command.Command):
655
662
  class AddServerSecurityGroup(command.Command):
656
663
  _description = _("Add security group(s) to server")
657
664
 
658
- def get_parser(self, prog_name):
665
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
659
666
  parser = super().get_parser(prog_name)
660
667
  parser.add_argument(
661
668
  'server',
@@ -673,7 +680,7 @@ class AddServerSecurityGroup(command.Command):
673
680
  )
674
681
  return parser
675
682
 
676
- def take_action(self, parsed_args):
683
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
677
684
  compute_client = self.app.client_manager.compute
678
685
 
679
686
  server = compute_client.find_server(
@@ -729,7 +736,7 @@ Specify ``--os-compute-api-version 2.20`` or higher to add a volume to a server
729
736
  with status ``SHELVED`` or ``SHELVED_OFFLOADED``."""
730
737
  )
731
738
 
732
- def get_parser(self, prog_name):
739
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
733
740
  parser = super().get_parser(prog_name)
734
741
  parser.add_argument(
735
742
  'server',
@@ -775,7 +782,9 @@ with status ``SHELVED`` or ``SHELVED_OFFLOADED``."""
775
782
  )
776
783
  return parser
777
784
 
778
- def take_action(self, parsed_args):
785
+ def take_action(
786
+ self, parsed_args: argparse.Namespace
787
+ ) -> tuple[Sequence[str], Iterable[Any]]:
779
788
  compute_client = self.app.client_manager.compute
780
789
  volume_client = self.app.client_manager.sdk_connection.volume
781
790
 
@@ -849,7 +858,12 @@ with status ``SHELVED`` or ``SHELVED_OFFLOADED``."""
849
858
 
850
859
 
851
860
  class NoneNICAction(argparse.Action):
852
- def __init__(self, option_strings, dest, help=None):
861
+ def __init__(
862
+ self,
863
+ option_strings: list[str],
864
+ dest: str,
865
+ help: str | None = None,
866
+ ) -> None:
853
867
  super().__init__(
854
868
  option_strings=option_strings,
855
869
  dest=dest,
@@ -859,7 +873,13 @@ class NoneNICAction(argparse.Action):
859
873
  help=help,
860
874
  )
861
875
 
862
- def __call__(self, parser, namespace, values, option_string=None):
876
+ def __call__(
877
+ self,
878
+ parser: argparse.ArgumentParser,
879
+ namespace: argparse.Namespace,
880
+ values: Any,
881
+ option_string: str | None = None,
882
+ ) -> None:
863
883
  # Make sure we have an empty dict rather than None
864
884
  if getattr(namespace, self.dest, None) is None:
865
885
  setattr(namespace, self.dest, [])
@@ -868,7 +888,12 @@ class NoneNICAction(argparse.Action):
868
888
 
869
889
 
870
890
  class AutoNICAction(argparse.Action):
871
- def __init__(self, option_strings, dest, help=None):
891
+ def __init__(
892
+ self,
893
+ option_strings: list[str],
894
+ dest: str,
895
+ help: str | None = None,
896
+ ) -> None:
872
897
  super().__init__(
873
898
  option_strings=option_strings,
874
899
  dest=dest,
@@ -878,7 +903,13 @@ class AutoNICAction(argparse.Action):
878
903
  help=help,
879
904
  )
880
905
 
881
- def __call__(self, parser, namespace, values, option_string=None):
906
+ def __call__(
907
+ self,
908
+ parser: argparse.ArgumentParser,
909
+ namespace: argparse.Namespace,
910
+ values: Any,
911
+ option_string: str | None = None,
912
+ ) -> None:
882
913
  # Make sure we have an empty dict rather than None
883
914
  if getattr(namespace, self.dest, None) is None:
884
915
  setattr(namespace, self.dest, [])
@@ -889,12 +920,12 @@ class AutoNICAction(argparse.Action):
889
920
  class NICAction(argparse.Action):
890
921
  def __init__(
891
922
  self,
892
- option_strings,
893
- dest,
894
- help=None,
895
- metavar=None,
896
- key=None,
897
- ):
923
+ option_strings: list[str],
924
+ dest: str,
925
+ help: str | None = None,
926
+ metavar: str | None = None,
927
+ key: str | None = None,
928
+ ) -> None:
898
929
  self.key = key
899
930
  super().__init__(
900
931
  option_strings=option_strings,
@@ -909,7 +940,13 @@ class NICAction(argparse.Action):
909
940
  metavar=metavar,
910
941
  )
911
942
 
912
- def __call__(self, parser, namespace, values, option_string=None):
943
+ def __call__(
944
+ self,
945
+ parser: argparse.ArgumentParser,
946
+ namespace: argparse.Namespace,
947
+ values: Any,
948
+ option_string: str | None = None,
949
+ ) -> None:
913
950
  # Make sure we have an empty dict rather than None
914
951
  if getattr(namespace, self.dest, None) is None:
915
952
  setattr(namespace, self.dest, [])
@@ -940,9 +977,9 @@ class NICAction(argparse.Action):
940
977
  }
941
978
 
942
979
  for kv_str in values.split(','):
943
- k, sep, v = kv_str.partition('=')
980
+ k, _sep, v = kv_str.partition('=')
944
981
 
945
- if k not in list(info) + ['tag'] or not v:
982
+ if k not in [*list(info), 'tag'] or not v:
946
983
  msg = _(
947
984
  "Invalid argument %s; argument must be of form "
948
985
  "'net-id=net-uuid,port-id=port-uuid,v4-fixed-ip=ip-addr,"
@@ -970,12 +1007,18 @@ class NICAction(argparse.Action):
970
1007
 
971
1008
 
972
1009
  class BDMLegacyAction(argparse.Action):
973
- def __call__(self, parser, namespace, values, option_string=None):
1010
+ def __call__(
1011
+ self,
1012
+ parser: argparse.ArgumentParser,
1013
+ namespace: argparse.Namespace,
1014
+ values: Any,
1015
+ option_string: str | None = None,
1016
+ ) -> None:
974
1017
  # Make sure we have an empty list rather than None
975
1018
  if getattr(namespace, self.dest, None) is None:
976
1019
  setattr(namespace, self.dest, [])
977
1020
 
978
- dev_name, sep, dev_map = values.partition('=')
1021
+ dev_name, _sep, dev_map = values.partition('=')
979
1022
  dev_map = dev_map.split(':') if dev_map else dev_map
980
1023
  if not dev_name or not dev_map or len(dev_map) > 4:
981
1024
  msg = _(
@@ -1014,7 +1057,9 @@ class BDMLegacyAction(argparse.Action):
1014
1057
 
1015
1058
 
1016
1059
  class BDMAction(parseractions.MultiKeyValueAction):
1017
- def __init__(self, option_strings, dest, **kwargs):
1060
+ def __init__(
1061
+ self, option_strings: list[str], dest: str, **kwargs: Any
1062
+ ) -> None:
1018
1063
  optional_keys = [
1019
1064
  'uuid',
1020
1065
  'source_type',
@@ -1039,7 +1084,7 @@ class BDMAction(parseractions.MultiKeyValueAction):
1039
1084
 
1040
1085
  # TODO(stephenfin): Remove once I549d0897ef3704b7f47000f867d6731ad15d3f2b
1041
1086
  # or similar lands in a release
1042
- def validate_keys(self, keys):
1087
+ def validate_keys(self, keys: Sequence[str]) -> None:
1043
1088
  """Validate the provided keys.
1044
1089
 
1045
1090
  :param keys: A list of keys to validate.
@@ -1075,7 +1120,13 @@ class BDMAction(parseractions.MultiKeyValueAction):
1075
1120
  },
1076
1121
  )
1077
1122
 
1078
- def __call__(self, parser, namespace, values, option_string=None):
1123
+ def __call__(
1124
+ self,
1125
+ parser: argparse.ArgumentParser,
1126
+ namespace: argparse.Namespace,
1127
+ values: Any,
1128
+ option_string: str | None = None,
1129
+ ) -> None:
1079
1130
  if getattr(namespace, self.dest, None) is None:
1080
1131
  setattr(namespace, self.dest, [])
1081
1132
 
@@ -1094,7 +1145,7 @@ class BDMAction(parseractions.MultiKeyValueAction):
1094
1145
  class CreateServer(command.ShowOne):
1095
1146
  _description = _("Create a new server")
1096
1147
 
1097
- def get_parser(self, prog_name):
1148
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
1098
1149
  parser = super().get_parser(prog_name)
1099
1150
  parser.add_argument(
1100
1151
  'server_name',
@@ -1535,8 +1586,10 @@ class CreateServer(command.ShowOne):
1535
1586
  )
1536
1587
  return parser
1537
1588
 
1538
- def take_action(self, parsed_args):
1539
- def _show_progress(progress):
1589
+ def take_action(
1590
+ self, parsed_args: argparse.Namespace
1591
+ ) -> tuple[Sequence[str], Iterable[Any]]:
1592
+ def _show_progress(progress: int | None) -> None:
1540
1593
  if progress:
1541
1594
  self.app.stdout.write(f'\rProgress: {progress}')
1542
1595
  self.app.stdout.flush()
@@ -1554,7 +1607,7 @@ class CreateServer(command.ShowOne):
1554
1607
 
1555
1608
  if not image and parsed_args.image_properties:
1556
1609
 
1557
- def _match_image(image_api, wanted_properties):
1610
+ def _match_image(image_api: Any, wanted_properties: Any) -> Any:
1558
1611
  image_list = image_api.images()
1559
1612
  images_matched = []
1560
1613
  for img in image_list:
@@ -1909,6 +1962,7 @@ class CreateServer(command.ShowOne):
1909
1962
 
1910
1963
  networks = parsed_args.nics[0]
1911
1964
  else:
1965
+ _networks = []
1912
1966
  for nic in parsed_args.nics:
1913
1967
  if 'tag' in nic:
1914
1968
  if not sdk_utils.supports_microversion(
@@ -1969,7 +2023,8 @@ class CreateServer(command.ShowOne):
1969
2023
  if nic.get('tag'): # tags are optional
1970
2024
  network['tag'] = nic['tag']
1971
2025
 
1972
- networks.append(network) # type: ignore[union-attr]
2026
+ _networks.append(network)
2027
+ networks = _networks
1973
2028
 
1974
2029
  if not parsed_args.nics and sdk_utils.supports_microversion(
1975
2030
  compute_client, '2.37'
@@ -2153,7 +2208,8 @@ class CreateServer(command.ShowOne):
2153
2208
  raise exceptions.CommandError(msg)
2154
2209
 
2155
2210
  data = _prep_server_detail(compute_client, image_client, server)
2156
- return zip(*sorted(data.items()))
2211
+ col_headers, col_data = zip(*sorted(data.items()))
2212
+ return col_headers, col_data
2157
2213
 
2158
2214
 
2159
2215
  class CreateServerDump(command.Command):
@@ -2168,7 +2224,7 @@ class CreateServerDump(command.Command):
2168
2224
  This command requires ``--os-compute-api-version`` 2.17 or greater.
2169
2225
  """
2170
2226
 
2171
- def get_parser(self, prog_name):
2227
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
2172
2228
  parser = super().get_parser(prog_name)
2173
2229
  parser.add_argument(
2174
2230
  'server',
@@ -2178,7 +2234,7 @@ class CreateServerDump(command.Command):
2178
2234
  )
2179
2235
  return parser
2180
2236
 
2181
- def take_action(self, parsed_args):
2237
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
2182
2238
  compute_client = self.app.client_manager.compute
2183
2239
  for name_or_id in parsed_args.server:
2184
2240
  server = compute_client.find_server(
@@ -2190,7 +2246,7 @@ class CreateServerDump(command.Command):
2190
2246
  class DeleteServer(command.Command):
2191
2247
  _description = _("Delete server(s)")
2192
2248
 
2193
- def get_parser(self, prog_name):
2249
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
2194
2250
  parser = super().get_parser(prog_name)
2195
2251
  parser.add_argument(
2196
2252
  'server',
@@ -2219,8 +2275,8 @@ class DeleteServer(command.Command):
2219
2275
  )
2220
2276
  return parser
2221
2277
 
2222
- def take_action(self, parsed_args):
2223
- def _show_progress(progress):
2278
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
2279
+ def _show_progress(progress: int | None) -> None:
2224
2280
  if progress:
2225
2281
  self.app.stdout.write(f'\rProgress: {progress}')
2226
2282
  self.app.stdout.flush()
@@ -2273,17 +2329,17 @@ class DeleteServer(command.Command):
2273
2329
  class PercentAction(argparse.Action):
2274
2330
  def __init__(
2275
2331
  self,
2276
- option_strings,
2277
- dest,
2278
- nargs=None,
2279
- const=None,
2280
- default=None,
2281
- type=None,
2282
- choices=None,
2283
- required=False,
2284
- help=None,
2285
- metavar=None,
2286
- ):
2332
+ option_strings: list[str],
2333
+ dest: str,
2334
+ nargs: int | str | None = None,
2335
+ const: Any = None,
2336
+ default: Any = None,
2337
+ type: Any = None,
2338
+ choices: Any = None,
2339
+ required: bool = False,
2340
+ help: str | None = None,
2341
+ metavar: str | tuple[str, ...] | None = None,
2342
+ ) -> None:
2287
2343
  if nargs == 0:
2288
2344
  raise ValueError(
2289
2345
  'nargs for store actions must be != 0; if you '
@@ -2307,7 +2363,13 @@ class PercentAction(argparse.Action):
2307
2363
  metavar=metavar,
2308
2364
  )
2309
2365
 
2310
- def __call__(self, parser, namespace, values, option_string=None):
2366
+ def __call__(
2367
+ self,
2368
+ parser: argparse.ArgumentParser,
2369
+ namespace: argparse.Namespace,
2370
+ values: Any,
2371
+ option_string: str | None = None,
2372
+ ) -> None:
2311
2373
  x = int(values)
2312
2374
  if not 0 < x <= 100:
2313
2375
  raise argparse.ArgumentError(self, "Must be between 0 and 100")
@@ -2317,7 +2379,7 @@ class PercentAction(argparse.Action):
2317
2379
  class ListServer(command.Lister):
2318
2380
  _description = _("List servers")
2319
2381
 
2320
- def get_parser(self, prog_name):
2382
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
2321
2383
  parser = super().get_parser(prog_name)
2322
2384
  parser.add_argument(
2323
2385
  '--reservation-id',
@@ -2657,7 +2719,9 @@ class ListServer(command.Lister):
2657
2719
  )
2658
2720
  return parser
2659
2721
 
2660
- def take_action(self, parsed_args):
2722
+ def take_action(
2723
+ self, parsed_args: argparse.Namespace
2724
+ ) -> tuple[tuple[str, ...], Iterable[tuple[Any, ...]]]:
2661
2725
  compute_client = self.app.client_manager.compute
2662
2726
  identity_client = self.app.client_manager.identity
2663
2727
  image_client = self.app.client_manager.image
@@ -3071,9 +3135,8 @@ class ListServer(command.Lister):
3071
3135
  s.image_id = IMAGE_STRING_FOR_BFV
3072
3136
 
3073
3137
  if not sdk_utils.supports_microversion(compute_client, '2.47'):
3074
- flavor = flavors.get(s.flavor['id'])
3075
- if flavor:
3076
- s.flavor_name = flavor.name
3138
+ if s.flavor['id'] in flavors:
3139
+ s.flavor_name = flavors[s.flavor['id']].name
3077
3140
  s.flavor_id = s.flavor['id']
3078
3141
  else:
3079
3142
  s.flavor_name = s.flavor['original_name']
@@ -3134,7 +3197,7 @@ class LockServer(command.Command):
3134
3197
  A non-admin user will not be able to execute actions."""
3135
3198
  )
3136
3199
 
3137
- def get_parser(self, prog_name):
3200
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
3138
3201
  parser = super().get_parser(prog_name)
3139
3202
  parser.add_argument(
3140
3203
  'server',
@@ -3153,7 +3216,7 @@ A non-admin user will not be able to execute actions."""
3153
3216
  )
3154
3217
  return parser
3155
3218
 
3156
- def take_action(self, parsed_args):
3219
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
3157
3220
  compute_client = self.app.client_manager.compute
3158
3221
 
3159
3222
  kwargs = {}
@@ -3189,16 +3252,25 @@ class MigrateServer(command.Command):
3189
3252
  _description = _(
3190
3253
  """Migrate server to different host.
3191
3254
 
3192
- A migrate operation is implemented as a resize operation using the same flavor
3193
- as the old server. This means that, like resize, migrate works by creating a
3194
- new server using the same flavor and copying the contents of the original disk
3195
- into a new one. As with resize, the migrate operation is a two-step process for
3196
- the user: the first step is to perform the migrate, and the second step is to
3197
- either confirm (verify) success and release the old server, or to declare a
3198
- revert to release the new server and restart the old one."""
3255
+ There are two types of migration operation: a cold migration and a live
3256
+ migration.
3257
+
3258
+ A cold migration operation is implemented as a resize operation
3259
+ using the same flavor as the old server. This means that, like resize, migrate
3260
+ works by shutting down the original server, creating a new server using the
3261
+ same flavor and copying the contents of the original disk into a new one.
3262
+ As with resize, the migrate operation is a two-step process for the user:
3263
+ the first step is to perform the migrate, and the second step is to either
3264
+ confirm (verify) success and release the old server, or to declare a revert
3265
+ to release the new server and restart the old one.
3266
+
3267
+ By comparison, a live migration operation does not involve shutting the server
3268
+ down, and is a one-step process that does not require a confirmation or revert
3269
+ to finish.
3270
+ """
3199
3271
  )
3200
3272
 
3201
- def get_parser(self, prog_name):
3273
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
3202
3274
  parser = super().get_parser(prog_name)
3203
3275
  parser.add_argument(
3204
3276
  'server',
@@ -3272,8 +3344,8 @@ revert to release the new server and restart the old one."""
3272
3344
  )
3273
3345
  return parser
3274
3346
 
3275
- def take_action(self, parsed_args):
3276
- def _show_progress(progress):
3347
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
3348
+ def _show_progress(progress: int | None) -> None:
3277
3349
  if progress:
3278
3350
  self.app.stdout.write(f'\rProgress: {progress}')
3279
3351
  self.app.stdout.flush()
@@ -3370,7 +3442,7 @@ revert to release the new server and restart the old one."""
3370
3442
  class PauseServer(command.Command):
3371
3443
  _description = _("Pause server(s)")
3372
3444
 
3373
- def get_parser(self, prog_name):
3445
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
3374
3446
  parser = super().get_parser(prog_name)
3375
3447
  parser.add_argument(
3376
3448
  'server',
@@ -3380,7 +3452,7 @@ class PauseServer(command.Command):
3380
3452
  )
3381
3453
  return parser
3382
3454
 
3383
- def take_action(self, parsed_args):
3455
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
3384
3456
  compute_client = self.app.client_manager.compute
3385
3457
  for server in parsed_args.server:
3386
3458
  server_id = compute_client.find_server(
@@ -3393,7 +3465,7 @@ class PauseServer(command.Command):
3393
3465
  class RebootServer(command.Command):
3394
3466
  _description = _("Perform a hard or soft server reboot")
3395
3467
 
3396
- def get_parser(self, prog_name):
3468
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
3397
3469
  parser = super().get_parser(prog_name)
3398
3470
  parser.add_argument(
3399
3471
  'server',
@@ -3424,8 +3496,8 @@ class RebootServer(command.Command):
3424
3496
  )
3425
3497
  return parser
3426
3498
 
3427
- def take_action(self, parsed_args):
3428
- def _show_progress(progress):
3499
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
3500
+ def _show_progress(progress: int | None) -> None:
3429
3501
  if progress:
3430
3502
  self.app.stdout.write(f'\rProgress: {progress}')
3431
3503
  self.app.stdout.flush()
@@ -3453,7 +3525,7 @@ class RebootServer(command.Command):
3453
3525
  class RebuildServer(command.ShowOne):
3454
3526
  _description = _("Rebuild server")
3455
3527
 
3456
- def get_parser(self, prog_name):
3528
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
3457
3529
  parser = super().get_parser(prog_name)
3458
3530
  parser.add_argument(
3459
3531
  'server',
@@ -3629,8 +3701,10 @@ class RebuildServer(command.ShowOne):
3629
3701
  )
3630
3702
  return parser
3631
3703
 
3632
- def take_action(self, parsed_args):
3633
- def _show_progress(progress):
3704
+ def take_action(
3705
+ self, parsed_args: argparse.Namespace
3706
+ ) -> tuple[Sequence[str], Iterable[Any]]:
3707
+ def _show_progress(progress: int | None) -> None:
3634
3708
  if progress:
3635
3709
  self.app.stdout.write(f'\rProgress: {progress}')
3636
3710
  self.app.stdout.flush()
@@ -3822,7 +3896,8 @@ class RebuildServer(command.ShowOne):
3822
3896
  data = _prep_server_detail(
3823
3897
  compute_client, image_client, server, refresh=False
3824
3898
  )
3825
- return zip(*sorted(data.items()))
3899
+ col_headers, col_data = zip(*sorted(data.items()))
3900
+ return col_headers, col_data
3826
3901
 
3827
3902
 
3828
3903
  class EvacuateServer(command.ShowOne):
@@ -3843,7 +3918,7 @@ root disk will be preserved and reused for the evacuated instance on the new
3843
3918
  host."""
3844
3919
  )
3845
3920
 
3846
- def get_parser(self, prog_name):
3921
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
3847
3922
  parser = super().get_parser(prog_name)
3848
3923
  parser.add_argument(
3849
3924
  'server',
@@ -3890,8 +3965,10 @@ host."""
3890
3965
  )
3891
3966
  return parser
3892
3967
 
3893
- def take_action(self, parsed_args):
3894
- def _show_progress(progress):
3968
+ def take_action(
3969
+ self, parsed_args: argparse.Namespace
3970
+ ) -> tuple[Sequence[str], Iterable[Any]]:
3971
+ def _show_progress(progress: int | None) -> None:
3895
3972
  if progress:
3896
3973
  self.app.stdout.write(f'\rProgress: {progress}')
3897
3974
  self.app.stdout.flush()
@@ -3946,13 +4023,14 @@ host."""
3946
4023
  raise exceptions.CommandError(msg)
3947
4024
 
3948
4025
  data = _prep_server_detail(compute_client, image_client, server)
3949
- return zip(*sorted(data.items()))
4026
+ col_headers, col_data = zip(*sorted(data.items()))
4027
+ return col_headers, col_data
3950
4028
 
3951
4029
 
3952
4030
  class RemoveFixedIP(command.Command):
3953
4031
  _description = _("Remove fixed IP address from server")
3954
4032
 
3955
- def get_parser(self, prog_name):
4033
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
3956
4034
  parser = super().get_parser(prog_name)
3957
4035
  parser.add_argument(
3958
4036
  "server",
@@ -3966,7 +4044,7 @@ class RemoveFixedIP(command.Command):
3966
4044
  )
3967
4045
  return parser
3968
4046
 
3969
- def take_action(self, parsed_args):
4047
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
3970
4048
  compute_client = self.app.client_manager.compute
3971
4049
 
3972
4050
  server = compute_client.find_server(
@@ -3977,10 +4055,11 @@ class RemoveFixedIP(command.Command):
3977
4055
  )
3978
4056
 
3979
4057
 
3980
- class RemoveFloatingIP(network_common.NetworkAndComputeCommand):
4058
+ class RemoveFloatingIP(command.Command):
3981
4059
  _description = _("Remove floating IP address from server")
3982
4060
 
3983
- def update_parser_common(self, parser):
4061
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
4062
+ parser = super().get_parser(prog_name)
3984
4063
  parser.add_argument(
3985
4064
  "server",
3986
4065
  metavar="<server>",
@@ -3995,7 +4074,8 @@ class RemoveFloatingIP(network_common.NetworkAndComputeCommand):
3995
4074
  )
3996
4075
  return parser
3997
4076
 
3998
- def take_action_network(self, client, parsed_args):
4077
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
4078
+ client = self.app.client_manager.network
3999
4079
  obj = client.find_ip(
4000
4080
  parsed_args.ip_address,
4001
4081
  ignore_missing=False,
@@ -4003,15 +4083,11 @@ class RemoveFloatingIP(network_common.NetworkAndComputeCommand):
4003
4083
 
4004
4084
  client.update_ip(obj, port_id=None)
4005
4085
 
4006
- def take_action_compute(self, client, parsed_args):
4007
- server = client.find_server(parsed_args.server, ignore_missing=False)
4008
- client.remove_floating_ip_from_server(server, parsed_args.ip_address)
4009
-
4010
4086
 
4011
4087
  class RemovePort(command.Command):
4012
4088
  _description = _("Remove port from server")
4013
4089
 
4014
- def get_parser(self, prog_name):
4090
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
4015
4091
  parser = super().get_parser(prog_name)
4016
4092
  parser.add_argument(
4017
4093
  "server",
@@ -4025,7 +4101,7 @@ class RemovePort(command.Command):
4025
4101
  )
4026
4102
  return parser
4027
4103
 
4028
- def take_action(self, parsed_args):
4104
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
4029
4105
  compute_client = self.app.client_manager.compute
4030
4106
 
4031
4107
  server = compute_client.find_server(
@@ -4050,7 +4126,7 @@ class RemovePort(command.Command):
4050
4126
  class RemoveNetwork(command.Command):
4051
4127
  _description = _("Remove all ports of a network from server")
4052
4128
 
4053
- def get_parser(self, prog_name):
4129
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
4054
4130
  parser = super().get_parser(prog_name)
4055
4131
  parser.add_argument(
4056
4132
  "server",
@@ -4064,7 +4140,7 @@ class RemoveNetwork(command.Command):
4064
4140
  )
4065
4141
  return parser
4066
4142
 
4067
- def take_action(self, parsed_args):
4143
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
4068
4144
  compute_client = self.app.client_manager.compute
4069
4145
 
4070
4146
  server = compute_client.find_server(
@@ -4090,7 +4166,7 @@ class RemoveNetwork(command.Command):
4090
4166
  class RemoveServerSecurityGroup(command.Command):
4091
4167
  _description = _("Remove security group from server")
4092
4168
 
4093
- def get_parser(self, prog_name):
4169
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
4094
4170
  parser = super().get_parser(prog_name)
4095
4171
  parser.add_argument(
4096
4172
  'server',
@@ -4108,7 +4184,7 @@ class RemoveServerSecurityGroup(command.Command):
4108
4184
  )
4109
4185
  return parser
4110
4186
 
4111
- def take_action(self, parsed_args):
4187
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
4112
4188
  compute_client = self.app.client_manager.compute
4113
4189
 
4114
4190
  server = compute_client.find_server(
@@ -4164,7 +4240,7 @@ Specify ``--os-compute-api-version 2.20`` or higher to remove a
4164
4240
  volume from a server with status ``SHELVED`` or ``SHELVED_OFFLOADED``."""
4165
4241
  )
4166
4242
 
4167
- def get_parser(self, prog_name):
4243
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
4168
4244
  parser = super().get_parser(prog_name)
4169
4245
  parser.add_argument(
4170
4246
  'server',
@@ -4178,7 +4254,7 @@ volume from a server with status ``SHELVED`` or ``SHELVED_OFFLOADED``."""
4178
4254
  )
4179
4255
  return parser
4180
4256
 
4181
- def take_action(self, parsed_args):
4257
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
4182
4258
  compute_client = self.app.client_manager.compute
4183
4259
  volume_client = self.app.client_manager.sdk_connection.volume
4184
4260
 
@@ -4206,7 +4282,7 @@ Specify ``--os-compute-api-version 2.87`` or higher to rescue a
4206
4282
  server booted from a volume."""
4207
4283
  )
4208
4284
 
4209
- def get_parser(self, prog_name):
4285
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
4210
4286
  parser = super().get_parser(prog_name)
4211
4287
  parser.add_argument(
4212
4288
  'server',
@@ -4231,7 +4307,7 @@ server booted from a volume."""
4231
4307
  )
4232
4308
  return parser
4233
4309
 
4234
- def take_action(self, parsed_args):
4310
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
4235
4311
  compute_client = self.app.client_manager.compute
4236
4312
  image_client = self.app.client_manager.image
4237
4313
 
@@ -4260,7 +4336,7 @@ confirm (verify) success and release the old server or to declare a revert to
4260
4336
  release the new server and restart the old one."""
4261
4337
  )
4262
4338
 
4263
- def get_parser(self, prog_name):
4339
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
4264
4340
  parser = super().get_parser(prog_name)
4265
4341
  parser.add_argument(
4266
4342
  'server',
@@ -4298,8 +4374,8 @@ release the new server and restart the old one."""
4298
4374
  )
4299
4375
  return parser
4300
4376
 
4301
- def take_action(self, parsed_args):
4302
- def _show_progress(progress):
4377
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
4378
+ def _show_progress(progress: int | None) -> None:
4303
4379
  if progress:
4304
4380
  self.app.stdout.write(f'\rProgress: {progress}')
4305
4381
  self.app.stdout.flush()
@@ -4356,7 +4432,7 @@ class ResizeConfirm(command.Command):
4356
4432
  Confirm (verify) success of resize operation and release the old server."""
4357
4433
  )
4358
4434
 
4359
- def get_parser(self, prog_name):
4435
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
4360
4436
  parser = super().get_parser(prog_name)
4361
4437
  parser.add_argument(
4362
4438
  'server',
@@ -4365,7 +4441,7 @@ Confirm (verify) success of resize operation and release the old server."""
4365
4441
  )
4366
4442
  return parser
4367
4443
 
4368
- def take_action(self, parsed_args):
4444
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
4369
4445
  compute_client = self.app.client_manager.compute
4370
4446
  server = compute_client.find_server(
4371
4447
  parsed_args.server, ignore_missing=False
@@ -4377,7 +4453,7 @@ Confirm (verify) success of resize operation and release the old server."""
4377
4453
  class MigrateConfirm(ResizeConfirm):
4378
4454
  _description = _("DEPRECATED: Use 'server migration confirm' instead.")
4379
4455
 
4380
- def take_action(self, parsed_args):
4456
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
4381
4457
  msg = _(
4382
4458
  "The 'server migrate confirm' command has been deprecated in "
4383
4459
  "favour of the 'server migration confirm' command."
@@ -4404,7 +4480,7 @@ Revert the resize operation. Release the new server and restart the old
4404
4480
  one."""
4405
4481
  )
4406
4482
 
4407
- def get_parser(self, prog_name):
4483
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
4408
4484
  parser = super().get_parser(prog_name)
4409
4485
  parser.add_argument(
4410
4486
  'server',
@@ -4413,7 +4489,7 @@ one."""
4413
4489
  )
4414
4490
  return parser
4415
4491
 
4416
- def take_action(self, parsed_args):
4492
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
4417
4493
  compute_client = self.app.client_manager.compute
4418
4494
  server = compute_client.find_server(
4419
4495
  parsed_args.server, ignore_missing=False
@@ -4425,7 +4501,7 @@ one."""
4425
4501
  class MigrateRevert(ResizeRevert):
4426
4502
  _description = _("DEPRECATED: Use 'server migration revert' instead.")
4427
4503
 
4428
- def take_action(self, parsed_args):
4504
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
4429
4505
  msg = _(
4430
4506
  "The 'server migrate revert' command has been deprecated in "
4431
4507
  "favour of the 'server migration revert' command."
@@ -4447,7 +4523,7 @@ one."""
4447
4523
  class RestoreServer(command.Command):
4448
4524
  _description = _("Restore server(s)")
4449
4525
 
4450
- def get_parser(self, prog_name):
4526
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
4451
4527
  parser = super().get_parser(prog_name)
4452
4528
  parser.add_argument(
4453
4529
  'server',
@@ -4457,7 +4533,7 @@ class RestoreServer(command.Command):
4457
4533
  )
4458
4534
  return parser
4459
4535
 
4460
- def take_action(self, parsed_args):
4536
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
4461
4537
  compute_client = self.app.client_manager.compute
4462
4538
  for server in parsed_args.server:
4463
4539
  server_id = compute_client.find_server(
@@ -4470,7 +4546,7 @@ class RestoreServer(command.Command):
4470
4546
  class ResumeServer(command.Command):
4471
4547
  _description = _("Resume server(s)")
4472
4548
 
4473
- def get_parser(self, prog_name):
4549
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
4474
4550
  parser = super().get_parser(prog_name)
4475
4551
  parser.add_argument(
4476
4552
  'server',
@@ -4480,7 +4556,7 @@ class ResumeServer(command.Command):
4480
4556
  )
4481
4557
  return parser
4482
4558
 
4483
- def take_action(self, parsed_args):
4559
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
4484
4560
  compute_client = self.app.client_manager.compute
4485
4561
  for server in parsed_args.server:
4486
4562
  server_id = compute_client.find_server(
@@ -4493,7 +4569,7 @@ class ResumeServer(command.Command):
4493
4569
  class SetServer(command.Command):
4494
4570
  _description = _("Set server properties")
4495
4571
 
4496
- def get_parser(self, prog_name):
4572
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
4497
4573
  parser = super().get_parser(prog_name)
4498
4574
  parser.add_argument(
4499
4575
  'server',
@@ -4593,7 +4669,7 @@ class SetServer(command.Command):
4593
4669
  return parser
4594
4670
 
4595
4671
  @staticmethod
4596
- def ask_user_yesno(msg):
4672
+ def ask_user_yesno(msg: str) -> bool:
4597
4673
  """Ask user Y/N question
4598
4674
 
4599
4675
  :param str msg: question text
@@ -4606,7 +4682,7 @@ class SetServer(command.Command):
4606
4682
  elif answer in ('n', 'N', 'no'):
4607
4683
  return False
4608
4684
 
4609
- def take_action(self, parsed_args):
4685
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
4610
4686
  compute_client = self.app.client_manager.compute
4611
4687
  server = compute_client.find_server(
4612
4688
  parsed_args.server, ignore_missing=False
@@ -4704,7 +4780,7 @@ class ShelveServer(command.Command):
4704
4780
  specified. This is an admin-only operation by default.
4705
4781
  """
4706
4782
 
4707
- def get_parser(self, prog_name):
4783
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
4708
4784
  parser = super().get_parser(prog_name)
4709
4785
  parser.add_argument(
4710
4786
  'servers',
@@ -4730,8 +4806,8 @@ class ShelveServer(command.Command):
4730
4806
  )
4731
4807
  return parser
4732
4808
 
4733
- def take_action(self, parsed_args):
4734
- def _show_progress(progress):
4809
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
4810
+ def _show_progress(progress: int | None) -> None:
4735
4811
  if progress:
4736
4812
  self.app.stdout.write(f'\rProgress: {progress}')
4737
4813
  self.app.stdout.flush()
@@ -4804,7 +4880,7 @@ Specify ``--os-compute-api-version 2.47`` or higher to see the embedded flavor
4804
4880
  information for the server."""
4805
4881
  )
4806
4882
 
4807
- def get_parser(self, prog_name):
4883
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
4808
4884
  parser = super().get_parser(prog_name)
4809
4885
  parser.add_argument(
4810
4886
  'server',
@@ -4830,7 +4906,9 @@ information for the server."""
4830
4906
  )
4831
4907
  return parser
4832
4908
 
4833
- def take_action(self, parsed_args):
4909
+ def take_action(
4910
+ self, parsed_args: argparse.Namespace
4911
+ ) -> tuple[Sequence[str], Iterable[Any]]:
4834
4912
  compute_client = self.app.client_manager.compute
4835
4913
  image_client = self.app.client_manager.image
4836
4914
 
@@ -4842,7 +4920,8 @@ information for the server."""
4842
4920
 
4843
4921
  if parsed_args.diagnostics:
4844
4922
  data = compute_client.get_server_diagnostics(server)
4845
- return zip(*sorted(data.items()))
4923
+ col_headers, col_data = zip(*sorted(data.items()))
4924
+ return col_headers, col_data
4846
4925
 
4847
4926
  topology = None
4848
4927
  if parsed_args.topology:
@@ -4860,13 +4939,14 @@ information for the server."""
4860
4939
  )
4861
4940
  if topology:
4862
4941
  data['topology'] = format_columns.DictColumn(topology)
4863
- return zip(*sorted(data.items()))
4942
+ col_headers, col_data = zip(*sorted(data.items()))
4943
+ return col_headers, col_data
4864
4944
 
4865
4945
 
4866
4946
  class SshServer(command.Command):
4867
4947
  _description = _("SSH to server")
4868
4948
 
4869
- def get_parser(self, prog_name):
4949
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
4870
4950
  parser = super().get_parser(prog_name)
4871
4951
  parser.add_argument(
4872
4952
  'server',
@@ -4960,7 +5040,7 @@ class SshServer(command.Command):
4960
5040
  )
4961
5041
  return parser
4962
5042
 
4963
- def take_action(self, parsed_args):
5043
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
4964
5044
  compute_client = self.app.client_manager.compute
4965
5045
 
4966
5046
  server = compute_client.find_server(
@@ -5017,7 +5097,7 @@ class SshServer(command.Command):
5017
5097
  ip_address_family,
5018
5098
  )
5019
5099
 
5020
- cmd = ' '.join(['ssh', ip_address] + args)
5100
+ cmd = ' '.join(['ssh', ip_address, *args])
5021
5101
  LOG.debug('ssh command: %s', cmd)
5022
5102
  # we intentionally pass through user-provided arguments and run this in
5023
5103
  # the user's shell
@@ -5027,7 +5107,7 @@ class SshServer(command.Command):
5027
5107
  class StartServer(command.Command):
5028
5108
  _description = _("Start server(s)")
5029
5109
 
5030
- def get_parser(self, prog_name):
5110
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
5031
5111
  parser = super().get_parser(prog_name)
5032
5112
  parser.add_argument(
5033
5113
  'server',
@@ -5046,7 +5126,7 @@ class StartServer(command.Command):
5046
5126
  )
5047
5127
  return parser
5048
5128
 
5049
- def take_action(self, parsed_args):
5129
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
5050
5130
  compute_client = self.app.client_manager.compute
5051
5131
  for server in parsed_args.server:
5052
5132
  server_id = compute_client.find_server(
@@ -5062,7 +5142,7 @@ class StartServer(command.Command):
5062
5142
  class StopServer(command.Command):
5063
5143
  _description = _("Stop server(s)")
5064
5144
 
5065
- def get_parser(self, prog_name):
5145
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
5066
5146
  parser = super().get_parser(prog_name)
5067
5147
  parser.add_argument(
5068
5148
  'server',
@@ -5081,7 +5161,7 @@ class StopServer(command.Command):
5081
5161
  )
5082
5162
  return parser
5083
5163
 
5084
- def take_action(self, parsed_args):
5164
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
5085
5165
  compute_client = self.app.client_manager.compute
5086
5166
  for server in parsed_args.server:
5087
5167
  server_id = compute_client.find_server(
@@ -5096,7 +5176,7 @@ class StopServer(command.Command):
5096
5176
  class SuspendServer(command.Command):
5097
5177
  _description = _("Suspend server(s)")
5098
5178
 
5099
- def get_parser(self, prog_name):
5179
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
5100
5180
  parser = super().get_parser(prog_name)
5101
5181
  parser.add_argument(
5102
5182
  'server',
@@ -5106,7 +5186,7 @@ class SuspendServer(command.Command):
5106
5186
  )
5107
5187
  return parser
5108
5188
 
5109
- def take_action(self, parsed_args):
5189
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
5110
5190
  compute_client = self.app.client_manager.compute
5111
5191
  for server in parsed_args.server:
5112
5192
  server_id = compute_client.find_server(
@@ -5119,7 +5199,7 @@ class SuspendServer(command.Command):
5119
5199
  class UnlockServer(command.Command):
5120
5200
  _description = _("Unlock server(s)")
5121
5201
 
5122
- def get_parser(self, prog_name):
5202
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
5123
5203
  parser = super().get_parser(prog_name)
5124
5204
  parser.add_argument(
5125
5205
  'server',
@@ -5129,7 +5209,7 @@ class UnlockServer(command.Command):
5129
5209
  )
5130
5210
  return parser
5131
5211
 
5132
- def take_action(self, parsed_args):
5212
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
5133
5213
  compute_client = self.app.client_manager.compute
5134
5214
  for server in parsed_args.server:
5135
5215
  server_id = compute_client.find_server(
@@ -5142,7 +5222,7 @@ class UnlockServer(command.Command):
5142
5222
  class UnpauseServer(command.Command):
5143
5223
  _description = _("Unpause server(s)")
5144
5224
 
5145
- def get_parser(self, prog_name):
5225
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
5146
5226
  parser = super().get_parser(prog_name)
5147
5227
  parser.add_argument(
5148
5228
  'server',
@@ -5152,7 +5232,7 @@ class UnpauseServer(command.Command):
5152
5232
  )
5153
5233
  return parser
5154
5234
 
5155
- def take_action(self, parsed_args):
5235
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
5156
5236
  compute_client = self.app.client_manager.compute
5157
5237
  for server in parsed_args.server:
5158
5238
  server_id = compute_client.find_server(
@@ -5165,7 +5245,7 @@ class UnpauseServer(command.Command):
5165
5245
  class UnrescueServer(command.Command):
5166
5246
  _description = _("Restore server from rescue mode")
5167
5247
 
5168
- def get_parser(self, prog_name):
5248
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
5169
5249
  parser = super().get_parser(prog_name)
5170
5250
  parser.add_argument(
5171
5251
  'server',
@@ -5174,7 +5254,7 @@ class UnrescueServer(command.Command):
5174
5254
  )
5175
5255
  return parser
5176
5256
 
5177
- def take_action(self, parsed_args):
5257
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
5178
5258
  compute_client = self.app.client_manager.compute
5179
5259
  server = compute_client.find_server(
5180
5260
  parsed_args.server, ignore_missing=False
@@ -5185,7 +5265,7 @@ class UnrescueServer(command.Command):
5185
5265
  class UnsetServer(command.Command):
5186
5266
  _description = _("Unset server properties and tags")
5187
5267
 
5188
- def get_parser(self, prog_name):
5268
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
5189
5269
  parser = super().get_parser(prog_name)
5190
5270
  parser.add_argument(
5191
5271
  'server',
@@ -5241,7 +5321,7 @@ class UnsetServer(command.Command):
5241
5321
  )
5242
5322
  return parser
5243
5323
 
5244
- def take_action(self, parsed_args):
5324
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
5245
5325
  compute_client = self.app.client_manager.compute
5246
5326
 
5247
5327
  server = compute_client.find_server(
@@ -5281,7 +5361,7 @@ class UnsetServer(command.Command):
5281
5361
  class UnshelveServer(command.Command):
5282
5362
  _description = _("Unshelve server(s)")
5283
5363
 
5284
- def get_parser(self, prog_name):
5364
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
5285
5365
  parser = super().get_parser(prog_name)
5286
5366
  parser.add_argument(
5287
5367
  'server',
@@ -5327,8 +5407,8 @@ class UnshelveServer(command.Command):
5327
5407
  )
5328
5408
  return parser
5329
5409
 
5330
- def take_action(self, parsed_args):
5331
- def _show_progress(progress):
5410
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
5411
+ def _show_progress(progress: int | None) -> None:
5332
5412
  if progress:
5333
5413
  self.app.stdout.write(f'\rProgress: {progress}')
5334
5414
  self.app.stdout.flush()