python-openstackclient 8.2.0__py3-none-any.whl → 8.3.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 (226) hide show
  1. openstackclient/api/object_store_v1.py +4 -1
  2. openstackclient/command.py +27 -0
  3. openstackclient/common/availability_zone.py +1 -1
  4. openstackclient/common/clientmanager.py +59 -21
  5. openstackclient/common/configuration.py +1 -1
  6. openstackclient/common/extension.py +1 -1
  7. openstackclient/common/limits.py +1 -1
  8. openstackclient/common/module.py +4 -2
  9. openstackclient/common/project_cleanup.py +10 -8
  10. openstackclient/common/quota.py +23 -6
  11. openstackclient/common/versions.py +1 -2
  12. openstackclient/compute/v2/agent.py +1 -1
  13. openstackclient/compute/v2/aggregate.py +6 -5
  14. openstackclient/compute/v2/console.py +5 -3
  15. openstackclient/compute/v2/console_connection.py +1 -1
  16. openstackclient/compute/v2/flavor.py +1 -1
  17. openstackclient/compute/v2/host.py +1 -1
  18. openstackclient/compute/v2/hypervisor.py +1 -1
  19. openstackclient/compute/v2/hypervisor_stats.py +1 -1
  20. openstackclient/compute/v2/keypair.py +1 -1
  21. openstackclient/compute/v2/server.py +76 -27
  22. openstackclient/compute/v2/server_backup.py +1 -1
  23. openstackclient/compute/v2/server_event.py +1 -1
  24. openstackclient/compute/v2/server_group.py +4 -2
  25. openstackclient/compute/v2/server_image.py +1 -1
  26. openstackclient/compute/v2/server_migration.py +1 -1
  27. openstackclient/compute/v2/server_volume.py +1 -1
  28. openstackclient/compute/v2/service.py +1 -1
  29. openstackclient/compute/v2/usage.py +6 -4
  30. openstackclient/identity/common.py +2 -1
  31. openstackclient/identity/v2_0/catalog.py +3 -2
  32. openstackclient/identity/v2_0/ec2creds.py +1 -1
  33. openstackclient/identity/v2_0/endpoint.py +1 -1
  34. openstackclient/identity/v2_0/project.py +17 -7
  35. openstackclient/identity/v2_0/role.py +1 -1
  36. openstackclient/identity/v2_0/role_assignment.py +3 -3
  37. openstackclient/identity/v2_0/service.py +1 -1
  38. openstackclient/identity/v2_0/token.py +1 -1
  39. openstackclient/identity/v2_0/user.py +2 -2
  40. openstackclient/identity/v3/access_rule.py +16 -4
  41. openstackclient/identity/v3/application_credential.py +30 -10
  42. openstackclient/identity/v3/catalog.py +3 -3
  43. openstackclient/identity/v3/consumer.py +1 -1
  44. openstackclient/identity/v3/credential.py +1 -1
  45. openstackclient/identity/v3/domain.py +10 -4
  46. openstackclient/identity/v3/ec2creds.py +1 -1
  47. openstackclient/identity/v3/endpoint.py +33 -12
  48. openstackclient/identity/v3/endpoint_group.py +1 -1
  49. openstackclient/identity/v3/federation_protocol.py +1 -1
  50. openstackclient/identity/v3/group.py +11 -5
  51. openstackclient/identity/v3/identity_provider.py +12 -10
  52. openstackclient/identity/v3/implied_role.py +1 -1
  53. openstackclient/identity/v3/limit.py +1 -1
  54. openstackclient/identity/v3/mapping.py +1 -1
  55. openstackclient/identity/v3/policy.py +1 -1
  56. openstackclient/identity/v3/project.py +10 -3
  57. openstackclient/identity/v3/region.py +1 -1
  58. openstackclient/identity/v3/registered_limit.py +16 -11
  59. openstackclient/identity/v3/role.py +20 -39
  60. openstackclient/identity/v3/role_assignment.py +12 -23
  61. openstackclient/identity/v3/service.py +1 -1
  62. openstackclient/identity/v3/service_provider.py +1 -1
  63. openstackclient/identity/v3/tag.py +3 -2
  64. openstackclient/identity/v3/token.py +3 -2
  65. openstackclient/identity/v3/trust.py +4 -2
  66. openstackclient/identity/v3/unscoped_saml.py +1 -1
  67. openstackclient/identity/v3/user.py +22 -13
  68. openstackclient/image/v1/image.py +19 -16
  69. openstackclient/image/v2/cache.py +1 -1
  70. openstackclient/image/v2/image.py +14 -11
  71. openstackclient/image/v2/info.py +1 -1
  72. openstackclient/image/v2/metadef_namespaces.py +1 -1
  73. openstackclient/image/v2/metadef_objects.py +1 -1
  74. openstackclient/image/v2/metadef_properties.py +3 -2
  75. openstackclient/image/v2/metadef_resource_type_association.py +1 -1
  76. openstackclient/image/v2/metadef_resource_types.py +1 -1
  77. openstackclient/image/v2/task.py +1 -1
  78. openstackclient/network/common.py +10 -9
  79. openstackclient/network/v2/address_group.py +4 -3
  80. openstackclient/network/v2/address_scope.py +8 -6
  81. openstackclient/network/v2/default_security_group_rule.py +9 -8
  82. openstackclient/network/v2/floating_ip.py +16 -9
  83. openstackclient/network/v2/floating_ip_port_forwarding.py +9 -6
  84. openstackclient/network/v2/ip_availability.py +7 -4
  85. openstackclient/network/v2/l3_conntrack_helper.py +11 -4
  86. openstackclient/network/v2/local_ip.py +13 -7
  87. openstackclient/network/v2/local_ip_association.py +7 -4
  88. openstackclient/network/v2/ndp_proxy.py +13 -6
  89. openstackclient/network/v2/network.py +33 -16
  90. openstackclient/network/v2/network_agent.py +5 -5
  91. openstackclient/network/v2/network_auto_allocated_topology.py +1 -1
  92. openstackclient/network/v2/network_flavor.py +1 -1
  93. openstackclient/network/v2/network_flavor_profile.py +1 -1
  94. openstackclient/network/v2/network_meter.py +1 -1
  95. openstackclient/network/v2/network_meter_rule.py +1 -1
  96. openstackclient/network/v2/network_qos_policy.py +7 -5
  97. openstackclient/network/v2/network_qos_rule.py +1 -1
  98. openstackclient/network/v2/network_qos_rule_type.py +1 -1
  99. openstackclient/network/v2/network_rbac.py +8 -5
  100. openstackclient/network/v2/network_segment.py +2 -2
  101. openstackclient/network/v2/network_segment_range.py +13 -6
  102. openstackclient/network/v2/network_service_provider.py +1 -1
  103. openstackclient/network/v2/network_trunk.py +65 -42
  104. openstackclient/network/v2/port.py +22 -20
  105. openstackclient/network/v2/router.py +19 -8
  106. openstackclient/network/v2/security_group.py +10 -6
  107. openstackclient/network/v2/security_group_rule.py +11 -5
  108. openstackclient/network/v2/subnet.py +17 -18
  109. openstackclient/network/v2/subnet_pool.py +11 -9
  110. openstackclient/network/v2/taas/__init__.py +0 -0
  111. openstackclient/network/v2/taas/tap_flow.py +245 -0
  112. openstackclient/network/v2/taas/tap_mirror.py +237 -0
  113. openstackclient/network/v2/taas/tap_service.py +211 -0
  114. openstackclient/object/v1/account.py +1 -1
  115. openstackclient/object/v1/container.py +1 -1
  116. openstackclient/object/v1/object.py +1 -1
  117. openstackclient/shell.py +18 -8
  118. openstackclient/tests/functional/identity/v3/test_catalog.py +42 -23
  119. openstackclient/tests/functional/identity/v3/test_role_assignment.py +174 -0
  120. openstackclient/tests/functional/image/v2/test_cache.py +54 -0
  121. openstackclient/tests/functional/image/v2/test_metadef_resource_type.py +55 -0
  122. openstackclient/tests/unit/common/test_command.py +1 -1
  123. openstackclient/tests/unit/common/test_extension.py +2 -3
  124. openstackclient/tests/unit/common/test_module.py +14 -7
  125. openstackclient/tests/unit/common/test_quota.py +20 -0
  126. openstackclient/tests/unit/compute/v2/test_aggregate.py +5 -3
  127. openstackclient/tests/unit/compute/v2/test_console.py +1 -4
  128. openstackclient/tests/unit/compute/v2/test_flavor.py +1 -3
  129. openstackclient/tests/unit/compute/v2/test_hypervisor_stats.py +1 -9
  130. openstackclient/tests/unit/compute/v2/test_server.py +364 -30
  131. openstackclient/tests/unit/compute/v2/test_server_backup.py +1 -3
  132. openstackclient/tests/unit/compute/v2/test_service.py +1 -3
  133. openstackclient/tests/unit/fakes.py +35 -134
  134. openstackclient/tests/unit/identity/test_common.py +100 -0
  135. openstackclient/tests/unit/identity/v2_0/test_project.py +4 -4
  136. openstackclient/tests/unit/identity/v3/fakes.py +10 -2
  137. openstackclient/tests/unit/identity/v3/test_application_credential.py +3 -3
  138. openstackclient/tests/unit/identity/v3/test_domain.py +1 -1
  139. openstackclient/tests/unit/identity/v3/test_endpoint.py +1 -1
  140. openstackclient/tests/unit/identity/v3/test_group.py +4 -2
  141. openstackclient/tests/unit/identity/v3/test_identity_provider.py +10 -10
  142. openstackclient/tests/unit/identity/v3/test_oauth.py +1 -1
  143. openstackclient/tests/unit/identity/v3/test_project.py +1 -1
  144. openstackclient/tests/unit/identity/v3/test_registered_limit.py +2 -2
  145. openstackclient/tests/unit/identity/v3/test_role.py +1 -82
  146. openstackclient/tests/unit/identity/v3/test_user.py +7 -51
  147. openstackclient/tests/unit/image/v2/test_image.py +111 -0
  148. openstackclient/tests/unit/network/test_common.py +9 -13
  149. openstackclient/tests/unit/network/v2/taas/__init__.py +0 -0
  150. openstackclient/tests/unit/network/v2/taas/test_osc_tap_flow.py +276 -0
  151. openstackclient/tests/unit/network/v2/taas/test_osc_tap_mirror.py +288 -0
  152. openstackclient/tests/unit/network/v2/taas/test_osc_tap_service.py +271 -0
  153. openstackclient/tests/unit/network/v2/test_address_group.py +19 -22
  154. openstackclient/tests/unit/network/v2/test_address_scope.py +10 -15
  155. openstackclient/tests/unit/network/v2/test_default_security_group_rule.py +38 -49
  156. openstackclient/tests/unit/network/v2/test_floating_ip_network.py +21 -27
  157. openstackclient/tests/unit/network/v2/test_floating_ip_port_forwarding.py +21 -18
  158. openstackclient/tests/unit/network/v2/test_ip_availability.py +6 -8
  159. openstackclient/tests/unit/network/v2/test_l3_conntrack_helper.py +6 -15
  160. openstackclient/tests/unit/network/v2/test_local_ip.py +12 -23
  161. openstackclient/tests/unit/network/v2/test_local_ip_association.py +13 -18
  162. openstackclient/tests/unit/network/v2/test_ndp_proxy.py +11 -21
  163. openstackclient/tests/unit/network/v2/test_network.py +41 -37
  164. openstackclient/tests/unit/network/v2/test_network_agent.py +13 -20
  165. openstackclient/tests/unit/network/v2/test_network_auto_allocated_topology.py +5 -8
  166. openstackclient/tests/unit/network/v2/test_network_flavor.py +14 -26
  167. openstackclient/tests/unit/network/v2/test_network_flavor_profile.py +14 -17
  168. openstackclient/tests/unit/network/v2/test_network_meter.py +7 -17
  169. openstackclient/tests/unit/network/v2/test_network_meter_rule.py +10 -20
  170. openstackclient/tests/unit/network/v2/test_network_qos_policy.py +7 -13
  171. openstackclient/tests/unit/network/v2/test_network_qos_rule.py +44 -54
  172. openstackclient/tests/unit/network/v2/test_network_qos_rule_type.py +2 -7
  173. openstackclient/tests/unit/network/v2/test_network_rbac.py +21 -36
  174. openstackclient/tests/unit/network/v2/test_network_segment.py +13 -29
  175. openstackclient/tests/unit/network/v2/test_network_segment_range.py +20 -19
  176. openstackclient/tests/unit/network/v2/test_network_service_provider.py +1 -4
  177. openstackclient/tests/unit/network/v2/test_network_trunk.py +52 -47
  178. openstackclient/tests/unit/network/v2/test_port.py +75 -86
  179. openstackclient/tests/unit/network/v2/test_router.py +104 -126
  180. openstackclient/tests/unit/network/v2/test_security_group_network.py +19 -26
  181. openstackclient/tests/unit/network/v2/test_security_group_rule_network.py +17 -18
  182. openstackclient/tests/unit/network/v2/test_subnet.py +35 -46
  183. openstackclient/tests/unit/network/v2/test_subnet_pool.py +21 -33
  184. openstackclient/tests/unit/volume/test_find_resource.py +4 -13
  185. openstackclient/tests/unit/volume/v2/test_volume_backup.py +3 -1
  186. openstackclient/tests/unit/volume/v3/test_volume.py +4 -0
  187. openstackclient/tests/unit/volume/v3/test_volume_backup.py +9 -0
  188. openstackclient/volume/client.py +7 -17
  189. openstackclient/volume/v2/backup_record.py +1 -1
  190. openstackclient/volume/v2/consistency_group.py +1 -1
  191. openstackclient/volume/v2/consistency_group_snapshot.py +1 -1
  192. openstackclient/volume/v2/qos_specs.py +1 -1
  193. openstackclient/volume/v2/service.py +1 -1
  194. openstackclient/volume/v2/volume.py +2 -2
  195. openstackclient/volume/v2/volume_backend.py +1 -1
  196. openstackclient/volume/v2/volume_backup.py +5 -3
  197. openstackclient/volume/v2/volume_host.py +1 -2
  198. openstackclient/volume/v2/volume_snapshot.py +2 -2
  199. openstackclient/volume/v2/volume_transfer_request.py +1 -1
  200. openstackclient/volume/v2/volume_type.py +11 -6
  201. openstackclient/volume/v3/block_storage_cleanup.py +1 -1
  202. openstackclient/volume/v3/block_storage_cluster.py +1 -1
  203. openstackclient/volume/v3/block_storage_log_level.py +1 -1
  204. openstackclient/volume/v3/block_storage_manage.py +1 -1
  205. openstackclient/volume/v3/block_storage_resource_filter.py +1 -1
  206. openstackclient/volume/v3/service.py +1 -1
  207. openstackclient/volume/v3/volume.py +2 -2
  208. openstackclient/volume/v3/volume_attachment.py +6 -5
  209. openstackclient/volume/v3/volume_backup.py +18 -3
  210. openstackclient/volume/v3/volume_group.py +1 -1
  211. openstackclient/volume/v3/volume_group_snapshot.py +1 -1
  212. openstackclient/volume/v3/volume_group_type.py +1 -1
  213. openstackclient/volume/v3/volume_message.py +1 -1
  214. openstackclient/volume/v3/volume_snapshot.py +2 -2
  215. openstackclient/volume/v3/volume_transfer_request.py +1 -1
  216. openstackclient/volume/v3/volume_type.py +15 -9
  217. {python_openstackclient-8.2.0.dist-info → python_openstackclient-8.3.0.dist-info}/METADATA +15 -13
  218. {python_openstackclient-8.2.0.dist-info → python_openstackclient-8.3.0.dist-info}/RECORD +224 -213
  219. {python_openstackclient-8.2.0.dist-info → python_openstackclient-8.3.0.dist-info}/WHEEL +1 -1
  220. {python_openstackclient-8.2.0.dist-info → python_openstackclient-8.3.0.dist-info}/entry_points.txt +15 -0
  221. {python_openstackclient-8.2.0.dist-info → python_openstackclient-8.3.0.dist-info/licenses}/AUTHORS +10 -0
  222. python_openstackclient-8.3.0.dist-info/pbr.json +1 -0
  223. openstackclient/tests/unit/common/test_logs.py +0 -221
  224. python_openstackclient-8.2.0.dist-info/pbr.json +0 -1
  225. {python_openstackclient-8.2.0.dist-info → python_openstackclient-8.3.0.dist-info/licenses}/LICENSE +0 -0
  226. {python_openstackclient-8.2.0.dist-info → python_openstackclient-8.3.0.dist-info}/top_level.txt +0 -0
