python-openstackclient 6.6.0__py3-none-any.whl → 7.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 (337) hide show
  1. openstackclient/api/api.py +7 -8
  2. openstackclient/api/compute_v2.py +352 -638
  3. openstackclient/api/image_v1.py +1 -1
  4. openstackclient/api/object_store_v1.py +3 -4
  5. openstackclient/common/availability_zone.py +1 -1
  6. openstackclient/common/clientmanager.py +16 -4
  7. openstackclient/common/configuration.py +1 -1
  8. openstackclient/common/extension.py +1 -1
  9. openstackclient/common/limits.py +66 -32
  10. openstackclient/common/module.py +3 -3
  11. openstackclient/common/progressbar.py +2 -2
  12. openstackclient/common/project_cleanup.py +5 -2
  13. openstackclient/common/quota.py +281 -410
  14. openstackclient/common/versions.py +1 -1
  15. openstackclient/compute/client.py +7 -116
  16. openstackclient/compute/v2/agent.py +75 -49
  17. openstackclient/compute/v2/aggregate.py +9 -9
  18. openstackclient/compute/v2/console.py +2 -2
  19. openstackclient/compute/v2/flavor.py +6 -6
  20. openstackclient/compute/v2/host.py +38 -33
  21. openstackclient/compute/v2/hypervisor.py +4 -3
  22. openstackclient/compute/v2/keypair.py +7 -8
  23. openstackclient/compute/v2/server.py +478 -396
  24. openstackclient/compute/v2/server_backup.py +1 -1
  25. openstackclient/compute/v2/server_group.py +4 -4
  26. openstackclient/compute/v2/server_image.py +1 -1
  27. openstackclient/compute/v2/server_migration.py +3 -4
  28. openstackclient/compute/v2/service.py +4 -4
  29. openstackclient/compute/v2/usage.py +3 -3
  30. openstackclient/identity/common.py +34 -0
  31. openstackclient/identity/v2_0/catalog.py +2 -2
  32. openstackclient/identity/v2_0/ec2creds.py +4 -4
  33. openstackclient/identity/v2_0/endpoint.py +4 -4
  34. openstackclient/identity/v2_0/project.py +6 -6
  35. openstackclient/identity/v2_0/role.py +5 -5
  36. openstackclient/identity/v2_0/role_assignment.py +1 -1
  37. openstackclient/identity/v2_0/service.py +4 -4
  38. openstackclient/identity/v2_0/token.py +2 -2
  39. openstackclient/identity/v2_0/user.py +7 -7
  40. openstackclient/identity/v3/access_rule.py +3 -3
  41. openstackclient/identity/v3/application_credential.py +127 -45
  42. openstackclient/identity/v3/catalog.py +2 -2
  43. openstackclient/identity/v3/consumer.py +4 -4
  44. openstackclient/identity/v3/credential.py +5 -5
  45. openstackclient/identity/v3/domain.py +5 -5
  46. openstackclient/identity/v3/ec2creds.py +4 -4
  47. openstackclient/identity/v3/endpoint.py +7 -7
  48. openstackclient/identity/v3/endpoint_group.py +8 -10
  49. openstackclient/identity/v3/federation_protocol.py +5 -5
  50. openstackclient/identity/v3/group.py +8 -8
  51. openstackclient/identity/v3/identity_provider.py +5 -5
  52. openstackclient/identity/v3/implied_role.py +3 -3
  53. openstackclient/identity/v3/limit.py +5 -5
  54. openstackclient/identity/v3/mapping.py +5 -5
  55. openstackclient/identity/v3/policy.py +5 -5
  56. openstackclient/identity/v3/project.py +5 -5
  57. openstackclient/identity/v3/region.py +5 -5
  58. openstackclient/identity/v3/registered_limit.py +5 -5
  59. openstackclient/identity/v3/role.py +7 -7
  60. openstackclient/identity/v3/role_assignment.py +92 -140
  61. openstackclient/identity/v3/service.py +64 -34
  62. openstackclient/identity/v3/service_provider.py +4 -4
  63. openstackclient/identity/v3/tag.py +2 -2
  64. openstackclient/identity/v3/token.py +5 -5
  65. openstackclient/identity/v3/trust.py +3 -3
  66. openstackclient/identity/v3/user.py +144 -80
  67. openstackclient/image/client.py +4 -4
  68. openstackclient/image/v1/image.py +8 -9
  69. openstackclient/image/v2/cache.py +12 -10
  70. openstackclient/image/v2/metadef_objects.py +44 -0
  71. openstackclient/image/v2/metadef_resource_type_association.py +189 -0
  72. openstackclient/image/v2/task.py +1 -1
  73. openstackclient/network/common.py +6 -5
  74. openstackclient/network/utils.py +2 -2
  75. openstackclient/network/v2/address_group.py +6 -6
  76. openstackclient/network/v2/address_scope.py +5 -5
  77. openstackclient/network/v2/default_security_group_rule.py +1 -1
  78. openstackclient/network/v2/floating_ip.py +8 -10
  79. openstackclient/network/v2/floating_ip_pool.py +6 -15
  80. openstackclient/network/v2/floating_ip_port_forwarding.py +5 -13
  81. openstackclient/network/v2/ip_availability.py +2 -2
  82. openstackclient/network/v2/l3_conntrack_helper.py +5 -5
  83. openstackclient/network/v2/network.py +8 -8
  84. openstackclient/network/v2/network_agent.py +8 -8
  85. openstackclient/network/v2/network_auto_allocated_topology.py +2 -2
  86. openstackclient/network/v2/network_flavor.py +6 -8
  87. openstackclient/network/v2/network_flavor_profile.py +4 -4
  88. openstackclient/network/v2/network_meter.py +3 -3
  89. openstackclient/network/v2/network_meter_rule.py +3 -3
  90. openstackclient/network/v2/network_qos_policy.py +5 -5
  91. openstackclient/network/v2/network_qos_rule.py +9 -9
  92. openstackclient/network/v2/network_qos_rule_type.py +1 -1
  93. openstackclient/network/v2/network_rbac.py +5 -5
  94. openstackclient/network/v2/network_segment.py +5 -5
  95. openstackclient/network/v2/network_segment_range.py +7 -7
  96. openstackclient/network/v2/network_trunk.py +7 -7
  97. openstackclient/network/v2/port.py +26 -12
  98. openstackclient/network/v2/router.py +403 -54
  99. openstackclient/network/v2/security_group.py +18 -14
  100. openstackclient/network/v2/security_group_rule.py +18 -15
  101. openstackclient/network/v2/subnet.py +15 -8
  102. openstackclient/network/v2/subnet_pool.py +6 -6
  103. openstackclient/object/v1/account.py +2 -2
  104. openstackclient/object/v1/container.py +7 -7
  105. openstackclient/object/v1/object.py +7 -7
  106. openstackclient/shell.py +4 -6
  107. openstackclient/tests/functional/base.py +1 -1
  108. openstackclient/tests/functional/common/test_extension.py +1 -1
  109. openstackclient/tests/functional/common/test_help.py +2 -2
  110. openstackclient/tests/functional/common/test_module.py +1 -1
  111. openstackclient/tests/functional/common/test_quota.py +43 -61
  112. openstackclient/tests/functional/compute/v2/common.py +2 -2
  113. openstackclient/tests/functional/compute/v2/test_flavor.py +2 -2
  114. openstackclient/tests/functional/compute/v2/test_keypair.py +1 -1
  115. openstackclient/tests/functional/compute/v2/test_server.py +5 -5
  116. openstackclient/tests/functional/compute/v2/test_server_event.py +1 -1
  117. openstackclient/tests/functional/identity/v2/common.py +3 -3
  118. openstackclient/tests/functional/identity/v3/common.py +14 -6
  119. openstackclient/tests/functional/identity/v3/test_application_credential.py +13 -19
  120. openstackclient/tests/functional/identity/v3/test_domain.py +1 -3
  121. openstackclient/tests/functional/identity/v3/test_endpoint.py +1 -1
  122. openstackclient/tests/functional/identity/v3/test_idp.py +1 -1
  123. openstackclient/tests/functional/identity/v3/test_limit.py +2 -2
  124. openstackclient/tests/functional/identity/v3/test_region.py +1 -3
  125. openstackclient/tests/functional/identity/v3/test_registered_limit.py +1 -1
  126. openstackclient/tests/functional/identity/v3/test_role.py +2 -2
  127. openstackclient/tests/functional/identity/v3/test_role_assignment.py +210 -0
  128. openstackclient/tests/functional/identity/v3/test_service.py +4 -6
  129. openstackclient/tests/functional/identity/v3/test_service_provider.py +1 -3
  130. openstackclient/tests/functional/image/base.py +1 -1
  131. openstackclient/tests/functional/image/v2/test_image.py +1 -1
  132. openstackclient/tests/functional/image/v2/test_info.py +1 -1
  133. openstackclient/tests/functional/network/v2/common.py +4 -6
  134. openstackclient/tests/functional/network/v2/test_network.py +5 -3
  135. openstackclient/tests/functional/network/v2/test_network_agent.py +7 -5
  136. openstackclient/tests/functional/network/v2/test_network_qos_rule.py +4 -4
  137. openstackclient/tests/functional/network/v2/test_port.py +11 -7
  138. openstackclient/tests/functional/network/v2/test_router.py +2 -2
  139. openstackclient/tests/functional/object/v1/common.py +1 -1
  140. openstackclient/tests/functional/object/v1/test_container.py +3 -3
  141. openstackclient/tests/functional/object/v1/test_object.py +9 -13
  142. openstackclient/tests/functional/volume/base.py +1 -1
  143. openstackclient/tests/functional/volume/v1/test_service.py +1 -1
  144. openstackclient/tests/functional/volume/v1/test_snapshot.py +2 -2
  145. openstackclient/tests/functional/volume/v1/test_transfer_request.py +2 -2
  146. openstackclient/tests/functional/volume/v1/test_volume_type.py +1 -1
  147. openstackclient/tests/functional/volume/v2/test_service.py +2 -2
  148. openstackclient/tests/functional/volume/v2/test_volume_backup.py +2 -2
  149. openstackclient/tests/functional/volume/v2/test_volume_snapshot.py +2 -2
  150. openstackclient/tests/functional/volume/v2/test_volume_type.py +1 -1
  151. openstackclient/tests/functional/volume/v3/test_volume_snapshot.py +2 -2
  152. openstackclient/tests/functional/volume/v3/test_volume_type.py +1 -1
  153. openstackclient/tests/unit/api/fakes.py +1 -1
  154. openstackclient/tests/unit/api/test_api.py +2 -2
  155. openstackclient/tests/unit/api/test_compute_v2.py +522 -707
  156. openstackclient/tests/unit/api/test_image_v1.py +1 -1
  157. openstackclient/tests/unit/api/test_image_v2.py +1 -1
  158. openstackclient/tests/unit/api/test_object_store_v1.py +4 -4
  159. openstackclient/tests/unit/common/test_limits.py +73 -35
  160. openstackclient/tests/unit/common/test_logs.py +2 -2
  161. openstackclient/tests/unit/common/test_module.py +4 -2
  162. openstackclient/tests/unit/common/test_project_cleanup.py +31 -6
  163. openstackclient/tests/unit/common/test_quota.py +490 -630
  164. openstackclient/tests/unit/compute/v2/fakes.py +37 -286
  165. openstackclient/tests/unit/compute/v2/test_agent.py +189 -147
  166. openstackclient/tests/unit/compute/v2/test_aggregate.py +18 -16
  167. openstackclient/tests/unit/compute/v2/test_console.py +4 -5
  168. openstackclient/tests/unit/compute/v2/test_flavor.py +59 -68
  169. openstackclient/tests/unit/compute/v2/test_host.py +83 -54
  170. openstackclient/tests/unit/compute/v2/test_hypervisor.py +28 -31
  171. openstackclient/tests/unit/compute/v2/test_hypervisor_stats.py +2 -2
  172. openstackclient/tests/unit/compute/v2/test_keypair.py +65 -50
  173. openstackclient/tests/unit/compute/v2/test_server.py +2895 -2459
  174. openstackclient/tests/unit/compute/v2/test_server_backup.py +1 -1
  175. openstackclient/tests/unit/compute/v2/test_server_event.py +14 -39
  176. openstackclient/tests/unit/compute/v2/test_server_group.py +28 -29
  177. openstackclient/tests/unit/compute/v2/test_server_migration.py +43 -68
  178. openstackclient/tests/unit/compute/v2/test_server_volume.py +17 -34
  179. openstackclient/tests/unit/compute/v2/test_service.py +34 -52
  180. openstackclient/tests/unit/compute/v2/test_usage.py +4 -4
  181. openstackclient/tests/unit/fakes.py +11 -11
  182. openstackclient/tests/unit/identity/v2_0/fakes.py +27 -10
  183. openstackclient/tests/unit/identity/v2_0/test_catalog.py +3 -3
  184. openstackclient/tests/unit/identity/v2_0/test_endpoint.py +7 -7
  185. openstackclient/tests/unit/identity/v2_0/test_project.py +8 -8
  186. openstackclient/tests/unit/identity/v2_0/test_role.py +10 -10
  187. openstackclient/tests/unit/identity/v2_0/test_role_assignment.py +4 -4
  188. openstackclient/tests/unit/identity/v2_0/test_service.py +6 -6
  189. openstackclient/tests/unit/identity/v2_0/test_token.py +4 -4
  190. openstackclient/tests/unit/identity/v2_0/test_user.py +8 -8
  191. openstackclient/tests/unit/identity/v3/fakes.py +59 -20
  192. openstackclient/tests/unit/identity/v3/test_access_rule.py +5 -5
  193. openstackclient/tests/unit/identity/v3/test_application_credential.py +212 -235
  194. openstackclient/tests/unit/identity/v3/test_catalog.py +3 -3
  195. openstackclient/tests/unit/identity/v3/test_consumer.py +7 -8
  196. openstackclient/tests/unit/identity/v3/test_credential.py +9 -9
  197. openstackclient/tests/unit/identity/v3/test_domain.py +8 -8
  198. openstackclient/tests/unit/identity/v3/test_endpoint.py +13 -13
  199. openstackclient/tests/unit/identity/v3/test_endpoint_group.py +12 -14
  200. openstackclient/tests/unit/identity/v3/test_group.py +12 -12
  201. openstackclient/tests/unit/identity/v3/test_identity_provider.py +8 -8
  202. openstackclient/tests/unit/identity/v3/test_implied_role.py +5 -5
  203. openstackclient/tests/unit/identity/v3/test_limit.py +7 -7
  204. openstackclient/tests/unit/identity/v3/test_mappings.py +7 -7
  205. openstackclient/tests/unit/identity/v3/test_oauth.py +5 -5
  206. openstackclient/tests/unit/identity/v3/test_project.py +16 -16
  207. openstackclient/tests/unit/identity/v3/test_protocol.py +7 -7
  208. openstackclient/tests/unit/identity/v3/test_region.py +7 -7
  209. openstackclient/tests/unit/identity/v3/test_registered_limit.py +12 -13
  210. openstackclient/tests/unit/identity/v3/test_role.py +13 -13
  211. openstackclient/tests/unit/identity/v3/test_role_assignment.py +410 -331
  212. openstackclient/tests/unit/identity/v3/test_service.py +93 -97
  213. openstackclient/tests/unit/identity/v3/test_service_provider.py +7 -7
  214. openstackclient/tests/unit/identity/v3/test_token.py +4 -4
  215. openstackclient/tests/unit/identity/v3/test_trust.py +9 -9
  216. openstackclient/tests/unit/identity/v3/test_unscoped_saml.py +4 -4
  217. openstackclient/tests/unit/identity/v3/test_user.py +299 -327
  218. openstackclient/tests/unit/image/v1/test_image.py +6 -6
  219. openstackclient/tests/unit/image/v2/fakes.py +46 -9
  220. openstackclient/tests/unit/image/v2/test_cache.py +2 -2
  221. openstackclient/tests/unit/image/v2/test_image.py +3 -3
  222. openstackclient/tests/unit/image/v2/test_metadef_objects.py +62 -0
  223. openstackclient/tests/unit/image/v2/test_metadef_resource_type_association.py +131 -0
  224. openstackclient/tests/unit/integ/base.py +1 -1
  225. openstackclient/tests/unit/integ/cli/test_project.py +4 -4
  226. openstackclient/tests/unit/integ/cli/test_shell.py +7 -7
  227. openstackclient/tests/unit/network/test_common.py +12 -21
  228. openstackclient/tests/unit/network/v2/fakes.py +64 -130
  229. openstackclient/tests/unit/network/v2/test_address_group.py +15 -15
  230. openstackclient/tests/unit/network/v2/test_address_scope.py +13 -13
  231. openstackclient/tests/unit/network/v2/test_default_security_group_rule.py +49 -27
  232. openstackclient/tests/unit/network/v2/test_floating_ip_compute.py +40 -38
  233. openstackclient/tests/unit/network/v2/test_floating_ip_network.py +15 -15
  234. openstackclient/tests/unit/network/v2/test_floating_ip_pool_compute.py +4 -7
  235. openstackclient/tests/unit/network/v2/test_floating_ip_pool_network.py +3 -5
  236. openstackclient/tests/unit/network/v2/test_floating_ip_port_forwarding.py +11 -11
  237. openstackclient/tests/unit/network/v2/test_ip_availability.py +6 -6
  238. openstackclient/tests/unit/network/v2/test_l3_conntrack_helper.py +11 -21
  239. openstackclient/tests/unit/network/v2/test_local_ip.py +7 -7
  240. openstackclient/tests/unit/network/v2/test_local_ip_association.py +3 -5
  241. openstackclient/tests/unit/network/v2/test_ndp_proxy.py +13 -13
  242. openstackclient/tests/unit/network/v2/test_network.py +23 -28
  243. openstackclient/tests/unit/network/v2/test_network_agent.py +17 -21
  244. openstackclient/tests/unit/network/v2/test_network_auto_allocated_topology.py +8 -8
  245. openstackclient/tests/unit/network/v2/test_network_compute.py +66 -65
  246. openstackclient/tests/unit/network/v2/test_network_flavor.py +17 -19
  247. openstackclient/tests/unit/network/v2/test_network_flavor_profile.py +13 -13
  248. openstackclient/tests/unit/network/v2/test_network_meter.py +11 -11
  249. openstackclient/tests/unit/network/v2/test_network_meter_rule.py +11 -11
  250. openstackclient/tests/unit/network/v2/test_network_qos_policy.py +11 -21
  251. openstackclient/tests/unit/network/v2/test_network_qos_rule.py +51 -77
  252. openstackclient/tests/unit/network/v2/test_network_qos_rule_type.py +5 -9
  253. openstackclient/tests/unit/network/v2/test_network_rbac.py +12 -12
  254. openstackclient/tests/unit/network/v2/test_network_segment.py +11 -15
  255. openstackclient/tests/unit/network/v2/test_network_segment_range.py +11 -13
  256. openstackclient/tests/unit/network/v2/test_network_service_provider.py +3 -5
  257. openstackclient/tests/unit/network/v2/test_network_trunk.py +11 -11
  258. openstackclient/tests/unit/network/v2/test_port.py +22 -25
  259. openstackclient/tests/unit/network/v2/test_router.py +721 -51
  260. openstackclient/tests/unit/network/v2/test_security_group_compute.py +65 -49
  261. openstackclient/tests/unit/network/v2/test_security_group_network.py +15 -15
  262. openstackclient/tests/unit/network/v2/test_security_group_rule_compute.py +57 -45
  263. openstackclient/tests/unit/network/v2/test_security_group_rule_network.py +11 -19
  264. openstackclient/tests/unit/network/v2/test_subnet.py +29 -25
  265. openstackclient/tests/unit/network/v2/test_subnet_pool.py +15 -15
  266. openstackclient/tests/unit/object/v1/fakes.py +1 -1
  267. openstackclient/tests/unit/object/v1/test_container.py +5 -5
  268. openstackclient/tests/unit/object/v1/test_container_all.py +6 -6
  269. openstackclient/tests/unit/object/v1/test_object.py +3 -3
  270. openstackclient/tests/unit/object/v1/test_object_all.py +5 -5
  271. openstackclient/tests/unit/test_shell.py +5 -5
  272. openstackclient/tests/unit/utils.py +4 -1
  273. openstackclient/tests/unit/volume/test_find_resource.py +2 -2
  274. openstackclient/tests/unit/volume/v1/fakes.py +5 -6
  275. openstackclient/tests/unit/volume/v1/test_volume.py +5 -4
  276. openstackclient/tests/unit/volume/v2/fakes.py +39 -259
  277. openstackclient/tests/unit/volume/v2/test_consistency_group_snapshot.py +5 -5
  278. openstackclient/tests/unit/volume/v2/test_qos_specs.py +9 -9
  279. openstackclient/tests/unit/volume/v2/test_volume.py +21 -87
  280. openstackclient/tests/unit/volume/v2/test_volume_backup.py +7 -368
  281. openstackclient/tests/unit/volume/v2/test_volume_snapshot.py +1 -1
  282. openstackclient/tests/unit/volume/v2/test_volume_transfer_request.py +0 -44
  283. openstackclient/tests/unit/volume/v2/test_volume_type.py +6 -87
  284. openstackclient/tests/unit/volume/v3/fakes.py +505 -22
  285. openstackclient/tests/unit/volume/v3/test_block_storage_cleanup.py +2 -3
  286. openstackclient/tests/unit/volume/v3/test_block_storage_cluster.py +10 -11
  287. openstackclient/tests/unit/volume/v3/test_block_storage_log_level.py +10 -6
  288. openstackclient/tests/unit/volume/v3/test_block_storage_manage.py +25 -17
  289. openstackclient/tests/unit/volume/v3/test_block_storage_resource_filter.py +6 -32
  290. openstackclient/tests/unit/volume/v3/test_service.py +271 -0
  291. openstackclient/tests/unit/volume/v3/test_volume.py +2177 -33
  292. openstackclient/tests/unit/volume/v3/test_volume_attachment.py +48 -52
  293. openstackclient/tests/unit/volume/v3/test_volume_backup.py +892 -0
  294. openstackclient/tests/unit/volume/v3/test_volume_group.py +19 -20
  295. openstackclient/tests/unit/volume/v3/test_volume_group_snapshot.py +14 -34
  296. openstackclient/tests/unit/volume/v3/test_volume_group_type.py +13 -16
  297. openstackclient/tests/unit/volume/v3/test_volume_message.py +10 -11
  298. openstackclient/tests/unit/volume/v3/test_volume_snapshot.py +161 -0
  299. openstackclient/tests/unit/volume/v3/test_volume_transfer_request.py +425 -0
  300. openstackclient/tests/unit/volume/v3/test_volume_type.py +1109 -0
  301. openstackclient/volume/v1/qos_specs.py +7 -7
  302. openstackclient/volume/v1/service.py +2 -2
  303. openstackclient/volume/v1/volume.py +12 -12
  304. openstackclient/volume/v1/volume_backup.py +7 -7
  305. openstackclient/volume/v1/volume_snapshot.py +8 -8
  306. openstackclient/volume/v1/volume_transfer_request.py +5 -5
  307. openstackclient/volume/v1/volume_type.py +7 -7
  308. openstackclient/volume/v2/backup_record.py +2 -2
  309. openstackclient/volume/v2/consistency_group.py +7 -9
  310. openstackclient/volume/v2/consistency_group_snapshot.py +4 -12
  311. openstackclient/volume/v2/qos_specs.py +7 -7
  312. openstackclient/volume/v2/service.py +2 -2
  313. openstackclient/volume/v2/volume.py +80 -80
  314. openstackclient/volume/v2/volume_backend.py +2 -2
  315. openstackclient/volume/v2/volume_backup.py +7 -217
  316. openstackclient/volume/v2/volume_host.py +2 -2
  317. openstackclient/volume/v2/volume_snapshot.py +8 -8
  318. openstackclient/volume/v2/volume_transfer_request.py +5 -37
  319. openstackclient/volume/v2/volume_type.py +7 -89
  320. openstackclient/volume/v3/service.py +56 -0
  321. openstackclient/volume/v3/volume.py +971 -0
  322. openstackclient/volume/v3/volume_attachment.py +31 -29
  323. openstackclient/volume/v3/volume_backup.py +670 -0
  324. openstackclient/volume/v3/volume_message.py +1 -1
  325. openstackclient/volume/v3/volume_snapshot.py +97 -0
  326. openstackclient/volume/v3/volume_transfer_request.py +233 -0
  327. openstackclient/volume/v3/volume_type.py +967 -0
  328. {python_openstackclient-6.6.0.dist-info → python_openstackclient-7.0.0.dist-info}/AUTHORS +4 -0
  329. {python_openstackclient-6.6.0.dist-info → python_openstackclient-7.0.0.dist-info}/METADATA +3 -3
  330. python_openstackclient-7.0.0.dist-info/RECORD +502 -0
  331. {python_openstackclient-6.6.0.dist-info → python_openstackclient-7.0.0.dist-info}/entry_points.txt +33 -27
  332. python_openstackclient-7.0.0.dist-info/pbr.json +1 -0
  333. python_openstackclient-6.6.0.dist-info/RECORD +0 -489
  334. python_openstackclient-6.6.0.dist-info/pbr.json +0 -1
  335. {python_openstackclient-6.6.0.dist-info → python_openstackclient-7.0.0.dist-info}/LICENSE +0 -0
  336. {python_openstackclient-6.6.0.dist-info → python_openstackclient-7.0.0.dist-info}/WHEEL +0 -0
  337. {python_openstackclient-6.6.0.dist-info → python_openstackclient-7.0.0.dist-info}/top_level.txt +0 -0
