octavia 14.0.0.0rc1__py3-none-any.whl → 15.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 (307) hide show
  1. octavia/amphorae/backends/agent/agent_jinja_cfg.py +1 -4
  2. octavia/amphorae/backends/agent/api_server/amphora_info.py +5 -5
  3. octavia/amphorae/backends/agent/api_server/keepalived.py +26 -53
  4. octavia/amphorae/backends/agent/api_server/keepalivedlvs.py +44 -83
  5. octavia/amphorae/backends/agent/api_server/loadbalancer.py +94 -112
  6. octavia/amphorae/backends/agent/api_server/lvs_listener_base.py +1 -1
  7. octavia/amphorae/backends/agent/api_server/osutils.py +11 -8
  8. octavia/amphorae/backends/agent/api_server/plug.py +12 -13
  9. octavia/amphorae/backends/agent/api_server/server.py +4 -3
  10. octavia/amphorae/backends/agent/api_server/templates/keepalived_lvs_check_script.sh.j2 +0 -4
  11. octavia/amphorae/backends/agent/api_server/util.py +23 -68
  12. octavia/amphorae/backends/agent/templates/amphora_agent_conf.template +0 -3
  13. octavia/amphorae/backends/health_daemon/health_daemon.py +6 -7
  14. octavia/amphorae/backends/health_daemon/health_sender.py +2 -2
  15. octavia/amphorae/backends/utils/haproxy_query.py +3 -6
  16. octavia/amphorae/backends/utils/interface.py +11 -50
  17. octavia/amphorae/backends/utils/interface_file.py +29 -16
  18. octavia/amphorae/backends/utils/ip_advertisement.py +1 -1
  19. octavia/amphorae/backends/utils/keepalivedlvs_query.py +7 -8
  20. octavia/amphorae/backends/utils/network_namespace.py +3 -3
  21. octavia/amphorae/backends/utils/nftable_utils.py +33 -11
  22. octavia/amphorae/drivers/driver_base.py +2 -2
  23. octavia/amphorae/drivers/haproxy/rest_api_driver.py +26 -38
  24. octavia/amphorae/drivers/health/heartbeat_udp.py +1 -1
  25. octavia/amphorae/drivers/keepalived/jinja/jinja_cfg.py +1 -2
  26. octavia/amphorae/drivers/keepalived/jinja/templates/keepalived_base.template +0 -1
  27. octavia/amphorae/drivers/noop_driver/driver.py +1 -1
  28. octavia/api/app.py +1 -2
  29. octavia/api/common/pagination.py +16 -22
  30. octavia/api/common/types.py +1 -1
  31. octavia/api/drivers/amphora_driver/v2/driver.py +6 -6
  32. octavia/api/drivers/driver_agent/driver_listener.py +3 -3
  33. octavia/api/drivers/driver_agent/driver_updater.py +1 -1
  34. octavia/api/drivers/noop_driver/driver.py +1 -1
  35. octavia/api/root_controller.py +2 -2
  36. octavia/api/v2/controllers/base.py +2 -4
  37. octavia/api/v2/controllers/health_monitor.py +5 -3
  38. octavia/api/v2/controllers/listener.py +2 -2
  39. octavia/api/v2/controllers/load_balancer.py +7 -0
  40. octavia/api/v2/controllers/member.py +12 -2
  41. octavia/api/v2/types/amphora.py +1 -1
  42. octavia/api/v2/types/availability_zone_profile.py +1 -2
  43. octavia/api/v2/types/availability_zones.py +1 -2
  44. octavia/api/v2/types/flavor_profile.py +1 -1
  45. octavia/api/v2/types/flavors.py +1 -1
  46. octavia/api/v2/types/health_monitor.py +1 -1
  47. octavia/api/v2/types/l7policy.py +1 -1
  48. octavia/api/v2/types/l7rule.py +1 -1
  49. octavia/api/v2/types/listener.py +3 -3
  50. octavia/api/v2/types/load_balancer.py +3 -3
  51. octavia/api/v2/types/member.py +2 -2
  52. octavia/api/v2/types/pool.py +2 -2
  53. octavia/api/v2/types/quotas.py +2 -2
  54. octavia/certificates/common/barbican.py +1 -1
  55. octavia/certificates/common/cert.py +1 -1
  56. octavia/certificates/generator/cert_gen.py +1 -1
  57. octavia/certificates/generator/local.py +5 -5
  58. octavia/certificates/manager/cert_mgr.py +1 -1
  59. octavia/certificates/manager/local.py +20 -20
  60. octavia/cmd/agent.py +3 -3
  61. octavia/cmd/driver_agent.py +2 -3
  62. octavia/cmd/health_checker.py +4 -4
  63. octavia/cmd/interface.py +4 -4
  64. octavia/cmd/prometheus_proxy.py +11 -13
  65. octavia/common/base_taskflow.py +3 -3
  66. octavia/common/clients.py +4 -4
  67. octavia/common/config.py +18 -24
  68. octavia/common/constants.py +28 -35
  69. octavia/common/data_models.py +2 -2
  70. octavia/common/jinja/haproxy/combined_listeners/jinja_cfg.py +5 -5
  71. octavia/common/jinja/logging/logging_jinja_cfg.py +1 -1
  72. octavia/common/jinja/lvs/jinja_cfg.py +1 -1
  73. octavia/common/jinja/user_data_jinja_cfg.py +1 -1
  74. octavia/common/keystone.py +1 -1
  75. octavia/common/policy.py +2 -3
  76. octavia/common/stats.py +1 -1
  77. octavia/common/tls_utils/cert_parser.py +2 -1
  78. octavia/common/utils.py +3 -3
  79. octavia/common/validate.py +9 -13
  80. octavia/compute/compute_base.py +1 -1
  81. octavia/compute/drivers/noop_driver/driver.py +1 -1
  82. octavia/compute/drivers/nova_driver.py +1 -1
  83. octavia/controller/healthmanager/health_manager.py +1 -1
  84. octavia/controller/housekeeping/house_keeping.py +2 -2
  85. octavia/controller/queue/v2/consumer.py +1 -2
  86. octavia/controller/queue/v2/endpoints.py +1 -1
  87. octavia/controller/worker/amphora_rate_limit.py +6 -6
  88. octavia/controller/worker/task_utils.py +1 -1
  89. octavia/controller/worker/v2/controller_worker.py +3 -3
  90. octavia/controller/worker/v2/flows/amphora_flows.py +15 -4
  91. octavia/controller/worker/v2/flows/flow_utils.py +6 -5
  92. octavia/controller/worker/v2/flows/health_monitor_flows.py +1 -1
  93. octavia/controller/worker/v2/flows/l7policy_flows.py +1 -1
  94. octavia/controller/worker/v2/flows/l7rule_flows.py +1 -1
  95. octavia/controller/worker/v2/flows/listener_flows.py +18 -6
  96. octavia/controller/worker/v2/flows/load_balancer_flows.py +1 -1
  97. octavia/controller/worker/v2/flows/member_flows.py +12 -19
  98. octavia/controller/worker/v2/flows/pool_flows.py +1 -1
  99. octavia/controller/worker/v2/taskflow_jobboard_driver.py +17 -3
  100. octavia/controller/worker/v2/tasks/compute_tasks.py +1 -3
  101. octavia/controller/worker/v2/tasks/network_tasks.py +3 -4
  102. octavia/db/base_models.py +21 -9
  103. octavia/db/migration/alembic_migrations/versions/034756a182a2_amphora_add_image_id.py +2 -2
  104. octavia/db/migration/alembic_migrations/versions/034b2dc2f3e0_modernize_l7policy_fields.py +31 -31
  105. octavia/db/migration/alembic_migrations/versions/0f242cf02c74_add_provider_column.py +2 -2
  106. octavia/db/migration/alembic_migrations/versions/10d38216ad34_add_timestamps_to_amphora.py +4 -4
  107. octavia/db/migration/alembic_migrations/versions/11e4bb2bb8ef_fix_ipv6_vip.py +1 -1
  108. octavia/db/migration/alembic_migrations/versions/13500e2e978d_update_url_and_name_size.py +6 -6
  109. octavia/db/migration/alembic_migrations/versions/14892634e228_update_vip.py +5 -5
  110. octavia/db/migration/alembic_migrations/versions/186509101b9b_add_server_group_id_to_loadbalancer.py +2 -2
  111. octavia/db/migration/alembic_migrations/versions/1afc932f1ca2_l7rule_support_client_cert.py +3 -3
  112. octavia/db/migration/alembic_migrations/versions/1e4c1d83044c_keepalived_configuration_datamodel.py +26 -26
  113. octavia/db/migration/alembic_migrations/versions/2351ea316465_adding_terminate_https_tls_ref_support.py +4 -4
  114. octavia/db/migration/alembic_migrations/versions/256852d5ff7c_add_lb_network_ip_to_amphora.py +2 -2
  115. octavia/db/migration/alembic_migrations/versions/27e54d00c3cd_add_monitor_address_and_port_to_member.py +4 -4
  116. octavia/db/migration/alembic_migrations/versions/298eac0640a7_add_amphora_vrrp_port_id_and_ha_port_id.py +4 -4
  117. octavia/db/migration/alembic_migrations/versions/29ff921a6eb_shared_pools.py +3 -3
  118. octavia/db/migration/alembic_migrations/versions/2ad093f6353f_add_listener_client_ca_tls_certificate_.py +2 -2
  119. octavia/db/migration/alembic_migrations/versions/31f7653ded67_allow_multiple_vips_per_loadbalancer.py +10 -10
  120. octavia/db/migration/alembic_migrations/versions/32e5c35b26a8_add_l7policy_and_l7rule_quota.py +4 -4
  121. octavia/db/migration/alembic_migrations/versions/357d17a6d5ac_update_lb_and_amphora_data_model_for_.py +20 -20
  122. octavia/db/migration/alembic_migrations/versions/35dee79d5865_initial_create.py +185 -185
  123. octavia/db/migration/alembic_migrations/versions/36b94648fef8_add_timestamp.py +2 -2
  124. octavia/db/migration/alembic_migrations/versions/392fb85b4419_add_primary_key_to_spares_pool.py +1 -1
  125. octavia/db/migration/alembic_migrations/versions/3a1e1cdb7b27_rename_amphora_host_id.py +1 -1
  126. octavia/db/migration/alembic_migrations/versions/3b199c848b96_create_no_monitor_operational_status.py +1 -1
  127. octavia/db/migration/alembic_migrations/versions/3e5b37a0bdb9_add_vrrp_ip_and_ha_ip_to_amphora.py +4 -4
  128. octavia/db/migration/alembic_migrations/versions/3f8ff3be828e_create_quotas_table.py +12 -12
  129. octavia/db/migration/alembic_migrations/versions/43287cd10fef_make_pool_lb_algorithm_larger.py +6 -6
  130. octavia/db/migration/alembic_migrations/versions/443fe6676637_add_network_id_to_vip.py +2 -2
  131. octavia/db/migration/alembic_migrations/versions/44a2414dd683_adding_name_column_to_member_and_health_.py +1 -1
  132. octavia/db/migration/alembic_migrations/versions/458c9ee2a011_l7_policies_and_rules.py +57 -57
  133. octavia/db/migration/alembic_migrations/versions/46d914b2a5e5_seed_the_spares_pool_table.py +2 -2
  134. octavia/db/migration/alembic_migrations/versions/48660b6643f0_add_new_states_for_amphora.py +3 -3
  135. octavia/db/migration/alembic_migrations/versions/4aeb9e23ad43_add_draining_operating_status.py +1 -1
  136. octavia/db/migration/alembic_migrations/versions/4c094013699a_update_load_balancer_amphora.py +9 -9
  137. octavia/db/migration/alembic_migrations/versions/4f65b4f91c39_amphora_add_flavor_id.py +2 -2
  138. octavia/db/migration/alembic_migrations/versions/4faaa983e7a9_update_member_address_column.py +1 -1
  139. octavia/db/migration/alembic_migrations/versions/4fe8240425b4_update_vip_add_subnet_id.py +2 -2
  140. octavia/db/migration/alembic_migrations/versions/52377704420e_add_timestamps_to_healthmonitor.py +9 -9
  141. octavia/db/migration/alembic_migrations/versions/5309960964f8_add_proxy_protocol_for_pool.py +3 -3
  142. octavia/db/migration/alembic_migrations/versions/543f5d8e4e56_add_a_column_busy_in_table_amphora_health.py +2 -2
  143. octavia/db/migration/alembic_migrations/versions/55874a4ceed6_add_l7policy_action_redirect_prefix.py +5 -5
  144. octavia/db/migration/alembic_migrations/versions/5a3ee5472c31_add_cert_expiration__infor_in_amphora_table.py +4 -4
  145. octavia/db/migration/alembic_migrations/versions/62816c232310_fix_migration_for_mysql_5_7.py +1 -1
  146. octavia/db/migration/alembic_migrations/versions/6742ca1b27c2_add_l7policy_redirect_http_code.py +2 -2
  147. octavia/db/migration/alembic_migrations/versions/6ac558d7fc21_add_prometheus_listener_protocol.py +3 -3
  148. octavia/db/migration/alembic_migrations/versions/6ffc710674ef_spares_pool_table.py +2 -2
  149. octavia/db/migration/alembic_migrations/versions/7432f1d4ea83_add_http_host_head_inject_for_http_health_check.py +4 -4
  150. octavia/db/migration/alembic_migrations/versions/74aae261694c_extend_pool_for_backend_ca_and_crl.py +4 -4
  151. octavia/db/migration/alembic_migrations/versions/76aacf2e176c_extend_support_udp_protocol.py +3 -3
  152. octavia/db/migration/alembic_migrations/versions/80dba23a159f_tags_support.py +3 -3
  153. octavia/db/migration/alembic_migrations/versions/82b9402e71fd_update_vip_address_size.py +1 -1
  154. octavia/db/migration/alembic_migrations/versions/8ac4ed24df3a_add_availability_zone_to_lb.py +4 -4
  155. octavia/db/migration/alembic_migrations/versions/8b47b2546312_sctp_support.py +2 -2
  156. octavia/db/migration/alembic_migrations/versions/8c0851bdf6c3_change_tls_container_id_length_in_sni_.py +1 -1
  157. octavia/db/migration/alembic_migrations/versions/92fe9857279_create_healthmanager_table.py +3 -3
  158. octavia/db/migration/alembic_migrations/versions/9b5473976d6d_add_provisioning_status_to_objects.py +10 -10
  159. octavia/db/migration/alembic_migrations/versions/a1f689aecc1d_extend_pool_for_support_backend_reencryption.py +2 -2
  160. octavia/db/migration/alembic_migrations/versions/a7f187cd221f_add_tls_boolean_type_for_reencryption.py +2 -2
  161. octavia/db/migration/alembic_migrations/versions/b9c703669314_add_flavor_and_flavor_profile_table.py +18 -18
  162. octavia/db/migration/alembic_migrations/versions/ba35e0fb88e1_add_backup_field_to_member.py +2 -2
  163. octavia/db/migration/alembic_migrations/versions/bf171d0d91c3_amphora_add_cached_zone.py +2 -2
  164. octavia/db/migration/alembic_migrations/versions/c761c8a71579_add_availability_zone_table.py +15 -15
  165. octavia/db/migration/alembic_migrations/versions/d85ca7258d21_modernize_l7rule.py +13 -13
  166. octavia/db/migration/alembic_migrations/versions/da371b422669_allowed_cidr_for_listeners.py +7 -7
  167. octavia/db/migration/alembic_migrations/versions/dcf88e59aae4_add_lb_algorithm_source_ip_port.py +3 -3
  168. octavia/db/migration/alembic_migrations/versions/e37941b010db_add_lb_flavor_constraint.py +11 -11
  169. octavia/db/migration/alembic_migrations/versions/e6672bda93bf_add_ping_and_tlshello_monitor_types.py +3 -3
  170. octavia/db/migration/alembic_migrations/versions/e6ee84f0abf3_add_proxy_v2_pool_protocol.py +3 -3
  171. octavia/db/migration/alembic_migrations/versions/ebbcc72b4e5e_add_octavia_owned_vip_column_to_vip_.py +2 -2
  172. octavia/db/migration/alembic_migrations/versions/f21ae3f21adc_add_client_auth_option.py +6 -6
  173. octavia/db/migration/alembic_migrations/versions/fc5582da7d8a_create_amphora_build_rate_limit_tables.py +11 -11
  174. octavia/db/migration/alembic_migrations/versions/ffad172e98c1_add_certificate_revoke_list_option.py +2 -2
  175. octavia/db/models.py +1 -1
  176. octavia/db/repositories.py +3 -3
  177. octavia/distributor/drivers/driver_base.py +1 -1
  178. octavia/distributor/drivers/noop_driver/driver.py +1 -1
  179. octavia/hacking/checks.py +4 -4
  180. octavia/image/drivers/noop_driver/driver.py +1 -1
  181. octavia/image/image_base.py +1 -1
  182. octavia/network/base.py +1 -1
  183. octavia/network/drivers/neutron/allowed_address_pairs.py +11 -9
  184. octavia/network/drivers/neutron/base.py +3 -3
  185. octavia/network/drivers/noop_driver/driver.py +1 -1
  186. octavia/policies/amphora.py +6 -12
  187. octavia/policies/availability_zone.py +5 -10
  188. octavia/policies/availability_zone_profile.py +5 -15
  189. octavia/policies/base.py +1 -20
  190. octavia/policies/flavor.py +5 -10
  191. octavia/policies/flavor_profile.py +5 -10
  192. octavia/policies/healthmonitor.py +6 -12
  193. octavia/policies/l7policy.py +6 -12
  194. octavia/policies/l7rule.py +5 -10
  195. octavia/policies/listener.py +7 -14
  196. octavia/policies/loadbalancer.py +9 -18
  197. octavia/policies/member.py +5 -10
  198. octavia/policies/pool.py +6 -12
  199. octavia/policies/provider.py +1 -2
  200. octavia/policies/provider_availability_zone.py +1 -3
  201. octavia/policies/provider_flavor.py +1 -2
  202. octavia/policies/quota.py +6 -12
  203. octavia/statistics/stats_base.py +1 -1
  204. octavia/tests/common/constants.py +1 -1
  205. octavia/tests/common/data_model_helpers.py +10 -10
  206. octavia/tests/common/sample_data_models.py +1 -1
  207. octavia/tests/common/sample_haproxy_prometheus +17 -17
  208. octavia/tests/common/sample_octavia_prometheus +6 -6
  209. octavia/tests/common/utils.py +2 -2
  210. octavia/tests/functional/amphorae/backend/agent/api_server/test_keepalivedlvs.py +36 -62
  211. octavia/tests/functional/amphorae/backend/agent/api_server/test_server.py +135 -296
  212. octavia/tests/functional/api/drivers/driver_agent/test_driver_agent.py +10 -11
  213. octavia/tests/functional/api/v2/base.py +2 -3
  214. octavia/tests/functional/api/v2/test_amphora.py +6 -6
  215. octavia/tests/functional/api/v2/test_availability_zone_profiles.py +13 -14
  216. octavia/tests/functional/api/v2/test_availability_zones.py +19 -19
  217. octavia/tests/functional/api/v2/test_flavor_profiles.py +19 -20
  218. octavia/tests/functional/api/v2/test_flavors.py +25 -25
  219. octavia/tests/functional/api/v2/test_health_monitor.py +35 -18
  220. octavia/tests/functional/api/v2/test_l7policy.py +11 -11
  221. octavia/tests/functional/api/v2/test_l7rule.py +19 -20
  222. octavia/tests/functional/api/v2/test_listener.py +26 -28
  223. octavia/tests/functional/api/v2/test_load_balancer.py +17 -17
  224. octavia/tests/functional/api/v2/test_member.py +53 -21
  225. octavia/tests/functional/api/v2/test_pool.py +11 -11
  226. octavia/tests/functional/api/v2/test_provider.py +7 -7
  227. octavia/tests/functional/api/v2/test_quotas.py +9 -9
  228. octavia/tests/functional/db/test_models.py +1 -1
  229. octavia/tests/functional/db/test_repositories.py +2 -2
  230. octavia/tests/unit/amphorae/backends/agent/api_server/test_amphora_info.py +60 -61
  231. octavia/tests/unit/amphorae/backends/agent/api_server/test_keepalived.py +3 -3
  232. octavia/tests/unit/amphorae/backends/agent/api_server/test_keepalivedlvs.py +1 -19
  233. octavia/tests/unit/amphorae/backends/agent/api_server/test_loadbalancer.py +94 -34
  234. octavia/tests/unit/amphorae/backends/agent/api_server/test_osutils.py +19 -21
  235. octavia/tests/unit/amphorae/backends/agent/api_server/test_plug.py +9 -11
  236. octavia/tests/unit/amphorae/backends/agent/api_server/test_util.py +11 -25
  237. octavia/tests/unit/amphorae/backends/agent/test_agent_jinja_cfg.py +0 -13
  238. octavia/tests/unit/amphorae/backends/health_daemon/test_health_daemon.py +10 -10
  239. octavia/tests/unit/amphorae/backends/utils/test_haproxy_query.py +1 -1
  240. octavia/tests/unit/amphorae/backends/utils/test_interface.py +33 -94
  241. octavia/tests/unit/amphorae/backends/utils/test_interface_file.py +32 -32
  242. octavia/tests/unit/amphorae/backends/utils/test_network_namespace.py +4 -6
  243. octavia/tests/unit/amphorae/backends/utils/test_nftable_utils.py +28 -22
  244. octavia/tests/unit/amphorae/drivers/haproxy/test_rest_api_driver_1_0.py +77 -118
  245. octavia/tests/unit/amphorae/drivers/health/test_heartbeat_udp.py +8 -8
  246. octavia/tests/unit/amphorae/drivers/keepalived/jinja/test_jinja_cfg.py +0 -4
  247. octavia/tests/unit/api/common/test_pagination.py +84 -14
  248. octavia/tests/unit/api/v2/types/test_availability_zone_profile.py +1 -1
  249. octavia/tests/unit/api/v2/types/test_availability_zones.py +1 -1
  250. octavia/tests/unit/api/v2/types/test_flavor_profile.py +1 -1
  251. octavia/tests/unit/api/v2/types/test_flavors.py +1 -1
  252. octavia/tests/unit/api/v2/types/test_health_monitor.py +1 -1
  253. octavia/tests/unit/api/v2/types/test_listener.py +1 -1
  254. octavia/tests/unit/api/v2/types/test_load_balancer.py +1 -1
  255. octavia/tests/unit/api/v2/types/test_pool.py +1 -1
  256. octavia/tests/unit/base.py +1 -0
  257. octavia/tests/unit/certificates/generator/local_csr.py +1 -1
  258. octavia/tests/unit/certificates/generator/test_local.py +5 -5
  259. octavia/tests/unit/certificates/manager/test_barbican.py +2 -3
  260. octavia/tests/unit/certificates/manager/test_barbican_legacy.py +1 -1
  261. octavia/tests/unit/certificates/manager/test_local.py +13 -14
  262. octavia/tests/unit/cmd/test_health_checker.py +1 -1
  263. octavia/tests/unit/cmd/test_prometheus_proxy.py +8 -1
  264. octavia/tests/unit/common/jinja/haproxy/combined_listeners/test_jinja_cfg.py +171 -216
  265. octavia/tests/unit/common/jinja/logging/test_logging_jinja_cfg.py +1 -1
  266. octavia/tests/unit/common/sample_configs/sample_configs_combined.py +1 -2
  267. octavia/tests/unit/common/test_base_taskflow.py +1 -1
  268. octavia/tests/unit/common/test_decorators.py +2 -2
  269. octavia/tests/unit/common/test_policy.py +3 -6
  270. octavia/tests/unit/common/tls_utils/test_cert_parser.py +4 -1
  271. octavia/tests/unit/controller/worker/v2/flows/test_listener_flows.py +10 -15
  272. octavia/tests/unit/controller/worker/v2/flows/test_load_balancer_flows.py +4 -6
  273. octavia/tests/unit/controller/worker/v2/tasks/test_network_tasks.py +6 -2
  274. octavia/tests/unit/controller/worker/v2/tasks/test_retry_tasks.py +1 -1
  275. octavia/tests/unit/controller/worker/v2/test_controller_worker.py +56 -1
  276. octavia/tests/unit/controller/worker/v2/test_taskflow_jobboard_driver.py +348 -0
  277. octavia/tests/unit/hacking/test_checks.py +3 -3
  278. octavia/tests/unit/image/drivers/noop_driver/test_driver.py +1 -1
  279. octavia/tests/unit/image/drivers/test_glance_driver.py +1 -1
  280. octavia/tests/unit/network/drivers/neutron/test_base.py +1 -1
  281. octavia/tests/unit/statistics/drivers/test_update_db.py +1 -1
  282. octavia/tests/unit/statistics/test_stats_base.py +1 -1
  283. octavia/volume/drivers/noop_driver/driver.py +1 -1
  284. octavia/volume/volume_base.py +1 -1
  285. {octavia-14.0.0.0rc1.dist-info → octavia-15.0.0.dist-info}/AUTHORS +6 -0
  286. {octavia-14.0.0.0rc1.dist-info → octavia-15.0.0.dist-info}/METADATA +3 -5
  287. {octavia-14.0.0.0rc1.dist-info → octavia-15.0.0.dist-info}/RECORD +302 -305
  288. octavia-15.0.0.dist-info/pbr.json +1 -0
  289. octavia/amphorae/backends/agent/api_server/templates/keepalived.sysvinit.j2 +0 -87
  290. octavia/amphorae/backends/agent/api_server/templates/keepalived.upstart.j2 +0 -29
  291. octavia/amphorae/backends/agent/api_server/templates/sysvinit.conf.j2 +0 -232
  292. octavia/amphorae/backends/agent/api_server/templates/upstart.conf.j2 +0 -71
  293. octavia-14.0.0.0rc1.dist-info/pbr.json +0 -1
  294. {octavia-14.0.0.0rc1.data → octavia-15.0.0.data}/data/share/octavia/LICENSE +0 -0
  295. {octavia-14.0.0.0rc1.data → octavia-15.0.0.data}/data/share/octavia/README.rst +0 -0
  296. {octavia-14.0.0.0rc1.data → octavia-15.0.0.data}/data/share/octavia/diskimage-create/README.rst +0 -0
  297. {octavia-14.0.0.0rc1.data → octavia-15.0.0.data}/data/share/octavia/diskimage-create/diskimage-create.sh +0 -0
  298. {octavia-14.0.0.0rc1.data → octavia-15.0.0.data}/data/share/octavia/diskimage-create/image-tests.sh +0 -0
  299. {octavia-14.0.0.0rc1.data → octavia-15.0.0.data}/data/share/octavia/diskimage-create/requirements.txt +0 -0
  300. {octavia-14.0.0.0rc1.data → octavia-15.0.0.data}/data/share/octavia/diskimage-create/test-requirements.txt +0 -0
  301. {octavia-14.0.0.0rc1.data → octavia-15.0.0.data}/data/share/octavia/diskimage-create/tox.ini +0 -0
  302. {octavia-14.0.0.0rc1.data → octavia-15.0.0.data}/data/share/octavia/diskimage-create/version.txt +0 -0
  303. {octavia-14.0.0.0rc1.data → octavia-15.0.0.data}/scripts/octavia-wsgi +0 -0
  304. {octavia-14.0.0.0rc1.dist-info → octavia-15.0.0.dist-info}/LICENSE +0 -0
  305. {octavia-14.0.0.0rc1.dist-info → octavia-15.0.0.dist-info}/WHEEL +0 -0
  306. {octavia-14.0.0.0rc1.dist-info → octavia-15.0.0.dist-info}/entry_points.txt +0 -0
  307. {octavia-14.0.0.0rc1.dist-info → octavia-15.0.0.dist-info}/top_level.txt +0 -0