@@ -20,11 +20,11 @@ import typing as ty
20
20
  from cliff import columns as cliff_columns
21
21
  from osc_lib.cli import format_columns
22
22
  from osc_lib.cli import parseractions
23
- from osc_lib.command import command
24
23
  from osc_lib import exceptions
25
24
  from osc_lib import utils
26
25
  from osc_lib.utils import tags as _tag
27
26
 
27
+ from openstackclient import command
28
28
  from openstackclient.i18n import _
29
29
  from openstackclient.identity import common as identity_common
30
30
  from openstackclient.network import common
@@ -44,7 +44,7 @@ def _update_arguments(obj_list, parsed_args_list, option):
44
44
  raise exceptions.CommandError(msg)
45
45
 
46
46
 
47
- class AllocationPoolsColumn(cliff_columns.FormattableColumn):
47
+ class AllocationPoolsColumn(cliff_columns.FormattableColumn[ty.Any]):
48
48
  def human_readable(self):
49
49
  pool_formatted = [
50
50
  '{}-{}'.format(pool.get('start', ''), pool.get('end', ''))
@@ -53,7 +53,7 @@ class AllocationPoolsColumn(cliff_columns.FormattableColumn):
53
53
  return ','.join(pool_formatted)
54
54
 
55
55
 
56
- class HostRoutesColumn(cliff_columns.FormattableColumn):
56
+ class HostRoutesColumn(cliff_columns.FormattableColumn[ty.Any]):
57
57
  def human_readable(self):
58
58
  # Map the host route keys to match --host-route option.
59
59
  return utils.format_list_of_dicts(
@@ -61,7 +61,7 @@ class HostRoutesColumn(cliff_columns.FormattableColumn):
61
61
  )
62
62
 
63
63
 
64
- class UnsortedListColumn(cliff_columns.FormattableColumn):
64
+ class UnsortedListColumn(cliff_columns.FormattableColumn[list[ty.Any]]):
65
65
  # format_columns.ListColumn sorts the output, but for things like
66
66
  # DNS server addresses the order matters
67
67
  def human_readable(self):
@@ -493,7 +493,7 @@ class ListSubnet(command.Lister):
493
493
  metavar='<ip-version>',
494
494
  dest='ip_version',
495
495
  help=_(
496
- "List only subnets of given IP version in output. "
496
+ "List only subnets with the specified IP version. "
497
497
  "Allowed values for IP version are 4 and 6."
498
498
  ),
499
499
  )
