python-openstackclient 10.0.0__py3-none-any.whl → 10.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 (203) hide show
  1. openstackclient/common/availability_zone.py +1 -1
  2. openstackclient/common/module.py +21 -27
  3. openstackclient/common/pagination.py +42 -4
  4. openstackclient/common/project_cleanup.py +1 -2
  5. openstackclient/common/quota.py +9 -5
  6. openstackclient/compute/v2/flavor.py +3 -1
  7. openstackclient/compute/v2/hypervisor.py +2 -0
  8. openstackclient/compute/v2/keypair.py +6 -2
  9. openstackclient/compute/v2/server.py +21 -12
  10. openstackclient/compute/v2/server_event.py +8 -1
  11. openstackclient/compute/v2/server_group.py +2 -0
  12. openstackclient/compute/v2/server_migration.py +3 -0
  13. openstackclient/compute/v2/server_volume.py +3 -1
  14. openstackclient/compute/v2/service.py +3 -1
  15. openstackclient/compute/v2/usage.py +2 -2
  16. openstackclient/identity/common.py +5 -1
  17. openstackclient/identity/v3/access_rule.py +6 -0
  18. openstackclient/identity/v3/application_credential.py +10 -3
  19. openstackclient/identity/v3/credential.py +4 -2
  20. openstackclient/identity/v3/domain.py +4 -2
  21. openstackclient/identity/v3/endpoint.py +57 -45
  22. openstackclient/identity/v3/federation_protocol.py +7 -5
  23. openstackclient/identity/v3/group.py +11 -10
  24. openstackclient/identity/v3/identity_provider.py +4 -1
  25. openstackclient/identity/v3/limit.py +5 -2
  26. openstackclient/identity/v3/mapping.py +36 -19
  27. openstackclient/identity/v3/project.py +18 -5
  28. openstackclient/identity/v3/region.py +4 -2
  29. openstackclient/identity/v3/registered_limit.py +3 -2
  30. openstackclient/identity/v3/role.py +2 -1
  31. openstackclient/identity/v3/role_assignment.py +3 -2
  32. openstackclient/identity/v3/service.py +4 -2
  33. openstackclient/identity/v3/service_provider.py +4 -2
  34. openstackclient/identity/v3/trust.py +8 -5
  35. openstackclient/identity/v3/user.py +38 -11
  36. openstackclient/image/v2/cache.py +2 -2
  37. openstackclient/image/v2/image.py +15 -9
  38. openstackclient/image/v2/metadef_namespaces.py +11 -10
  39. openstackclient/image/v2/metadef_objects.py +5 -5
  40. openstackclient/image/v2/metadef_properties.py +7 -4
  41. openstackclient/image/v2/task.py +11 -22
  42. openstackclient/network/utils.py +0 -41
  43. openstackclient/network/v2/address_group.py +13 -1
  44. openstackclient/network/v2/address_scope.py +13 -8
  45. openstackclient/network/v2/bgpvpn/bgpvpn.py +33 -19
  46. openstackclient/network/v2/bgpvpn/network_association.py +25 -13
  47. openstackclient/network/v2/bgpvpn/port_association.py +35 -21
  48. openstackclient/network/v2/bgpvpn/router_association.py +27 -14
  49. openstackclient/network/v2/default_security_group_rule.py +14 -6
  50. openstackclient/network/v2/floating_ip.py +12 -4
  51. openstackclient/network/v2/floating_ip_port_forwarding.py +12 -2
  52. openstackclient/network/v2/fwaas/group.py +34 -1
  53. openstackclient/network/v2/fwaas/rule.py +39 -3
  54. openstackclient/network/v2/ip_availability.py +13 -4
  55. openstackclient/network/v2/l3_conntrack_helper.py +14 -1
  56. openstackclient/network/v2/local_ip.py +4 -1
  57. openstackclient/network/v2/local_ip_association.py +4 -1
  58. openstackclient/network/v2/ndp_proxy.py +4 -1
  59. openstackclient/network/v2/network.py +87 -20
  60. openstackclient/network/v2/network_agent.py +32 -10
  61. openstackclient/network/v2/network_auto_allocated_topology.py +6 -5
  62. openstackclient/network/v2/network_flavor.py +19 -6
  63. openstackclient/network/v2/network_flavor_profile.py +20 -6
  64. openstackclient/network/v2/network_meter.py +19 -6
  65. openstackclient/network/v2/network_meter_rule.py +20 -2
  66. openstackclient/network/v2/network_qos_policy.py +15 -7
  67. openstackclient/network/v2/network_qos_rule.py +16 -1
  68. openstackclient/network/v2/network_qos_rule_type.py +16 -5
  69. openstackclient/network/v2/network_rbac.py +12 -5
  70. openstackclient/network/v2/network_segment.py +13 -1
  71. openstackclient/network/v2/network_segment_range.py +15 -3
  72. openstackclient/network/v2/network_trunk.py +4 -1
  73. openstackclient/network/v2/port.py +88 -12
  74. openstackclient/network/v2/router.py +27 -16
  75. openstackclient/network/v2/security_group.py +18 -49
  76. openstackclient/network/v2/security_group_rule.py +18 -5
  77. openstackclient/network/v2/subnet.py +15 -7
  78. openstackclient/network/v2/subnet_pool.py +13 -8
  79. openstackclient/network/v2/taas/tap_flow.py +13 -3
  80. openstackclient/network/v2/taas/tap_mirror.py +7 -4
  81. openstackclient/network/v2/taas/tap_service.py +4 -1
  82. openstackclient/object/v1/container.py +3 -1
  83. openstackclient/object/v1/object.py +3 -1
  84. openstackclient/tests/functional/identity/v3/common.py +34 -0
  85. openstackclient/tests/functional/identity/v3/test_application_credential.py +1 -1
  86. openstackclient/tests/functional/identity/v3/test_mapping.py +81 -0
  87. openstackclient/tests/functional/volume/v3/test_volume_group.py +163 -0
  88. openstackclient/tests/unit/common/test_limits.py +1 -1
  89. openstackclient/tests/unit/common/test_module.py +77 -44
  90. openstackclient/tests/unit/common/test_quota.py +9 -0
  91. openstackclient/tests/unit/compute/v2/fakes.py +1 -57
  92. openstackclient/tests/unit/compute/v2/test_agent.py +4 -4
  93. openstackclient/tests/unit/compute/v2/test_aggregate.py +1 -1
  94. openstackclient/tests/unit/compute/v2/test_console.py +2 -2
  95. openstackclient/tests/unit/compute/v2/test_console_connection.py +1 -1
  96. openstackclient/tests/unit/compute/v2/test_flavor.py +1 -1
  97. openstackclient/tests/unit/compute/v2/test_host.py +3 -3
  98. openstackclient/tests/unit/compute/v2/test_hypervisor.py +2 -2
  99. openstackclient/tests/unit/compute/v2/test_hypervisor_stats.py +1 -1
  100. openstackclient/tests/unit/compute/v2/test_keypair.py +1 -1
  101. openstackclient/tests/unit/compute/v2/test_server.py +15 -15
  102. openstackclient/tests/unit/compute/v2/test_server_backup.py +1 -1
  103. openstackclient/tests/unit/compute/v2/test_server_event.py +2 -2
  104. openstackclient/tests/unit/compute/v2/test_server_group.py +1 -1
  105. openstackclient/tests/unit/compute/v2/test_server_image.py +1 -1
  106. openstackclient/tests/unit/compute/v2/test_server_migration.py +4 -4
  107. openstackclient/tests/unit/compute/v2/test_server_share.py +4 -4
  108. openstackclient/tests/unit/compute/v2/test_server_volume.py +2 -2
  109. openstackclient/tests/unit/compute/v2/test_service.py +3 -3
  110. openstackclient/tests/unit/compute/v2/test_usage.py +1 -1
  111. openstackclient/tests/unit/identity/v2_0/fakes.py +3 -7
  112. openstackclient/tests/unit/identity/v2_0/test_endpoint.py +1 -1
  113. openstackclient/tests/unit/identity/v2_0/test_project.py +1 -1
  114. openstackclient/tests/unit/identity/v2_0/test_role.py +1 -1
  115. openstackclient/tests/unit/identity/v2_0/test_role_assignment.py +1 -1
  116. openstackclient/tests/unit/identity/v2_0/test_service.py +1 -1
  117. openstackclient/tests/unit/identity/v2_0/test_token.py +2 -2
  118. openstackclient/tests/unit/identity/v2_0/test_user.py +1 -1
  119. openstackclient/tests/unit/identity/v3/fakes.py +5 -38
  120. openstackclient/tests/unit/identity/v3/test_access_rule.py +3 -3
  121. openstackclient/tests/unit/identity/v3/test_application_credential.py +4 -4
  122. openstackclient/tests/unit/identity/v3/test_credential.py +5 -5
  123. openstackclient/tests/unit/identity/v3/test_domain.py +5 -5
  124. openstackclient/tests/unit/identity/v3/test_endpoint.py +6 -6
  125. openstackclient/tests/unit/identity/v3/test_endpoint_group.py +1 -1
  126. openstackclient/tests/unit/identity/v3/test_group.py +8 -8
  127. openstackclient/tests/unit/identity/v3/test_implied_role.py +1 -1
  128. openstackclient/tests/unit/identity/v3/test_limit.py +5 -5
  129. openstackclient/tests/unit/identity/v3/test_mappings.py +163 -79
  130. openstackclient/tests/unit/identity/v3/test_project.py +28 -5
  131. openstackclient/tests/unit/identity/v3/test_protocol.py +3 -3
  132. openstackclient/tests/unit/identity/v3/test_region.py +5 -5
  133. openstackclient/tests/unit/identity/v3/test_registered_limit.py +5 -5
  134. openstackclient/tests/unit/identity/v3/test_role.py +8 -8
  135. openstackclient/tests/unit/identity/v3/test_role_assignment.py +1 -1
  136. openstackclient/tests/unit/identity/v3/test_service.py +5 -5
  137. openstackclient/tests/unit/identity/v3/test_token.py +2 -2
  138. openstackclient/tests/unit/identity/v3/test_trust.py +4 -4
  139. openstackclient/tests/unit/identity/v3/test_user.py +73 -6
  140. openstackclient/tests/unit/network/v2/fakes.py +5 -77
  141. openstackclient/tests/unit/network/v2/fwaas/test_group.py +28 -2
  142. openstackclient/tests/unit/network/v2/fwaas/test_rule.py +28 -3
  143. openstackclient/tests/unit/network/v2/test_address_group.py +24 -0
  144. openstackclient/tests/unit/network/v2/test_address_scope.py +24 -0
  145. openstackclient/tests/unit/network/v2/test_floating_ip.py +24 -0
  146. openstackclient/tests/unit/network/v2/test_floating_ip_port_forwarding.py +24 -0
  147. openstackclient/tests/unit/network/v2/test_ip_availability.py +25 -0
  148. openstackclient/tests/unit/network/v2/test_l3_conntrack_helper.py +29 -3
  149. openstackclient/tests/unit/network/v2/test_network.py +74 -12
  150. openstackclient/tests/unit/network/v2/test_network_agent.py +50 -1
  151. openstackclient/tests/unit/network/v2/test_network_flavor.py +24 -0
  152. openstackclient/tests/unit/network/v2/test_network_flavor_profile.py +24 -0
  153. openstackclient/tests/unit/network/v2/test_network_meter.py +24 -0
  154. openstackclient/tests/unit/network/v2/test_network_qos_policy.py +24 -0
  155. openstackclient/tests/unit/network/v2/test_network_qos_rule_type.py +24 -0
  156. openstackclient/tests/unit/network/v2/test_network_rbac.py +24 -0
  157. openstackclient/tests/unit/network/v2/test_network_segment.py +24 -0
  158. openstackclient/tests/unit/network/v2/test_network_segment_range.py +24 -0
  159. openstackclient/tests/unit/network/v2/test_port.py +166 -0
  160. openstackclient/tests/unit/network/v2/test_router.py +28 -7
  161. openstackclient/tests/unit/network/v2/test_security_group.py +22 -0
  162. openstackclient/tests/unit/network/v2/test_security_group_rule.py +25 -0
  163. openstackclient/tests/unit/network/v2/test_subnet.py +28 -4
  164. openstackclient/tests/unit/network/v2/test_subnet_pool.py +24 -0
  165. openstackclient/tests/unit/volume/v2/fakes.py +20 -140
  166. openstackclient/tests/unit/volume/v2/test_volume_backup.py +5 -9
  167. openstackclient/tests/unit/volume/v2/test_volume_snapshot.py +6 -0
  168. openstackclient/tests/unit/volume/v3/fakes.py +204 -100
  169. openstackclient/tests/unit/volume/v3/test_backup_record.py +114 -0
  170. openstackclient/tests/unit/volume/v3/test_consistency_group.py +720 -0
  171. openstackclient/tests/unit/volume/v3/test_consistency_group_snapshot.py +354 -0
  172. openstackclient/tests/unit/volume/v3/test_qos_specs.py +455 -0
  173. openstackclient/tests/unit/volume/v3/test_volume_attachment.py +2 -0
  174. openstackclient/tests/unit/volume/v3/test_volume_backend.py +158 -0
  175. openstackclient/tests/unit/volume/v3/test_volume_backup.py +5 -9
  176. openstackclient/tests/unit/volume/v3/test_volume_group_type.py +65 -0
  177. openstackclient/tests/unit/volume/v3/test_volume_host.py +115 -0
  178. openstackclient/tests/unit/volume/v3/test_volume_snapshot.py +6 -0
  179. openstackclient/volume/v2/volume.py +4 -2
  180. openstackclient/volume/v2/volume_backup.py +2 -3
  181. openstackclient/volume/v2/volume_snapshot.py +3 -4
  182. openstackclient/volume/v3/backup_record.py +94 -0
  183. openstackclient/volume/v3/consistency_group.py +400 -0
  184. openstackclient/volume/v3/consistency_group_snapshot.py +225 -0
  185. openstackclient/volume/v3/qos_specs.py +389 -0
  186. openstackclient/volume/v3/volume.py +4 -2
  187. openstackclient/volume/v3/volume_attachment.py +5 -1
  188. openstackclient/volume/v3/volume_backend.py +130 -0
  189. openstackclient/volume/v3/volume_backup.py +2 -3
  190. openstackclient/volume/v3/volume_group_snapshot.py +4 -6
  191. openstackclient/volume/v3/volume_group_type.py +1 -1
  192. openstackclient/volume/v3/volume_host.py +74 -0
  193. openstackclient/volume/v3/volume_message.py +3 -1
  194. openstackclient/volume/v3/volume_snapshot.py +2 -1
  195. {python_openstackclient-10.0.0.dist-info → python_openstackclient-10.1.0.dist-info}/METADATA +3 -4
  196. {python_openstackclient-10.0.0.dist-info → python_openstackclient-10.1.0.dist-info}/RECORD +202 -188
  197. {python_openstackclient-10.0.0.dist-info → python_openstackclient-10.1.0.dist-info}/entry_points.txt +24 -24
  198. {python_openstackclient-10.0.0.dist-info → python_openstackclient-10.1.0.dist-info}/licenses/AUTHORS +5 -0
  199. python_openstackclient-10.1.0.dist-info/pbr.json +1 -0
  200. python_openstackclient-10.0.0.dist-info/pbr.json +0 -1
  201. {python_openstackclient-10.0.0.dist-info → python_openstackclient-10.1.0.dist-info}/WHEEL +0 -0
  202. {python_openstackclient-10.0.0.dist-info → python_openstackclient-10.1.0.dist-info}/licenses/LICENSE +0 -0
  203. {python_openstackclient-10.0.0.dist-info → python_openstackclient-10.1.0.dist-info}/top_level.txt +0 -0