@@ -25,9 +25,9 @@ from openstackclient.tests.unit import utils as tests_utils
25
25
 
26
26
  class TestRouter(network_fakes.TestNetworkV2):
27
27
  def setUp(self):
28
- super(TestRouter, self).setUp()
28
+ super().setUp()
29
29
 
30
- self.projects_mock = self.app.client_manager.identity.projects
30
+ self.projects_mock = self.identity_client.projects
31
31
 
32
32
 
33
33
  class TestAddPortToRouter(TestRouter):
@@ -39,12 +39,12 @@ class TestAddPortToRouter(TestRouter):
39
39
  )
40
40
 
41
41
  def setUp(self):
42
- super(TestAddPortToRouter, self).setUp()
42
+ super().setUp()
43
43
 
44
44
  self.network_client.find_router = mock.Mock(return_value=self._router)
45
45
  self.network_client.find_port = mock.Mock(return_value=self._port)
46
46
 
47
- self.cmd = router.AddPortToRouter(self.app, self.namespace)
47
+ self.cmd = router.AddPortToRouter(self.app, None)
48
48
 
49
49
  def test_add_port_no_option(self):
50
50
  arglist = []
@@ -75,7 +75,7 @@ class TestAddPortToRouter(TestRouter):
75
75
  self._router,
76
76
  **{
77
77
  'port_id': self._router.port,
78
- }
78
+ },
79
79
  )
80
80
  self.assertIsNone(result)
81
81
 
@@ -89,12 +89,12 @@ class TestAddSubnetToRouter(TestRouter):
89
89
  )
90
90
 
91
91
  def setUp(self):
92
- super(TestAddSubnetToRouter, self).setUp()
92
+ super().setUp()
93
93
 
94
94
  self.network_client.find_router = mock.Mock(return_value=self._router)
95
95
  self.network_client.find_subnet = mock.Mock(return_value=self._subnet)
96
96
 
97
- self.cmd = router.AddSubnetToRouter(self.app, self.namespace)
97
+ self.cmd = router.AddSubnetToRouter(self.app, None)
98
98
 
99
99
  def test_add_subnet_no_option(self):
100
100
  arglist = []
@@ -130,6 +130,7 @@ class TestAddSubnetToRouter(TestRouter):
130
130
  class TestCreateRouter(TestRouter):
131
131
  # The new router created.
132
132
  new_router = network_fakes.FakeRouter.create_one_router()
133
+ _extensions = {'fake': network_fakes.create_one_extension()}
133
134
 
134
135
  columns = (
135
136
  'admin_state_up',
@@ -163,15 +164,17 @@ class TestCreateRouter(TestRouter):
163
164
  )
164
165
 
165
166
  def setUp(self):
166
- super(TestCreateRouter, self).setUp()
167
+ super().setUp()
167
168
 
168
169
  self.network_client.create_router = mock.Mock(
169
170
  return_value=self.new_router
170
171
  )
171
172
  self.network_client.set_tags = mock.Mock(return_value=None)
172
-
173
+ self.network_client.find_extension = mock.Mock(
174
+ side_effect=lambda name: self._extensions.get(name)
175
+ )
173
176
  # Get the command object to test
174
- self.cmd = router.CreateRouter(self.app, self.namespace)
177
+ self.cmd = router.CreateRouter(self.app, None)
175
178
 
176
179
  def test_create_no_options(self):
177
180
  arglist = []
@@ -228,9 +231,9 @@ class TestCreateRouter(TestRouter):
228
231
  ('enable', True),
229
232
  ('distributed', False),
230
233
  ('ha', False),
231
- ('external_gateway', _network.name),
234
+ ('external_gateways', [_network.name]),
232
235
  ('enable_snat', True),
233
- ('fixed_ip', [{'ip-address': '2001:db8::1'}]),
236
+ ('fixed_ips', [{'ip-address': '2001:db8::1'}]),
234
237
  ]
235
238
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
236
239
 
@@ -381,13 +384,15 @@ class TestCreateRouter(TestRouter):
381
384
  def test_create_with_no_tag(self):
382
385
  self._test_create_with_tag(add_tags=False)
383
386
 
384
- def test_create_with_flavor_id(self):
387
+ def test_create_with_flavor_id_or_name(self):
385
388
  _flavor = network_fakes.create_one_network_flavor()
389
+ self.network_client.find_flavor = mock.Mock(return_value=_flavor)
386
390
  arglist = [
387
391
  self.new_router.name,
388
392
  '--flavor-id',
389
393
  _flavor.id,
390
394
  ]
395
+ arglist_with_name = [self.new_router.name, '--flavor-id', _flavor.name]
391
396
  verifylist = [
392
397
  ('name', self.new_router.name),
393
398
  ('enable', True),
@@ -407,13 +412,103 @@ class TestCreateRouter(TestRouter):
407
412
  self.assertEqual(self.columns, columns)
408
413
  self.assertCountEqual(self.data, data)
409
414
 
415
+ self.network_client.create_router.reset_mock()
416
+ verifylist_w_name = [
417
+ ('name', self.new_router.name),
418
+ ('enable', True),
419
+ ('distributed', False),
420
+ ('ha', False),
421
+ ('flavor_id', _flavor.name),
422
+ ]
423
+ parsed_args_w_name = self.check_parser(
424
+ self.cmd, arglist_with_name, verifylist_w_name
425
+ )
426
+ columns, data = self.cmd.take_action(parsed_args_w_name)
427
+ self.network_client.create_router.assert_called_once_with(
428
+ **{
429
+ 'admin_state_up': True,
430
+ 'name': self.new_router.name,
431
+ 'flavor_id': _flavor.id,
432
+ }
433
+ )
434
+ self.assertEqual(self.columns, columns)
435
+ self.assertCountEqual(self.data, data)
436
+
437
+ def test_create_with_enable_default_route_bfd(self):
438
+ self.network_client.find_extension = mock.Mock(
439
+ return_value=network_fakes.create_one_extension(
440
+ attrs={'name': 'external-gateway-multihoming'}
441
+ )
442
+ )
443
+ arglist = [self.new_router.name, '--enable-default-route-bfd']
444
+ verifylist = [
445
+ ('name', self.new_router.name),
446
+ ('enable_default_route_bfd', True),
447
+ ]
448
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
449
+ columns, data = self.cmd.take_action(parsed_args)
450
+ self.network_client.create_router.assert_called_once_with(
451
+ name=self.new_router.name,
452
+ admin_state_up=True,
453
+ enable_default_route_bfd=True,
454
+ )
455
+ self.assertEqual(self.columns, columns)
456
+ self.assertCountEqual(self.data, data)
457
+
458
+ def test_create_with_enable_default_route_bfd_no_extension(self):
459
+ arglist = [self.new_router.name, '--enable-default-route-bfd']
460
+ verifylist = [
461
+ ('name', self.new_router.name),
462
+ ('enable_default_route_bfd', True),
463
+ ]
464
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
465
+ self.assertRaises(
466
+ exceptions.CommandError,
467
+ self.cmd.take_action,
468
+ parsed_args,
469
+ )
470
+
471
+ def test_create_with_enable_default_route_ecmp(self):
472
+ self.network_client.find_extension = mock.Mock(
473
+ return_value=network_fakes.create_one_extension(
474
+ attrs={'name': 'external-gateway-multihoming'}
475
+ )
476
+ )
477
+ arglist = [self.new_router.name, '--enable-default-route-ecmp']
478
+ verifylist = [
479
+ ('name', self.new_router.name),
480
+ ('enable_default_route_ecmp', True),
481
+ ]
482
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
483
+ columns, data = self.cmd.take_action(parsed_args)
484
+ self.network_client.create_router.assert_called_once_with(
485
+ name=self.new_router.name,
486
+ admin_state_up=True,
487
+ enable_default_route_ecmp=True,
488
+ )
489
+ self.assertEqual(self.columns, columns)
490
+ self.assertCountEqual(self.data, data)
491
+
492
+ def test_create_with_enable_default_route_ecmp_no_extension(self):
493
+ arglist = [self.new_router.name, '--enable-default-route-ecmp']
494
+ verifylist = [
495
+ ('name', self.new_router.name),
496
+ ('enable_default_route_ecmp', True),
497
+ ]
498
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
499
+ self.assertRaises(
500
+ exceptions.CommandError,
501
+ self.cmd.take_action,
502
+ parsed_args,
503
+ )
504
+
410
505
 
411
506
  class TestDeleteRouter(TestRouter):
412
507
  # The routers to delete.
413
508
  _routers = network_fakes.FakeRouter.create_routers(count=2)
414
509
 
415
510
  def setUp(self):
416
- super(TestDeleteRouter, self).setUp()
511
+ super().setUp()
417
512
 
418
513
  self.network_client.delete_router = mock.Mock(return_value=None)
419
514
 
@@ -422,7 +517,7 @@ class TestDeleteRouter(TestRouter):
422
517
  )