@@ -501,12 +501,12 @@ class ListSubnet(command.Lister):
501
501
  dhcp_enable_group.add_argument(
502
502
  '--dhcp',
503
503
  action='store_true',
504
- help=_("List subnets which have DHCP enabled"),
504
+ help=_("List only subnets which have DHCP enabled"),
505
505
  )
506
506
  dhcp_enable_group.add_argument(
507
507
  '--no-dhcp',
508
508
  action='store_true',
509
- help=_("List subnets which have DHCP disabled"),
509
+ help=_("List only subnets which have DHCP disabled"),
510
510
  )
511
511
  parser.add_argument(
512
512
  '--service-type',
@@ -514,7 +514,7 @@ class ListSubnet(command.Lister):
514
514
  action='append',
515
515
  dest='service_types',
516
516
  help=_(
517
- "List only subnets of a given service type in output, "
517
+ "List only subnets with the specified service type, "
518
518
  "for example, network:floatingip_agent_gateway. "
519
519
  "Must be a valid device owner value for a network port "
520
520
  "(repeat option to list multiple service types)."
@@ -524,8 +524,7 @@ class ListSubnet(command.Lister):
524
524
  '--project',
525
525
  metavar='<project>',
526
526
  help=_(
527
- "List only subnets which belong to a given project "
528
- "in output (name or ID)"
527
+ "List only subnets with the specified project (name or ID)"
529
528
  ),
530
529
  )
531
530
  identity_common.add_project_domain_option_to_parser(parser)
@@ -533,26 +532,26 @@ class ListSubnet(command.Lister):
533
532
  '--network',
534
533
  metavar='<network>',
535
534
  help=_(
536
- "List only subnets which belong to a given network "
537
- "in output (name or ID)"
535
+ "List only subnets which belong to the specified network "
536
+ "(name or ID)"
538
537
  ),
539
538
  )