@@ -18,12 +18,14 @@ import logging
18
18
  from typing import Any
19
19
 
20
20
  from openstack import exceptions as sdk_exceptions
21
+ from openstack.network.v2 import floating_ip as _floating_ip
21
22
  from osc_lib.cli import format_columns
22
23
  from osc_lib import exceptions
23
24
  from osc_lib import utils
24
25
  from osc_lib.utils import tags as _tag
25
26
 
26
27
  from openstackclient import command
28
+ from openstackclient.common import pagination
27
29
  from openstackclient.i18n import _
28
30
  from openstackclient.identity import common as identity_common
29
31
  from openstackclient.network import common
@@ -35,7 +37,9 @@ _formatters = {
35
37
  }
36
38
 
37
39
 
38
- def _get_network_columns(item: Any) -> tuple[tuple[str, ...], tuple[str, ...]]:
40
+ def _get_network_columns(
41
+ item: _floating_ip.FloatingIP,
42
+ ) -> tuple[tuple[str, ...], tuple[str, ...]]:
39
43
  hidden_columns = ['location', 'tenant_id']
40
44
  return utils.get_osc_show_columns_for_sdk_resource(
41
45
  item, {}, hidden_columns
@@ -231,9 +235,6 @@ class DeleteFloatingIP(command.Command):
231
235
 
232
236
 
233
237
  class ListFloatingIP(command.Lister):
234
- # TODO(songminglong): Use SDK resource mapped attribute names once
235
- # the OSC minimum requirements include SDK 1.0
236
-
237
238
  _description = _("List floating IP(s)")
238
239
 
239
240
  def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
@@ -311,6 +312,7 @@ class ListFloatingIP(command.Lister):
311
312
  default=False,
312
313
  help=_("List additional fields in output"),
313
314
  )