@@ -26,16 +26,26 @@ from octavia.common import utils
26
26
  LOG = logging.getLogger(__name__)
27
27
 
28
28
 
29
- def write_nftable_vip_rules_file(interface_name, rules):
29
+ def write_nftable_rules_file(interface_name, rules):
30
30
  flags = os.O_WRONLY | os.O_CREAT | os.O_TRUNC
31
31
  # mode 00600
32
32
  mode = stat.S_IRUSR | stat.S_IWUSR
33
33
 
34
34
  # Create some strings shared on both code paths
35
- table_string = f'table {consts.NFT_FAMILY} {consts.NFT_VIP_TABLE} {{\n'
36
- chain_string = f' chain {consts.NFT_VIP_CHAIN} {{\n'
37
- hook_string = (f' type filter hook ingress device {interface_name} '
38
- f'priority {consts.NFT_SRIOV_PRIORITY}; policy drop;\n')
35
+ table_string = f'table {consts.NFT_FAMILY} {consts.NFT_TABLE} {{\n'
36
+ chain_string = f' chain {consts.NFT_CHAIN} {{\n'
37
+ vip_chain_string = f' chain {consts.NFT_VIP_CHAIN} {{\n'
38
+ hook_string = (' type filter hook input priority filter; '
39
+ 'policy drop;\n')
40
+
41
+ # Conntrack is used to allow flow return traffic
42
+ conntrack_string = (' ct state vmap { established : accept, '
43
+ 'related : accept, invalid : drop }\n')
44
+
45
+ # Allow loopback traffic on the loopback interface, no where else
46
+ loopback_string = ' iif lo accept\n'
47
+ loopback_addr_string = ' ip saddr 127.0.0.0/8 drop\n'
48
+ loopback_ipv6_addr_string = ' ip6 saddr ::1 drop\n'
39
49
 
