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
@@ -136,8 +136,7 @@ class CreateRequestToken(command.ShowOne):
136
136
  '--project',
137
137
  metavar='<project>',
138
138
  help=_(
139
- 'Project that consumer wants to access (name or ID)'
140
- ' (required)'
139
+ 'Project that consumer wants to access (name or ID) (required)'
141
140
  ),
142
141
  required=True,
143
142
  )
@@ -123,37 +123,67 @@ class CreateTrust(command.ShowOne):
123
123
  # pointless, and trusts are immutable, so let's enforce it at the
124
124
  # client level.
125
125
  try:
126
- trustor_id = identity_client.find_user(
127
- parsed_args.trustor, parsed_args.trustor_domain
128
- ).id
129
- kwargs['trustor_id'] = trustor_id
126
+ if parsed_args.trustor_domain:
127
+ trustor_domain_id = identity_client.find_domain(
128
+ parsed_args.trustor_domain, ignore_missing=False
129
+ ).id
130
+ trustor_id = identity_client.find_user(
131
+ parsed_args.trustor,
132
+ ignore_missing=False,
133
+ domain_id=trustor_domain_id,
134
+ ).id
135
+ else:
136
+ trustor_id = identity_client.find_user(
137
+ parsed_args.trustor, ignore_missing=False
138
+ ).id
139
+ kwargs['trustor_user_id'] = trustor_id
130
140
  except sdk_exceptions.ForbiddenException:
131
- kwargs['trustor_id'] = parsed_args.trustor
141
+ kwargs['trustor_user_id'] = parsed_args.trustor
132
142
 
133
143
  try:
134
- trustee_id = identity_client.find_user(
135
- parsed_args.trustee, parsed_args.trustee_domain
136
- ).id
137
- kwargs['trustee_id'] = trustee_id
144
+ if parsed_args.trustee_domain:
145
+ trustee_domain_id = identity_client.find_domain(
146
+ parsed_args.trustee_domain, ignore_missing=False
147
+ ).id
148
+ trustee_id = identity_client.find_user(
149
+ parsed_args.trustee,
150
+ ignore_missing=False,
151
+ domain_id=trustee_domain_id,
152
+ ).id
153
+ else:
154
+ trustee_id = identity_client.find_user(
155
+ parsed_args.trustee, ignore_missing=False
156
+ ).id
157
+ kwargs['trustee_user_id'] = trustee_id
138
158
  except sdk_exceptions.ForbiddenException:
139
- kwargs['trustee_id'] = parsed_args.trustee
159
+ kwargs['trustee_user_id'] = parsed_args.trustee
140
160
 
141
161
  try:
142
- project_id = identity_client.find_project(
143
- parsed_args.project, parsed_args.project_domain
144
- ).id
162
+ if parsed_args.project_domain:
163
+ project_domain_id = identity_client.find_domain(
164
+ parsed_args.project_domain, ignore_missing=False
165
+ ).id
166
+ project_id = identity_client.find_project(
167
+ parsed_args.project,
168
+ ignore_missing=False,
169
+ domain_id=project_domain_id,
170
+ ).id
171
+ else:
172
+ project_id = identity_client.find_project(
173
+ parsed_args.project, ignore_missing=False
174
+ ).id
145
175
  kwargs['project_id'] = project_id
146
176
  except sdk_exceptions.ForbiddenException:
147
177
  kwargs['project_id'] = parsed_args.project
148
178
 
149
- role_ids = []
179
+ roles = []
150
180
  for role in parsed_args.roles:
151
181
  try:
152
182
  role_id = identity_client.find_role(role).id
153
183
  except sdk_exceptions.ForbiddenException:
154
184
  role_id = role
155
- role_ids.append(role_id)
156
- kwargs['roles'] = role_ids
185
+ roles.append({"id": role_id})
186
+ kwargs['roles'] = roles
157
187
 
158
188
  if parsed_args.expiration:
159
189
  expires_at = datetime.datetime.strptime(
@@ -161,8 +191,7 @@ class CreateTrust(command.ShowOne):
161
191
  )