315
+ pagination.add_marker_pagination_option_to_parser(parser)
314
316
  return parser
315
317
 
316
318
  def take_action(
@@ -398,6 +400,12 @@ class ListFloatingIP(command.Lister):
398
400
  ).id
399
401
  router_ids.append(router_id)
400
402
  query['router_id'] = router_ids
403
+ if parsed_args.marker is not None:
404
+ query['marker'] = parsed_args.marker
405
+ if parsed_args.limit is not None:
406
+ query['limit'] = parsed_args.limit
407
+ if parsed_args.max_items is not None:
408
+ query['max_items'] = parsed_args.max_items
401
409
 
402
410
  _tag.get_tag_filtering_args(parsed_args, query)
403
411
 
@@ -18,10 +18,12 @@ import logging
18
18
  from collections.abc import Iterable, Sequence
19
19
  from typing import Any
20
20
 
21
+ from openstack.network.v2 import port_forwarding as _port_forwarding
21
22
  from osc_lib import exceptions
22
23
  from osc_lib import utils
23
24
 
24
25
  from openstackclient import command
26
+ from openstackclient.common import pagination
25
27
  from openstackclient.i18n import _
26
28
  from openstackclient.network import common
27
29
 
@@ -91,7 +93,9 @@ def validate_port(port: int) -> None:
91
93
  raise exceptions.CommandError(msg)