40
50
  # Allow ICMP destination unreachable for PMTUD
41
51
  icmp_string = ' icmp type destination-unreachable accept\n'
@@ -47,38 +57,50 @@ def write_nftable_vip_rules_file(interface_name, rules):
47
57
  dhcp_string = ' udp sport 67 udp dport 68 accept\n'
48
58
  dhcpv6_string = ' udp sport 547 udp dport 546 accept\n'
49
59
 
60
+ # If the packet came in on the VIP interface, goto the VIP rules chain
61
+ vip_interface_goto_string = (
62
+ f' iifname {consts.NETNS_PRIMARY_INTERFACE} '
63
+ f'goto {consts.NFT_VIP_CHAIN}\n')
64
+
50
65
  # Check if an existing rules file exists or we be need to create an
51
66
  # "drop all" file with no rules except for VRRP. If it exists, we should
52
67
  # not overwrite it here as it could be a reboot unless we were passed new
53
68
  # rules.
54
- if os.path.isfile(consts.NFT_VIP_RULES_FILE):
69
+ if os.path.isfile(consts.NFT_RULES_FILE):
55
70
  if not rules:
56
71
  return
57
72
  with os.fdopen(
58
- os.open(consts.NFT_VIP_RULES_FILE, flags, mode), 'w') as file:
73
+ os.open(consts.NFT_RULES_FILE, flags, mode), 'w') as file:
59
74
  # Clear the existing rules in the kernel