540
539
  parser.add_argument(
541
540
  '--gateway',
542
541
  metavar='<gateway>',
543
- help=_("List only subnets of given gateway IP in output"),
542
+ help=_("List only subnets with the specified gateway IP"),
544
543
  )
545
544
  parser.add_argument(
546
545
  '--name',
547
546
  metavar='<name>',
548
- help=_("List only subnets of given name in output"),
547
+ help=_("List only subnets with the specified name"),
549
548
  )
550
549
  parser.add_argument(
551
550
  '--subnet-range',
552
551
  metavar='<subnet-range>',
553
552
  help=_(
554
- "List only subnets of given subnet range "
555
- "(in CIDR notation) in output. "
553
+ "List only subnets with the specified subnet range "
554
+ "(in CIDR notation). "
556
555
  "For example, --subnet-range 10.10.0.0/16"
557
556
  ),
558
557
  )
@@ -560,8 +559,8 @@ class ListSubnet(command.Lister):
560
559
  '--subnet-pool',
561
560
  metavar='<subnet-pool>',
562
561
  help=_(
563
- "List only subnets which belong to a given subnet pool "
564
- "in output (name or ID)"
562
+ "List only subnets which belong to the specified subnet pool "
563
+ "(name or ID)"
565
564
  ),
566
565
  )