92
94
 
93
95
 
94
- def _get_columns(item: Any) -> tuple[tuple[str, ...], tuple[str, ...]]:
96
+ def _get_columns(
97
+ item: _port_forwarding.PortForwarding,
98
+ ) -> tuple[tuple[str, ...], tuple[str, ...]]:
95
99
  hidden_columns = ['location', 'tenant_id']
96
100
  return utils.get_osc_show_columns_for_sdk_resource(
97
101
  item, {}, hidden_columns
@@ -294,7 +298,7 @@ class ListFloatingIPPortForwarding(command.Lister):
294
298
  "specified protocol number"
295
299
  ),
296
300
  )
297
-
301
+ pagination.add_marker_pagination_option_to_parser(parser)
298
302
  return parser
299
303
 
300
304
  def take_action(
@@ -340,6 +344,12 @@ class ListFloatingIPPortForwarding(command.Lister):
340
344
  )
341
345
  if parsed_args.protocol is not None:
342
346
  query['protocol'] = parsed_args.protocol
347
+ if parsed_args.marker is not None:
348
+ query['marker'] = parsed_args.marker
349
+ if parsed_args.limit is not None:
350
+ query['limit'] = parsed_args.limit
351
+ if parsed_args.max_items is not None:
352
+ query['max_items'] = parsed_args.max_items
343
353
 