60
75
  # Note: The "nft -f" method is atomic, so clearing the rules will
61
76
  # not leave the amphora exposed.
62
77
  # Create and delete the table to not get errors if the table does
63
78
  # not exist yet.
64
- file.write(f'table {consts.NFT_FAMILY} {consts.NFT_VIP_TABLE} '
79
+ file.write(f'table {consts.NFT_FAMILY} {consts.NFT_TABLE} '
65
80
  '{}\n')
66
81
  file.write(f'delete table {consts.NFT_FAMILY} '
67
- f'{consts.NFT_VIP_TABLE}\n')
82
+ f'{consts.NFT_TABLE}\n')
68
83
  file.write(table_string)
69
84
  file.write(chain_string)
70
85
  file.write(hook_string)
86
+ file.write(conntrack_string)
87
+ file.write(loopback_string)
88
+ file.write(loopback_addr_string)
89
+ file.write(loopback_ipv6_addr_string)
71
90
  file.write(icmp_string)
72
91
  file.write(icmpv6_string)
73
92
  file.write(dhcp_string)
74
93
  file.write(dhcpv6_string)
94
+ file.write(vip_interface_goto_string)
95
+ file.write(' }\n') # close the chain
96
+ file.write(vip_chain_string)
75
97
  for rule in rules:
76
98
  file.write(f' {_build_rule_cmd(rule)}\n')
77
99
  file.write(' }\n') # close the chain
78
100
  file.write('}\n') # close the table
79
101
  else: # No existing rules, create the "drop all" base rules
80
102
  with os.fdopen(
81
- os.open(consts.NFT_VIP_RULES_FILE, flags, mode), 'w') as file:
103
+ os.open(consts.NFT_RULES_FILE, flags, mode), 'w') as file:
82
104
  file.write(table_string)
83
105
  file.write(chain_string)
84
106
  file.write(hook_string)
@@ -113,7 +135,7 @@ def _build_rule_cmd(rule):
113
135
 
114
136
 
115
137
  def load_nftables_file():
116
- cmd = [consts.NFT_CMD, '-o', '-f', consts.NFT_VIP_RULES_FILE]
138
+ cmd = [consts.NFT_CMD, '-o', '-f', consts.NFT_RULES_FILE]
117
139
  try:
118
140
  with network_namespace.NetworkNamespace(consts.AMPHORA_NAMESPACE):
119
141
  subprocess.check_output(cmd, stderr=subprocess.STDOUT)
@@ -19,7 +19,7 @@ from typing import Optional
19
19
  from octavia.db import models as db_models
20
20
 
21
21
 
22
- class AmphoraLoadBalancerDriver(object, metaclass=abc.ABCMeta):
22
+ class AmphoraLoadBalancerDriver(metaclass=abc.ABCMeta):
23
23
  @abc.abstractmethod
24
24
  def update_amphora_listeners(self, loadbalancer, amphora,
25
25
  timeout_dict):
@@ -264,7 +264,7 @@ class AmphoraLoadBalancerDriver(object, metaclass=abc.ABCMeta):
264
264
  """
265
265
 
266
266
 
267
- class VRRPDriverMixin(object, metaclass=abc.ABCMeta):
267
+ class VRRPDriverMixin(metaclass=abc.ABCMeta):
268
268
  """Abstract mixin class for VRRP support in loadbalancer amphorae
269
269
 
270
270
  Usage: To plug VRRP support in another service driver XYZ, use:
@@ -14,6 +14,7 @@
14
14
  # under the License.
15
15
  import functools
16
16
  import hashlib
17
+ import json
17
18
  import os
18
19
  import ssl
19
20
  import time
@@ -24,7 +25,6 @@ from oslo_context import context as oslo_context
24
25
  from oslo_log import log as logging
25
26
  from oslo_utils.secretutils import md5
26
27
  import requests
27
- import simplejson
28
28
  from stevedore import driver as stevedore_driver
29
29
 
30
30
  from octavia.amphorae.driver_exceptions import exceptions as driver_except
@@ -308,7 +308,7 @@ class HaproxyAmphoraLoadBalancerDriver(
308
308
  for cert_id in certs_to_delete:
309
309
  self.clients[amphora.api_version].delete_cert_pem(
310
310
  amphora, listener.load_balancer.id,
311
- '{id}.pem'.format(id=cert_id))
311
+ f'{cert_id}.pem')
312
312
 
313
313
  # See how many non-UDP/SCTP listeners we have left