567
566
  _tag.add_tag_filtering_option_to_parser(parser, _('subnets'))
@@ -17,11 +17,11 @@ import logging
17
17
 
18
18
  from osc_lib.cli import format_columns
19
19
  from osc_lib.cli import parseractions
20
- from osc_lib.command import command
21
20
  from osc_lib import exceptions
22
21
  from osc_lib import utils
23
22
  from osc_lib.utils import tags as _tag
24
23
 
24
+ from openstackclient import command
25
25
  from openstackclient.i18n import _
26
26
  from openstackclient.identity import common as identity_common
27
27
  from openstackclient.network import common
@@ -278,26 +278,27 @@ class ListSubnetPool(command.Lister):
278
278
  shared_group.add_argument(
279
279
  '--share',
280
280
  action='store_true',
281
- help=_("List subnet pools shared between projects"),
281
+ help=_("List only subnet pools shared between projects"),
282
282
  )
283
283
  shared_group.add_argument(
284
284
  '--no-share',
285
285
  action='store_true',
286
- help=_("List subnet pools not shared between projects"),
286
+ help=_("List only subnet pools not shared between projects"),
287
287
  )
288
288
  default_group = parser.add_mutually_exclusive_group()
289
289
  default_group.add_argument(
290
290
  '--default',
291
291
  action='store_true',
292
292
  help=_(
293
- "List subnet pools used as the default external subnet pool"
293
+ "List only subnet pools used as the default external "
294
+ "subnet pool"
294
295
  ),
295
296
  )
296
297
  default_group.add_argument(
297
298
  '--no-default',
298
299
  action='store_true',
299
300
  help=_(
300
- "List subnet pools not used as the default external "
301
+ "List only subnet pools not used as the default external "
301
302
  "subnet pool"
302
303
  ),
303
304
  )
@@ -305,21 +306,22 @@ class ListSubnetPool(command.Lister):
305
306
  '--project',
306
307
  metavar='<project>',
307
308
  help=_(
308
- "List subnet pools according to their project (name or ID)"
309
+ "List only subnet pools with the specified project "
310
+ "(name or ID)"
309
311
  ),
310
312
  )
311
313
  identity_common.add_project_domain_option_to_parser(parser)
312
314
  parser.add_argument(
313
315
  '--name',
314
316
  metavar='<name>',
315
- help=_("List only subnet pools of given name in output"),
317
+ help=_("List only subnet pools with the specified name"),
316
318
  )
317
319
  parser.add_argument(
318
320
  '--address-scope',
319
321
  metavar='<address-scope>',
320
322
  help=_(
321
- "List only subnet pools of given address scope "
322
- "in output (name or ID)"
323
+ "List only subnet pools with the specified address scope "
324
+ "(name or ID)"
323
325
  ),
324
326
  )
325
327
  _tag.add_tag_filtering_option_to_parser(parser, _('subnet pools'))