423
518
 
424
519
  # Get the command object to test
425
- self.cmd = router.DeleteRouter(self.app, self.namespace)
520
+ self.cmd = router.DeleteRouter(self.app, None)
426
521
 
427
522
  def test_router_delete(self):
428
523
  arglist = [
@@ -571,10 +666,10 @@ class TestListRouter(TestRouter):
571
666
  )
572
667
 
573
668
  def setUp(self):
574
- super(TestListRouter, self).setUp()
669
+ super().setUp()
575
670
 
576
671
  # Get the command object to test
577
- self.cmd = router.ListRouter(self.app, self.namespace)
672
+ self.cmd = router.ListRouter(self.app, None)
578
673
 
579
674
  self.network_client.agent_hosted_routers = mock.Mock(
580
675
  return_value=self.routers
@@ -834,12 +929,12 @@ class TestRemovePortFromRouter(TestRouter):
834
929
  )
835
930
 
836
931
  def setUp(self):
837
- super(TestRemovePortFromRouter, self).setUp()
932
+ super().setUp()
838
933
 
839
934
  self.network_client.find_router = mock.Mock(return_value=self._router)
840
935
  self.network_client.find_port = mock.Mock(return_value=self._port)
841
936
 
842
- self.cmd = router.RemovePortFromRouter(self.app, self.namespace)
937
+ self.cmd = router.RemovePortFromRouter(self.app, None)
843
938
 
844
939
  def test_remove_port_no_option(self):
845
940
  arglist = []
@@ -881,12 +976,12 @@ class TestRemoveSubnetFromRouter(TestRouter):
881
976
  )
882
977
 
883
978
  def setUp(self):
884
- super(TestRemoveSubnetFromRouter, self).setUp()
979
+ super().setUp()
885
980
 
886
981
  self.network_client.find_router = mock.Mock(return_value=self._router)
887
982
  self.network_client.find_subnet = mock.Mock(return_value=self._subnet)
888
983
 
889
- self.cmd = router.RemoveSubnetFromRouter(self.app, self.namespace)
984
+ self.cmd = router.RemoveSubnetFromRouter(self.app, None)
890
985
 
891
986
  def test_remove_subnet_no_option(self):
892
987
  arglist = []
@@ -922,11 +1017,11 @@ class TestAddExtraRoutesToRouter(TestRouter):
922
1017
  _router = network_fakes.FakeRouter.create_one_router()
923
1018
 
924
1019
  def setUp(self):
925
- super(TestAddExtraRoutesToRouter, self).setUp()
1020
+ super().setUp()
926
1021
  self.network_client.add_extra_routes_to_router = mock.Mock(
927
1022
  return_value=self._router
928
1023
  )
929
- self.cmd = router.AddExtraRoutesToRouter(self.app, self.namespace)
1024
+ self.cmd = router.AddExtraRoutesToRouter(self.app, None)
930
1025
  self.network_client.find_router = mock.Mock(return_value=self._router)
931
1026
 
932
1027
  def test_add_no_extra_route(self):
@@ -1011,11 +1106,11 @@ class TestRemoveExtraRoutesFromRouter(TestRouter):
1011
1106
  _router = network_fakes.FakeRouter.create_one_router()
1012
1107
 
1013
1108
  def setUp(self):
1014
- super(TestRemoveExtraRoutesFromRouter, self).setUp()
1109
+ super().setUp()
1015
1110
  self.network_client.remove_extra_routes_from_router = mock.Mock(
1016
1111
  return_value=self._router
1017
1112
  )
1018
- self.cmd = router.RemoveExtraRoutesFromRouter(self.app, self.namespace)
1113
+ self.cmd = router.RemoveExtraRoutesFromRouter(self.app, None)
1019
1114
  self.network_client.find_router = mock.Mock(return_value=self._router)
1020
1115
 
1021
1116
  def test_remove_no_extra_route(self):
@@ -1100,13 +1195,16 @@ class TestSetRouter(TestRouter):
1100
1195
  # The router to set.
1101
1196
  _default_route = {'destination': '10.20.20.0/24', 'nexthop': '10.20.30.1'}
1102
1197
  _network = network_fakes.create_one_network()
1103
- _subnet = network_fakes.FakeSubnet.create_one_subnet()
1198
+ _subnet = network_fakes.FakeSubnet.create_one_subnet(
1199
+ attrs={'network_id': _network.id}
1200
+ )
1104
1201
  _router = network_fakes.FakeRouter.create_one_router(
1105
1202
  attrs={'routes': [_default_route], 'tags': ['green', 'red']}
1106
1203
  )
1204
+ _extensions = {'fake': network_fakes.create_one_extension()}
1107
1205
 
1108
1206
  def setUp(self):
1109
- super(TestSetRouter, self).setUp()
1207
+ super().setUp()
1110
1208
  self.network_client.update_router = mock.Mock(return_value=None)
1111
1209
  self.network_client.set_tags = mock.Mock(return_value=None)
1112
1210
  self.network_client.find_router = mock.Mock(return_value=self._router)
@@ -1114,9 +1212,11 @@ class TestSetRouter(TestRouter):
1114
1212
  return_value=self._network
1115
1213
  )
1116
1214
  self.network_client.find_subnet = mock.Mock(return_value=self._subnet)
1117
-
1215
+ self.network_client.find_extension = mock.Mock(
1216
+ side_effect=lambda name: self._extensions.get(name)
1217
+ )
1118
1218
  # Get the command object to test
1119
- self.cmd = router.SetRouter(self.app, self.namespace)
1219
+ self.cmd = router.SetRouter(self.app, None)
1120
1220
 
1121
1221
  def test_set_this(self):
1122
1222
  arglist = [
@@ -1297,7 +1397,7 @@ class TestSetRouter(TestRouter):
1297
1397
  self._router.id,
1298
1398
  ]
1299
1399
  verifylist = [
1300
- ('fixed_ip', [{'subnet': "'abc'"}]),
1400
+ ('fixed_ips', [{'subnet': "'abc'"}]),
1301
1401
  ('router', self._router.id),
1302
1402
  ]
1303
1403
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -1312,7 +1412,7 @@ class TestSetRouter(TestRouter):
1312
1412
  self._router.id,
1313
1413
  ]
1314
1414
  verifylist = [
1315
- ('external_gateway', self._network.id),
1415
+ ('external_gateways', [self._network.id]),
1316
1416
  ('router', self._router.id),
1317
1417
  ]
1318
1418
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -1320,7 +1420,7 @@ class TestSetRouter(TestRouter):
1320
1420
  result = self.cmd.take_action(parsed_args)
1321
1421
  self.network_client.update_router.assert_called_with(
1322
1422
  self._router,
1323
- **{'external_gateway_info': {'network_id': self._network.id}}
1423
+ **{'external_gateway_info': {'network_id': self._network.id}},
1324
1424
  )
1325
1425
  self.assertIsNone(result)
1326
1426
 
@@ -1335,8 +1435,8 @@ class TestSetRouter(TestRouter):
1335
1435
  ]
1336
1436
  verifylist = [
1337
1437
  ('router', self._router.id),
1338
- ('external_gateway', self._network.id),
1339
- ('fixed_ip', [{'subnet': "'abc'"}]),
1438
+ ('external_gateways', [self._network.id]),
1439
+ ('fixed_ips', [{'subnet': "'abc'"}]),
1340
1440
  ('enable_snat', True),
1341
1441
  ]
1342
1442
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -1354,7 +1454,7 @@ class TestSetRouter(TestRouter):
1354
1454
  ],
1355
1455
  'enable_snat': True,
1356
1456
  }
1357
- }
1457
+ },
1358
1458
  )
1359
1459
  self.assertIsNone(result)
1360
1460
 
@@ -1369,8 +1469,8 @@ class TestSetRouter(TestRouter):
1369
1469
  ]
1370
1470
  verifylist = [
1371
1471
  ('router', self._router.id),
1372
- ('external_gateway', self._network.id),
1373
- ('fixed_ip', [{'ip-address': "10.0.1.1"}]),
1472
+ ('external_gateways', [self._network.id]),
1473
+ ('fixed_ips', [{'ip-address': "10.0.1.1"}]),
1374
1474
  ('enable_snat', True),
1375
1475
  ]
1376
1476
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -1388,7 +1488,7 @@ class TestSetRouter(TestRouter):
1388
1488
  ],
1389
1489
  'enable_snat': True,
1390
1490
  }
1391
- }
1491
+ },
1392
1492
  )
1393
1493
  self.assertIsNone(result)
1394
1494
 
@@ -1403,8 +1503,8 @@ class TestSetRouter(TestRouter):
1403
1503
  ]
1404
1504
  verifylist = [
1405
1505
  ('router', self._router.id),
1406
- ('external_gateway', self._network.id),
1407
- ('fixed_ip', [{'subnet': "'abc'", 'ip-address': "10.0.1.1"}]),
1506
+ ('external_gateways', [self._network.id]),
1507
+ ('fixed_ips', [{'subnet': "'abc'", 'ip-address': "10.0.1.1"}]),
1408
1508
  ('enable_snat', True),
1409
1509
  ]
1410
1510
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -1423,7 +1523,7 @@ class TestSetRouter(TestRouter):
1423
1523
  ],
1424
1524
  'enable_snat': True,
1425
1525
  }
1426
- }
1526
+ },
1427
1527
  )
1428
1528
  self.assertIsNone(result)
1429
1529
 
@@ -1468,7 +1568,7 @@ class TestSetRouter(TestRouter):
1468
1568
  ]
1469
1569
  verifylist = [
1470
1570
  ('router', self._router.id),
1471
- ('external_gateway', self._network.id),
1571
+ ('external_gateways', [self._network.id]),
1472
1572
  ('qos_policy', qos_policy.id),
1473
1573
  ]
1474
1574
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -1481,7 +1581,7 @@ class TestSetRouter(TestRouter):
1481
1581
  'network_id': self._network.id,
1482
1582
  'qos_policy_id': qos_policy.id,
1483
1583
  }
1484
- }
1584
+ },
1485
1585
  )
1486
1586
  self.assertIsNone(result)
1487
1587
 
@@ -1494,7 +1594,7 @@ class TestSetRouter(TestRouter):
1494
1594
  ]
1495
1595
  verifylist = [
1496
1596
  ('router', self._router.id),
1497
- ('external_gateway', self._network.id),
1597
+ ('external_gateways', [self._network.id]),
1498
1598
  ('no_qos_policy', True),
1499
1599
  ]
1500
1600
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -1507,7 +1607,7 @@ class TestSetRouter(TestRouter):
1507
1607
  'network_id': self._network.id,
1508
1608
  'qos_policy_id': None,
1509
1609
  }
1510
- }
1610
+ },
1511
1611
  )
1512
1612
  self.assertIsNone(result)
1513
1613
 
@@ -1526,7 +1626,7 @@ class TestSetRouter(TestRouter):
1526
1626
  ]
1527
1627
  verifylist = [
1528
1628
  ('router', self._router.id),
1529
- ('external_gateway', self._network.id),
1629
+ ('external_gateways', [self._network.id]),
1530
1630
  ('qos_policy', qos_policy.id),
1531
1631
  ('no_qos_policy', True),
1532
1632
  ]
@@ -1634,13 +1734,13 @@ class TestShowRouter(TestRouter):
1634
1734
  )
1635
1735
 
1636
1736
  def setUp(self):
1637
- super(TestShowRouter, self).setUp()
1737
+ super().setUp()
1638
1738
 
1639
1739
  self.network_client.find_router = mock.Mock(return_value=self._router)
1640
1740
  self.network_client.ports = mock.Mock(return_value=[self._port])
1641
1741
 
1642
1742
  # Get the command object to test
1643
- self.cmd = router.ShowRouter(self.app, self.namespace)
1743
+ self.cmd = router.ShowRouter(self.app, None)
1644
1744
 
1645
1745
  def test_show_no_options(self):
1646
1746
  arglist = []
@@ -1717,7 +1817,7 @@ class TestShowRouter(TestRouter):
1717
1817
 
1718
1818
  class TestUnsetRouter(TestRouter):
1719
1819
  def setUp(self):
1720
- super(TestUnsetRouter, self).setUp()
1820
+ super().setUp()
1721
1821
  self.fake_network = network_fakes.create_one_network()
1722
1822
  self.fake_qos_policy = (
1723
1823
  network_fakes.FakeNetworkQosPolicy.create_one_qos_policy()
@@ -1747,8 +1847,15 @@ class TestUnsetRouter(TestRouter):
1747
1847
  )
1748
1848
  self.network_client.update_router = mock.Mock(return_value=None)
1749
1849
  self.network_client.set_tags = mock.Mock(return_value=None)
1850
+ self._extensions = {'fake': network_fakes.create_one_extension()}
1851
+ self.network_client.find_extension = mock.Mock(
1852
+ side_effect=lambda name: self._extensions.get(name)
1853
+ )
1854
+ self.network_client.remove_external_gateways = mock.Mock(
1855
+ return_value=None
1856
+ )
1750
1857
  # Get the command object to test
1751
- self.cmd = router.UnsetRouter(self.app, self.namespace)
1858
+ self.cmd = router.UnsetRouter(self.app, None)
1752
1859
 
1753
1860
  def test_unset_router_params(self):
1754
1861
  arglist = [
@@ -1799,7 +1906,7 @@ class TestUnsetRouter(TestRouter):
1799
1906
  '--external-gateway',
1800
1907
  self._testrouter.name,
1801
1908
  ]
1802
- verifylist = [('external_gateway', True)]
1909
+ verifylist = [('external_gateways', True)]
1803
1910
  parsed_args = self.check_parser(self.cmd, arglist, verifylist)
1804
1911
  result = self.cmd.take_action(parsed_args)
1805
1912
  attrs = {'external_gateway_info': {}}
@@ -1808,6 +1915,33 @@ class TestUnsetRouter(TestRouter):
1808
1915
  )
1809
1916
  self.assertIsNone(result)
1810
1917
 
1918
+ def test_unset_router_external_gateway_multiple_supported(self):
1919
+ # Add the relevant extension in order to test the alternate behavior.
1920
+ self._extensions = {
1921
+ 'external-gateway-multihoming': network_fakes.create_one_extension(
1922
+ attrs={'name': 'external-gateway-multihoming'}
1923
+ )
1924
+ }
1925
+ arglist = [
1926
+ '--external-gateway',
1927
+ self._testrouter.name,
1928
+ ]
1929
+ verifylist = [('external_gateways', True)]
1930
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
1931
+ result = self.cmd.take_action(parsed_args)
1932
+ # The removal of all gateways should be requested using the multiple
1933
+ # gateways API.
1934
+ self.network_client.remove_external_gateways.assert_called_once_with(
1935
+ self._testrouter, body={'router': {'external_gateways': {}}}
1936
+ )
1937
+ # The compatibility API will also be called in order to potentially
1938
+ # unset other parameters along with external_gateway_info which
1939
+ # should already be empty at that point anyway.
1940
+ self.network_client.update_router.assert_called_once_with(
1941
+ self._testrouter, **{'external_gateway_info': {}}
1942
+ )
1943
+ self.assertIsNone(result)
1944
+
1811
1945
  def _test_unset_tags(self, with_tags=True):
1812
1946
  if with_tags:
1813
1947
  arglist = ['--tag', 'red', '--tag', 'blue']
@@ -1895,3 +2029,539 @@ class TestUnsetRouter(TestRouter):
1895
2029
  self.assertRaises(
1896
2030
  exceptions.CommandError, self.cmd.take_action, parsed_args
1897
2031
  )
2032
+
2033
+
2034
+ class TestGatewayOps(TestRouter):
2035
+ def setUp(self):
2036
+ super().setUp()
2037
+ self._networks = []
2038
+ self._network = network_fakes.create_one_network()
2039
+ self._networks.append(self._network)
2040
+
2041
+ self._router = network_fakes.FakeRouter.create_one_router(
2042
+ {
2043
+ 'external_gateway_info': {
2044
+ 'network_id': self._network.id,
2045
+ },
2046
+ }
2047
+ )
2048
+ self._subnet = network_fakes.FakeSubnet.create_one_subnet(
2049
+ attrs={'network_id': self._network.id}
2050
+ )
2051
+ self._extensions = {
2052
+ 'external-gateway-multihoming': network_fakes.create_one_extension(
2053
+ attrs={'name': 'external-gateway-multihoming'}
2054
+ )
2055
+ }
2056
+ self.network_client.find_extension = mock.Mock(
2057
+ side_effect=lambda name: self._extensions.get(name)
2058
+ )
2059
+ self.network_client.find_router = mock.Mock(return_value=self._router)
2060
+
2061
+ def _find_network(name_or_id, ignore_missing):
2062
+ for network in self._networks:
2063
+ if name_or_id in (network.id, network.name):
2064
+ return network
2065
+ if ignore_missing:
2066
+ return None
2067
+ raise Exception('Test resource not found')
2068
+
2069
+ self.network_client.find_network = mock.Mock(side_effect=_find_network)
2070
+
2071
+ self.network_client.find_subnet = mock.Mock(return_value=self._subnet)
2072
+ self.network_client.add_external_gateways = mock.Mock(
2073
+ return_value=None
2074
+ )
2075
+ self.network_client.remove_external_gateways = mock.Mock(
2076
+ return_value=None
2077
+ )
2078
+
2079
+
2080
+ class TestCreateMultipleGateways(TestGatewayOps):
2081
+ _columns = (
2082
+ 'admin_state_up',
2083
+ 'availability_zone_hints',
2084
+ 'availability_zones',
2085
+ 'description',
2086
+ 'distributed',
2087
+ 'external_gateway_info',
2088
+ 'ha',
2089
+ 'id',
2090
+ 'name',
2091
+ 'project_id',
2092
+ 'routes',
2093
+ 'status',
2094
+ 'tags',
2095
+ )
2096
+
2097
+ def setUp(self):
2098
+ super().setUp()
2099
+ self._second_network = network_fakes.create_one_network()
2100
+ self._networks.append(self._second_network)
2101
+
2102
+ self.network_client.create_router = mock.Mock(
2103
+ return_value=self._router
2104
+ )
2105
+ self.network_client.update_router = mock.Mock(return_value=None)
2106
+ self.network_client.update_external_gateways = mock.Mock(
2107
+ return_value=None
2108
+ )
2109
+
2110
+ self._data = (
2111
+ router.AdminStateColumn(self._router.admin_state_up),
2112
+ format_columns.ListColumn(self._router.availability_zone_hints),
2113
+ format_columns.ListColumn(self._router.availability_zones),
2114
+ self._router.description,
2115
+ self._router.distributed,
2116
+ router.RouterInfoColumn(self._router.external_gateway_info),
2117
+ self._router.ha,
2118
+ self._router.id,
2119
+ self._router.name,
2120
+ self._router.project_id,
2121
+ router.RoutesColumn(self._router.routes),
2122
+ self._router.status,
2123
+ format_columns.ListColumn(self._router.tags),
2124
+ )
2125
+ self.cmd = router.CreateRouter(self.app, None)
2126
+
2127
+ def test_create_one_gateway(self):
2128
+ arglist = [
2129
+ "--external-gateway",
2130
+ self._network.id,
2131
+ self._router.name,
2132
+ ]
2133
+ verifylist = [
2134
+ ('name', self._router.name),
2135
+ ('external_gateways', [self._network.id]),
2136
+ ]
2137
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
2138
+
2139
+ columns, data = self.cmd.take_action(parsed_args)
2140
+ self.network_client.update_external_gateways.assert_called_with(
2141
+ self._router,
2142
+ body={
2143
+ 'router': {
2144
+ 'external_gateways': [
2145
+ {
2146
+ 'network_id': self._network.id,
2147
+ }
2148
+ ]
2149
+ }
2150
+ },
2151
+ )
2152
+ self.assertEqual(self._columns, columns)
2153
+ self.assertCountEqual(self._data, data)
2154
+
2155
+ def test_create_multiple_gateways(self):
2156
+ arglist = [
2157
+ self._router.name,
2158
+ "--external-gateway",
2159
+ self._network.id,
2160
+ "--external-gateway",
2161
+ self._network.id,
2162
+ "--external-gateway",
2163
+ self._second_network.id,
2164
+ '--fixed-ip',
2165
+ f'subnet={self._subnet.id},ip-address=10.0.1.1',
2166
+ '--fixed-ip',
2167
+ f'subnet={self._subnet.id},ip-address=10.0.1.2',
2168
+ ]
2169
+ verifylist = [
2170
+ ('name', self._router.name),
2171
+ (
2172
+ 'external_gateways',
2173
+ [self._network.id, self._network.id, self._second_network.id],
2174
+ ),
2175
+ ]
2176
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
2177
+ columns, data = self.cmd.take_action(parsed_args)
2178
+
2179
+ # The router will not have a gateway after the create call, but it
2180
+ # will be added after the update call.
2181
+ self.network_client.create_router.assert_called_once_with(
2182
+ **{
2183
+ 'admin_state_up': True,
2184
+ 'name': self._router.name,
2185
+ }
2186
+ )
2187
+ self.network_client.update_external_gateways.assert_called_with(
2188
+ self._router,
2189
+ body={
2190
+ 'router': {
2191
+ 'external_gateways': [
2192
+ {
2193
+ 'network_id': self._network.id,
2194
+ 'external_fixed_ips': [
2195
+ {
2196
+ 'subnet_id': self._subnet.id,
2197
+ 'ip_address': '10.0.1.1',
2198
+ }
2199
+ ],
2200
+ },
2201
+ {
2202
+ 'network_id': self._network.id,
2203
+ 'external_fixed_ips': [
2204
+ {
2205
+ 'subnet_id': self._subnet.id,
2206
+ 'ip_address': '10.0.1.2',
2207
+ }
2208
+ ],
2209
+ },
2210
+ {
2211
+ 'network_id': self._second_network.id,
2212
+ },
2213
+ ]
2214
+ }
2215
+ },
2216
+ )
2217
+ self.assertEqual(self._columns, columns)
2218
+ self.assertCountEqual(self._data, data)
2219
+
2220
+
2221
+ class TestUpdateMultipleGateways(TestGatewayOps):
2222
+ def setUp(self):
2223
+ super().setUp()
2224
+ self._second_network = network_fakes.create_one_network()
2225
+ self._networks.append(self._second_network)
2226
+
2227
+ self.network_client.update_router = mock.Mock(return_value=None)
2228
+ self.network_client.update_external_gateways = mock.Mock(
2229
+ return_value=None
2230
+ )
2231
+ self.cmd = router.SetRouter(self.app, None)
2232
+
2233
+ def test_update_one_gateway(self):
2234
+ arglist = [
2235
+ "--external-gateway",
2236
+ self._network.id,
2237
+ "--no-qos-policy",
2238
+ self._router.name,
2239
+ ]
2240
+ verifylist = [
2241
+ ('router', self._router.name),
2242
+ ('external_gateways', [self._network.id]),
2243
+ ('no_qos_policy', True),
2244
+ ]
2245
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
2246
+ result = self.cmd.take_action(parsed_args)
2247
+ self.network_client.update_external_gateways.assert_called_with(
2248
+ self._router,
2249
+ body={
2250
+ 'router': {
2251
+ 'external_gateways': [
2252
+ {'network_id': self._network.id, 'qos_policy_id': None}
2253
+ ]
2254
+ }
2255
+ },
2256
+ )
2257
+ self.assertIsNone(result)
2258
+
2259
+ def test_update_multiple_gateways(self):
2260
+ arglist = [
2261
+ self._router.name,
2262
+ "--external-gateway",
2263
+ self._network.id,
2264
+ "--external-gateway",
2265
+ self._network.id,
2266
+ "--external-gateway",
2267
+ self._second_network.id,
2268
+ '--fixed-ip',
2269
+ f'subnet={self._subnet.id},ip-address=10.0.1.1',
2270
+ '--fixed-ip',
2271
+ f'subnet={self._subnet.id},ip-address=10.0.1.2',
2272
+ "--no-qos-policy",
2273
+ ]
2274
+ verifylist = [
2275
+ ('router', self._router.name),
2276
+ (
2277
+ 'external_gateways',
2278
+ [self._network.id, self._network.id, self._second_network.id],
2279
+ ),
2280
+ ('no_qos_policy', True),
2281
+ ]
2282
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
2283
+ result = self.cmd.take_action(parsed_args)
2284
+ self.network_client.update_external_gateways.assert_called_with(
2285
+ self._router,
2286
+ body={
2287
+ 'router': {
2288
+ 'external_gateways': [
2289
+ {
2290
+ 'network_id': self._network.id,
2291
+ 'external_fixed_ips': [
2292
+ {
2293
+ 'subnet_id': self._subnet.id,
2294
+ 'ip_address': '10.0.1.1',
2295
+ }
2296
+ ],
2297
+ 'qos_policy_id': None,
2298
+ },
2299
+ {
2300
+ 'network_id': self._network.id,
2301
+ 'external_fixed_ips': [
2302
+ {
2303
+ 'subnet_id': self._subnet.id,
2304
+ 'ip_address': '10.0.1.2',
2305
+ }
2306
+ ],
2307
+ 'qos_policy_id': None,
2308
+ },
2309
+ {
2310
+ 'network_id': self._second_network.id,
2311
+ 'qos_policy_id': None,
2312
+ },
2313
+ ]
2314
+ }
2315
+ },
2316
+ )
2317
+ self.assertIsNone(result)
2318
+
2319
+
2320
+ class TestAddGatewayRouter(TestGatewayOps):
2321
+ def setUp(self):
2322
+ super().setUp()
2323
+ # Get the command object to test
2324
+ self.cmd = router.AddGatewayToRouter(self.app, None)
2325
+
2326
+ self.network_client.add_external_gateways.return_value = self._router
2327
+
2328
+ def test_add_gateway_network_only(self):
2329
+ arglist = [
2330
+ self._router.name,
2331
+ self._network.id,
2332
+ ]
2333
+ verifylist = [
2334
+ ('router', self._router.name),
2335
+ ('external_gateways', [self._network.id]),
2336
+ ]
2337
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
2338
+ result = self.cmd.take_action(parsed_args)
2339
+ self.network_client.add_external_gateways.assert_called_with(
2340
+ self._router,
2341
+ body={
2342
+ 'router': {
2343
+ 'external_gateways': [{'network_id': self._network.id}]
2344
+ }
2345
+ },
2346
+ )
2347
+ self.assertEqual(result[1][result[0].index('id')], self._router.id)
2348
+
2349
+ def test_add_gateway_network_fixed_ip(self):
2350
+ arglist = [
2351
+ self._router.name,
2352
+ self._network.id,
2353
+ '--fixed-ip',
2354
+ f'subnet={self._subnet.id},ip-address=10.0.1.1',
2355
+ ]
2356
+ verifylist = [
2357
+ ('router', self._router.name),
2358
+ ('external_gateways', [self._network.id]),
2359
+ ]
2360
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
2361
+ result = self.cmd.take_action(parsed_args)
2362
+ self.network_client.add_external_gateways.assert_called_with(
2363
+ self._router,
2364
+ body={
2365
+ 'router': {
2366
+ 'external_gateways': [
2367
+ {
2368
+ 'network_id': self._network.id,
2369
+ 'external_fixed_ips': [
2370
+ {
2371
+ 'subnet_id': self._subnet.id,
2372
+ 'ip_address': '10.0.1.1',
2373
+ }
2374
+ ],
2375
+ }
2376
+ ]
2377
+ }
2378
+ },
2379
+ )
2380
+ self.assertEqual(result[1][result[0].index('id')], self._router.id)
2381
+
2382
+ def test_add_gateway_network_multiple_fixed_ips(self):
2383
+ arglist = [
2384
+ self._router.name,
2385
+ self._network.id,
2386
+ '--fixed-ip',
2387
+ f'subnet={self._subnet.id},ip-address=10.0.1.1',
2388
+ '--fixed-ip',
2389
+ f'subnet={self._subnet.id},ip-address=10.0.1.2',
2390
+ ]
2391
+ verifylist = [
2392
+ ('router', self._router.name),
2393
+ ('external_gateways', [self._network.id]),
2394
+ (
2395
+ 'fixed_ips',
2396
+ [
2397
+ {'ip-address': '10.0.1.1', 'subnet': self._subnet.id},
2398
+ {'ip-address': '10.0.1.2', 'subnet': self._subnet.id},
2399
+ ],
2400
+ ),
2401
+ ]
2402
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
2403
+ result = self.cmd.take_action(parsed_args)
2404
+ self.network_client.add_external_gateways.assert_called_with(
2405
+ self._router,
2406
+ body={
2407
+ 'router': {
2408
+ 'external_gateways': [
2409
+ {
2410
+ 'network_id': self._network.id,
2411
+ 'external_fixed_ips': [
2412
+ {
2413
+ 'subnet_id': self._subnet.id,
2414
+ 'ip_address': '10.0.1.1',
2415
+ },
2416
+ {
2417
+ 'subnet_id': self._subnet.id,
2418
+ 'ip_address': '10.0.1.2',
2419
+ },
2420
+ ],
2421
+ }
2422
+ ]
2423
+ }
2424
+ },
2425
+ )
2426
+ self.assertEqual(result[1][result[0].index('id')], self._router.id)
2427
+
2428
+ def test_add_gateway_network_only_no_extension(self):
2429
+ self._extensions = {}
2430
+ arglist = [
2431
+ self._router.name,
2432
+ self._network.id,
2433
+ ]
2434
+ verifylist = [
2435
+ ('router', self._router.name),
2436
+ ('external_gateways', [self._network.id]),
2437
+ ]
2438
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
2439
+ self.assertRaises(
2440
+ exceptions.CommandError, self.cmd.take_action, parsed_args
2441
+ )
2442
+
2443
+
2444
+ class TestRemoveGatewayRouter(TestGatewayOps):
2445
+ def setUp(self):
2446
+ super().setUp()
2447
+ # Get the command object to test
2448
+ self.cmd = router.RemoveGatewayFromRouter(self.app, None)
2449
+
2450
+ self.network_client.remove_external_gateways.return_value = (
2451
+ self._router
2452
+ )
2453
+
2454
+ def test_remove_gateway_network_only(self):
2455
+ arglist = [
2456
+ self._router.name,
2457
+ self._network.id,
2458
+ ]
2459
+ verifylist = [
2460
+ ('router', self._router.name),
2461
+ ('external_gateways', [self._network.id]),
2462
+ ]
2463
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
2464
+ result = self.cmd.take_action(parsed_args)
2465
+ self.network_client.remove_external_gateways.assert_called_with(
2466
+ self._router,
2467
+ body={
2468
+ 'router': {
2469
+ 'external_gateways': [{'network_id': self._network.id}]
2470
+ }
2471
+ },
2472
+ )
2473
+ self.assertEqual(result[1][result[0].index('id')], self._router.id)
2474
+
2475
+ def test_remove_gateway_network_fixed_ip(self):
2476
+ arglist = [
2477
+ self._router.name,
2478
+ self._network.id,
2479
+ '--fixed-ip',
2480
+ f'subnet={self._subnet.id},ip-address=10.0.1.1',
2481
+ ]
2482
+ verifylist = [
2483
+ ('router', self._router.name),
2484
+ ('external_gateways', [self._network.id]),
2485
+ ]
2486
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
2487
+ result = self.cmd.take_action(parsed_args)
2488
+ self.network_client.remove_external_gateways.assert_called_with(
2489
+ self._router,
2490
+ body={
2491
+ 'router': {
2492
+ 'external_gateways': [
2493
+ {
2494
+ 'network_id': self._network.id,
2495
+ 'external_fixed_ips': [
2496
+ {
2497
+ 'subnet_id': self._subnet.id,
2498
+ 'ip_address': '10.0.1.1',
2499
+ }
2500
+ ],
2501
+ }
2502
+ ]
2503
+ }
2504
+ },
2505
+ )
2506
+ self.assertEqual(result[1][result[0].index('id')], self._router.id)
2507
+
2508
+ def test_remove_gateway_network_multiple_fixed_ips(self):
2509
+ arglist = [
2510
+ self._router.name,
2511
+ self._network.id,
2512
+ '--fixed-ip',
2513
+ f'subnet={self._subnet.id},ip-address=10.0.1.1',
2514
+ '--fixed-ip',
2515
+ f'subnet={self._subnet.id},ip-address=10.0.1.2',
2516
+ ]
2517
+ verifylist = [
2518
+ ('router', self._router.name),
2519
+ ('external_gateways', [self._network.id]),
2520
+ (
2521
+ 'fixed_ips',
2522
+ [
2523
+ {'ip-address': '10.0.1.1', 'subnet': self._subnet.id},
2524
+ {'ip-address': '10.0.1.2', 'subnet': self._subnet.id},
2525
+ ],
2526
+ ),
2527
+ ]
2528
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
2529
+ result = self.cmd.take_action(parsed_args)
2530
+ self.network_client.remove_external_gateways.assert_called_with(
2531
+ self._router,
2532
+ body={
2533
+ 'router': {
2534
+ 'external_gateways': [
2535
+ {
2536
+ 'network_id': self._network.id,
2537
+ 'external_fixed_ips': [
2538
+ {
2539
+ 'subnet_id': self._subnet.id,
2540
+ 'ip_address': '10.0.1.1',
2541
+ },
2542
+ {
2543
+ 'subnet_id': self._subnet.id,
2544
+ 'ip_address': '10.0.1.2',
2545
+ },
2546
+ ],
2547
+ }
2548
+ ]
2549
+ }
2550
+ },
2551
+ )
2552
+ self.assertEqual(result[1][result[0].index('id')], self._router.id)
2553
+
2554
+ def test_remove_gateway_network_only_no_extension(self):
2555
+ self._extensions = {}
2556
+ arglist = [
2557
+ self._router.name,
2558
+ self._network.id,
2559
+ ]
2560
+ verifylist = [
2561
+ ('router', self._router.name),
2562
+ ('external_gateways', [self._network.id]),
2563
+ ]
2564
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
2565
+ self.assertRaises(
2566
+ exceptions.CommandError, self.cmd.take_action, parsed_args
2567
+ )