162
192
  kwargs['expires_at'] = expires_at
163
193
 
164
- if parsed_args.is_impersonation:
165
- kwargs['is_impersonation'] = parsed_args.is_impersonation
194
+ kwargs['impersonation'] = bool(parsed_args.is_impersonation)
166
195
 
167
196
  trust = identity_client.create_trust(**kwargs)
168
197
 
@@ -204,7 +233,7 @@ class DeleteTrust(command.Command):
204
233
 
205
234
  if errors > 0:
206
235
  total = len(parsed_args.trust)
207
- msg = _("%(errors)s of %(total)s trusts failed " "to delete.") % {
236
+ msg = _("%(errors)s of %(total)s trusts failed to delete.") % {
208
237
  'errors': errors,
209
238
  'total': total,
210
239
  }
@@ -289,9 +318,19 @@ class ListTrust(command.Lister):
289
318
  trustor = None
290
319
  if parsed_args.trustor:
291
320
  try:
292
- trustor_id = identity_client.find_user(
293
- parsed_args.trustor, parsed_args.trustor_domain
294
- ).id
321
+ if parsed_args.trustor_domain:
322
+ trustor_domain_id = identity_client.find_domain(
323
+ parsed_args.trustor_domain, ignore_missing=False
324
+ ).id
325
+ trustor_id = identity_client.find_user(
326
+ parsed_args.trustor,
327
+ ignore_missing=False,
328
+ domain_id=trustor_domain_id,
329
+ ).id
330
+ else:
331
+ trustor_id = identity_client.find_user(
332
+ parsed_args.trustor, ignore_missing=False
333
+ ).id
295
334
  trustor = trustor_id
296
335
  except sdk_exceptions.ForbiddenException:
297
336
  trustor = parsed_args.trustor
@@ -299,9 +338,19 @@ class ListTrust(command.Lister):
299
338
  trustee = None
300
339
  if parsed_args.trustee:
301
340
  try:
302
- trustee_id = identity_client.find_user(
303
- parsed_args.trustee, parsed_args.trustee_domain
304
- ).id
341
+ if parsed_args.trustee_domain:
342
+ trustee_domain_id = identity_client.find_domain(
343
+ parsed_args.trustee_domain, ignore_missing=False
344
+ ).id
345
+ trustee_id = identity_client.find_user(
346
+ parsed_args.trustee,
347
+ ignore_missing=False,
348
+ domain_id=trustee_domain_id,
349
+ ).id
350
+ else:
351
+ trustee_id = identity_client.find_user(
352
+ parsed_args.trustee, ignore_missing=False
353
+ ).id
305
354
  trustee = trustee_id
306
355
  except sdk_exceptions.ForbiddenException:
307
356
  trustee = parsed_args.trustee
@@ -17,6 +17,7 @@
17
17
 
18
18
  import copy
19
19
  import logging
20
+ import typing as ty
20
21
 
21
22
  from openstack import exceptions as sdk_exc
22
23
  from osc_lib.command import command
@@ -40,6 +41,7 @@ def _format_user(user):
40
41
  'name',
41
42
  'description',
42
43
  'password_expires_at',
44
+ 'options',
43
45
  )
44
46
  column_headers = (
45
47
  'default_project_id',
@@ -50,6 +52,7 @@ def _format_user(user):
50
52
  'name',
51
53
  'description',
52
54
  'password_expires_at',
55
+ 'options',
53
56
  )
54
57
  return (
55
58
  column_headers,
@@ -58,7 +61,7 @@ def _format_user(user):
58
61
 
59
62
 
60
63
  def _get_options_for_user(identity_client, parsed_args):
61
- options = {}
64
+ options: dict[str, ty.Any] = {}
62
65
  if parsed_args.ignore_lockout_failure_attempts:
63
66
  options['ignore_lockout_failure_attempts'] = True
64
67
  if parsed_args.no_ignore_lockout_failure_attempts:
@@ -288,7 +291,7 @@ class CreateUser(command.ShowOne):
288
291
  elif parsed_args.password_prompt:
289
292
  password = utils.get_password(self.app.stdin)
290
293
 
291
- if not parsed_args.password:
294
+ if not password:
292
295
  LOG.warning(
293
296
  _(
294
297
  "No password was supplied, authentication will fail "
@@ -377,7 +380,7 @@ class DeleteUser(command.Command):
377
380
 
378
381
  if errors > 0:
379
382
  total = len(parsed_args.users)
380
- msg = _("%(errors)s of %(total)s users failed " "to delete.") % {
383
+ msg = _("%(errors)s of %(total)s users failed to delete.") % {
381
384
  'errors': errors,
382
385
  'total': total,
383
386
  }
@@ -411,6 +414,24 @@ class ListUser(command.Lister):
411
414
  default=False,
412
415
  help=_('List additional fields in output'),
413
416
  )
417
+ parser.add_argument(
418
+ '--enabled',
419
+ action='store_true',
420
+ dest='is_enabled',
421
+ default=None,
422
+ help=_(
423
+ 'List only enabled users, does nothing with --project and --group'
424
+ ),
425
+ )
426
+ parser.add_argument(
427
+ '--disabled',
428
+ action='store_false',
429
+ dest='is_enabled',
430
+ default=None,
431
+ help=_(
432
+ 'List only disabled users, does nothing with --project and --group'
433
+ ),
434
+ )
414
435
  return parser
415
436
 
416
437
  def take_action(self, parsed_args):
@@ -430,6 +451,9 @@ class ListUser(command.Lister):
430
451
  ignore_missing=False,
431
452
  ).id
432
453
 
454
+ if parsed_args.is_enabled is not None:
455
+ enabled = parsed_args.is_enabled
456
+
433
457
  if parsed_args.project:
434
458
  if domain is not None:
435
459
  project = identity_client.find_project(
@@ -468,9 +492,15 @@ class ListUser(command.Lister):
468
492
  group=group,
469
493
  )
470
494
  else:
471
- data = identity_client.users(
472
- domain_id=domain,
473
- )
495
+ if parsed_args.is_enabled is not None:
496
+ data = identity_client.users(
497
+ domain_id=domain,
498
+ is_enabled=enabled,
499
+ )
500
+ else:
501
+ data = identity_client.users(
502
+ domain_id=domain,
503
+ )
474
504
 
475
505
  # Column handling
476
506
  if parsed_args.long:
@@ -612,10 +642,12 @@ class SetUser(command.Command):
612
642
  if parsed_args.description:
613
643
  kwargs['description'] = parsed_args.description
614
644
  if parsed_args.project:
615
- project_domain_id = identity_client.find_domain(
616
- name_or_id=parsed_args.project_domain,
617
- ignore_missing=False,
618
- ).id
645
+ project_domain_id = None
646
+ if parsed_args.project_domain:
647
+ project_domain_id = identity_client.find_domain(
648
+ name_or_id=parsed_args.project_domain,
649
+ ignore_missing=False,
650
+ ).id
619
651
  project_id = identity_client.find_project(
620
652
  name_or_id=parsed_args.project,
621
653
  ignore_missing=False,
@@ -656,6 +688,8 @@ class SetPasswordUser(command.Command):
656
688
 
657
689
  def take_action(self, parsed_args):
658
690
  identity_client = self.app.client_manager.sdk_connection.identity
691
+ conn = self.app.client_manager.sdk_connection
692
+ user_id = conn.config.get_auth().get_user_id(conn.identity)
659
693
 
660
694
  # FIXME(gyee): there are two scenarios:
661
695
  #
@@ -698,7 +732,9 @@ class SetPasswordUser(command.Command):
698
732
  )
699
733
 
700
734
  identity_client.update_user(
701
- current_password=current_password, password=password
735
+ user=user_id,
736
+ current_password=current_password,
737
+ password=password,
702
738
  )
703
739
 
704
740
 
@@ -11,7 +11,6 @@
11
11
  # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
12
  # License for the specific language governing permissions and limitations
13
13
  # under the License.
14
- #
15
14
 
16
15
  import logging
17
16
 
@@ -21,13 +20,11 @@ from openstackclient.i18n import _
21
20
 
22
21
  LOG = logging.getLogger(__name__)
23
22
 
23
+ # global variables used when building the shell
24
24
  DEFAULT_API_VERSION = '2'
25
25
  API_VERSION_OPTION = 'os_image_api_version'
26
26
  API_NAME = 'image'
27
- API_VERSIONS = {
28
- '1': 'openstack.connection.Connection',
29
- '2': 'openstack.connection.Connection',
30
- }
27
+ API_VERSIONS = ('1', '2')
31
28
 
32
29
 
33
30
  def make_client(instance):
@@ -49,3 +46,8 @@ def build_option_parser(parser):
49
46
  % DEFAULT_API_VERSION,
50
47
  )
51
48
  return parser
49
+
50
+
51
+ def check_api_version(check_version):
52
+ # SDK supports auto-negotiation for us: always return True
53
+ return True
@@ -30,12 +30,6 @@ from osc_lib import utils
30
30
 
31
31
  from openstackclient.i18n import _
32
32
 
33
- if os.name == "nt":
34
- import msvcrt
35
- else:
36
- msvcrt = None
37
-
38
-
39
33
  CONTAINER_CHOICES = ["ami", "ari", "aki", "bare", "docker", "ova", "ovf"]
40
34
  DEFAULT_CONTAINER_FORMAT = 'bare'
41
35
  DEFAULT_DISK_FORMAT = 'raw'
@@ -53,7 +47,6 @@ DISK_CHOICES = [
53
47
  "ploop",
54
48
  ]
55
49
 
56
-
57
50
  LOG = logging.getLogger(__name__)
58
51
 
59
52
 
@@ -323,8 +316,10 @@ class CreateImage(command.ShowOne):
323
316
  else:
324
317
  # Read file from stdin
325
318
  if not sys.stdin.isatty():
326
- if msvcrt:
327
- msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
319
+ if os.name == "nt":
320
+ import msvcrt
321
+
322
+ msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY) # type: ignore
328
323
  if hasattr(sys.stdin, 'buffer'):
329
324
  kwargs['data'] = sys.stdin.buffer
330
325
  else:
@@ -384,8 +379,7 @@ class DeleteImage(command.Command):
384
379
  except Exception as e:
385
380
  result += 1
386
381
  msg = _(
387
- "Failed to delete image with name or "
388
- "ID '%(image)s': %(e)s"
382
+ "Failed to delete image with name or ID '%(image)s': %(e)s"
389
383
  )
390
384
  LOG.error(msg, {'image': image, 'e': e})
391
385
 
@@ -468,7 +462,7 @@ class ListImage(command.Lister):
468
462
  kwargs['is_private'] = True
469
463
 
470
464
  if parsed_args.long:
471
- columns = (
465
+ columns: tuple[str, ...] = (
472
466
  'ID',
473
467
  'Name',
474
468
  'Disk Format',
@@ -481,7 +475,7 @@ class ListImage(command.Lister):
481
475
  'owner_id',
482
476
  'properties',
483
477
  )
484
- column_headers = (
478
+ column_headers: tuple[str, ...] = (
485
479
  'ID',
486
480
  'Name',
487
481
  'Disk Format',
@@ -775,8 +769,10 @@ class SetImage(command.Command):
775
769
  # Read file from stdin
776
770
  if sys.stdin.isatty() is not True:
777
771
  if parsed_args.stdin:
778
- if msvcrt:
779
- msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
772
+ if os.name == "nt":
773
+ import msvcrt
774
+
775
+ msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY) # type: ignore
780
776
  if hasattr(sys.stdin, 'buffer'):
781
777
  kwargs['data'] = sys.stdin.buffer
782
778
  else:
@@ -131,8 +131,7 @@ class QueueCachedImage(command.Command):
131
131
  except Exception as e:
132
132
  failures += 1
133
133
  msg = _(
134
- "Failed to queue image with name or "
135
- "ID '%(image)s': %(e)s"
134
+ "Failed to queue image with name or ID '%(image)s': %(e)s"
136
135
  )
137
136
  LOG.error(msg, {'image': image, 'e': e})
138
137
 
@@ -171,8 +170,7 @@ class DeleteCachedImage(command.Command):
171
170
  except Exception as e:
172
171
  failures += 1
173
172
  msg = _(
174
- "Failed to delete image with name or "
175
- "ID '%(image)s': %(e)s"
173
+ "Failed to delete image with name or ID '%(image)s': %(e)s"
176
174
  )
177
175
  LOG.error(msg, {'image': image, 'e': e})
178
176
 
@@ -17,13 +17,15 @@
17
17
 
18
18
  import argparse
19
19
  from base64 import b64encode
20
+ import copy
20
21
  import logging
21
22
  import os
22
23
  import sys
24
+ import typing as ty
23
25
 
24
- from cinderclient import api_versions
25
26
  from openstack import exceptions as sdk_exceptions
26
27
  from openstack.image import image_signer
28
+ from openstack import utils as sdk_utils
27
29
  from osc_lib.api import utils as api_utils
28
30
  from osc_lib.cli import format_columns
29
31
  from osc_lib.cli import parseractions
@@ -36,12 +38,6 @@ from openstackclient.common import progressbar
36
38
  from openstackclient.i18n import _
37
39
  from openstackclient.identity import common as identity_common
38
40
 
39
- if os.name == "nt":
40
- import msvcrt
41
- else:
42
- msvcrt = None
43
-
44
-
45
41
  CONTAINER_CHOICES = ["ami", "ari", "aki", "bare", "docker", "ova", "ovf"]
46
42
  DEFAULT_CONTAINER_FORMAT = 'bare'
47
43
  DEFAULT_DISK_FORMAT = 'raw'
@@ -60,7 +56,6 @@ DISK_CHOICES = [
60
56
  ]
61
57
  MEMBER_STATUS_CHOICES = ["accepted", "pending", "rejected", "all"]
62
58
 
63
-
64
59
  LOG = logging.getLogger(__name__)
65
60
 
66
61
 
@@ -154,8 +149,10 @@ def get_data_from_stdin():
154
149
  image = sys.stdin
155
150
  if hasattr(sys.stdin, 'buffer'):
156
151
  image = sys.stdin.buffer
157
- if msvcrt:
158
- msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
152
+ if os.name == "nt":
153
+ import msvcrt
154
+
155
+ msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY) # type: ignore
159
156
 
160
157
  return image
161
158
  else:
@@ -359,8 +356,7 @@ class CreateImage(command.ShowOne):
359
356
  action="store_true",
360
357
  default=False,
361
358
  help=_(
362
- "Show upload progress bar "
363
- "(ignored if passing data via stdin)"
359
+ "Show upload progress bar (ignored if passing data via stdin)"
364
360
  ),
365
361
  )
366
362
  parser.add_argument(
@@ -401,8 +397,7 @@ class CreateImage(command.ShowOne):
401
397
  metavar="<tag>",
402
398
  action='append',
403
399
  help=_(
404
- "Set a tag on this image "
405
- "(repeat option to set multiple tags)"
400
+ "Set a tag on this image (repeat option to set multiple tags)"
406
401
  ),
407
402
  )
408
403
  parser.add_argument(
@@ -434,7 +429,7 @@ class CreateImage(command.ShowOne):
434
429
 
435
430
  # Build an attribute dict from the parsed args, only include
436
431
  # attributes that were actually set on the command line
437
- kwargs = {'allow_duplicates': True}
432
+ kwargs: dict[str, ty.Any] = {'allow_duplicates': True}
438
433
  copy_attrs = (
439
434
  'name',
440
435
  'id',
@@ -582,7 +577,7 @@ class CreateImage(command.ShowOne):
582
577
  return _format_image(image)
583
578
 
584
579
  def _take_action_volume(self, parsed_args):
585
- volume_client = self.app.client_manager.volume
580
+ volume_client = self.app.client_manager.sdk_connection.volume
586
581
 
587
582
  unsupported_opts = {
588
583
  # 'name', # 'name' is a positional argument and will always exist
@@ -613,12 +608,14 @@ class CreateImage(command.ShowOne):
613
608
  # version
614
609
  LOG.warning(msg % opt_name)
615
610
 
616
- source_volume = utils.find_resource(
617
- volume_client.volumes,
618
- parsed_args.volume,
611
+ source_volume = volume_client.find_volume(
612
+ parsed_args.volume, ignore_missing=False
619
613
  )
620
- kwargs = {}
621
- if volume_client.api_version < api_versions.APIVersion('3.1'):
614
+ kwargs: dict[str, ty.Any] = {
615
+ 'visibility': None,
616
+ 'protected': None,
617
+ }
618
+ if not sdk_utils.supports_microversion(volume_client, '3.1'):
622
619
  if parsed_args.visibility or parsed_args.is_protected is not None:
623
620
  msg = _(
624
621
  '--os-volume-api-version 3.1 or greater is required '
@@ -627,20 +624,18 @@ class CreateImage(command.ShowOne):
627
624
  )
628
625
  raise exceptions.CommandError(msg)
629
626
  else:
630
- kwargs.update(
631
- visibility=parsed_args.visibility or 'private',
632
- protected=parsed_args.is_protected or False,
633
- )
627
+ kwargs['visibility'] = parsed_args.visibility or 'private'
628
+ kwargs['protected'] = parsed_args.is_protected or False
634
629
 
635
- response, body = volume_client.volumes.upload_to_image(
630
+ response = volume_client.upload_volume_to_image(
636
631
  source_volume.id,
637
- parsed_args.force,
638
632
  parsed_args.name,
639
- parsed_args.container_format,
640
- parsed_args.disk_format,
633
+ force=parsed_args.force,
634
+ disk_format=parsed_args.disk_format,
635
+ container_format=parsed_args.container_format,
641
636
  **kwargs,
642
637
  )
643
- info = body['os-volume_upload_image']
638
+ info = copy.deepcopy(response)
644
639
  try:
645
640
  info['volume_type'] = info['volume_type']['name']
646
641
  except TypeError:
@@ -705,8 +700,7 @@ class DeleteImage(command.Command):
705
700
  except Exception as e:
706
701
  result += 1
707
702
  msg = _(
708
- "Failed to delete image with name or "
709
- "ID '%(image)s': %(e)s"
703
+ "Failed to delete image with name or ID '%(image)s': %(e)s"
710
704
  )
711
705
  LOG.error(msg, {'image': image, 'e': e})
712
706
 
@@ -884,7 +878,7 @@ class ListImage(command.Lister):
884
878
  if parsed_args.is_hidden:
885
879
  kwargs['is_hidden'] = parsed_args.is_hidden
886
880
  if parsed_args.long:
887
- columns = (
881
+ columns: tuple[str, ...] = (
888
882
  'ID',
889
883
  'Name',
890
884
  'Disk Format',
@@ -897,7 +891,7 @@ class ListImage(command.Lister):
897
891
  'owner_id',
898
892
  'tags',
899
893
  )
900
- column_headers = (
894
+ column_headers: tuple[str, ...] = (
901
895
  'ID',
902
896
  'Name',
903
897
  'Disk Format',
@@ -959,7 +953,7 @@ class ListImageProjects(command.Lister):
959
953
 
960
954
  def take_action(self, parsed_args):
961
955
  image_client = self.app.client_manager.image
962
- columns = ("Image ID", "Member ID", "Status")
956
+ columns: tuple[str, ...] = ("Image ID", "Member ID", "Status")
963
957
 
964
958
  image_id = image_client.find_image(
965
959
  parsed_args.image,
@@ -1153,8 +1147,7 @@ class SetImage(command.Command):
1153
1147
  default=None,
1154
1148
  action='append',
1155
1149
  help=_(
1156
- "Set a tag on this image "
1157
- "(repeat option to set multiple tags)"
1150
+ "Set a tag on this image (repeat option to set multiple tags)"
1158
1151
  ),
1159
1152
  )
1160
1153
  parser.add_argument(
@@ -1457,7 +1450,6 @@ class UnsetImage(command.Command):
1457
1450
  ignore_missing=False,
1458
1451
  )
1459
1452
 
1460
- kwargs = {}
1461
1453
  tagret = 0
1462
1454
  propret = 0
1463
1455
  if parsed_args.tags:
@@ -1466,10 +1458,11 @@ class UnsetImage(command.Command):
1466
1458
  image_client.remove_tag(image.id, k)
1467
1459
  except Exception:
1468
1460
  LOG.error(
1469
- _("tag unset failed, '%s' is a " "nonexistent tag "), k
1461
+ _("tag unset failed, '%s' is a nonexistent tag "), k
1470
1462
  )
1471
1463
  tagret += 1
1472
1464
 
1465
+ kwargs: dict[str, ty.Any] = {}
1473
1466
  if parsed_args.properties:
1474
1467
  for k in parsed_args.properties:
1475
1468
  if k in image:
@@ -1519,7 +1512,7 @@ class UnsetImage(command.Command):
1519
1512
  raise exceptions.CommandError(msg)
1520
1513
  elif propret > 0:
1521
1514
  msg = _(
1522
- "Failed to unset %(propret)s of %(proptotal)s" " properties."
1515
+ "Failed to unset %(propret)s of %(proptotal)s properties."
1523
1516
  ) % {'propret': propret, 'proptotal': proptotal}
1524
1517
  raise exceptions.CommandError(msg)
1525
1518
 
@@ -1551,8 +1544,7 @@ class StageImage(command.Command):
1551
1544
  action='store_true',
1552
1545
  default=False,
1553
1546
  help=_(
1554
- 'Show upload progress bar '
1555
- '(ignored if passing data via stdin)'
1547
+ 'Show upload progress bar (ignored if passing data via stdin)'
1556
1548
  ),
1557
1549
  )
1558
1550
  parser.add_argument(
@@ -1583,7 +1575,7 @@ class StageImage(command.Command):
1583
1575
  else:
1584
1576
  fp = get_data_from_stdin()
1585
1577
 
1586
- kwargs = {}
1578
+ kwargs: dict[str, ty.Any] = {}
1587
1579
 
1588
1580
  if parsed_args.progress and parsed_args.filename:
1589
1581
  # NOTE(stephenfin): we only show a progress bar if the user
@@ -1689,7 +1681,8 @@ class ImportImage(command.ShowOne):
1689
1681
  "'copy-image' import method)"
1690
1682
  ),
1691
1683
  )
1692
- parser.add_argument(
1684
+ allow_failure_group = parser.add_mutually_exclusive_group()
1685
+ allow_failure_group.add_argument(
1693
1686
  '--allow-failure',
1694
1687
  action='store_true',
1695
1688
  dest='allow_failure',
@@ -1700,9 +1693,9 @@ class ImportImage(command.ShowOne):
1700
1693
  'Only usable with --stores or --all-stores'
1701
1694
  ),
1702
1695
  )
1703
- parser.add_argument(
1696
+ allow_failure_group.add_argument(
1704
1697
  '--disallow-failure',
1705
- action='store_true',
1698
+ action='store_false',
1706
1699
  dest='allow_failure',
1707
1700
  default=True,
1708
1701
  help=_(
@@ -1866,8 +1859,8 @@ class StoresInfo(command.Lister):
1866
1859
  def take_action(self, parsed_args):
1867
1860
  image_client = self.app.client_manager.image
1868
1861
  try:
1869
- columns = ("id", "description", "is_default")
1870
- column_headers = ("ID", "Description", "Default")
1862
+ columns: tuple[str, ...] = ("id", "description", "is_default")
1863
+ column_headers: tuple[str, ...] = ("ID", "Description", "Default")
1871
1864
  if parsed_args.detail:
1872
1865
  columns += ("properties",)
1873
1866
  column_headers += ("Properties",)