File without changes
@@ -0,0 +1,245 @@
1
+ # All Rights Reserved 2020
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may
4
+ # not use this file except in compliance with the License. You may obtain
5
+ # a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
+ # License for the specific language governing permissions and limitations
13
+ # under the License.
14
+
15
+ import logging
16
+
17
+ from osc_lib.cli import format_columns
18
+ from osc_lib.cli import identity as identity_utils
19
+ from osc_lib import exceptions
20
+ from osc_lib import utils as osc_utils
21
+ from osc_lib.utils import columns as column_util
22
+
23
+ from openstackclient import command
24
+ from openstackclient.i18n import _
25
+ from openstackclient.identity import common
26
+ from openstackclient.network.v2.taas import tap_service
27
+
28
+ LOG = logging.getLogger(__name__)
29
+
30
+ TAP_FLOW = 'tap_flow'
31
+ TAP_FLOWS = f'{TAP_FLOW}s'
32
+
33
+ _attr_map = [
34
+ ('id', 'ID', column_util.LIST_BOTH),
35
+ ('tenant_id', 'Tenant', column_util.LIST_LONG_ONLY),
36
+ ('name', 'Name', column_util.LIST_BOTH),
37
+ ('status', 'Status', column_util.LIST_BOTH),
38
+ ('source_port', 'source_port', column_util.LIST_BOTH),
39
+ ('tap_service_id', 'tap_service_id', column_util.LIST_BOTH),
40
+ ('direction', 'Direction', column_util.LIST_BOTH),
41
+ ]
42
+
43
+ _formatters = {
44
+ 'vlan_filter': format_columns.ListColumn,
45
+ }
46
+
47
+
48
+ def _add_updatable_args(parser):
49
+ parser.add_argument('--name', help=_('Name of the tap flow.'))
50
+ parser.add_argument(
51
+ '--description', help=_('Description of the tap flow.')
52
+ )
53
+
54
+
55
+ class CreateTapFlow(command.ShowOne):
56
+ _description = _("Create a new tap flow.")
57
+
58
+ def get_parser(self, prog_name):
59
+ parser = super().get_parser(prog_name)
60
+ identity_utils.add_project_owner_option_to_parser(parser)
61
+ _add_updatable_args(parser)
62
+ parser.add_argument(
63
+ '--port',
64
+ required=True,
65
+ metavar="SOURCE_PORT",
66
+ help=_('Source port (name or ID) to monitor.'),
67
+ )
68
+ parser.add_argument(
69
+ '--tap-service',
70
+ required=True,
71
+ metavar="TAP_SERVICE",
72
+ help=_(
73
+ 'Tap service (name or ID) to associate with this tap flow.'
74
+ ),
75
+ )
76
+ parser.add_argument(
77
+ '--direction',
78
+ required=True,
79
+ metavar="DIRECTION",
80
+ choices=['IN', 'OUT', 'BOTH'],
81
+ type=lambda s: s.upper(),
82
+ help=_(
83
+ 'Direction of the Tap flow. Valid options are: '
84
+ 'IN, OUT and BOTH'
85
+ ),
86
+ )
87
+ parser.add_argument(
88
+ '--vlan-filter',
89
+ required=False,
90
+ metavar="VLAN_FILTER",
91
+ help=_('VLAN IDs to mirror in the form of range string.'),
92
+ )
93
+ return parser
94
+
95
+ def take_action(self, parsed_args):
96
+ client = self.app.client_manager.network
97
+ attrs = {}
98
+ if parsed_args.name is not None:
99
+ attrs['name'] = parsed_args.name
100
+ if parsed_args.description is not None:
101
+ attrs['description'] = parsed_args.description
102
+ if parsed_args.port is not None:
103
+ source_port = client.find_port(
104
+ parsed_args.port, ignore_missing=False
105
+ ).id
106
+ attrs['source_port'] = source_port
107
+ if parsed_args.tap_service is not None:
108
+ tap_service_id = client.find_tap_service(
109
+ parsed_args.tap_service, ignore_missing=False
110
+ ).id
111
+ attrs['tap_service_id'] = tap_service_id
112
+ if parsed_args.direction is not None:
113
+ attrs['direction'] = parsed_args.direction
114
+ if parsed_args.vlan_filter is not None:
115
+ attrs['vlan_filter'] = parsed_args.vlan_filter
116
+ if 'project' in parsed_args and parsed_args.project is not None:
117
+ attrs['project_id'] = common.find_project(
118
+ self.app.client_manager.identity,
119
+ parsed_args.project,
120
+ parsed_args.project_domain,
121
+ ).id
122
+ obj = client.create_tap_flow(**attrs)
123
+ display_columns, columns = tap_service._get_columns(obj)
124
+ data = osc_utils.get_dict_properties(obj, columns)
125
+ return display_columns, data
126
+
127
+
128
+ class ListTapFlow(command.Lister):
129
+ _description = _("List tap flows.")
130
+
131
+ def get_parser(self, prog_name):
132
+ parser = super().get_parser(prog_name)
133
+ identity_utils.add_project_owner_option_to_parser(parser)
134
+
135
+ return parser
136
+
137
+ def take_action(self, parsed_args):
138
+ client = self.app.client_manager.network
139
+ params = {}
140
+ if parsed_args.project is not None:
141
+ params['project_id'] = common.find_project(
142
+ self.app.client_manager.identity,
143
+ parsed_args.project,
144
+ parsed_args.project_domain,
145
+ ).id
146
+ objs = client.tap_flows(retrieve_all=True, params=params)
147
+ headers, columns = column_util.get_column_definitions(
148
+ _attr_map, long_listing=True
149
+ )
150
+ return (
151
+ headers,
152
+ (
153
+ osc_utils.get_dict_properties(
154
+ s, columns, formatters=_formatters
155
+ )
156
+ for s in objs
157
+ ),
158
+ )
159
+
160
+
161
+ class ShowTapFlow(command.ShowOne):
162
+ _description = _("Show tap flow details.")
163
+
164
+ def get_parser(self, prog_name):
165
+ parser = super().get_parser(prog_name)
166
+ parser.add_argument(
167
+ TAP_FLOW,
168
+ metavar=f"<{TAP_FLOW}>",
169
+ help=_("Tap flow to display (name or ID)."),
170
+ )
171
+ return parser
172
+
173
+ def take_action(self, parsed_args):
174
+ client = self.app.client_manager.network
175
+ id = client.find_tap_flow(
176
+ parsed_args.tap_flow, ignore_missing=False
177
+ ).id
178
+ obj = client.get_tap_flow(id)
179
+ display_columns, columns = tap_service._get_columns(obj)
180
+ data = osc_utils.get_dict_properties(obj, columns)
181
+ return display_columns, data
182
+
183
+
184
+ class DeleteTapFlow(command.Command):
185
+ _description = _("Delete a tap flow.")
186
+
187
+ def get_parser(self, prog_name):
188
+ parser = super().get_parser(prog_name)
189
+ parser.add_argument(
190
+ TAP_FLOW,
191
+ metavar=f"<{TAP_FLOW}>",
192
+ nargs="+",
193
+ help=_("Tap flow to delete (name or ID)."),
194
+ )
195
+ return parser
196
+
197
+ def take_action(self, parsed_args):
198
+ client = self.app.client_manager.network
199
+ fails = 0
200
+ for id_or_name in parsed_args.tap_flow:
201
+ try:
202
+ id = client.find_tap_flow(id_or_name, ignore_missing=False).id
203
+ client.delete_tap_flow(id)
204
+ except Exception as e:
205
+ fails += 1
206
+ LOG.error(
207
+ "Failed to delete tap flow with name or ID "
208
+ "'%(id_or_name)s': %(e)s",
209
+ {'id_or_name': id_or_name, 'e': e},
210
+ )
211
+ if fails > 0:
212
+ msg = _("Failed to delete %(fails)s of %(total)s tap flow.") % {
213
+ 'fails': fails,
214
+ 'total': len(parsed_args.tap_flow),
215
+ }
216
+ raise exceptions.CommandError(msg)
217
+
218
+
219
+ class UpdateTapFlow(command.ShowOne):
220
+ _description = _("Update a tap flow.")
221
+
222
+ def get_parser(self, prog_name):
223
+ parser = super().get_parser(prog_name)
224
+ parser.add_argument(
225
+ TAP_FLOW,
226
+ metavar=f"<{TAP_FLOW}>",
227
+ help=_("Tap flow to modify (name or ID)."),
228
+ )
229
+ _add_updatable_args(parser)
230
+ return parser
231
+
232
+ def take_action(self, parsed_args):
233
+ client = self.app.client_manager.network
234
+ original_t_f = client.find_tap_flow(
235
+ parsed_args.tap_flow, ignore_missing=False
236
+ ).id
237
+ attrs = {}
238
+ if parsed_args.name is not None:
239
+ attrs['name'] = parsed_args.name
240
+ if parsed_args.description is not None:
241
+ attrs['description'] = parsed_args.description
242
+ obj = client.update_tap_flow(original_t_f, **attrs)
243
+ columns, display_columns = column_util.get_columns(obj, _attr_map)
244
+ data = osc_utils.get_dict_properties(obj, columns)
245
+ return display_columns, data
@@ -0,0 +1,237 @@
1
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may
2
+ # not use this file except in compliance with the License. You may obtain
3
+ # a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10
+ # License for the specific language governing permissions and limitations
11
+ # under the License.
12
+
13
+ import logging
14
+
15
+ from osc_lib.cli import identity as identity_utils
16
+ from osc_lib import exceptions
17
+ from osc_lib import utils as osc_utils
18
+ from osc_lib.utils import columns as column_util
19
+
20
+ from openstackclient import command
21
+ from openstackclient.i18n import _
22
+ from openstackclient.identity import common
23
+ from openstackclient.network.v2 import port as osc_port
24
+ from openstackclient.network.v2.taas import tap_service
25
+
26
+ LOG = logging.getLogger(__name__)
27
+
28
+ TAP_MIRROR = 'tap_mirror'
29
+ TAP_MIRRORS = f'{TAP_MIRROR}s'
30
+
31
+ _attr_map = [
32
+ ('id', 'ID', column_util.LIST_BOTH),
33
+ ('tenant_id', 'Tenant', column_util.LIST_LONG_ONLY),
34
+ ('name', 'Name', column_util.LIST_BOTH),
35
+ ('port_id', 'Port', column_util.LIST_BOTH),
36
+ ('directions', 'Directions', column_util.LIST_LONG_ONLY),
37
+ ('remote_ip', 'Remote IP', column_util.LIST_BOTH),
38
+ ('mirror_type', 'Mirror Type', column_util.LIST_LONG_ONLY),
39
+ ]
40
+
41
+
42
+ def _get_columns(item):
43
+ column_map: dict[str, str] = {}
44
+ hidden_columns = ['location', 'tenant_id']
45
+ return osc_utils.get_osc_show_columns_for_sdk_resource(
46
+ item, column_map, hidden_columns
47
+ )
48
+
49
+
50
+ class CreateTapMirror(command.ShowOne):
51
+ _description = _("Create a new tap mirror.")
52
+
53
+ def get_parser(self, prog_name):
54
+ parser = super().get_parser(prog_name)
55
+ identity_utils.add_project_owner_option_to_parser(parser)
56
+ tap_service._add_updatable_args(parser)
57
+ parser.add_argument(
58
+ '--port',
59
+ dest='port_id',
60
+ required=True,
61
+ metavar="PORT",
62
+ help=_('Port (name or ID) to which the Tap Mirror is connected.'),
63
+ )
64
+ parser.add_argument(
65
+ '--directions',
66
+ dest='directions',
67
+ action=osc_port.JSONKeyValueAction,
68
+ required=True,
69
+ help=_(
70
+ 'Dictionary of direction and tunnel_id. Valid directions are: '
71
+ 'IN and OUT.'
72
+ ),
73
+ )
74
+ parser.add_argument(
75
+ '--remote-ip',
76
+ dest='remote_ip',
77
+ required=True,
78
+ help=_(
79
+ 'Remote IP address for the tap mirror (remote end of the '
80
+ 'GRE or ERSPAN v1 tunnel).'
81
+ ),
82
+ )
83
+ parser.add_argument(
84
+ '--mirror-type',
85
+ dest='mirror_type',
86
+ required=True,
87
+ help=_('Mirror type. Valid values are: gre and erspanv1.'),
88
+ )
89
+ return parser
90
+
91
+ def take_action(self, parsed_args):
92
+ client = self.app.client_manager.network
93
+ attrs = {}
94
+ if parsed_args.name is not None:
95
+ attrs['name'] = parsed_args.name
96
+ if parsed_args.description is not None:
97
+ attrs['description'] = parsed_args.description
98
+ if parsed_args.port_id is not None:
99
+ port_id = client.find_port(
100
+ parsed_args.port_id, ignore_missing=False
101
+ ).id
102
+ attrs['port_id'] = port_id
103
+ if parsed_args.directions is not None:
104
+ attrs['directions'] = parsed_args.directions
105
+ if parsed_args.remote_ip is not None:
106
+ attrs['remote_ip'] = parsed_args.remote_ip
107
+ if parsed_args.mirror_type is not None:
108
+ attrs['mirror_type'] = parsed_args.mirror_type
109
+ if 'project' in parsed_args and parsed_args.project is not None:
110
+ attrs['project_id'] = common.find_project(
111
+ self.app.client_manager.identity,
112
+ parsed_args.project,
113
+ parsed_args.project_domain,
114
+ ).id
115
+ obj = client.create_tap_mirror(**attrs)
116
+ display_columns, columns = tap_service._get_columns(obj)
117
+ data = osc_utils.get_dict_properties(obj, columns)
118
+ return display_columns, data
119
+
120
+
121
+ class ListTapMirror(command.Lister):
122
+ _description = _("List tap mirrors.")
123
+
124
+ def get_parser(self, prog_name):
125
+ parser = super().get_parser(prog_name)
126
+ identity_utils.add_project_owner_option_to_parser(parser)
127
+
128
+ return parser
129
+
130
+ def take_action(self, parsed_args):
131
+ client = self.app.client_manager.network
132
+ params = {}
133
+ if parsed_args.project is not None:
134
+ params['project_id'] = common.find_project(
135
+ self.app.client_manager.identity,
136
+ parsed_args.project,
137
+ parsed_args.project_domain,
138
+ ).id
139
+ objs = client.tap_mirrors(retrieve_all=True, params=params)
140
+ headers, columns = column_util.get_column_definitions(
141
+ _attr_map, long_listing=True
142
+ )
143
+ return (
144
+ headers,
145
+ (osc_utils.get_dict_properties(s, columns) for s in objs),
146
+ )
147
+
148
+
149
+ class ShowTapMirror(command.ShowOne):
150
+ _description = _("Show tap mirror details.")
151
+
152
+ def get_parser(self, prog_name):
153
+ parser = super().get_parser(prog_name)
154
+ parser.add_argument(
155
+ TAP_MIRROR,
156
+ metavar=f"<{TAP_MIRROR}>",
157
+ help=_("Tap mirror to display (name or ID)."),
158
+ )
159
+ return parser
160
+
161
+ def take_action(self, parsed_args):
162
+ client = self.app.client_manager.network
163
+ id = client.find_tap_mirror(
164
+ parsed_args.tap_mirror, ignore_missing=False
165
+ ).id
166
+ obj = client.get_tap_mirror(id)
167
+ display_columns, columns = tap_service._get_columns(obj)
168
+ data = osc_utils.get_dict_properties(obj, columns)
169
+ return display_columns, data
170
+
171
+
172
+ class DeleteTapMirror(command.Command):
173
+ _description = _("Delete a tap mirror.")
174
+
175
+ def get_parser(self, prog_name):
176
+ parser = super().get_parser(prog_name)
177
+ parser.add_argument(
178
+ TAP_MIRROR,
179
+ metavar=f"<{TAP_MIRROR}>",
180
+ nargs="+",
181
+ help=_("Tap mirror to delete (name or ID)."),
182
+ )
183
+ return parser
184
+
185
+ def take_action(self, parsed_args):
186
+ client = self.app.client_manager.network
187
+ fails = 0
188
+ for id_or_name in parsed_args.tap_mirror:
189
+ try:
190
+ id = client.find_tap_mirror(
191
+ id_or_name, ignore_missing=False
192
+ ).id
193
+
194
+ client.delete_tap_mirror(id)
195
+ LOG.warning("Tap Mirror %(id)s deleted", {'id': id})
196
+ except Exception as e:
197
+ fails += 1
198
+ LOG.error(
199
+ "Failed to delete Tap Mirror with name or ID "
200
+ "'%(id_or_name)s': %(e)s",
201
+ {'id_or_name': id_or_name, 'e': e},
202
+ )
203
+ if fails > 0:
204
+ msg = _("Failed to delete %(fails)s of %(total)s Tap Mirror.") % {
205
+ 'fails': fails,
206
+ 'total': len(parsed_args.tap_mirror),
207
+ }
208
+ raise exceptions.CommandError(msg)
209
+
210
+
211
+ class UpdateTapMirror(command.ShowOne):
212
+ _description = _("Update a tap mirror.")
213
+
214
+ def get_parser(self, prog_name):
215
+ parser = super().get_parser(prog_name)
216
+ parser.add_argument(
217
+ TAP_MIRROR,
218
+ metavar=f"<{TAP_MIRROR}>",
219
+ help=_("Tap mirror to modify (name or ID)."),
220
+ )
221
+ tap_service._add_updatable_args(parser)
222
+ return parser
223
+
224
+ def take_action(self, parsed_args):
225
+ client = self.app.client_manager.network
226
+ original_t_s = client.find_tap_mirror(
227
+ parsed_args.tap_mirror, ignore_missing=False
228
+ ).id
229
+ attrs = {}
230
+ if parsed_args.name is not None:
231
+ attrs['name'] = parsed_args.name
232
+ if parsed_args.description is not None:
233
+ attrs['description'] = parsed_args.description
234
+ obj = client.update_tap_mirror(original_t_s, **attrs)
235
+ display_columns, columns = tap_service._get_columns(obj)
236
+ data = osc_utils.get_dict_properties(obj, columns)
237
+ return display_columns, data