344
354
  obj = client.find_ip(
345
355
  parsed_args.floating_ip,
@@ -60,7 +60,6 @@ _attr_map_dict = {x[0]: x[1] for x in _attr_map}
60
60
  def _get_common_parser(
61
61
  parser: argparse.ArgumentParser,
62
62
  ) -> argparse.ArgumentParser:
63
- parser.add_argument('--name', help=_('Name for the firewall group'))
64
63
  parser.add_argument(
65
64
  '--description',
66
65
  metavar='<description>',
@@ -184,6 +183,23 @@ class CreateFirewallGroup(command.ShowOne):
184
183
  def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
185
184
  parser = super().get_parser(prog_name)
186
185
  _get_common_parser(parser)
186
+ # TODO(slaweq): Remove the deprecated --name option and make the
187
+ # positional name argument required (remove nargs='?') once the
188
+ # deprecation period is over.
189
+ parser.add_argument(
190
+ 'positional_name',
191
+ nargs='?',
192
+ metavar='<name>',
193
+ default=None,
194
+ help=_('Name for the firewall group'),
195
+ )
196
+ parser.add_argument(
197
+ '--name',
198
+ help=_(
199
+ '(Deprecated, please pass name as a positional argument) '
200
+ 'Name for the firewall group'
201
+ ),
202
+ )
187
203
  identity_utils.add_project_owner_option_to_parser(parser)
188
204
  port_group = parser.add_mutually_exclusive_group()
189
205
  port_group.add_argument(
@@ -207,6 +223,22 @@ class CreateFirewallGroup(command.ShowOne):
207
223
  self, parsed_args: argparse.Namespace
208
224
  ) -> tuple[Sequence[str], Iterable[Any]]:
209
225
  client = self.app.client_manager.network
226
+ # TODO(slaweq): Remove this --name deprecation handling once the
227
+ # deprecation period is over.
228
+ if parsed_args.positional_name and parsed_args.name:
229
+ msg = _(
230
+ "Cannot specify name as both a positional argument "
231
+ "and with the --name option."
232
+ )
233
+ raise exceptions.CommandError(msg)
234
+ if parsed_args.name:
235
+ LOG.warning(
236
+ 'The --name option is deprecated for the "firewall group '
237
+ 'create" command, please pass the name as a positional '
238
+ 'argument instead.'
239
+ )
240
+ elif parsed_args.positional_name:
241
+ parsed_args.name = parsed_args.positional_name
210
242
  attrs = _get_common_attrs(self.app.client_manager, parsed_args)
211
243
  if 'project' in parsed_args and parsed_args.project is not None:
212
244
  attrs['project_id'] = identity_common.find_project(
@@ -300,6 +332,7 @@ class SetFirewallGroup(command.Command):
300
332
  metavar='<firewall-group>',
301
333
  help=_('Firewall group to update (name or ID)'),
302
334
  )
335
+ parser.add_argument('--name', help=_('Name for the firewall group'))
303
336
  parser.add_argument(
304
337
  '--port',
305
338
  metavar='<port>',
@@ -74,9 +74,6 @@ def _convert_to_lowercase(string: str) -> str:
74
74
  def _get_common_parser(
75
75
  parser: argparse.ArgumentParser,
76
76
  ) -> argparse.ArgumentParser:
77
- parser.add_argument(
78
- '--name', metavar='<name>', help=_('Name of the firewall rule')
79
- )
80
77
  parser.add_argument(
81
78
  '--description',
82
79
  metavar='<description>',
@@ -288,6 +285,24 @@ class CreateFirewallRule(command.ShowOne):
288
285
  def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
289
286
  parser = super().get_parser(prog_name)
290
287
  _get_common_parser(parser)
288
+ # TODO(slaweq): Remove the deprecated --name option and make the
289
+ # positional name argument required (remove nargs='?') once the
290
+ # deprecation period is over.
291
+ parser.add_argument(
292
+ 'positional_name',
293
+ nargs='?',
294
+ metavar='<name>',
295
+ default=None,
296
+ help=_('Name of the firewall rule'),
297
+ )
298
+ parser.add_argument(
299
+ '--name',
300
+ metavar='<name>',
301
+ help=_(
302
+ '(Deprecated, please pass name as a positional argument) '
303
+ 'Name of the firewall rule'
304
+ ),
305
+ )
291
306
  identity_utils.add_project_owner_option_to_parser(parser)
292
307
  return parser
293
308
 
@@ -295,6 +310,22 @@ class CreateFirewallRule(command.ShowOne):
295
310
  self, parsed_args: argparse.Namespace
296
311
  ) -> tuple[Sequence[str], Iterable[Any]]:
297
312
  client = self.app.client_manager.network
313
+ # TODO(slaweq): Remove this --name deprecation handling once the
314
+ # deprecation period is over.
315
+ if parsed_args.positional_name and parsed_args.name:
316
+ msg = _(
317
+ "Cannot specify name as both a positional argument "
318
+ "and with the --name option."
319
+ )
320
+ raise exceptions.CommandError(msg)
321
+ if parsed_args.name:
322
+ LOG.warning(
323
+ 'The --name option is deprecated for the "firewall group '
324
+ 'rule create" command, please pass the name as a positional '
325
+ 'argument instead.'
326
+ )
327
+ elif parsed_args.positional_name:
328
+ parsed_args.name = parsed_args.positional_name
298
329
  attrs = _get_common_attrs(self.app.client_manager, parsed_args)
299
330
  if 'project' in parsed_args and parsed_args.project is not None:
300
331
  attrs['project_id'] = identity_common.find_project(
@@ -415,6 +446,11 @@ class SetFirewallRule(command.Command):
415
446
  metavar='<firewall-rule>',
416
447
  help=_('Firewall rule to set (name or ID)'),
417
448
  )
449
+ parser.add_argument(
450
+ '--name',
451
+ metavar='<name>',
452
+ help=_('Name of the firewall rule'),
453
+ )
418
454
  return parser
419
455
 
420
456
  def take_action(self, parsed_args: argparse.Namespace) -> None:
@@ -17,10 +17,12 @@ import argparse
17
17
  from collections.abc import Iterable, Sequence
18
18
  from typing import Any
19
19
 
20
+ from openstack.network.v2 import network_ip_availability as _ip_availability
20
21
  from osc_lib.cli import format_columns
21
22
  from osc_lib import utils
22
23
 
23
24
  from openstackclient import command
25
+ from openstackclient.common import pagination
24
26
  from openstackclient.i18n import _
25
27
  from openstackclient.identity import common as identity_common
26
28
 
@@ -29,15 +31,15 @@ _formatters = {
29
31
  }
30
32
 
31
33
 
32
- def _get_columns(item: Any) -> tuple[tuple[str, ...], tuple[str, ...]]:
34
+ def _get_columns(
35
+ item: _ip_availability.NetworkIPAvailability,
36
+ ) -> tuple[tuple[str, ...], tuple[str, ...]]:
33
37
  hidden_columns = ['id', 'name', 'location', 'tenant_id']
34
38
  return utils.get_osc_show_columns_for_sdk_resource(
35
39
  item, {}, hidden_columns
36
40
  )
37
41
 
38
42
 
39
- # TODO(ankur-gupta-f): Use the SDK resource mapped attribute names once
40
- # the OSC minimum requirements include SDK 1.0.
41
43
  class ListIPAvailability(command.Lister):
42
44
  _description = _("List IP availability for network")
43
45
 
@@ -64,6 +66,7 @@ class ListIPAvailability(command.Lister):
64
66
  ),
65
67
  )
66
68
  identity_common.add_project_domain_option_to_parser(parser)
69
+ pagination.add_marker_pagination_option_to_parser(parser)
67
70
  return parser
68
71
 
69
72
  def take_action(
@@ -87,7 +90,6 @@ class ListIPAvailability(command.Lister):
87
90
  filters = {}
88
91
  if parsed_args.ip_version:
89
92
  filters['ip_version'] = parsed_args.ip_version
90
-
91
93
  if parsed_args.project:
92
94
  identity_client = self.app.client_manager.identity
93
95
  project_id = identity_common.find_project(
@@ -96,6 +98,13 @@ class ListIPAvailability(command.Lister):
96
98
  parsed_args.project_domain,
97
99
  ).id
98
100
  filters['project_id'] = project_id
101
+ if parsed_args.marker is not None:
102
+ filters['marker'] = parsed_args.marker
103
+ if parsed_args.limit is not None:
104
+ filters['limit'] = parsed_args.limit
105
+ if parsed_args.max_items is not None:
106
+ filters['max_items'] = parsed_args.max_items
107
+
99
108
  data = client.network_ip_availabilities(**filters)
100
109
  return (
101
110
  column_headers,
@@ -18,16 +18,20 @@ import logging
18
18
  from collections.abc import Iterable, Sequence
19
19
  from typing import Any
20
20
 
21
+ from openstack.network.v2 import l3_conntrack_helper as _l3_conntrack_helper
21
22
  from osc_lib import exceptions
22
23
  from osc_lib import utils
23
24
 
24
25
  from openstackclient import command
26
+ from openstackclient.common import pagination
25
27
  from openstackclient.i18n import _
26
28
 
27
29
  LOG = logging.getLogger(__name__)
28
30
 
29
31
 
30
- def _get_columns(item: Any) -> tuple[tuple[str, ...], tuple[str, ...]]:
32
+ def _get_columns(
33
+ item: _l3_conntrack_helper.ConntrackHelper,
34
+ ) -> tuple[tuple[str, ...], tuple[str, ...]]:
31
35
  hidden_columns = ['location', 'tenant_id']
32
36
  return utils.get_osc_show_columns_for_sdk_resource(
33
37
  item, {}, hidden_columns
@@ -176,6 +180,7 @@ class ListConntrackHelper(command.Lister):
176
180
  'the netfilter conntrack target rule (name or ID)'
177
181
  ),
178
182
  )
183
+ pagination.add_marker_pagination_option_to_parser(parser)
179
184
 
180
185
  return parser
181
186
 
@@ -197,7 +202,15 @@ class ListConntrackHelper(command.Lister):
197
202
  'Protocol',
198
203
  'Port',
199
204
  )
205
+
200
206
  attrs = _get_attrs(client, parsed_args)
207
+ if parsed_args.marker is not None:
208
+ attrs['marker'] = parsed_args.marker
209
+ if parsed_args.limit is not None:
210
+ attrs['limit'] = parsed_args.limit
211
+ if parsed_args.max_items is not None:
212
+ attrs['max_items'] = parsed_args.max_items
213
+
201
214
  data = client.conntrack_helpers(attrs.pop('router_id'), **attrs)
202
215
 
203
216
  return (
@@ -20,6 +20,7 @@ import logging
20
20
  from collections.abc import Iterable, Sequence
21
21
  from typing import Any
22
22
 
23
+ from openstack.network.v2 import local_ip as _local_ip
23
24
  from osc_lib import exceptions
24
25
  from osc_lib import utils
25
26
 
@@ -30,7 +31,9 @@ from openstackclient.identity import common as identity_common
30
31
  LOG = logging.getLogger(__name__)
31
32
 
32
33
 
33
- def _get_columns(item: Any) -> tuple[tuple[str, ...], tuple[str, ...]]:
34
+ def _get_columns(
35
+ item: _local_ip.LocalIP,
36
+ ) -> tuple[tuple[str, ...], tuple[str, ...]]:
34
37
  hidden_columns = ['location', 'tenant_id']
35
38
  return utils.get_osc_show_columns_for_sdk_resource(
36
39
  item, {}, hidden_columns
@@ -20,6 +20,7 @@ import logging
20
20
  from collections.abc import Iterable, Sequence
21
21
  from typing import Any
22
22
 
23
+ from openstack.network.v2 import local_ip_association as _local_ip_association
23
24
  from osc_lib import exceptions
24
25
  from osc_lib import utils
25
26
 
@@ -30,7 +31,9 @@ from openstackclient.identity import common as identity_common
30
31
  LOG = logging.getLogger(__name__)
31
32
 
32
33
 
33
- def _get_columns(item: Any) -> tuple[tuple[str, ...], tuple[str, ...]]:
34
+ def _get_columns(
35
+ item: _local_ip_association.LocalIPAssociation,
36
+ ) -> tuple[tuple[str, ...], tuple[str, ...]]:
34
37
  hidden_columns = ['location', 'name', 'id', 'tenant_id']
35
38
  return utils.get_osc_show_columns_for_sdk_resource(
36
39
  item, {}, hidden_columns
@@ -20,6 +20,7 @@ import logging
20
20
  from collections.abc import Iterable, Sequence
21
21
  from typing import Any
22
22
 
23
+ from openstack.network.v2 import ndp_proxy as _ndp_proxy
23
24
  from osc_lib import exceptions
24
25
  from osc_lib import utils
25
26
 
@@ -31,7 +32,9 @@ from openstackclient.identity import common as identity_common
31
32
  LOG = logging.getLogger(__name__)
32
33
 
33
34
 
34
- def _get_columns(item: Any) -> tuple[tuple[str, ...], tuple[str, ...]]:
35
+ def _get_columns(
36
+ item: _ndp_proxy.NDPProxy,
37
+ ) -> tuple[tuple[str, ...], tuple[str, ...]]:
35
38
  hidden_columns = ['location']
36
39
  return utils.get_osc_show_columns_for_sdk_resource(
37
40
  item, {}, hidden_columns
@@ -18,12 +18,14 @@ import logging
18
18
  from typing import Any
19
19
 
20
20
  from cliff import columns as cliff_columns
21
+ from openstack.network.v2 import network as _network
21
22
  from osc_lib.cli import format_columns
22
23
  from osc_lib import exceptions
23
24
  from osc_lib import utils
24
25
  from osc_lib.utils import tags as _tag
25
26
 
26
27
  from openstackclient import command
28
+ from openstackclient.common import pagination
27
29
  from openstackclient.i18n import _
28
30
  from openstackclient.identity import common as identity_common
29
31
  from openstackclient.network import common
@@ -54,7 +56,9 @@ _formatters = {
54
56
  }
55
57
 
56
58
 
57
- def _get_columns_network(item: Any) -> tuple[tuple[str, ...], tuple[str, ...]]:
59
+ def _get_columns_network(
60
+ item: _network.Network,
61
+ ) -> tuple[tuple[str, ...], tuple[str, ...]]:
58
62
  column_map = {
59
63
  'subnet_ids': 'subnets',
60
64
  'is_admin_state_up': 'admin_state_up',
@@ -146,6 +150,13 @@ def _get_attrs_network(
146
150
  attrs['qos_policy_id'] = _qos_policy.id
147
151
  if 'no_qos_policy' in parsed_args and parsed_args.no_qos_policy:
148
152
  attrs['qos_policy_id'] = None
153
+
154
+ # Set pvlan
155
+ if parsed_args.pvlan:
156
+ attrs['pvlan'] = True
157
+ if parsed_args.no_pvlan:
158
+ attrs['pvlan'] = False
159
+
149
160
  # Update DNS network options
150
161
  if parsed_args.dns_domain is not None:
151
162
  attrs['dns_domain'] = parsed_args.dns_domain
@@ -208,8 +219,6 @@ def _add_additional_network_options(parser: argparse.ArgumentParser) -> None:
208
219
  )
209
220
 
210
221
 
211
- # TODO(sindhu): Use the SDK resource mapped attribute names once the
212
- # OSC minimum requirements include SDK 1.0.
213
222
  class CreateNetwork(command.ShowOne, common.NeutronCommandWithExtraArgs):
214
223
  _description = _("Create new network")
215
224
 
@@ -348,6 +357,24 @@ class CreateNetwork(command.ShowOne, common.NeutronCommandWithExtraArgs):
348
357
  help=_("Disable VLAN QinQ (S-Tag ethtype 0x8a88) for the network"),
349
358
  )
350
359
 
360
+ pvlan_grp = parser.add_mutually_exclusive_group()
361
+ pvlan_grp.add_argument(
362
+ '--pvlan',
363
+ action='store_true',
364
+ help=_(
365
+ "Enable Private VLAN for the network "
366
+ "(PVLAN extension required)"
367
+ ),
368
+ )
369
+ pvlan_grp.add_argument(
370
+ '--no-pvlan',
371
+ action='store_true',
372
+ help=_(
373
+ "Disable Private VLAN for the network "
374
+ "(PVLAN extension required)"
375
+ ),
376
+ )
377
+
351
378
  _add_additional_network_options(parser)
352
379
  _tag.add_tag_option_to_parser_for_create(parser, _('network'))
353
380
  return parser
@@ -367,6 +394,11 @@ class CreateNetwork(command.ShowOne, common.NeutronCommandWithExtraArgs):
367
394
  if parsed_args.no_qinq_vlan:
368
395
  attrs['vlan_qinq'] = False
369
396
 
397
+ if parsed_args.pvlan:
398
+ attrs['pvlan'] = True
399
+ if parsed_args.no_pvlan:
400
+ attrs['pvlan'] = False
401
+
370
402
  if attrs.get('vlan_transparent') and attrs.get('vlan_qinq'):
371
403
  msg = _(
372
404
  "--transparent-vlan and --qinq-vlan can not be both enabled "
@@ -374,6 +406,14 @@ class CreateNetwork(command.ShowOne, common.NeutronCommandWithExtraArgs):
374
406
  )
375
407
  raise exceptions.CommandError(msg)
376
408
 
409
+ if (
410
+ attrs.get('port_security_enabled') is False
411
+ and attrs.get('pvlan') is True
412
+ ):
413
+ msg = _(
414
+ "--disable-port-security and --pvlan can not be used together."
415
+ )
416
+ raise exceptions.CommandError(msg)
377
417
  if (
378
418
  parsed_args.segmentation_id
379
419
  and not parsed_args.provider_network_type
@@ -439,8 +479,6 @@ class DeleteNetwork(command.Command):
439
479
  raise exceptions.CommandError(msg)
440
480
 
441
481
 
442
- # TODO(sindhu): Use the SDK resource mapped attribute names once the
443
- # OSC minimum requirements include SDK 1.0.
444
482
  class ListNetwork(command.Lister):
445
483
  _description = _("List networks")
446
484
 
@@ -542,6 +580,7 @@ class ListNetwork(command.Lister):
542
580
  help=_('List only networks hosted the specified agent (ID only)'),
543
581
  )
544
582
  _tag.add_tag_filtering_option_to_parser(parser, _('networks'))
583
+ pagination.add_marker_pagination_option_to_parser(parser)
545
584
  return parser
546
585
 
547
586
  def take_action(
@@ -576,7 +615,15 @@ class ListNetwork(command.Lister):
576
615
  'Availability Zones',
577
616
  'Tags',
578
617
  )
579
- elif parsed_args.agent_id:
618
+ else:
619
+ columns = ('id', 'name', 'subnet_ids')
620
+ column_headers = (
621
+ 'ID',
622
+ 'Name',
623
+ 'Subnets',
624
+ )
625
+
626
+ if parsed_args.agent_id:
580
627
  columns = ('id', 'name', 'subnet_ids')
581
628
  column_headers = (
582
629
  'ID',
@@ -585,7 +632,6 @@ class ListNetwork(command.Lister):
585
632
  )
586
633
  client = self.app.client_manager.network
587
634
  dhcp_agent = client.get_agent(parsed_args.agent_id)
588
- data = client.dhcp_agent_hosting_networks(dhcp_agent)
589
635
 
590
636
  return (
591
637
  column_headers,
@@ -595,16 +641,9 @@ class ListNetwork(command.Lister):
595
641
  columns,
596
642
  formatters=_formatters,
597
643
  )
598
- for s in data
644
+ for s in client.dhcp_agent_hosting_networks(dhcp_agent)
599
645
  ),
600
646
  )
601
- else:
602
- columns = ('id', 'name', 'subnet_ids')
603
- column_headers = (
604
- 'ID',
605
- 'Name',
606
- 'Subnets',
607
- )
608
647
 
609
648
  args = {}
610
649
 
@@ -653,9 +692,14 @@ class ListNetwork(command.Lister):
653
692
  args['provider:segmentation_id'] = parsed_args.segmentation_id
654
693
  args['provider_segmentation_id'] = parsed_args.segmentation_id
655
694
 
656
- _tag.get_tag_filtering_args(parsed_args, args)
695
+ if parsed_args.marker is not None:
696
+ args['marker'] = parsed_args.marker
697
+ if parsed_args.limit is not None:
698
+ args['limit'] = parsed_args.limit
699
+ if parsed_args.max_items is not None:
700
+ args['max_items'] = parsed_args.max_items
657
701
 
658
- data = client.networks(**args)
702
+ _tag.get_tag_filtering_args(parsed_args, args)
659
703
 
660
704
  return (
661
705
  column_headers,
@@ -665,13 +709,11 @@ class ListNetwork(command.Lister):
665
709
  columns,
666
710
  formatters=_formatters,
667
711
  )
668
- for s in data
712
+ for s in client.networks(**args)
669
713
  ),
670
714
  )
671
715
 
672
716
 
673
- # TODO(sindhu): Use the SDK resource mapped attribute names once the
674
- # OSC minimum requirements include SDK 1.0.
675
717
  class SetNetwork(common.NeutronCommandWithExtraArgs):
676
718
  _description = _("Set network properties")
677
719
 
@@ -770,6 +812,23 @@ class SetNetwork(common.NeutronCommandWithExtraArgs):
770
812
  action='store_true',
771
813
  help=_("Remove the QoS policy attached to this network"),
772
814
  )