314
314
  non_lvs_listener_count = len([
@@ -451,7 +451,7 @@ class HaproxyAmphoraLoadBalancerDriver(
451
451
  for cert in certs:
452
452
  pem = cert_parser.build_pem(cert)
453
453
  md5sum = md5(pem, usedforsecurity=False).hexdigest() # nosec
454
- name = '{id}.pem'.format(id=cert.id)
454
+ name = f'{cert.id}.pem'
455
455
  cert_filename_list.append(
456
456
  os.path.join(
457
457
  CONF.haproxy_amphora.base_cert_dir, obj_id, name))
@@ -460,10 +460,10 @@ class HaproxyAmphoraLoadBalancerDriver(
460
460
  if certs:
461
461
  # Build and upload the crt-list file for haproxy
462
462
  crt_list = "\n".join(cert_filename_list)
463
- crt_list = f'{crt_list}\n'.encode('utf-8')
463
+ crt_list = f'{crt_list}\n'.encode()
464
464
  md5sum = md5(crt_list,
465
465
  usedforsecurity=False).hexdigest() # nosec
466
- name = '{id}.pem'.format(id=listener.id)
466
+ name = f'{listener.id}.pem'
467
467
  self._upload_cert(amphora, obj_id, crt_list, md5sum, name)
468
468
  return {'tls_cert': tls_cert, 'sni_certs': sni_certs}
469
469
 
@@ -482,7 +482,7 @@ class HaproxyAmphoraLoadBalancerDriver(
482
482
  pass
483
483
  md5sum = md5(secret, usedforsecurity=False).hexdigest() # nosec
484
484
  id = hashlib.sha1(secret).hexdigest() # nosec
485
- name = '{id}.pem'.format(id=id)
485
+ name = f'{id}.pem'
486
486
 
487
487
  if amphora and obj_id:
488
488
  self._upload_cert(
@@ -520,7 +520,7 @@ class HaproxyAmphoraLoadBalancerDriver(
520
520
  except AttributeError:
521
521
  pass
522
522
  md5sum = md5(pem, usedforsecurity=False).hexdigest() # nosec
523
- name = '{id}.pem'.format(id=tls_cert.id)
523
+ name = f'{tls_cert.id}.pem'
524
524
  if amphora and obj_id:
525
525
  self._upload_cert(amphora, obj_id, pem=pem,
526
526
  md5sum=md5sum, name=name)
@@ -625,11 +625,11 @@ class CustomHostNameCheckingAdapter(requests.adapters.HTTPAdapter):
625
625
 
626
626
  def init_poolmanager(self, *pool_args, **pool_kwargs):
627
627
  proto = CONF.amphora_agent.agent_tls_protocol.replace('.', '_')
628
- pool_kwargs['ssl_version'] = getattr(ssl, "PROTOCOL_%s" % proto)
628
+ pool_kwargs['ssl_version'] = getattr(ssl, f"PROTOCOL_{proto}")
629
629
  return super().init_poolmanager(*pool_args, **pool_kwargs)
630
630
 
631
631
 
632
- class AmphoraAPIClientBase(object):
632
+ class AmphoraAPIClientBase:
633
633
  def __init__(self):
634
634
  super().__init__()
635
635
 
@@ -646,19 +646,13 @@ class AmphoraAPIClientBase(object):
646
646
 
647
647
  def _base_url(self, ip, api_version=None):
648
648
  if utils.is_ipv6_lla(ip):
649
- ip = '[{ip}%{interface}]'.format(
650
- ip=ip,
651
- interface=CONF.haproxy_amphora.lb_network_interface)
649
+ ip = f'[{ip}%{CONF.haproxy_amphora.lb_network_interface}]'
652
650
  elif utils.is_ipv6(ip):
653
- ip = '[{ip}]'.format(ip=ip)
651
+ ip = f'[{ip}]'
654
652
  if api_version:
655
- return "https://{ip}:{port}/{version}/".format(
656
- ip=ip,
657
- port=CONF.haproxy_amphora.bind_port,
658
- version=api_version)
659
- return "https://{ip}:{port}/".format(
660
- ip=ip,
661
- port=CONF.haproxy_amphora.bind_port)
653
+ return (f"https://{ip}:{CONF.haproxy_amphora.bind_port}"
654
+ f"/{api_version}/")
655
+ return f"https://{ip}:{CONF.haproxy_amphora.bind_port}/"
662
656
 
663
657
  def request(self, method: str, amp: db_models.Amphora, path: str = '/',
664
658
  timeout_dict: Optional[dict] = None,
@@ -723,7 +717,7 @@ class AmphoraAPIClientBase(object):
723
717
  if 'No suitable network interface found' in json_data:
724
718
  LOG.debug("Amphora network interface not found.")
725
719
  raise requests.ConnectionError
726
- except simplejson.JSONDecodeError: # if r.json() fails
720
+ except json.JSONDecodeError: # if r.json() fails
727
721
  pass # TODO(rm_work) Should we do something?
728
722
  return r
729
723
  except (requests.ConnectionError, requests.Timeout) as e:
@@ -774,31 +768,28 @@ class AmphoraAPIClient1_0(AmphoraAPIClientBase):
774
768
  def upload_config(self, amp, loadbalancer_id, config, timeout_dict=None):
775
769
  r = self.put(
776
770
  amp,
777
- 'loadbalancer/{amphora_id}/{loadbalancer_id}/haproxy'.format(
778
- amphora_id=amp.id, loadbalancer_id=loadbalancer_id),
771
+ f'loadbalancer/{amp.id}/{loadbalancer_id}/haproxy',
779
772
  timeout_dict, data=config)
780
773
  return exc.check_exception(r)
781
774
 
782
775
  def get_listener_status(self, amp, listener_id):
783
776
  r = self.get(
784
777
  amp,
785
- 'listeners/{listener_id}'.format(listener_id=listener_id))
778
+ f'listeners/{listener_id}')
786
779
  if exc.check_exception(r):
787
780
  return r.json()
788
781
  return None
789
782
 
790
783
  def _action(self, action, amp, object_id, timeout_dict=None):
791
784
  r = self.put(
792
- amp, 'loadbalancer/{object_id}/{action}'.format(
793
- object_id=object_id, action=action),
785
+ amp, f'loadbalancer/{object_id}/{action}',
794
786
  timeout_dict=timeout_dict)
795
787
  return exc.check_exception(r)
796
788
 
797
789
  def upload_cert_pem(self, amp, loadbalancer_id, pem_filename, pem_file):
798
790
  r = self.put(
799
791
  amp,
800
- 'loadbalancer/{loadbalancer_id}/certificates/{filename}'.format(
801
- loadbalancer_id=loadbalancer_id, filename=pem_filename),
792
+ f'loadbalancer/{loadbalancer_id}/certificates/{pem_filename}',
802
793
  data=pem_file)
803
794
  return exc.check_exception(r)
804
795
 
@@ -806,8 +797,7 @@ class AmphoraAPIClient1_0(AmphoraAPIClientBase):
806
797
  ignore=tuple()):
807
798
  r = self.get(
808
799
  amp,
809
- 'loadbalancer/{loadbalancer_id}/certificates/{filename}'.format(
810
- loadbalancer_id=loadbalancer_id, filename=pem_filename))
800
+ f'loadbalancer/{loadbalancer_id}/certificates/{pem_filename}')
811
801
  if exc.check_exception(r, ignore):
812
802
  return r.json().get("md5sum")
813
803
  return None
@@ -815,8 +805,7 @@ class AmphoraAPIClient1_0(AmphoraAPIClientBase):
815
805
  def delete_cert_pem(self, amp, loadbalancer_id, pem_filename):
816
806
  r = self.delete(
817
807
  amp,
818
- 'loadbalancer/{loadbalancer_id}/certificates/{filename}'.format(
819
- loadbalancer_id=loadbalancer_id, filename=pem_filename))
808
+ f'loadbalancer/{loadbalancer_id}/certificates/{pem_filename}')
820
809
  return exc.check_exception(r, (404,))
821
810
 
822
811
  def update_cert_for_rotation(self, amp, pem_file):
@@ -825,7 +814,7 @@ class AmphoraAPIClient1_0(AmphoraAPIClientBase):
825
814
 
826
815
  def delete_listener(self, amp, object_id):
827
816
  r = self.delete(
828
- amp, 'listeners/{object_id}'.format(object_id=object_id))
817
+ amp, f'listeners/{object_id}')
829
818
  return exc.check_exception(r, (404,))
830
819
 
831
820
  def get_info(self, amp, raise_retry_exception=False,
@@ -855,7 +844,7 @@ class AmphoraAPIClient1_0(AmphoraAPIClientBase):
855
844
 
856
845
  def plug_vip(self, amp, vip, net_info):
857
846
  r = self.post(amp,
858
- 'plug/vip/{vip}'.format(vip=vip),
847
+ f'plug/vip/{vip}',
859
848
  json=net_info)
860
849
  return exc.check_exception(r)
861
850
 
@@ -864,12 +853,12 @@ class AmphoraAPIClient1_0(AmphoraAPIClientBase):
864
853
  return exc.check_exception(r)
865
854
 
866
855
  def _vrrp_action(self, action, amp, timeout_dict=None):
867
- r = self.put(amp, 'vrrp/{action}'.format(action=action),
856
+ r = self.put(amp, f'vrrp/{action}',
868
857
  timeout_dict=timeout_dict)
869
858
  return exc.check_exception(r)
870
859
 
871
860
  def get_interface(self, amp, ip_addr, timeout_dict=None, log_error=True):
872
- r = self.get(amp, 'interface/{ip_addr}'.format(ip_addr=ip_addr),
861
+ r = self.get(amp, f'interface/{ip_addr}',
873
862
  timeout_dict=timeout_dict)
874
863
  return exc.check_exception(r, log_error=log_error).json()
875
864
 
@@ -877,8 +866,7 @@ class AmphoraAPIClient1_0(AmphoraAPIClientBase):
877
866
  def upload_udp_config(self, amp, listener_id, config, timeout_dict=None):
878
867
  r = self.put(
879
868
  amp,
880
- 'listeners/{amphora_id}/{listener_id}/udp_listener'.format(
881
- amphora_id=amp.id, listener_id=listener_id), timeout_dict,
869
+ f'listeners/{amp.id}/{listener_id}/udp_listener', timeout_dict,
882
870
  data=config)
883
871
  return exc.check_exception(r)
884
872
 
@@ -37,7 +37,7 @@ CONF = cfg.CONF
37
37
  LOG = logging.getLogger(__name__)
38
38
 
39
39
 
40
- class UDPStatusGetter(object):
40
+ class UDPStatusGetter:
41
41
  """This class defines methods that will gather heartbeats
42
42
 
43
43
  The heartbeats are transmitted via UDP and this class will bind to a port
@@ -30,7 +30,7 @@ CONF = cfg.CONF
30
30
  LOG = logging.getLogger(__name__)
31
31
 
32
32
 
33
- class KeepalivedJinjaTemplater(object):
33
+ class KeepalivedJinjaTemplater:
34
34
 
35
35
  def __init__(self, keepalived_template=None):
36
36
  """Keepalived configuration generation
@@ -123,7 +123,6 @@ class KeepalivedJinjaTemplater(object):
123
123
  peers_ips.append(amp.vrrp_ip)
124
124
  return self.get_template(self.keepalived_template).render(
125
125
  {'vrrp_group_name': loadbalancer.vrrp_group.vrrp_group_name,
126
- 'amp_role': amphora.role,
127
126
  'amp_intf': amphora.vrrp_interface,
128
127
  'amp_vrrp_id': amphora.vrrp_id,
129
128
  'amp_priority': amphora.vrrp_priority,
@@ -21,7 +21,6 @@ vrrp_script check_script {
21
21
  }
22
22
 
23
23
  vrrp_instance {{ vrrp_group_name }} {
24
- state {{ amp_role }}
25
24
  interface {{ amp_intf }}
26
25
  virtual_router_id {{ amp_vrrp_id }}
27
26
  priority {{ amp_priority }}
@@ -23,7 +23,7 @@ from octavia.db import repositories
23
23
  LOG = logging.getLogger(__name__)
24
24
 
25
25
 
26
- class NoopManager(object):
26
+ class NoopManager:
27
27
 
28
28
  def __init__(self):
29
29
  super().__init__()
octavia/api/app.py CHANGED
@@ -80,8 +80,7 @@ def _wrap_app(app):
80
80
  audit_map_file=CONF.audit.audit_map_file,
81
81
  ignore_req_list=CONF.audit.ignore_req_list
82
82
  )
83
- except (EnvironmentError, OSError,
84
- audit_middleware.PycadfAuditApiConfigError) as e:
83
+ except (OSError, audit_middleware.PycadfAuditApiConfigError) as e:
85
84
  raise exceptions.InputFileError(
86
85
  file_name=CONF.audit.audit_map_file,
87
86
  reason=e
@@ -32,7 +32,7 @@ CONF = cfg.CONF
32
32
  LOG = logging.getLogger(__name__)
33
33
 
34
34
 
35
- class PaginationHelper(object):
35
+ class PaginationHelper:
36
36
  """Class helping to interact with pagination functionality
37
37
 
38
38
  Pass this class to `db.repositories` to apply it on query
@@ -142,40 +142,34 @@ class PaginationHelper(object):
142
142
 
143
143
  def _make_links(self, model_list):
144
144
  if CONF.api_settings.api_base_uri:
145
- path_url = "{api_base_url}{path}".format(
146
- api_base_url=CONF.api_settings.api_base_uri.rstrip('/'),
147
- path=request.path)
145
+ path_url = (f"{CONF.api_settings.api_base_uri.rstrip('/')}"
146
+ f"{request.path}")
148
147
  else:
149
148
  path_url = request.path_url
150
149
  links = []
151
150
  if model_list:
152
- prev_attr = ["limit={}".format(self.limit)]
151
+ prev_attr = [f"limit={self.limit}"]
153
152
  if self.params.get('sort'):
154
- prev_attr.append("sort={}".format(self.params.get('sort')))
153
+ prev_attr.append(f"sort={self.params.get('sort')}")
155
154
  if self.params.get('sort_key'):
156
- prev_attr.append("sort_key={}".format(
157
- self.params.get('sort_key')))
155
+ prev_attr.append(f"sort_key={self.params.get('sort_key')}")
158
156
  next_attr = copy.copy(prev_attr)
159
157
  if self.marker:
160
- prev_attr.append("marker={}".format(model_list[0].get('id')))
158
+ prev_attr.append(f"marker={model_list[0].get('id')}")
161
159
  prev_attr.append("page_reverse=True")
162
160
  prev_link = {
163
161
  "rel": "previous",
164
- "href": "{url}?{params}".format(
165
- url=path_url,
166
- params="&".join(prev_attr))
162
+ "href": f"{path_url}?{'&'.join(prev_attr)}"
167
163
  }
168
164
  links.append(prev_link)
169
165
  # TODO(rm_work) Do we need to know when there are more vs exact?
170
166
  # We safely know if we have a full page, but it might include the
171
167
  # last element or it might not, it is unclear
172
- if len(model_list) >= self.limit:
173
- next_attr.append("marker={}".format(model_list[-1].get('id')))
168
+ if self.limit is None or len(model_list) >= self.limit:
169
+ next_attr.append(f"marker={model_list[-1].get('id')}")
174
170
  next_link = {
175
171
  "rel": "next",
176
- "href": "{url}?{params}".format(
177
- url=path_url,
178
- params="&".join(next_attr))
172
+ "href": f"{path_url}?{'&'.join(next_attr)}"
179
173
  }
180
174
  links.append(next_link)
181
175
  links = [types.PageType(**link) for link in links]
@@ -361,7 +355,7 @@ class PaginationHelper(object):
361
355
  attr = sa_sql.expression.case(
362
356
  (model_attr.isnot(None), model_attr),
363
357
  else_=default)
364
- crit_attrs.append((attr == marker_values[j]))
358
+ crit_attrs.append(attr == marker_values[j])
365
359
 
366
360
  model_attr = getattr(model, self.sort_keys[i][0])
367
361
  default = PaginationHelper._get_default_column_value(
@@ -372,14 +366,14 @@ class PaginationHelper(object):
372
366
  this_sort_dir = self.sort_keys[i][1]
373
367
  if this_sort_dir == constants.DESC:
374
368
  if self.page_reverse == "True":
375
- crit_attrs.append((attr > marker_values[i]))
369
+ crit_attrs.append(attr > marker_values[i])
376
370
  else:
377
- crit_attrs.append((attr < marker_values[i]))
371
+ crit_attrs.append(attr < marker_values[i])
378
372
  elif this_sort_dir == constants.ASC:
379
373
  if self.page_reverse == "True":
380
- crit_attrs.append((attr < marker_values[i]))
374
+ crit_attrs.append(attr < marker_values[i])
381
375
  else:
382
- crit_attrs.append((attr > marker_values[i]))
376
+ crit_attrs.append(attr > marker_values[i])
383
377
  else:
384
378
  raise exceptions.InvalidSortDirection(
385
379
  key=this_sort_dir)
@@ -127,7 +127,7 @@ class BaseMeta(wtypes.BaseMeta):
127
127
  get_tenant_id, set_tenant_id)
128
128
  # This will let us know if tenant_id was explicitly set to Unset
129
129
  dct['_unset_tenant'] = False
130
- return super(BaseMeta, mcs).__new__(mcs, name, bases, dct)
130
+ return super().__new__(mcs, name, bases, dct)
131
131
 
132
132
 
133
133
  class BaseType(wtypes.Base, metaclass=BaseMeta):
@@ -76,8 +76,8 @@ class AmphoraProviderDriver(driver_base.ProviderDriver):
76
76
 
77
77
  def _validate_pool_algorithm(self, pool):
78
78
  if pool.lb_algorithm not in AMPHORA_SUPPORTED_LB_ALGORITHMS:
79
- msg = ('Amphora provider does not support %s algorithm.'
80
- % pool.lb_algorithm)
79
+ msg = (f'Amphora provider does not support {pool.lb_algorithm} '
80
+ f'algorithm.')
81
81
  raise exceptions.UnsupportedOptionError(
82
82
  user_fault_string=msg,
83
83
  operator_fault_string=msg)
@@ -473,9 +473,9 @@ class AmphoraProviderDriver(driver_base.ProviderDriver):
473
473
  except js_exceptions.ValidationError as e:
474
474
  error_object = ''
475
475
  if e.relative_path:
476
- error_object = '{} '.format(e.relative_path[0])
476
+ error_object = f'{e.relative_path[0]} '
477
477
  raise exceptions.UnsupportedOptionError(
478
- user_fault_string='{0}{1}'.format(error_object, e.message),
478
+ user_fault_string=f'{error_object}{e.message}',
479
479
  operator_fault_string=str(e))
480
480
  except Exception as e:
481
481
  raise exceptions.DriverError(
@@ -559,9 +559,9 @@ class AmphoraProviderDriver(driver_base.ProviderDriver):
559
559
  except js_exceptions.ValidationError as e:
560
560
  error_object = ''
561
561
  if e.relative_path:
562
- error_object = '{} '.format(e.relative_path[0])
562
+ error_object = f'{e.relative_path[0]} '
563
563
  raise exceptions.UnsupportedOptionError(
564
- user_fault_string='{0}{1}'.format(error_object, e.message),
564
+ user_fault_string=f'{error_object}{e.message}',
565
565
  operator_fault_string=str(e))
566
566
  except Exception as e:
567
567
  raise exceptions.DriverError(
@@ -62,7 +62,7 @@ class StatusRequestHandler(socketserver.BaseRequestHandler):
62
62
 
63
63
  # Send the response
64
64
  json_data = jsonutils.dump_as_bytes(response)
65
- len_str = '{}\n'.format(len(json_data)).encode('utf-8')
65
+ len_str = f'{len(json_data)}\n'.encode()
66
66
  try:
67
67
  self.request.send(len_str)
68
68
  self.request.sendall(json_data)
@@ -86,7 +86,7 @@ class StatsRequestHandler(socketserver.BaseRequestHandler):
86
86
 
87
87
  # Send the response
88
88
  json_data = jsonutils.dump_as_bytes(response)
89
- len_str = '{}\n'.format(len(json_data)).encode('utf-8')
89
+ len_str = f'{len(json_data)}\n'.encode()
90
90
  try:
91
91
  self.request.send(len_str)
92
92
  self.request.sendall(json_data)
@@ -109,7 +109,7 @@ class GetRequestHandler(socketserver.BaseRequestHandler):
109
109
 
110
110
  # Send the response
111
111
  json_data = jsonutils.dump_as_bytes(response)
112
- len_str = '{}\n'.format(len(json_data)).encode('utf-8')
112
+ len_str = f'{len(json_data)}\n'.encode()
113
113
  try:
114
114
  self.request.send(len_str)
115
115
  self.request.sendall(json_data)
@@ -29,7 +29,7 @@ from octavia.statistics import stats_base
29
29
  LOG = logging.getLogger(__name__)
30
30
 
31
31
 
32
- class DriverUpdater(object):
32
+ class DriverUpdater:
33
33
 
34
34
  def __init__(self, **kwargs):
35
35
  self.repos = repo.Repositories()
@@ -23,7 +23,7 @@ from octavia.api.drivers import utils as driver_utils
23
23
  LOG = logging.getLogger(__name__)
24
24
 
25
25
 
26
- class NoopManager(object):
26
+ class NoopManager:
27
27
  def __init__(self):
28
28
  super().__init__()
29
29
  self.driverconfig = {}
@@ -27,7 +27,7 @@ CONF = cfg.CONF
27
27
  LOG = logging.getLogger(__name__)
28
28
 
29
29
 
30
- class RootController(object):
30
+ class RootController:
31
31
  """The controller with which the pecan wsgi app should be created."""
32
32
 
33
33
  def __init__(self):
@@ -65,7 +65,7 @@ class RootController(object):
65
65
  host_url = pecan_request.path_url
66
66
 
67
67
  if not host_url.endswith('/'):
68
- host_url = '{}/'.format(host_url)
68
+ host_url = f'{host_url}/'
69
69
 
70
70
  versions = []
71
71
  self._add_a_version(versions, 'v2.0', 'v2', 'SUPPORTED',
@@ -223,8 +223,7 @@ class BaseController(pecan_rest.RestController):
223
223
 
224
224
  def _auth_get_all(self, context, project_id):
225
225
  # Check authorization to list objects under all projects
226
- action = '{rbac_obj}{action}'.format(
227
- rbac_obj=self.RBAC_TYPE, action=constants.RBAC_GET_ALL_GLOBAL)
226
+ action = f'{self.RBAC_TYPE}{constants.RBAC_GET_ALL_GLOBAL}'
228
227
  target = {'project_id': project_id}
229
228
  if not policy.get_enforcer().authorize(action, target,
230
229
  context, do_raise=False):
@@ -247,8 +246,7 @@ class BaseController(pecan_rest.RestController):
247
246
 
248
247
  def _auth_validate_action(self, context, project_id, action):
249
248
  # Check that the user is authorized to do an action in this object
250
- action = '{rbac_obj}{action}'.format(
251
- rbac_obj=self.RBAC_TYPE, action=action)
249
+ action = f'{self.RBAC_TYPE}{action}'
252
250
  target = {'project_id': project_id}
253
251
  policy.get_enforcer().authorize(action, target, context)
254
252
 
@@ -152,7 +152,7 @@ class HealthMonitorController(base.BaseController):
152
152
  if hm_dict.get('http_version') and hm_dict.get('domain_name'):
153
153
  if hm_dict['http_version'] < 1.1:
154
154
  raise exceptions.InvalidOption(
155
- value='http_version %s' % hm_dict['http_version'],
155
+ value=f"http_version {hm_dict['http_version']}",
156
156
  option='health monitors HTTP 1.1 domain name health check')
157
157
 
158
158
  try:
@@ -188,7 +188,9 @@ class HealthMonitorController(base.BaseController):
188
188
  request.type == consts.HEALTH_MONITOR_UDP_CONNECT)
189
189
  conf_min_delay = (
190
190
  CONF.api_settings.udp_connect_min_interval_health_monitor)
191
- if hm_is_type_udp and request.delay < conf_min_delay:
191
+ if (hm_is_type_udp and
192
+ not isinstance(request.delay, wtypes.UnsetType) and
193
+ request.delay < conf_min_delay):
192
194
  raise exceptions.ValidationException(detail=_(
193
195
  "The request delay value %(delay)s should be larger than "
194
196
  "%(conf_min_delay)s for %(type)s health monitor type.") % {
@@ -315,7 +317,7 @@ class HealthMonitorController(base.BaseController):
315
317
  http_version = health_monitor.http_version or db_hm.http_version
316
318
  if http_version < 1.1:
317
319
  raise exceptions.InvalidOption(
318
- value='http_version %s' % http_version,
320
+ value=f'http_version {http_version}',
319
321
  option='health monitors HTTP 1.1 domain name health check')
320
322
 
321
323
  def _set_default_on_none(self, health_monitor):
@@ -136,7 +136,7 @@ class ListenersController(base.BaseController):
136
136
  constants.LISTENER_PROTOCOLS_SUPPORTING_HEADER_INSERTION):
137
137
  raise exceptions.InvalidOption(
138
138
  value='insert-headers',
139
- option='a %s protocol listener.' % listener_protocol)
139
+ option=f'a {listener_protocol} protocol listener.')
140
140
  if list(set(insert_header_list) - (
141
141
  set(constants.SUPPORTED_HTTP_HEADERS +
142
142
  constants.SUPPORTED_SSL_HEADERS))):
@@ -155,7 +155,7 @@ class ListenersController(base.BaseController):
155
155
  headers.append(header_name)
156
156
  raise exceptions.InvalidOption(
157
157
  value=headers,
158
- option='%s protocol listener.' % listener_protocol)
158
+ option=f'{listener_protocol} protocol listener.')
159
159
 
160
160
  def _validate_cidr_compatible_with_vip(self, vips, allowed_cidrs):
161
161
  for cidr in allowed_cidrs: