python-openstackclient 7.3.1__py3-none-any.whl → 8.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 (235) 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 +2 -5
  9. openstackclient/compute/v2/agent.py +5 -5
  10. openstackclient/compute/v2/aggregate.py +17 -15
  11. openstackclient/compute/v2/console.py +3 -4
  12. openstackclient/compute/v2/flavor.py +14 -18
  13. openstackclient/compute/v2/host.py +3 -3
  14. openstackclient/compute/v2/hypervisor.py +10 -4
  15. openstackclient/compute/v2/hypervisor_stats.py +1 -1
  16. openstackclient/compute/v2/keypair.py +8 -10
  17. openstackclient/compute/v2/server.py +70 -112
  18. openstackclient/compute/v2/server_backup.py +1 -1
  19. openstackclient/compute/v2/server_event.py +7 -16
  20. openstackclient/compute/v2/server_group.py +6 -6
  21. openstackclient/compute/v2/server_image.py +1 -1
  22. openstackclient/compute/v2/server_migration.py +6 -6
  23. openstackclient/compute/v2/server_volume.py +4 -4
  24. openstackclient/compute/v2/service.py +9 -13
  25. openstackclient/compute/v2/usage.py +4 -6
  26. openstackclient/identity/client.py +2 -4
  27. openstackclient/identity/common.py +16 -17
  28. openstackclient/identity/v2_0/ec2creds.py +4 -3
  29. openstackclient/identity/v2_0/endpoint.py +12 -10
  30. openstackclient/identity/v2_0/project.py +6 -6
  31. openstackclient/identity/v2_0/role.py +1 -1
  32. openstackclient/identity/v2_0/service.py +7 -7
  33. openstackclient/identity/v2_0/user.py +6 -21
  34. openstackclient/identity/v3/access_rule.py +2 -5
  35. openstackclient/identity/v3/consumer.py +4 -3
  36. openstackclient/identity/v3/credential.py +8 -9
  37. openstackclient/identity/v3/domain.py +1 -1
  38. openstackclient/identity/v3/ec2creds.py +4 -3
  39. openstackclient/identity/v3/endpoint.py +104 -88
  40. openstackclient/identity/v3/endpoint_group.py +1 -1
  41. openstackclient/identity/v3/group.py +3 -4
  42. openstackclient/identity/v3/identity_provider.py +1 -2
  43. openstackclient/identity/v3/limit.py +4 -9
  44. openstackclient/identity/v3/mapping.py +4 -3
  45. openstackclient/identity/v3/policy.py +5 -8
  46. openstackclient/identity/v3/project.py +6 -6
  47. openstackclient/identity/v3/region.py +2 -5
  48. openstackclient/identity/v3/registered_limit.py +4 -8
  49. openstackclient/identity/v3/role.py +15 -16
  50. openstackclient/identity/v3/service.py +8 -8
  51. openstackclient/identity/v3/service_provider.py +3 -6
  52. openstackclient/identity/v3/tag.py +2 -2
  53. openstackclient/identity/v3/token.py +1 -2
  54. openstackclient/identity/v3/trust.py +74 -25
  55. openstackclient/identity/v3/user.py +9 -6
  56. openstackclient/image/client.py +2 -5
  57. openstackclient/image/v1/image.py +11 -15
  58. openstackclient/image/v2/cache.py +2 -4
  59. openstackclient/image/v2/image.py +30 -37
  60. openstackclient/image/v2/metadef_namespaces.py +4 -3
  61. openstackclient/image/v2/metadef_resource_type_association.py +1 -2
  62. openstackclient/image/v2/metadef_resource_types.py +1 -2
  63. openstackclient/locale/tr_TR/LC_MESSAGES/openstackclient.po +9 -1370
  64. openstackclient/network/client.py +4 -10
  65. openstackclient/network/common.py +16 -12
  66. openstackclient/network/utils.py +3 -3
  67. openstackclient/network/v2/address_group.py +5 -9
  68. openstackclient/network/v2/address_scope.py +2 -3
  69. openstackclient/network/v2/default_security_group_rule.py +1 -2
  70. openstackclient/network/v2/floating_ip.py +14 -21
  71. openstackclient/network/v2/floating_ip_port_forwarding.py +7 -7
  72. openstackclient/network/v2/ip_availability.py +1 -2
  73. openstackclient/network/v2/l3_conntrack_helper.py +8 -12
  74. openstackclient/network/v2/local_ip.py +24 -26
  75. openstackclient/network/v2/local_ip_association.py +4 -5
  76. openstackclient/network/v2/ndp_proxy.py +9 -10
  77. openstackclient/network/v2/network.py +12 -16
  78. openstackclient/network/v2/network_agent.py +29 -37
  79. openstackclient/network/v2/network_auto_allocated_topology.py +4 -5
  80. openstackclient/network/v2/network_flavor.py +1 -1
  81. openstackclient/network/v2/network_flavor_profile.py +5 -5
  82. openstackclient/network/v2/network_meter.py +3 -3
  83. openstackclient/network/v2/network_meter_rule.py +5 -8
  84. openstackclient/network/v2/network_qos_policy.py +4 -4
  85. openstackclient/network/v2/network_qos_rule.py +4 -5
  86. openstackclient/network/v2/network_rbac.py +4 -4
  87. openstackclient/network/v2/network_segment.py +6 -7
  88. openstackclient/network/v2/network_segment_range.py +16 -20
  89. openstackclient/network/v2/network_trunk.py +24 -16
  90. openstackclient/network/v2/port.py +42 -31
  91. openstackclient/network/v2/router.py +55 -41
  92. openstackclient/network/v2/security_group.py +8 -15
  93. openstackclient/network/v2/security_group_rule.py +9 -10
  94. openstackclient/network/v2/subnet.py +31 -30
  95. openstackclient/network/v2/subnet_pool.py +4 -4
  96. openstackclient/object/client.py +2 -3
  97. openstackclient/object/v1/container.py +2 -3
  98. openstackclient/object/v1/object.py +2 -9
  99. openstackclient/shell.py +22 -5
  100. openstackclient/tests/functional/base.py +2 -2
  101. openstackclient/tests/functional/common/test_quota.py +3 -1
  102. openstackclient/tests/functional/compute/v2/common.py +12 -6
  103. openstackclient/tests/functional/compute/v2/test_server.py +2 -3
  104. openstackclient/tests/functional/compute/v2/test_server_event.py +1 -1
  105. openstackclient/tests/functional/identity/v2/test_user.py +1 -1
  106. openstackclient/tests/functional/identity/v3/common.py +3 -8
  107. openstackclient/tests/functional/identity/v3/test_application_credential.py +10 -10
  108. openstackclient/tests/functional/identity/v3/test_endpoint.py +3 -3
  109. openstackclient/tests/functional/identity/v3/test_group.py +3 -3
  110. openstackclient/tests/functional/identity/v3/test_idp.py +3 -7
  111. openstackclient/tests/functional/identity/v3/test_limit.py +4 -4
  112. openstackclient/tests/functional/identity/v3/test_project.py +5 -14
  113. openstackclient/tests/functional/identity/v3/test_region.py +1 -3
  114. openstackclient/tests/functional/identity/v3/test_registered_limit.py +3 -3
  115. openstackclient/tests/functional/identity/v3/test_role.py +1 -1
  116. openstackclient/tests/functional/identity/v3/test_role_assignment.py +13 -31
  117. openstackclient/tests/functional/identity/v3/test_service_provider.py +3 -7
  118. openstackclient/tests/functional/identity/v3/test_user.py +8 -8
  119. openstackclient/tests/functional/network/v2/common.py +7 -3
  120. openstackclient/tests/functional/network/v2/test_address_group.py +4 -0
  121. openstackclient/tests/functional/network/v2/test_l3_conntrack_helper.py +15 -11
  122. openstackclient/tests/functional/network/v2/test_local_ip.py +4 -0
  123. openstackclient/tests/functional/network/v2/test_network_meter_rule.py +2 -2
  124. openstackclient/tests/functional/network/v2/test_network_ndp_proxy.py +2 -3
  125. openstackclient/tests/functional/network/v2/test_network_rbac.py +2 -2
  126. openstackclient/tests/functional/network/v2/test_network_trunk.py +1 -1
  127. openstackclient/tests/functional/network/v2/test_port.py +17 -7
  128. openstackclient/tests/functional/network/v2/test_router.py +42 -0
  129. openstackclient/tests/functional/network/v2/test_subnet_pool.py +4 -0
  130. openstackclient/tests/unit/api/test_compute_v2.py +67 -87
  131. openstackclient/tests/unit/common/test_availability_zone.py +6 -14
  132. openstackclient/tests/unit/common/test_command.py +1 -1
  133. openstackclient/tests/unit/common/test_extension.py +5 -7
  134. openstackclient/tests/unit/common/test_limits.py +1 -1
  135. openstackclient/tests/unit/common/test_project_cleanup.py +5 -6
  136. openstackclient/tests/unit/common/test_quota.py +51 -28
  137. openstackclient/tests/unit/compute/v2/fakes.py +4 -10
  138. openstackclient/tests/unit/compute/v2/test_agent.py +16 -16
  139. openstackclient/tests/unit/compute/v2/test_aggregate.py +56 -60
  140. openstackclient/tests/unit/compute/v2/test_console.py +16 -16
  141. openstackclient/tests/unit/compute/v2/test_flavor.py +71 -71
  142. openstackclient/tests/unit/compute/v2/test_host.py +8 -8
  143. openstackclient/tests/unit/compute/v2/test_hypervisor.py +22 -30
  144. openstackclient/tests/unit/compute/v2/test_hypervisor_stats.py +2 -2
  145. openstackclient/tests/unit/compute/v2/test_keypair.py +24 -24
  146. openstackclient/tests/unit/compute/v2/test_server.py +524 -560
  147. openstackclient/tests/unit/compute/v2/test_server_backup.py +5 -7
  148. openstackclient/tests/unit/compute/v2/test_server_event.py +16 -18
  149. openstackclient/tests/unit/compute/v2/test_server_group.py +25 -31
  150. openstackclient/tests/unit/compute/v2/test_server_image.py +6 -8
  151. openstackclient/tests/unit/compute/v2/test_server_migration.py +37 -37
  152. openstackclient/tests/unit/compute/v2/test_server_volume.py +12 -12
  153. openstackclient/tests/unit/compute/v2/test_service.py +39 -45
  154. openstackclient/tests/unit/compute/v2/test_usage.py +5 -5
  155. openstackclient/tests/unit/identity/v2_0/fakes.py +1 -1
  156. openstackclient/tests/unit/identity/v3/test_access_rule.py +1 -3
  157. openstackclient/tests/unit/identity/v3/test_application_credential.py +1 -1
  158. openstackclient/tests/unit/identity/v3/test_credential.py +4 -4
  159. openstackclient/tests/unit/identity/v3/test_endpoint.py +167 -172
  160. openstackclient/tests/unit/identity/v3/test_mappings.py +2 -2
  161. openstackclient/tests/unit/identity/v3/test_trust.py +5 -2
  162. openstackclient/tests/unit/identity/v3/test_user.py +16 -0
  163. openstackclient/tests/unit/image/v1/fakes.py +2 -2
  164. openstackclient/tests/unit/image/v2/test_image.py +39 -1
  165. openstackclient/tests/unit/integ/cli/test_shell.py +1 -2
  166. openstackclient/tests/unit/network/test_common.py +2 -2
  167. openstackclient/tests/unit/network/v2/test_floating_ip_compute.py +8 -14
  168. openstackclient/tests/unit/network/v2/test_floating_ip_network.py +49 -35
  169. openstackclient/tests/unit/network/v2/test_floating_ip_pool_compute.py +1 -1
  170. openstackclient/tests/unit/network/v2/test_network_compute.py +11 -11
  171. openstackclient/tests/unit/network/v2/test_network_trunk.py +2 -2
  172. openstackclient/tests/unit/network/v2/test_port.py +33 -5
  173. openstackclient/tests/unit/network/v2/test_router.py +120 -7
  174. openstackclient/tests/unit/network/v2/test_security_group_compute.py +11 -19
  175. openstackclient/tests/unit/network/v2/test_security_group_rule_compute.py +14 -14
  176. openstackclient/tests/unit/object/v1/test_object_all.py +4 -3
  177. openstackclient/tests/unit/test_shell.py +16 -13
  178. openstackclient/tests/unit/volume/v2/test_volume.py +1 -1
  179. openstackclient/tests/unit/volume/v2/test_volume_transfer_request.py +1 -1
  180. openstackclient/tests/unit/volume/v3/fakes.py +2 -8
  181. openstackclient/tests/unit/volume/v3/test_volume.py +1 -1
  182. openstackclient/tests/unit/volume/v3/test_volume_attachment.py +3 -3
  183. openstackclient/tests/unit/volume/v3/test_volume_snapshot.py +1 -2
  184. openstackclient/tests/unit/volume/v3/test_volume_transfer_request.py +1 -1
  185. openstackclient/volume/client.py +1 -3
  186. openstackclient/volume/v2/consistency_group.py +4 -8
  187. openstackclient/volume/v2/consistency_group_snapshot.py +1 -2
  188. openstackclient/volume/v2/qos_specs.py +1 -2
  189. openstackclient/volume/v2/volume.py +8 -16
  190. openstackclient/volume/v2/volume_backup.py +6 -7
  191. openstackclient/volume/v2/volume_snapshot.py +8 -9
  192. openstackclient/volume/v2/volume_transfer_request.py +0 -3
  193. openstackclient/volume/v2/volume_type.py +10 -21
  194. openstackclient/volume/v3/block_storage_cluster.py +3 -3
  195. openstackclient/volume/v3/block_storage_manage.py +1 -3
  196. openstackclient/volume/v3/volume.py +18 -19
  197. openstackclient/volume/v3/volume_attachment.py +3 -2
  198. openstackclient/volume/v3/volume_backup.py +7 -8
  199. openstackclient/volume/v3/volume_group.py +2 -1
  200. openstackclient/volume/v3/volume_group_snapshot.py +2 -1
  201. openstackclient/volume/v3/volume_snapshot.py +4 -3
  202. openstackclient/volume/v3/volume_type.py +10 -21
  203. {python_openstackclient-7.3.1.dist-info → python_openstackclient-8.0.0.dist-info}/AUTHORS +4 -0
  204. {python_openstackclient-7.3.1.dist-info → python_openstackclient-8.0.0.dist-info}/METADATA +7 -13
  205. {python_openstackclient-7.3.1.dist-info → python_openstackclient-8.0.0.dist-info}/RECORD +210 -233
  206. {python_openstackclient-7.3.1.dist-info → python_openstackclient-8.0.0.dist-info}/WHEEL +1 -1
  207. {python_openstackclient-7.3.1.dist-info → python_openstackclient-8.0.0.dist-info}/entry_points.txt +0 -41
  208. python_openstackclient-8.0.0.dist-info/pbr.json +1 -0
  209. openstackclient/tests/functional/volume/v1/__init__.py +0 -0
  210. openstackclient/tests/functional/volume/v1/common.py +0 -35
  211. openstackclient/tests/functional/volume/v1/test_qos.py +0 -100
  212. openstackclient/tests/functional/volume/v1/test_service.py +0 -76
  213. openstackclient/tests/functional/volume/v1/test_snapshot.py +0 -232
  214. openstackclient/tests/functional/volume/v1/test_transfer_request.py +0 -111
  215. openstackclient/tests/functional/volume/v1/test_volume.py +0 -228
  216. openstackclient/tests/functional/volume/v1/test_volume_type.py +0 -213
  217. openstackclient/tests/unit/volume/v1/__init__.py +0 -0
  218. openstackclient/tests/unit/volume/v1/fakes.py +0 -615
  219. openstackclient/tests/unit/volume/v1/test_qos_specs.py +0 -471
  220. openstackclient/tests/unit/volume/v1/test_service.py +0 -295
  221. openstackclient/tests/unit/volume/v1/test_transfer_request.py +0 -380
  222. openstackclient/tests/unit/volume/v1/test_type.py +0 -633
  223. openstackclient/tests/unit/volume/v1/test_volume.py +0 -1447
  224. openstackclient/tests/unit/volume/v1/test_volume_backup.py +0 -435
  225. openstackclient/volume/v1/__init__.py +0 -0
  226. openstackclient/volume/v1/qos_specs.py +0 -377
  227. openstackclient/volume/v1/service.py +0 -136
  228. openstackclient/volume/v1/volume.py +0 -734
  229. openstackclient/volume/v1/volume_backup.py +0 -302
  230. openstackclient/volume/v1/volume_snapshot.py +0 -433
  231. openstackclient/volume/v1/volume_transfer_request.py +0 -200
  232. openstackclient/volume/v1/volume_type.py +0 -520
  233. python_openstackclient-7.3.1.dist-info/pbr.json +0 -1
  234. {python_openstackclient-7.3.1.dist-info → python_openstackclient-8.0.0.dist-info}/LICENSE +0 -0
  235. {python_openstackclient-7.3.1.dist-info → python_openstackclient-8.0.0.dist-info}/top_level.txt +0 -0
@@ -18,6 +18,7 @@ import collections
18
18
  import copy
19
19
  import json
20
20
  import logging
21
+ import typing as ty
21
22
 
22
23
  from cliff import columns as cliff_columns
23
24
  from osc_lib.cli import format_columns
@@ -104,21 +105,21 @@ def _passed_multiple_gateways(extension_supported, external_gateways):
104
105
 
105
106
 
106
107
  def _get_external_gateway_attrs(client_manager, parsed_args):
107
- attrs = {}
108
+ attrs: dict[str, ty.Any] = {}
108
109
 
109
110
  if parsed_args.external_gateways:
110
111
  external_gateways: collections.defaultdict[str, list[dict]] = (
111
112
  collections.defaultdict(list)
112
113
  )
113
114
  n_client = client_manager.network
114
- first_network_id = None
115
+ first_network_id = ''
115
116
 
116
117
  for gw_net_name_or_id in parsed_args.external_gateways:
117
118
  gateway_info = {}
118
119
  gw_net = n_client.find_network(
119
120
  gw_net_name_or_id, ignore_missing=False
120
121
  )
121
- if first_network_id is None:
122
+ if not first_network_id:
122
123
  first_network_id = gw_net.id
123
124
  gateway_info['network_id'] = gw_net.id
124
125
  if 'disable_snat' in parsed_args and parsed_args.disable_snat:
@@ -146,7 +147,7 @@ def _get_external_gateway_attrs(client_manager, parsed_args):
146
147
  for ip_spec in parsed_args.fixed_ips:
147
148
  # If there is only one gateway, this value will represent the
148
149
  # network ID for it, otherwise it will be overridden.
149
- ip_net_id = first_network_id
150
+ ip_net_id: str = first_network_id
150
151
 
151
152
  if ip_spec.get('subnet', False):
152
153
  subnet_name_id = ip_spec.pop('subnet')
@@ -237,6 +238,9 @@ def _get_attrs(client_manager, parsed_args):
237
238
  if 'flavor_id' in parsed_args and parsed_args.flavor_id is not None:
238
239
  flavor = n_client.find_flavor(parsed_args.flavor_id)
239
240
  attrs['flavor_id'] = flavor.id
241
+ elif 'flavor' in parsed_args and parsed_args.flavor is not None:
242
+ flavor = n_client.find_flavor(parsed_args.flavor, ignore_missing=False)
243
+ attrs['flavor_id'] = flavor.id
240
244
 
241
245
  for attr in ('enable_default_route_bfd', 'enable_default_route_ecmp'):
242
246
  value = getattr(parsed_args, attr, None)
@@ -255,7 +259,7 @@ def _parser_add_bfd_ecmp_arguments(parser):
255
259
  action='store_true',
256
260
  help=_(
257
261
  "Enable BFD sessions for default routes inferred from "
258
- "the external gateway port subnets for this router."
262
+ "the external gateway port subnets for this router"
259
263
  ),
260
264
  )
261
265
  parser.add_argument(
@@ -265,7 +269,7 @@ def _parser_add_bfd_ecmp_arguments(parser):
265
269
  action='store_false',
266
270
  help=_(
267
271
  "Disable BFD sessions for default routes inferred from "
268
- "the external gateway port subnets for this router."
272
+ "the external gateway port subnets for this router"
269
273
  ),
270
274
  )
271
275
  parser.add_argument(
@@ -275,7 +279,7 @@ def _parser_add_bfd_ecmp_arguments(parser):
275
279
  action='store_true',
276
280
  help=_(
277
281
  "Add ECMP default routes if multiple are available via "
278
- "different gateway ports."
282
+ "different gateway ports"
279
283
  ),
280
284
  )
281
285
  parser.add_argument(
@@ -283,7 +287,7 @@ def _parser_add_bfd_ecmp_arguments(parser):
283
287
  dest='enable_default_route_ecmp',
284
288
  default=None,
285
289
  action='store_false',
286
- help=_("Add default route only for first gateway port."),
290
+ help=_("Add default route only for first gateway port"),
287
291
  )
288
292
 
289
293
 
@@ -364,7 +368,7 @@ class AddExtraRoutesToRouter(command.ShowOne):
364
368
  metavar='<router>',
365
369
  help=_(
366
370
  "Router to which extra static routes "
367
- "will be added (name or ID)."
371
+ "will be added (name or ID)"
368
372
  ),
369
373
  )
370
374
  parser.add_argument(
@@ -379,7 +383,7 @@ class AddExtraRoutesToRouter(command.ShowOne):
379
383
  "destination: destination subnet (in CIDR notation), "
380
384
  "gateway: nexthop IP address. "
381
385
  "Repeat option to add multiple routes. "
382
- "Trying to add a route that's already present "
386
+ "Trying to add a route that is already present "
383
387
  "(exactly, including destination and nexthop) "
384
388
  "in the routing table is allowed and is considered "
385
389
  "a successful operation."
@@ -415,7 +419,7 @@ class RemoveExtraRoutesFromRouter(command.ShowOne):
415
419
  metavar='<router>',
416
420
  help=_(
417
421
  "Router from which extra static routes "
418
- "will be removed (name or ID)."
422
+ "will be removed (name or ID)"
419
423
  ),
420
424
  )
421
425
  parser.add_argument(
@@ -430,7 +434,7 @@ class RemoveExtraRoutesFromRouter(command.ShowOne):
430
434
  "destination: destination subnet (in CIDR notation), "
431
435
  "gateway: nexthop IP address. "
432
436
  "Repeat option to remove multiple routes. "
433
- "Trying to remove a route that's already missing "
437
+ "Trying to remove a route that is already missing "
434
438
  "(fully, including destination and nexthop) "
435
439
  "from the routing table is allowed and is considered "
436
440
  "a successful operation."
@@ -522,9 +526,9 @@ class CreateRouter(command.ShowOne, common.NeutronCommandWithExtraArgs):
522
526
  metavar="<network>",
523
527
  action='append',
524
528
  help=_(
525
- "External Network used as router's gateway (name or ID). "
529
+ "External Network used as router's gateway (name or ID) "
526
530
  "(repeat option to set multiple gateways per router "
527
- "if the L3 service plugin in use supports it)."
531
+ "if the L3 service plugin in use supports it)"
528
532
  ),
529
533
  dest='external_gateways',
530
534
  )
@@ -538,7 +542,7 @@ class CreateRouter(command.ShowOne, common.NeutronCommandWithExtraArgs):
538
542
  "Desired IP and/or subnet (name or ID) "
539
543
  "on external gateway: "
540
544
  "subnet=<subnet>,ip-address=<ip-address> "
541
- "(repeat option to set multiple fixed IP addresses)."
545
+ "(repeat option to set multiple fixed IP addresses)"
542
546
  ),
543
547
  )
544
548
  snat_group = parser.add_mutually_exclusive_group()
@@ -578,6 +582,11 @@ class CreateRouter(command.ShowOne, common.NeutronCommandWithExtraArgs):
578
582
  help=argparse.SUPPRESS,
579
583
  )
580
584
  _parser_add_bfd_ecmp_arguments(parser)
585
+ parser.add_argument(
586
+ '--qos-policy',
587
+ metavar='<qos-policy>',
588
+ help=_('Attach QoS policy to router gateway IPs'),
589
+ )
581
590
 
582
591
  return parser
583
592
 
@@ -600,6 +609,13 @@ class CreateRouter(command.ShowOne, common.NeutronCommandWithExtraArgs):
600
609
  )
601
610
  raise exceptions.CommandError(msg)
602
611
 
612
+ if parsed_args.qos_policy and not parsed_args.external_gateways:
613
+ msg = _(
614
+ "You must specify '--external-gateway' in order "
615
+ "to define a QoS policy"
616
+ )
617
+ raise exceptions.CommandError(msg)
618
+
603
619
  if parsed_args.enable_ndp_proxy is not None:
604
620
  attrs['enable_ndp_proxy'] = parsed_args.enable_ndp_proxy
605
621
 
@@ -668,7 +684,7 @@ class DeleteRouter(command.Command):
668
684
 
669
685
  if result > 0:
670
686
  total = len(parsed_args.router)