815
+ pvlan_grp = parser.add_mutually_exclusive_group()
816
+ pvlan_grp.add_argument(
817
+ '--pvlan',
818
+ action='store_true',
819
+ help=_(
820
+ "Enable Private VLAN for the network. PVLAN extension "
821
+ "required."
822
+ ),
823
+ )
824
+ pvlan_grp.add_argument(
825
+ '--no-pvlan',
826
+ action='store_true',
827
+ help=_(
828
+ "Disable Private VLAN for the network (Default). "
829
+ "PVLAN extension required."
830
+ ),
831
+ )
773
832
  _tag.add_tag_option_to_parser_for_set(parser, _('network'))
774
833
  _add_additional_network_options(parser)
775
834
  return parser
@@ -782,6 +841,14 @@ class SetNetwork(common.NeutronCommandWithExtraArgs):
782
841
  attrs.update(
783
842
  self._parse_extra_properties(parsed_args.extra_properties)
784
843
  )
844
+ if (
845
+ attrs.get('port_security_enabled') is False
846
+ and attrs.get('pvlan') is True
847
+ ):
848
+ msg = _(
849
+ "--disable-port-security and --pvlan can not be used together."
850
+ )
851
+ raise exceptions.CommandError(msg)
785
852
  if attrs:
786
853
  with common.check_missing_extension_if_error(
787
854
  self.app.client_manager.network, attrs