671
- msg = _("%(result)s of %(total)s routers failed " "to delete.") % {
687
+ msg = _("%(result)s of %(total)s routers failed to delete.") % {
672
688
  'result': result,
673
689
  'total': total,
674
690
  }
@@ -719,14 +735,14 @@ class ListRouter(command.Lister):
719
735
  identity_client = self.app.client_manager.identity
720
736
  client = self.app.client_manager.network
721
737
 
722
- columns = (
738
+ columns: tuple[str, ...] = (
723
739
  'id',
724
740
  'name',
725
741
  'status',
726
742
  'is_admin_state_up',
727
743
  'project_id',
728
744
  )
729
- column_headers = (
745
+ column_headers: tuple[str, ...] = (
730
746
  'ID',
731
747
  'Name',
732
748
  'Status',
@@ -772,27 +788,27 @@ class ListRouter(command.Lister):
772
788
  d.is_distributed is not None
773
789
  and 'is_distributed' not in columns
774
790
  ):
775
- columns = columns + ('is_distributed',)
776
- column_headers = column_headers + ('Distributed',)
791
+ columns += ('is_distributed',)
792
+ column_headers += ('Distributed',)
777
793
  if d.is_ha is not None and 'is_ha' not in columns:
778
- columns = columns + ('is_ha',)
779
- column_headers = column_headers + ('HA',)
794
+ columns += ('is_ha',)
795
+ column_headers += ('HA',)
780
796
  if parsed_args.long:
781
- columns = columns + (
797
+ columns += (
782
798
  'routes',
783
799
  'external_gateway_info',
784
800
  )
785
- column_headers = column_headers + (
801
+ column_headers += (
786
802
  'Routes',
787
803
  'External gateway info',
788
804
  )
789
805
  # availability zone will be available only when
790
806
  # router_availability_zone extension is enabled
791
807
  if client.find_extension("router_availability_zone"):
792
- columns = columns + ('availability_zones',)
793
- column_headers = column_headers + ('Availability zones',)
794
- columns = columns + ('tags',)
795
- column_headers = column_headers + ('Tags',)
808
+ columns += ('availability_zones',)
809
+ column_headers += ('Availability zones',)
810
+ columns += ('tags',)
811
+ column_headers += ('Tags',)
796
812
 
797
813
  return (
798
814
  column_headers,
@@ -924,7 +940,7 @@ class SetRouter(common.NeutronCommandWithExtraArgs):
924
940
  default=None,
925
941
  required_keys=['destination', 'gateway'],
926
942
  help=_(
927
- "Add routes to the router "
943
+ "Add routes to the router. "
928
944
  "destination: destination subnet (in CIDR notation) "
929
945
  "gateway: nexthop IP address "
930
946
  "(repeat option to add multiple routes). "
@@ -948,7 +964,7 @@ class SetRouter(common.NeutronCommandWithExtraArgs):
948
964
  '--ha',
949
965
  action='store_true',
950
966
  help=_(
951
- "Set the router as highly available " "(disabled router only)"
967
+ "Set the router as highly available (disabled router only)"
952
968
  ),
953
969
  )
954
970
  routes_ha.add_argument(
@@ -964,7 +980,7 @@ class SetRouter(common.NeutronCommandWithExtraArgs):
964
980
  metavar="<network>",
965
981
  action='append',
966
982
  help=_(
967
- "External Network used as router's gateway (name or ID). "
983
+ "External Network used as router's gateway (name or ID) "
968
984
  "(repeat option to set multiple gateways per router "
969
985
  "if the L3 service plugin in use supports it)."
970
986
  ),
@@ -980,7 +996,7 @@ class SetRouter(common.NeutronCommandWithExtraArgs):
980
996
  "Desired IP and/or subnet (name or ID) "
981
997
  "on external gateway: "
982
998
  "subnet=<subnet>,ip-address=<ip-address> "
983
- "(repeat option to set multiple fixed IP addresses)."
999
+ "(repeat option to set multiple fixed IP addresses)"
984
1000
  ),
985
1001
  )
986
1002
  snat_group = parser.add_mutually_exclusive_group()
@@ -1160,7 +1176,7 @@ class UnsetRouter(common.NeutronUnsetCommandWithExtraArgs):
1160
1176
  default=None,
1161
1177
  required_keys=['destination', 'gateway'],
1162
1178
  help=_(
1163
- "Routes to be removed from the router "
1179
+ "Routes to be removed from the router. "
1164
1180
  "destination: destination subnet (in CIDR notation) "
1165
1181
  "gateway: nexthop IP address "
1166
1182
  "(repeat option to unset multiple routes)"
@@ -1213,7 +1229,7 @@ class UnsetRouter(common.NeutronUnsetCommandWithExtraArgs):
1213
1229
  ):
1214
1230
  pass
1215
1231
  except (KeyError, TypeError):
1216
- msg = _("Router does not have external network or qos policy")
1232
+ msg = _("Router does not have external network or QoS policy")
1217
1233
  raise exceptions.CommandError(msg)
1218
1234
  else:
1219
1235
  attrs['external_gateway_info'] = {
@@ -1250,13 +1266,12 @@ class AddGatewayToRouter(command.ShowOne):
1250
1266
  parser.add_argument(
1251
1267
  'router',
1252
1268
  metavar="<router>",
1253
- help=_("Router to modify (name or ID)."),
1269
+ help=_("Router to modify (name or ID)"),
1254
1270
  )
1255
1271
  parser.add_argument(
1256
1272
  metavar="<network>",
1257
1273
  help=_(
1258
- "External Network to a attach a router gateway to (name or "
1259
- "ID)."
1274
+ "External Network to a attach a router gateway to (name or ID)"
1260
1275
  ),
1261
1276
  dest='external_gateways',
1262
1277
  # The argument is stored in a list in order to reuse the
@@ -1273,7 +1288,7 @@ class AddGatewayToRouter(command.ShowOne):
1273
1288
  "Desired IP and/or subnet (name or ID) "
1274
1289
  "on external gateway: "
1275
1290
  "subnet=<subnet>,ip-address=<ip-address> "
1276
- "(repeat option to set multiple fixed IP addresses)."
1291
+ "(repeat option to set multiple fixed IP addresses)"
1277
1292
  ),
1278
1293
  )
1279
1294
  return parser
@@ -1323,8 +1338,7 @@ class RemoveGatewayFromRouter(command.ShowOne):
1323
1338
  parser.add_argument(
1324
1339
  metavar="<network>",
1325
1340
  help=_(
1326
- "External Network to remove a router gateway from (name or "
1327
- "ID)."
1341
+ "External Network to remove a router gateway from (name or ID)"
1328
1342
  ),
1329
1343
  dest='external_gateways',
1330
1344
  # The argument is stored in a list in order to reuse the
@@ -1341,7 +1355,7 @@ class RemoveGatewayFromRouter(command.ShowOne):
1341
1355
  "IP and/or subnet (name or ID) on the external gateway "
1342
1356
  "which is used to identify a particular gateway if multiple "
1343
1357
  "are attached to the same network: subnet=<subnet>,"
1344
- "ip-address=<ip-address>."
1358
+ "ip-address=<ip-address>"
1345
1359
  ),
1346
1360
  )
1347
1361
  return parser
@@ -126,7 +126,7 @@ class CreateSecurityGroup(
126
126
  "--stateful",
127
127
  action='store_true',
128
128
  default=None,
129
- help=_("Security group is stateful (Default)"),
129
+ help=_("Security group is stateful (default)"),
130
130
  )
131
131
  stateful_group.add_argument(
132
132
  "--stateless",
@@ -239,10 +239,7 @@ class ListSecurityGroup(common.NetworkAndComputeLister):
239
239
  '--project',
240
240
  metavar='<project>',
241
241
  help=self.enhance_help_neutron(
242
- _(
243
- "List security groups according to the project (name or "
244
- "ID)"
245
- )
242
+ _("List security groups according to the project (name or ID)")
246
243
  ),
247
244
  )
248
245
  identity_common.add_project_domain_option_to_parser(
@@ -280,7 +277,7 @@ class ListSecurityGroup(common.NetworkAndComputeLister):
280
277
  fields=self.FIELDS_TO_RETRIEVE, **filters
281
278
  )
282
279
 
283
- columns = ("ID", "Name", "Description", "Project ID", "tags")
280
+ columns = ("id", "name", "description", "project_id", "tags")
284
281
  column_headers = ("ID", "Name", "Description", "Project", "Tags")
285
282
  return (
286
283
  column_headers,
@@ -300,15 +297,11 @@ class ListSecurityGroup(common.NetworkAndComputeLister):
300
297
  all_projects=parsed_args.all_projects,
301
298
  )
302
299
 
303
- columns = (
304
- "ID",
305
- "Name",
306
- "Description",
307
- )
308
- column_headers = columns
300
+ columns: tuple[str, ...] = ("id", "name", "description")
301
+ column_headers: tuple[str, ...] = ("ID", "Name", "Description")
309
302
  if parsed_args.all_projects:
310
- columns = columns + ('Tenant ID',)
311
- column_headers = column_headers + ('Project',)
303
+ columns += ('tenant_id',)
304
+ column_headers += ('Project',)
312
305
  return (
313
306
  column_headers,
314
307
  (
@@ -345,7 +338,7 @@ class SetSecurityGroup(
345
338
  "--stateful",
346
339
  action='store_true',
347
340
  default=None,
348
- help=_("Security group is stateful (Default)"),
341
+ help=_("Security group is stateful (default)"),
349
342
  )
350
343
  stateful_group.add_argument(
351
344
  "--stateless",
@@ -30,10 +30,9 @@ LOG = logging.getLogger(__name__)
30
30
 
31
31
 
32
32
  def _get_columns(item):
33
- column_map = {}
34
33
  hidden_columns = ['location', 'tenant_id']
35
34
  return utils.get_osc_show_columns_for_sdk_resource(
36
- item, column_map, hidden_columns
35
+ item, {}, hidden_columns
37
36
  )
38
37
 
39
38
 
@@ -451,7 +450,7 @@ class ListSecurityGroupRule(common.NetworkAndComputeLister):
451
450
  return parser
452
451
 
453
452
  def _get_column_headers(self, parsed_args):
454
- column_headers = (
453
+ column_headers: tuple[str, ...] = (
455
454
  'ID',
456
455
  'IP Protocol',
457
456
  'Ethertype',
@@ -461,9 +460,9 @@ class ListSecurityGroupRule(common.NetworkAndComputeLister):
461
460
  'Remote Security Group',
462
461
  )
463
462
  if self.is_neutron:
464
- column_headers = column_headers + ('Remote Address Group',)
463
+ column_headers += ('Remote Address Group',)
465
464
  if parsed_args.group is None:
466
- column_headers = column_headers + ('Security Group',)
465
+ column_headers += ('Security Group',)
467
466
  return column_headers
468
467
 
469
468
  def take_action_network(self, client, parsed_args):
@@ -474,7 +473,7 @@ class ListSecurityGroupRule(common.NetworkAndComputeLister):
474
473
  self.log.warning(msg)
475
474
 
476
475
  column_headers = self._get_column_headers(parsed_args)
477
- columns = (
476
+ columns: tuple[str, ...] = (
478
477
  'id',
479
478
  'protocol',
480
479
  'ether_type',
@@ -496,7 +495,7 @@ class ListSecurityGroupRule(common.NetworkAndComputeLister):
496
495
  ).id
497
496
  query = {'security_group_id': security_group_id}
498
497
  else:
499
- columns = columns + ('security_group_id',)
498
+ columns += ('security_group_id',)
500
499
 
501
500
  if parsed_args.ingress:
502
501
  query['direction'] = 'ingress'
@@ -523,7 +522,7 @@ class ListSecurityGroupRule(common.NetworkAndComputeLister):
523
522
 
524
523
  def take_action_compute(self, client, parsed_args):
525
524
  column_headers = self._get_column_headers(parsed_args)
526
- columns = (
525
+ columns: tuple[str, ...] = (
527
526
  "ID",
528
527
  "IP Protocol",
529
528
  "Ethertype",
@@ -539,7 +538,7 @@ class ListSecurityGroupRule(common.NetworkAndComputeLister):
539
538
  )
540
539
  rules_to_list = security_group['rules']
541
540
  else:
542
- columns = columns + ('parent_group_id',)
541
+ columns += ('parent_group_id',)
543
542
  for security_group in compute_v2.list_security_groups(
544
543
  client, all_projects=parsed_args.all_projects
545
544
  ):
@@ -608,7 +607,7 @@ class ShowSecurityGroupRule(common.NetworkAndComputeShowOne):
608
607
 
609
608
  if obj is None:
610
609
  msg = (
611
- _("Could not find security group rule " "with ID '%s'")
610
+ _("Could not find security group rule with ID '%s'")
612
611
  % parsed_args.rule
613
612
  )
614
613
  raise exceptions.CommandError(msg)
@@ -15,6 +15,7 @@
15
15
 
16
16
  import copy
17
17
  import logging
18
+ import typing as ty
18
19
 
19
20
  from cliff import columns as cliff_columns
20
21
  from osc_lib.cli import format_columns
@@ -84,8 +85,8 @@ def _get_common_parse_arguments(parser, is_create=True):
84
85
  action=parseractions.MultiKeyValueAction,
85
86
  required_keys=['start', 'end'],
86
87
  help=_(
87
- "Allocation pool IP addresses for this subnet "
88
- "e.g.: start=192.168.199.2,end=192.168.199.254 "
88
+ "Allocation pool IP addresses for this subnet, "
89
+ "for example, start=192.168.199.2,end=192.168.199.254 "
89
90
  "(repeat option to add multiple IP addresses)"
90
91
  ),
91
92
  )
@@ -127,10 +128,10 @@ def _get_common_parse_arguments(parser, is_create=True):
127
128
  action=parseractions.MultiKeyValueAction,
128
129
  required_keys=['destination', 'gateway'],
129
130
  help=_(
130
- "Additional route for this subnet "
131
- "e.g.: destination=10.10.0.0/16,gateway=192.168.71.254 "
131
+ "Additional route for this subnet, "
132
+ "for example, destination=10.10.0.0/16,gateway=192.168.71.254 "
132
133
  "destination: destination subnet (in CIDR notation) "
133
- "gateway: nexthop IP address "
134
+ "gateway: next-hop IP address "
134
135
  "(repeat option to add multiple routes)"
135
136
  ),
136
137
  )
@@ -150,8 +151,8 @@ def _get_common_parse_arguments(parser, is_create=True):
150
151
  action='append',
151
152
  dest='service_types',
152
153
  help=_(
153
- "Service type for this subnet "
154
- "e.g.: network:floatingip_agent_gateway. "
154
+ "Service type for this subnet, "
155
+ "for example, network:floatingip_agent_gateway. "
155
156
  "Must be a valid device owner value for a network port "
156
157
  "(repeat option to set multiple service types)"
157
158
  ),
@@ -365,8 +366,8 @@ class CreateSubnet(command.ShowOne, common.NeutronCommandWithExtraArgs):
365
366
  "<ip-address>: Specific IP address to use as the gateway, "
366
367
  "'auto': Gateway address should automatically be chosen "
367
368
  "from within the subnet itself, 'none': This subnet will "
368
- "not use a gateway, e.g.: --gateway 192.168.9.1, "
369
- "--gateway auto, --gateway none (default is 'auto')."
369
+ "not use a gateway. For example, --gateway 192.168.9.1, "
370
+ "--gateway auto or --gateway none (default is 'auto')."
370
371
  ),
371
372
  )
372
373
  parser.add_argument(
@@ -375,7 +376,7 @@ class CreateSubnet(command.ShowOne, common.NeutronCommandWithExtraArgs):
375
376
  default=4,
376
377
  choices=[4, 6],
377
378
  help=_(
378
- "IP version (default is 4). Note that when subnet pool is "
379
+ "IP version (default is 4). Note that when subnet pool is "
379
380
  "specified, IP version is determined from the subnet pool "
380
381
  "and this option is ignored."
381
382
  ),
@@ -400,7 +401,7 @@ class CreateSubnet(command.ShowOne, common.NeutronCommandWithExtraArgs):
400
401
  '--network-segment',
401
402
  metavar='<network-segment>',
402
403
  help=_(
403
- "Network segment to associate with this subnet " "(name or ID)"
404
+ "Network segment to associate with this subnet (name or ID)"
404
405
  ),
405
406
  )
406
407
  parser.add_argument(
@@ -465,7 +466,7 @@ class DeleteSubnet(command.Command):
465
466
 
466
467
  if result > 0:
467
468
  total = len(parsed_args.subnet)
468
- msg = _("%(result)s of %(total)s subnets failed " "to delete.") % {
469
+ msg = _("%(result)s of %(total)s subnets failed to delete.") % {
469
470
  'result': result,
470
471
  'total': total,
471
472
  }
@@ -513,10 +514,10 @@ class ListSubnet(command.Lister):
513
514
  action='append',
514
515
  dest='service_types',
515
516
  help=_(
516
- "List only subnets of a given service type in output "
517
- "e.g.: network:floatingip_agent_gateway. "
517
+ "List only subnets of a given service type in output, "
518
+ "for example, network:floatingip_agent_gateway. "
518
519
  "Must be a valid device owner value for a network port "
519
- "(repeat option to list multiple service types)"
520
+ "(repeat option to list multiple service types)."
520
521
  ),
521
522
  )
522
523
  parser.add_argument(
@@ -551,8 +552,8 @@ class ListSubnet(command.Lister):
551
552
  metavar='<subnet-range>',
552
553
  help=_(
553
554
  "List only subnets of given subnet range "
554
- "(in CIDR notation) in output "
555
- "e.g.: --subnet-range 10.10.0.0/16"
555
+ "(in CIDR notation) in output. "
556
+ "For example, --subnet-range 10.10.0.0/16"
556
557
  ),
557
558
  )
558
559
  parser.add_argument(
@@ -560,7 +561,7 @@ class ListSubnet(command.Lister):
560
561
  metavar='<subnet-pool>',
561
562
  help=_(
562
563
  "List only subnets which belong to a given subnet pool "
563
- "in output (Name or ID)"
564
+ "in output (name or ID)"
564
565
  ),
565
566
  )
566
567
  _tag.add_tag_filtering_option_to_parser(parser, _('subnets'))
@@ -606,8 +607,8 @@ class ListSubnet(command.Lister):
606
607
  _tag.get_tag_filtering_args(parsed_args, filters)
607
608
  data = network_client.subnets(**filters)
608
609
 
609
- headers = ('ID', 'Name', 'Network', 'Subnet')
610
- columns = ('id', 'name', 'network_id', 'cidr')
610
+ headers: tuple[str, ...] = ('ID', 'Name', 'Network', 'Subnet')
611
+ columns: tuple[str, ...] = ('id', 'name', 'network_id', 'cidr')
611
612
  if parsed_args.long:
612
613
  headers += (
613
614
  'Project',
@@ -684,8 +685,8 @@ class SetSubnet(common.NeutronCommandWithExtraArgs):
684
685
  help=_(
685
686
  "Specify a gateway for the subnet. The options are: "
686
687
  "<ip-address>: Specific IP address to use as the gateway, "
687
- "'none': This subnet will not use a gateway, "
688
- "e.g.: --gateway 192.168.9.1, --gateway none."
688
+ "'none': This subnet will not use a gateway. "
689
+ "For example, --gateway 192.168.9.1 or --gateway none."
689
690
  ),
690
691
  )
691
692
  parser.add_argument(
@@ -694,7 +695,7 @@ class SetSubnet(common.NeutronCommandWithExtraArgs):
694
695
  help=_(
695
696
  "Network segment to associate with this subnet (name or "
696
697
  "ID). It is only allowed to set the segment if the current "
697
- "value is `None`, the network must also have only one "
698
+ "value is `None`. The network must also have only one "
698
699
  "segment and only one subnet can exist on the network."
699
700
  ),
700
701
  )
@@ -774,7 +775,7 @@ class UnsetSubnet(common.NeutronUnsetCommandWithExtraArgs):
774
775
  required_keys=['start', 'end'],
775
776
  help=_(
776
777
  'Allocation pool IP addresses to be removed from this '
777
- 'subnet e.g.: start=192.168.199.2,end=192.168.199.254 '
778
+ 'subnet, for example, start=192.168.199.2,end=192.168.199.254 '
778
779
  '(repeat option to unset multiple allocation pools)'
779
780
  ),
780
781
  )
@@ -800,10 +801,10 @@ class UnsetSubnet(common.NeutronUnsetCommandWithExtraArgs):
800
801
  action=parseractions.MultiKeyValueAction,
801
802
  required_keys=['destination', 'gateway'],
802
803
  help=_(
803
- 'Route to be removed from this subnet '
804
- 'e.g.: destination=10.10.0.0/16,gateway=192.168.71.254 '
804
+ 'Route to be removed from this subnet, '
805
+ 'for example, destination=10.10.0.0/16,gateway=192.168.71.254 '
805
806
  'destination: destination subnet (in CIDR notation) '
806
- 'gateway: nexthop IP address '
807
+ 'gateway: next-hop IP address '
807
808
  '(repeat option to unset multiple host routes)'
808
809
  ),
809
810
  )
@@ -813,8 +814,8 @@ class UnsetSubnet(common.NeutronUnsetCommandWithExtraArgs):
813
814
  action='append',
814
815
  dest='service_types',
815
816
  help=_(
816
- 'Service type to be removed from this subnet '
817
- 'e.g.: network:floatingip_agent_gateway. '
817
+ 'Service type to be removed from this subnet, '
818
+ 'for example, network:floatingip_agent_gateway. '
818
819
  'Must be a valid device owner value for a network port '
819
820
  '(repeat option to unset multiple service types)'
820
821
  ),
@@ -831,7 +832,7 @@ class UnsetSubnet(common.NeutronUnsetCommandWithExtraArgs):
831
832
  client = self.app.client_manager.network
832
833
  obj = client.find_subnet(parsed_args.subnet, ignore_missing=False)
833
834
 
834
- attrs = {}
835
+ attrs: dict[str, ty.Any] = {}
835
836
  if parsed_args.gateway:
836
837
  attrs['gateway_ip'] = None
837
838
  if parsed_args.dns_nameservers: