octavia 12.0.0.0rc2__py3-none-any.whl → 13.0.0.0rc1__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 (193) hide show
  1. octavia/amphorae/backends/agent/api_server/osutils.py +1 -0
  2. octavia/amphorae/backends/agent/api_server/plug.py +21 -7
  3. octavia/amphorae/backends/agent/api_server/templates/amphora-netns.systemd.j2 +2 -2
  4. octavia/amphorae/backends/agent/api_server/util.py +21 -0
  5. octavia/amphorae/backends/health_daemon/health_daemon.py +9 -3
  6. octavia/amphorae/backends/health_daemon/health_sender.py +2 -0
  7. octavia/amphorae/backends/utils/interface.py +14 -6
  8. octavia/amphorae/backends/utils/interface_file.py +6 -3
  9. octavia/amphorae/backends/utils/keepalivedlvs_query.py +8 -9
  10. octavia/amphorae/drivers/driver_base.py +1 -2
  11. octavia/amphorae/drivers/haproxy/rest_api_driver.py +11 -25
  12. octavia/amphorae/drivers/health/heartbeat_udp.py +34 -24
  13. octavia/amphorae/drivers/keepalived/jinja/jinja_cfg.py +3 -12
  14. octavia/amphorae/drivers/noop_driver/driver.py +3 -5
  15. octavia/api/common/pagination.py +4 -4
  16. octavia/api/drivers/amphora_driver/v2/driver.py +11 -5
  17. octavia/api/drivers/driver_agent/driver_get.py +22 -14
  18. octavia/api/drivers/driver_agent/driver_updater.py +8 -4
  19. octavia/api/drivers/utils.py +4 -2
  20. octavia/api/healthcheck/healthcheck_plugins.py +4 -2
  21. octavia/api/root_controller.py +4 -1
  22. octavia/api/v2/controllers/amphora.py +35 -38
  23. octavia/api/v2/controllers/availability_zone_profiles.py +43 -33
  24. octavia/api/v2/controllers/availability_zones.py +22 -18
  25. octavia/api/v2/controllers/flavor_profiles.py +37 -28
  26. octavia/api/v2/controllers/flavors.py +19 -15
  27. octavia/api/v2/controllers/health_monitor.py +44 -33
  28. octavia/api/v2/controllers/l7policy.py +52 -40
  29. octavia/api/v2/controllers/l7rule.py +68 -55
  30. octavia/api/v2/controllers/listener.py +88 -61
  31. octavia/api/v2/controllers/load_balancer.py +52 -34
  32. octavia/api/v2/controllers/member.py +63 -52
  33. octavia/api/v2/controllers/pool.py +55 -42
  34. octavia/api/v2/controllers/quotas.py +5 -3
  35. octavia/api/v2/types/listener.py +15 -0
  36. octavia/cmd/octavia_worker.py +0 -3
  37. octavia/cmd/status.py +1 -4
  38. octavia/common/clients.py +25 -45
  39. octavia/common/config.py +64 -22
  40. octavia/common/constants.py +3 -2
  41. octavia/common/data_models.py +7 -1
  42. octavia/common/jinja/haproxy/combined_listeners/jinja_cfg.py +12 -1
  43. octavia/common/jinja/haproxy/combined_listeners/templates/macros.j2 +5 -2
  44. octavia/common/jinja/lvs/jinja_cfg.py +4 -2
  45. octavia/common/keystone.py +58 -5
  46. octavia/common/validate.py +35 -0
  47. octavia/compute/drivers/noop_driver/driver.py +6 -0
  48. octavia/controller/healthmanager/health_manager.py +3 -6
  49. octavia/controller/housekeeping/house_keeping.py +36 -37
  50. octavia/controller/worker/amphora_rate_limit.py +5 -4
  51. octavia/controller/worker/task_utils.py +57 -41
  52. octavia/controller/worker/v2/controller_worker.py +160 -103
  53. octavia/controller/worker/v2/flows/listener_flows.py +3 -0
  54. octavia/controller/worker/v2/flows/load_balancer_flows.py +9 -14
  55. octavia/controller/worker/v2/tasks/amphora_driver_tasks.py +152 -91
  56. octavia/controller/worker/v2/tasks/compute_tasks.py +4 -2
  57. octavia/controller/worker/v2/tasks/database_tasks.py +542 -400
  58. octavia/controller/worker/v2/tasks/network_tasks.py +119 -79
  59. octavia/db/api.py +26 -23
  60. octavia/db/base_models.py +2 -2
  61. octavia/db/healthcheck.py +2 -1
  62. octavia/db/migration/alembic_migrations/versions/632152d2d32e_add_http_strict_transport_security_.py +42 -0
  63. octavia/db/models.py +12 -2
  64. octavia/db/prepare.py +2 -0
  65. octavia/db/repositories.py +462 -482
  66. octavia/hacking/checks.py +1 -1
  67. octavia/network/base.py +0 -14
  68. octavia/network/drivers/neutron/allowed_address_pairs.py +92 -135
  69. octavia/network/drivers/neutron/base.py +65 -77
  70. octavia/network/drivers/neutron/utils.py +69 -85
  71. octavia/network/drivers/noop_driver/driver.py +0 -7
  72. octavia/statistics/drivers/update_db.py +10 -10
  73. octavia/tests/common/constants.py +91 -84
  74. octavia/tests/common/sample_data_models.py +13 -1
  75. octavia/tests/fixtures.py +32 -0
  76. octavia/tests/functional/amphorae/backend/agent/api_server/test_server.py +9 -10
  77. octavia/tests/functional/api/drivers/driver_agent/test_driver_agent.py +260 -15
  78. octavia/tests/functional/api/test_root_controller.py +3 -28
  79. octavia/tests/functional/api/v2/base.py +5 -3
  80. octavia/tests/functional/api/v2/test_amphora.py +18 -5
  81. octavia/tests/functional/api/v2/test_availability_zone_profiles.py +1 -0
  82. octavia/tests/functional/api/v2/test_listener.py +51 -19
  83. octavia/tests/functional/api/v2/test_load_balancer.py +10 -1
  84. octavia/tests/functional/db/base.py +31 -16
  85. octavia/tests/functional/db/test_models.py +27 -28
  86. octavia/tests/functional/db/test_repositories.py +407 -50
  87. octavia/tests/unit/amphorae/backends/agent/api_server/test_amphora_info.py +2 -0
  88. octavia/tests/unit/amphorae/backends/agent/api_server/test_osutils.py +1 -1
  89. octavia/tests/unit/amphorae/backends/agent/api_server/test_plug.py +54 -6
  90. octavia/tests/unit/amphorae/backends/agent/api_server/test_util.py +35 -0
  91. octavia/tests/unit/amphorae/backends/health_daemon/test_health_daemon.py +8 -0
  92. octavia/tests/unit/amphorae/backends/health_daemon/test_health_sender.py +18 -0
  93. octavia/tests/unit/amphorae/backends/utils/test_interface.py +81 -0
  94. octavia/tests/unit/amphorae/backends/utils/test_interface_file.py +2 -0
  95. octavia/tests/unit/amphorae/backends/utils/test_keepalivedlvs_query.py +129 -5
  96. octavia/tests/unit/amphorae/drivers/haproxy/test_rest_api_driver_1_0.py +42 -20
  97. octavia/tests/unit/amphorae/drivers/health/test_heartbeat_udp.py +18 -20
  98. octavia/tests/unit/amphorae/drivers/keepalived/jinja/test_jinja_cfg.py +4 -4
  99. octavia/tests/unit/amphorae/drivers/noop_driver/test_driver.py +4 -1
  100. octavia/tests/unit/api/drivers/driver_agent/test_driver_get.py +3 -3
  101. octavia/tests/unit/api/drivers/driver_agent/test_driver_updater.py +11 -13
  102. octavia/tests/unit/base.py +6 -0
  103. octavia/tests/unit/cmd/test_interface.py +2 -2
  104. octavia/tests/unit/cmd/test_status.py +2 -2
  105. octavia/tests/unit/common/jinja/haproxy/combined_listeners/test_jinja_cfg.py +152 -1
  106. octavia/tests/unit/common/sample_configs/sample_configs_combined.py +10 -3
  107. octavia/tests/unit/common/test_clients.py +0 -39
  108. octavia/tests/unit/common/test_keystone.py +54 -0
  109. octavia/tests/unit/common/test_validate.py +67 -0
  110. octavia/tests/unit/controller/healthmanager/test_health_manager.py +8 -22
  111. octavia/tests/unit/controller/housekeeping/test_house_keeping.py +3 -64
  112. octavia/tests/unit/controller/worker/test_amphora_rate_limit.py +1 -1
  113. octavia/tests/unit/controller/worker/test_task_utils.py +44 -24
  114. octavia/tests/unit/controller/worker/v2/flows/test_load_balancer_flows.py +0 -1
  115. octavia/tests/unit/controller/worker/v2/tasks/test_amphora_driver_tasks.py +49 -26
  116. octavia/tests/unit/controller/worker/v2/tasks/test_database_tasks.py +399 -196
  117. octavia/tests/unit/controller/worker/v2/tasks/test_database_tasks_quota.py +37 -64
  118. octavia/tests/unit/controller/worker/v2/tasks/test_network_tasks.py +3 -14
  119. octavia/tests/unit/controller/worker/v2/test_controller_worker.py +2 -2
  120. octavia/tests/unit/network/drivers/neutron/test_allowed_address_pairs.py +456 -561
  121. octavia/tests/unit/network/drivers/neutron/test_base.py +181 -194
  122. octavia/tests/unit/network/drivers/neutron/test_utils.py +14 -30
  123. octavia/tests/unit/statistics/drivers/test_update_db.py +7 -5
  124. {octavia-12.0.0.0rc2.data → octavia-13.0.0.0rc1.data}/data/share/octavia/README.rst +1 -1
  125. {octavia-12.0.0.0rc2.dist-info → octavia-13.0.0.0rc1.dist-info}/AUTHORS +4 -0
  126. {octavia-12.0.0.0rc2.dist-info → octavia-13.0.0.0rc1.dist-info}/METADATA +4 -4
  127. {octavia-12.0.0.0rc2.dist-info → octavia-13.0.0.0rc1.dist-info}/RECORD +141 -189
  128. {octavia-12.0.0.0rc2.dist-info → octavia-13.0.0.0rc1.dist-info}/entry_points.txt +1 -2
  129. octavia-13.0.0.0rc1.dist-info/pbr.json +1 -0
  130. octavia/api/drivers/amphora_driver/v1/__init__.py +0 -11
  131. octavia/api/drivers/amphora_driver/v1/driver.py +0 -547
  132. octavia/controller/queue/v1/__init__.py +0 -11
  133. octavia/controller/queue/v1/consumer.py +0 -64
  134. octavia/controller/queue/v1/endpoints.py +0 -160
  135. octavia/controller/worker/v1/__init__.py +0 -11
  136. octavia/controller/worker/v1/controller_worker.py +0 -1157
  137. octavia/controller/worker/v1/flows/__init__.py +0 -11
  138. octavia/controller/worker/v1/flows/amphora_flows.py +0 -610
  139. octavia/controller/worker/v1/flows/health_monitor_flows.py +0 -105
  140. octavia/controller/worker/v1/flows/l7policy_flows.py +0 -94
  141. octavia/controller/worker/v1/flows/l7rule_flows.py +0 -100
  142. octavia/controller/worker/v1/flows/listener_flows.py +0 -128
  143. octavia/controller/worker/v1/flows/load_balancer_flows.py +0 -692
  144. octavia/controller/worker/v1/flows/member_flows.py +0 -230
  145. octavia/controller/worker/v1/flows/pool_flows.py +0 -127
  146. octavia/controller/worker/v1/tasks/__init__.py +0 -11
  147. octavia/controller/worker/v1/tasks/amphora_driver_tasks.py +0 -453
  148. octavia/controller/worker/v1/tasks/cert_task.py +0 -51
  149. octavia/controller/worker/v1/tasks/compute_tasks.py +0 -335
  150. octavia/controller/worker/v1/tasks/database_tasks.py +0 -2756
  151. octavia/controller/worker/v1/tasks/lifecycle_tasks.py +0 -173
  152. octavia/controller/worker/v1/tasks/model_tasks.py +0 -41
  153. octavia/controller/worker/v1/tasks/network_tasks.py +0 -970
  154. octavia/controller/worker/v1/tasks/retry_tasks.py +0 -74
  155. octavia/tests/unit/api/drivers/amphora_driver/v1/__init__.py +0 -11
  156. octavia/tests/unit/api/drivers/amphora_driver/v1/test_driver.py +0 -824
  157. octavia/tests/unit/controller/queue/v1/__init__.py +0 -11
  158. octavia/tests/unit/controller/queue/v1/test_consumer.py +0 -61
  159. octavia/tests/unit/controller/queue/v1/test_endpoints.py +0 -189
  160. octavia/tests/unit/controller/worker/v1/__init__.py +0 -11
  161. octavia/tests/unit/controller/worker/v1/flows/__init__.py +0 -11
  162. octavia/tests/unit/controller/worker/v1/flows/test_amphora_flows.py +0 -474
  163. octavia/tests/unit/controller/worker/v1/flows/test_health_monitor_flows.py +0 -72
  164. octavia/tests/unit/controller/worker/v1/flows/test_l7policy_flows.py +0 -67
  165. octavia/tests/unit/controller/worker/v1/flows/test_l7rule_flows.py +0 -67
  166. octavia/tests/unit/controller/worker/v1/flows/test_listener_flows.py +0 -91
  167. octavia/tests/unit/controller/worker/v1/flows/test_load_balancer_flows.py +0 -431
  168. octavia/tests/unit/controller/worker/v1/flows/test_member_flows.py +0 -106
  169. octavia/tests/unit/controller/worker/v1/flows/test_pool_flows.py +0 -77
  170. octavia/tests/unit/controller/worker/v1/tasks/__init__.py +0 -11
  171. octavia/tests/unit/controller/worker/v1/tasks/test_amphora_driver_tasks.py +0 -792
  172. octavia/tests/unit/controller/worker/v1/tasks/test_cert_task.py +0 -46
  173. octavia/tests/unit/controller/worker/v1/tasks/test_compute_tasks.py +0 -634
  174. octavia/tests/unit/controller/worker/v1/tasks/test_database_tasks.py +0 -2615
  175. octavia/tests/unit/controller/worker/v1/tasks/test_database_tasks_quota.py +0 -415
  176. octavia/tests/unit/controller/worker/v1/tasks/test_lifecycle_tasks.py +0 -401
  177. octavia/tests/unit/controller/worker/v1/tasks/test_model_tasks.py +0 -44
  178. octavia/tests/unit/controller/worker/v1/tasks/test_network_tasks.py +0 -1788
  179. octavia/tests/unit/controller/worker/v1/tasks/test_retry_tasks.py +0 -47
  180. octavia/tests/unit/controller/worker/v1/test_controller_worker.py +0 -2096
  181. octavia-12.0.0.0rc2.dist-info/pbr.json +0 -1
  182. {octavia-12.0.0.0rc2.data → octavia-13.0.0.0rc1.data}/data/share/octavia/LICENSE +0 -0
  183. {octavia-12.0.0.0rc2.data → octavia-13.0.0.0rc1.data}/data/share/octavia/diskimage-create/README.rst +0 -0
  184. {octavia-12.0.0.0rc2.data → octavia-13.0.0.0rc1.data}/data/share/octavia/diskimage-create/diskimage-create.sh +0 -0
  185. {octavia-12.0.0.0rc2.data → octavia-13.0.0.0rc1.data}/data/share/octavia/diskimage-create/image-tests.sh +0 -0
  186. {octavia-12.0.0.0rc2.data → octavia-13.0.0.0rc1.data}/data/share/octavia/diskimage-create/requirements.txt +0 -0
  187. {octavia-12.0.0.0rc2.data → octavia-13.0.0.0rc1.data}/data/share/octavia/diskimage-create/test-requirements.txt +0 -0
  188. {octavia-12.0.0.0rc2.data → octavia-13.0.0.0rc1.data}/data/share/octavia/diskimage-create/tox.ini +0 -0
  189. {octavia-12.0.0.0rc2.data → octavia-13.0.0.0rc1.data}/data/share/octavia/diskimage-create/version.txt +0 -0
  190. {octavia-12.0.0.0rc2.data → octavia-13.0.0.0rc1.data}/scripts/octavia-wsgi +0 -0
  191. {octavia-12.0.0.0rc2.dist-info → octavia-13.0.0.0rc1.dist-info}/LICENSE +0 -0
  192. {octavia-12.0.0.0rc2.dist-info → octavia-13.0.0.0rc1.dist-info}/WHEEL +0 -0
  193. {octavia-12.0.0.0rc2.dist-info → octavia-13.0.0.0rc1.dist-info}/top_level.txt +0 -0
@@ -34,7 +34,6 @@ from octavia.common import constants
34
34
  from octavia.common import data_models
35
35
  from octavia.common import exceptions
36
36
  from octavia.common import validate
37
- from octavia.db import api as db_api
38
37
  from octavia.db import prepare as db_prepare
39
38
  from octavia.i18n import _
40
39
 
@@ -54,7 +53,9 @@ class PoolsController(base.BaseController):
54
53
  def get(self, id, fields=None):
55
54
  """Gets a pool's details."""
56
55
  context = pecan_request.context.get('octavia_context')
57
- db_pool = self._get_db_pool(context.session, id, show_deleted=False)
56
+ with context.session.begin():
57
+ db_pool = self._get_db_pool(context.session, id,
58
+ show_deleted=False)
58
59
 
59
60
  self._auth_validate_action(context, db_pool.project_id,
60
61
  constants.RBAC_GET_ONE)
@@ -73,10 +74,11 @@ class PoolsController(base.BaseController):
73
74
 
74
75
  query_filter = self._auth_get_all(context, project_id)
75
76
 
76
- db_pools, links = self.repositories.pool.get_all_API_list(
77
- context.session, show_deleted=False,
78
- pagination_helper=pcontext.get(constants.PAGINATION_HELPER),
79
- **query_filter)
77
+ with context.session.begin():
78
+ db_pools, links = self.repositories.pool.get_all_API_list(
79
+ context.session, show_deleted=False,
80
+ pagination_helper=pcontext.get(constants.PAGINATION_HELPER),
81
+ **query_filter)
80
82
  result = self._convert_db_to_type(db_pools, [pool_types.PoolResponse])
81
83
  if fields is not None:
82
84
  result = self._filter_fields(result, fields)
@@ -141,9 +143,11 @@ class PoolsController(base.BaseController):
141
143
  validate.check_alpn_protocols(pool_dict['alpn_protocols'])
142
144
 
143
145
  try:
144
- return self.repositories.create_pool_on_load_balancer(
146
+ ret = self.repositories.create_pool_on_load_balancer(
145
147
  lock_session, pool_dict,
146
148
  listener_id=listener_id)
149
+ lock_session.flush()
150
+ return ret
147
151
  except odb_exceptions.DBDuplicateEntry as e:
148
152
  raise exceptions.IDAlreadyExists() from e
149
153
  except odb_exceptions.DBReferenceError as e:
@@ -211,19 +215,20 @@ class PoolsController(base.BaseController):
211
215
  pool = pool_.pool
212
216
  context = pecan_request.context.get('octavia_context')
213
217
  listener = None
214
- if pool.loadbalancer_id:
215
- pool.project_id, provider = self._get_lb_project_id_provider(
216
- context.session, pool.loadbalancer_id)
217
- elif pool.listener_id:
218
- listener = self.repositories.listener.get(
219
- context.session, id=pool.listener_id)
220
- pool.loadbalancer_id = listener.load_balancer_id
221
- pool.project_id, provider = self._get_lb_project_id_provider(
222
- context.session, pool.loadbalancer_id)
223
- else:
224
- msg = _("Must provide at least one of: "
225
- "loadbalancer_id, listener_id")
226
- raise exceptions.ValidationException(detail=msg)
218
+ with context.session.begin():
219
+ if pool.loadbalancer_id:
220
+ pool.project_id, provider = self._get_lb_project_id_provider(
221
+ context.session, pool.loadbalancer_id)
222
+ elif pool.listener_id:
223
+ listener = self.repositories.listener.get(
224
+ context.session, id=pool.listener_id)
225
+ pool.loadbalancer_id = listener.load_balancer_id
226
+ pool.project_id, provider = self._get_lb_project_id_provider(
227
+ context.session, pool.loadbalancer_id)
228
+ else:
229
+ msg = _("Must provide at least one of: "
230
+ "loadbalancer_id, listener_id")
231
+ raise exceptions.ValidationException(detail=msg)
227
232
 
228
233
  self._auth_validate_action(context, pool.project_id,
229
234
  constants.RBAC_POST)
@@ -252,11 +257,11 @@ class PoolsController(base.BaseController):
252
257
  # Load the driver early as it also provides validation
253
258
  driver = driver_factory.get_driver(provider)
254
259
 
255
- lock_session = db_api.get_session(autocommit=False)
260
+ context.session.begin()
256
261
  try:
257
262
  if self.repositories.check_quota_met(
258
263
  context.session,
259
- lock_session,
264
+ context.session,
260
265
  data_models.Pool,
261
266
  pool.project_id):
262
267
  raise exceptions.QuotaException(
@@ -268,16 +273,16 @@ class PoolsController(base.BaseController):
268
273
 
269
274
  listener_id = pool_dict.pop('listener_id', None)
270
275
  if listener_id:
271
- if listener_repo.has_default_pool(lock_session,
276
+ if listener_repo.has_default_pool(context.session,
272
277
  listener_id):
273
278
  raise exceptions.DuplicatePoolEntry()
274
279
 
275
280
  self._test_lb_and_listener_statuses(
276
- lock_session, lb_id=pool_dict['load_balancer_id'],
281
+ context.session, lb_id=pool_dict['load_balancer_id'],
277
282
  listener_ids=[listener_id] if listener_id else [])
278
283
 
279
284
  db_pool = self._validate_create_pool(
280
- lock_session, pool_dict, listener_id)
285
+ context.session, pool_dict, listener_id)
281
286
 
282
287
  # Prepare the data for the driver data model
283
288
  provider_pool = (
@@ -289,12 +294,13 @@ class PoolsController(base.BaseController):
289
294
  driver_utils.call_provider(
290
295
  driver.name, driver.pool_create, provider_pool)
291
296
 
292
- lock_session.commit()
297
+ context.session.commit()
293
298
  except Exception:
294
299
  with excutils.save_and_reraise_exception():
295
- lock_session.rollback()
300
+ context.session.rollback()
296
301
 
297
- db_pool = self._get_db_pool(context.session, db_pool.id)
302
+ with context.session.begin():
303
+ db_pool = self._get_db_pool(context.session, db_pool.id)
298
304
  result = self._convert_db_to_type(db_pool, pool_types.PoolResponse)
299
305
  return pool_types.PoolRootResponse(pool=result)
300
306
 
@@ -435,10 +441,12 @@ class PoolsController(base.BaseController):
435
441
  """Updates a pool on a load balancer."""
436
442
  pool = pool_.pool
437
443
  context = pecan_request.context.get('octavia_context')
438
- db_pool = self._get_db_pool(context.session, id, show_deleted=False)
444
+ with context.session.begin():
445
+ db_pool = self._get_db_pool(context.session, id,
446
+ show_deleted=False)
439
447
 
440
- project_id, provider = self._get_lb_project_id_provider(
441
- context.session, db_pool.load_balancer_id)
448
+ project_id, provider = self._get_lb_project_id_provider(
449
+ context.session, db_pool.load_balancer_id)
442
450
 
443
451
  self._auth_validate_action(context, project_id, constants.RBAC_PUT)
444
452
 
@@ -458,9 +466,9 @@ class PoolsController(base.BaseController):
458
466
  # Load the driver early as it also provides validation
459
467
  driver = driver_factory.get_driver(provider)
460
468
 
461
- with db_api.get_lock_session() as lock_session:
469
+ with context.session.begin():
462
470
  self._test_lb_and_listener_statuses(
463
- lock_session, lb_id=db_pool.load_balancer_id,
471
+ context.session, lb_id=db_pool.load_balancer_id,
464
472
  listener_ids=self._get_affected_listener_ids(db_pool))
465
473
 
466
474
  # Prepare the data for the driver data model
@@ -483,13 +491,14 @@ class PoolsController(base.BaseController):
483
491
  # Update the database to reflect what the driver just accepted
484
492
  pool.provisioning_status = constants.PENDING_UPDATE
485
493
  db_pool_dict = pool.to_dict(render_unsets=False)
486
- self.repositories.update_pool_and_sp(lock_session, id,
494
+ self.repositories.update_pool_and_sp(context.session, id,
487
495
  db_pool_dict)
488
496
 
489
497
  # Force SQL alchemy to query the DB, otherwise we get inconsistent
490
498
  # results
491
499
  context.session.expire_all()
492
- db_pool = self._get_db_pool(context.session, id)
500
+ with context.session.begin():
501
+ db_pool = self._get_db_pool(context.session, id)
493
502
  result = self._convert_db_to_type(db_pool, pool_types.PoolResponse)
494
503
  return pool_types.PoolRootResponse(pool=result)
495
504
 
@@ -497,10 +506,12 @@ class PoolsController(base.BaseController):
497
506
  def delete(self, id):
498
507
  """Deletes a pool from a load balancer."""
499
508
  context = pecan_request.context.get('octavia_context')
500
- db_pool = self._get_db_pool(context.session, id, show_deleted=False)
509
+ with context.session.begin():
510
+ db_pool = self._get_db_pool(context.session, id,
511
+ show_deleted=False)
501
512
 
502
- project_id, provider = self._get_lb_project_id_provider(
503
- context.session, db_pool.load_balancer_id)
513
+ project_id, provider = self._get_lb_project_id_provider(
514
+ context.session, db_pool.load_balancer_id)
504
515
 
505
516
  self._auth_validate_action(context, project_id, constants.RBAC_DELETE)
506
517
 
@@ -511,12 +522,12 @@ class PoolsController(base.BaseController):
511
522
  # Load the driver early as it also provides validation
512
523
  driver = driver_factory.get_driver(provider)
513
524
 
514
- with db_api.get_lock_session() as lock_session:
525
+ with context.session.begin():
515
526
  self._test_lb_and_listener_statuses(
516
- lock_session, lb_id=db_pool.load_balancer_id,
527
+ context.session, lb_id=db_pool.load_balancer_id,
517
528
  listener_ids=self._get_affected_listener_ids(db_pool))
518
529
  self.repositories.pool.update(
519
- lock_session, db_pool.id,
530
+ context.session, db_pool.id,
520
531
  provisioning_status=constants.PENDING_DELETE)
521
532
 
522
533
  LOG.info("Sending delete Pool %s to provider %s", id, driver.name)
@@ -536,7 +547,9 @@ class PoolsController(base.BaseController):
536
547
  context = pecan_request.context.get('octavia_context')
537
548
  if pool_id and remainder and remainder[0] == 'members':
538
549
  remainder = remainder[1:]
539
- db_pool = self.repositories.pool.get(context.session, id=pool_id)
550
+ with context.session.begin():
551
+ db_pool = self.repositories.pool.get(context.session,
552
+ id=pool_id)
540
553
  if not db_pool:
541
554
  LOG.info("Pool %s not found.", pool_id)
542
555
  raise exceptions.NotFound(resource=data_models.Pool._name(),
@@ -72,8 +72,9 @@ class QuotasController(base.BaseController):
72
72
  self._auth_validate_action(context, project_id, constants.RBAC_PUT)
73
73
 
74
74
  quotas_dict = quotas.to_dict()
75
- self.repositories.quotas.update(context.session, project_id,
76
- **quotas_dict)
75
+ with context.session.begin():
76
+ self.repositories.quotas.update(context.session, project_id,
77
+ **quotas_dict)
77
78
  db_quotas = self._get_db_quotas(context.session, project_id)
78
79
  return self._convert_db_to_type(db_quotas, quota_types.QuotaResponse)
79
80
 
@@ -87,7 +88,8 @@ class QuotasController(base.BaseController):
87
88
 
88
89
  self._auth_validate_action(context, project_id, constants.RBAC_DELETE)
89
90
 
90
- self.repositories.quotas.delete(context.session, project_id)
91
+ with context.session.begin():
92
+ self.repositories.quotas.delete(context.session, project_id)
91
93
  db_quotas = self._get_db_quotas(context.session, project_id)
92
94
  return self._convert_db_to_type(db_quotas, quota_types.QuotaResponse)
93
95
 
@@ -63,6 +63,9 @@ class ListenerResponse(BaseListenerType):
63
63
  tls_ciphers = wtypes.StringType()
64
64
  tls_versions = wtypes.wsattr(wtypes.ArrayType(wtypes.StringType()))
65
65
  alpn_protocols = wtypes.wsattr(wtypes.ArrayType(types.AlpnProtocolType()))
66
+ hsts_max_age = wtypes.wsattr(wtypes.IntegerType())
67
+ hsts_include_subdomains = wtypes.wsattr(bool)
68
+ hsts_preload = wtypes.wsattr(bool)
66
69
 
67
70
  @classmethod
68
71
  def from_data_model(cls, data_model, children=False):
@@ -86,6 +89,9 @@ class ListenerResponse(BaseListenerType):
86
89
 
87
90
  listener.tls_versions = data_model.tls_versions
88
91
  listener.alpn_protocols = data_model.alpn_protocols
92
+ listener.hsts_max_age = data_model.hsts_max_age
93
+ listener.hsts_include_subdomains = data_model.hsts_include_subdomains
94
+ listener.hsts_preload = data_model.hsts_preload
89
95
 
90
96
  return listener
91
97
 
@@ -155,6 +161,9 @@ class ListenerPOST(BaseListenerType):
155
161
  tls_versions = wtypes.wsattr(wtypes.ArrayType(wtypes.StringType(
156
162
  max_length=32)))
157
163
  alpn_protocols = wtypes.wsattr(wtypes.ArrayType(types.AlpnProtocolType()))
164
+ hsts_max_age = wtypes.wsattr(wtypes.IntegerType(minimum=0))
165
+ hsts_include_subdomains = wtypes.wsattr(bool, default=False)
166
+ hsts_preload = wtypes.wsattr(bool, default=False)
158
167
 
159
168
 
160
169
  class ListenerRootPOST(types.BaseType):
@@ -196,6 +205,9 @@ class ListenerPUT(BaseListenerType):
196
205
  tls_versions = wtypes.wsattr(wtypes.ArrayType(wtypes.StringType(
197
206
  max_length=32)))
198
207
  alpn_protocols = wtypes.wsattr(wtypes.ArrayType(types.AlpnProtocolType()))
208
+ hsts_max_age = wtypes.wsattr(wtypes.IntegerType(minimum=0))
209
+ hsts_include_subdomains = wtypes.wsattr(bool)
210
+ hsts_preload = wtypes.wsattr(bool)
199
211
 
200
212
 
201
213
  class ListenerRootPUT(types.BaseType):
@@ -247,6 +259,9 @@ class ListenerSingleCreate(BaseListenerType):
247
259
  tls_versions = wtypes.wsattr(wtypes.ArrayType(wtypes.StringType(
248
260
  max_length=32)))
249
261
  alpn_protocols = wtypes.wsattr(wtypes.ArrayType(types.AlpnProtocolType()))
262
+ hsts_max_age = wtypes.wsattr(wtypes.IntegerType())
263
+ hsts_include_subdomains = wtypes.wsattr(bool, default=False)
264
+ hsts_preload = wtypes.wsattr(bool, default=False)
250
265
 
251
266
 
252
267
  class ListenerStatusResponse(BaseListenerType):
@@ -20,7 +20,6 @@ from oslo_config import cfg
20
20
  from oslo_reports import guru_meditation_report as gmr
21
21
 
22
22
  from octavia.common import service as octavia_service
23
- from octavia.controller.queue.v1 import consumer as consumer_v1
24
23
  from octavia.controller.queue.v2 import consumer as consumer_v2
25
24
  from octavia import version
26
25
 
@@ -33,8 +32,6 @@ def main():
33
32
  gmr.TextGuruMeditation.setup_autorun(version)
34
33
 
35
34
  sm = cotyledon.ServiceManager()
36
- sm.add(consumer_v1.ConsumerService, workers=CONF.controller_worker.workers,
37
- args=(CONF,))
38
35
  sm.add(consumer_v2.ConsumerService,
39
36
  workers=CONF.controller_worker.workers, args=(CONF,))
40
37
  oslo_config_glue.setup(sm, CONF, reload_method="mutate")
octavia/cmd/status.py CHANGED
@@ -22,7 +22,6 @@ from stevedore import driver as stevedore_driver
22
22
  # Need to import to load config
23
23
  from octavia.common import config # noqa: F401 pylint: disable=unused-import
24
24
  from octavia.common import constants
25
- from octavia.common import policy
26
25
  from octavia.controller.worker.v2 import taskflow_jobboard_driver as tsk_driver
27
26
  from octavia.i18n import _
28
27
 
@@ -77,9 +76,8 @@ class Checks(upgradecheck.UpgradeCommands):
77
76
  'section.'))
78
77
 
79
78
  def _check_amphorav2(self):
80
- default_provider_driver = CONF.api_settings.default_provider_driver
81
79
  enabled_provider_drivers = CONF.api_settings.enabled_provider_drivers
82
- if (default_provider_driver == constants.AMPHORAV2 or
80
+ if (constants.AMPHORA in enabled_provider_drivers or
83
81
  constants.AMPHORAV2 in enabled_provider_drivers):
84
82
  persistence = self._check_persistence()
85
83
  if isinstance(persistence, upgradecheck.Result):
@@ -120,7 +118,6 @@ class Checks(upgradecheck.UpgradeCommands):
120
118
 
121
119
 
122
120
  def main():
123
- policy.Policy()
124
121
  return upgradecheck.main(
125
122
  CONF, project='octavia', upgrade_command=Checks())
126
123
 
octavia/common/clients.py CHANGED
@@ -12,9 +12,11 @@
12
12
 
13
13
  from cinderclient import client as cinder_client
14
14
  from glanceclient import client as glance_client
15
- from neutronclient.neutron import client as neutron_client
15
+ from keystoneauth1 import session
16
+ from keystoneauth1 import token_endpoint
16
17
  from novaclient import api_versions
17
18
  from novaclient import client as nova_client
19
+ import openstack
18
20
  from oslo_config import cfg
19
21
  from oslo_log import log as logging
20
22
  from oslo_utils import excutils
@@ -25,7 +27,6 @@ LOG = logging.getLogger(__name__)
25
27
  CONF = cfg.CONF
26
28
 
27
29
  GLANCE_VERSION = '2'
28
- NEUTRON_VERSION = '2.0'
29
30
  NOVA_VERSION = '2.15'
30
31
  CINDER_VERSION = '3'
31
32
 
@@ -73,38 +74,20 @@ class NeutronAuth(object):
73
74
  neutron_client = None
74
75
 
75
76
  @classmethod
76
- def get_neutron_client(cls, region, service_name=None, endpoint=None,
77
- endpoint_type='publicURL', insecure=False,
78
- ca_cert=None):
79
- """Create neutron client object.
80
-
81
- :param region: The region of the service
82
- :param service_name: The name of the neutron service in the catalog
83
- :param endpoint: The endpoint of the service
84
- :param endpoint_type: The endpoint_type of the service
85
- :param insecure: Turn off certificate validation
86
- :param ca_cert: CA Cert file path
87
- :return: a Neutron Client object.
88
- :raises Exception: if the client cannot be created
89
- """
90
- ksession = keystone.KeystoneSession()
77
+ def get_neutron_client(cls):
78
+ """Create neutron client object."""
79
+ ksession = keystone.KeystoneSession('neutron')
91
80
  if not cls.neutron_client:
92
- kwargs = {'region_name': region,
93
- 'session': ksession.get_session(),
94
- 'endpoint_type': endpoint_type,
95
- 'insecure': insecure}
96
- if service_name:
97
- kwargs['service_name'] = service_name
98
- if endpoint:
99
- kwargs['endpoint_override'] = endpoint
100
- if ca_cert:
101
- kwargs['ca_cert'] = ca_cert
102
- try:
103
- cls.neutron_client = neutron_client.Client(
104
- NEUTRON_VERSION, **kwargs)
105
- except Exception:
106
- with excutils.save_and_reraise_exception():
107
- LOG.exception("Error creating Neutron client.")
81
+ sess = ksession.get_session()
82
+
83
+ kwargs = {}
84
+ if CONF.neutron.endpoint_override:
85
+ kwargs['network_endpoint_override'] = (
86
+ CONF.neutron.endpoint_override)
87
+
88
+ conn = openstack.connection.Connection(
89
+ session=sess, **kwargs)
90
+ cls.neutron_client = conn
108
91
  return cls.neutron_client
109
92
 
110
93
  @classmethod
@@ -113,26 +96,23 @@ class NeutronAuth(object):
113
96
 
114
97
  It's possible that the token in the context is a trust scoped
115
98
  which can't be used to initialize a keystone session.
116
-
117
99
  We directly use the token and endpoint_url to initialize neutron
118
100
  client.
119
101
  """
120
- neutron_endpoint = CONF.neutron.endpoint
121
- if not neutron_endpoint:
122
- session = keystone.KeystoneSession().get_session()
123
- endpoint_data = session.get_endpoint_data(
102
+ sess = keystone.KeystoneSession('neutron').get_session()
103
+ neutron_endpoint = CONF.neutron.endpoint_override
104
+ if neutron_endpoint is None:
105
+ endpoint_data = sess.get_endpoint_data(
124
106
  service_type='network', interface=CONF.neutron.endpoint_type,
125
107
  region_name=CONF.neutron.region_name)
126
108
  neutron_endpoint = endpoint_data.catalog_url
127
109
 
128
- kwargs = {
129
- 'token': context.auth_token,
130
- 'endpoint_url': neutron_endpoint,
131
- 'insecure': CONF.neutron.insecure,
132
- 'ca_cert': CONF.neutron.ca_certificates_file
133
- }
110
+ user_auth = token_endpoint.Token(neutron_endpoint, context.auth_token)
111
+ user_sess = session.Session(auth=user_auth)
134
112
 
135
- return neutron_client.Client(NEUTRON_VERSION, **kwargs)
113
+ conn = openstack.connection.Connection(
114
+ session=user_sess, oslo_conf=CONF)
115
+ return conn.network
136
116
 
137
117
 
138
118
  class GlanceAuth(object):
octavia/common/config.py CHANGED
@@ -37,10 +37,6 @@ from octavia import version
37
37
 
38
38
  LOG = logging.getLogger(__name__)
39
39
 
40
- EXTRA_LOG_LEVEL_DEFAULTS = [
41
- 'neutronclient.v2_0.client=INFO',
42
- ]
43
-
44
40
  core_opts = [
45
41
  cfg.HostnameOpt('host', default=utils.get_hostname(),
46
42
  sample_default='<server-hostname.example.com>',
@@ -89,7 +85,7 @@ api_opts = [
89
85
  'octavia.api.drivers entrypoint.'),
90
86
  default={'amphora': 'The Octavia Amphora driver.',
91
87
  'octavia': 'Deprecated alias of the Octavia Amphora '
92
- 'driver.',
88
+ 'driver.',
93
89
  }),
94
90
  cfg.StrOpt('default_provider_driver', default='amphora',
95
91
  help=_('Default provider driver.')),
@@ -747,21 +743,27 @@ cinder_opts = [
747
743
  ]
748
744
 
749
745
  neutron_opts = [
750
- cfg.StrOpt('service_name',
751
- help=_('The name of the neutron service in the '
752
- 'keystone catalog')),
753
746
  cfg.StrOpt('endpoint', help=_('A new endpoint to override the endpoint '
754
- 'in the keystone catalog.')),
755
- cfg.StrOpt('region_name',
756
- help=_('Region in Identity service catalog to use for '
757
- 'communication with the OpenStack services.')),
758
- cfg.StrOpt('endpoint_type', default='publicURL',
759
- help=_('Endpoint interface in identity service to use')),
747
+ 'in the keystone catalog.'),
748
+ deprecated_for_removal=True,
749
+ deprecated_reason=_('The endpoint_override option defined by '
750
+ 'keystoneauth1 is the new name for this '
751
+ 'option.'),
752
+ deprecated_since='2023.2/Bobcat'),
753
+ cfg.StrOpt('endpoint_type', help=_('Endpoint interface in identity '
754
+ 'service to use'),
755
+ deprecated_for_removal=True,
756
+ deprecated_reason=_('This option was replaced by the '
757
+ 'valid_interfaces option defined by '
758
+ 'keystoneauth.'),
759
+ deprecated_since='2023.2/Bobcat'),
760
760
  cfg.StrOpt('ca_certificates_file',
761
- help=_('CA certificates file path')),
762
- cfg.BoolOpt('insecure',
763
- default=False,
764
- help=_('Disable certificate validation on SSL connections ')),
761
+ help=_('CA certificates file path'),
762
+ deprecated_for_removal=True,
763
+ deprecated_reason=_('The cafile option defined by '
764
+ 'keystoneauth1 is the new name for this '
765
+ 'option.'),
766
+ deprecated_since='2023.2/Bobcat'),
765
767
  ]
766
768
 
767
769
  glance_opts = [
@@ -902,8 +904,16 @@ _SQL_CONNECTION_DEFAULT = 'sqlite://'
902
904
  db_options.set_defaults(cfg.CONF, connection=_SQL_CONNECTION_DEFAULT,
903
905
  max_pool_size=10, max_overflow=20, pool_timeout=10)
904
906
 
905
- ks_loading.register_auth_conf_options(cfg.CONF, constants.SERVICE_AUTH)
906
- ks_loading.register_session_conf_options(cfg.CONF, constants.SERVICE_AUTH)
907
+
908
+ def register_ks_options(group):
909
+ ks_loading.register_auth_conf_options(cfg.CONF, group)
910
+ ks_loading.register_session_conf_options(cfg.CONF, group)
911
+ ks_loading.register_adapter_conf_options(cfg.CONF, group,
912
+ include_deprecated=False)
913
+
914
+
915
+ register_ks_options(constants.SERVICE_AUTH)
916
+ register_ks_options('neutron')
907
917
 
908
918
 
909
919
  def register_cli_opts():
@@ -911,6 +921,31 @@ def register_cli_opts():
911
921
  logging.register_options(cfg.CONF)
912
922
 
913
923
 
924
+ def handle_neutron_deprecations():
925
+ # Apply neutron deprecated options to their new setting if needed
926
+
927
+ # Basicaly: if the value of the deprecated option is not the default:
928
+ # * convert it to a valid "new" value if needed
929
+ # * set it as the default for the new option
930
+ # Thus [neutron].<new_option> has an higher precedence than
931
+ # [neutron].<deprecated_option>
932
+ loc = cfg.CONF.get_location('endpoint', 'neutron')
933
+ if loc and loc.location != cfg.Locations.opt_default:
934
+ cfg.CONF.set_default('endpoint_override', cfg.CONF.neutron.endpoint,
935
+ 'neutron')
936
+
937
+ loc = cfg.CONF.get_location('endpoint_type', 'neutron')
938
+ if loc and loc.location != cfg.Locations.opt_default:
939
+ endpoint_type = cfg.CONF.neutron.endpoint_type.replace('URL', '')
940
+ cfg.CONF.set_default('valid_interfaces', [endpoint_type],
941
+ 'neutron')
942
+
943
+ loc = cfg.CONF.get_location('ca_certificates_file', 'neutron')
944
+ if loc and loc.location != cfg.Locations.opt_default:
945
+ cfg.CONF.set_default('cafile', cfg.CONF.neutron.ca_certificates_file,
946
+ 'neutron')
947
+
948
+
914
949
  def init(args, **kwargs):
915
950
  register_cli_opts()
916
951
  cfg.CONF(args=args, project='octavia',
@@ -920,14 +955,20 @@ def init(args, **kwargs):
920
955
  setup_remote_debugger()
921
956
  validate.check_default_ciphers_prohibit_list_conflict()
922
957
 
958
+ # Override default auth_type for plugins with the default from service_auth
959
+ auth_type = cfg.CONF.service_auth.auth_type
960
+ cfg.CONF.set_default('auth_type', auth_type, 'neutron')
961
+
962
+ handle_neutron_deprecations()
963
+
923
964
 
924
965
  def setup_logging(conf):
925
966
  """Sets up the logging options for a log with supplied name.
926
967
 
927
968
  :param conf: a cfg.ConfOpts object
928
969
  """
929
- logging.set_defaults(default_log_levels=logging.get_default_log_levels() +
930
- EXTRA_LOG_LEVEL_DEFAULTS)
970
+ ll = logging.get_default_log_levels()
971
+ logging.set_defaults(default_log_levels=ll)
931
972
  product_name = "octavia"
932
973
  logging.setup(conf, product_name)
933
974
  LOG.info("Logging enabled!")
@@ -944,6 +985,7 @@ def _enable_pydev(debugger_host, debugger_port):
944
985
  import pydevd # pylint: disable=import-outside-toplevel
945
986
 
946
987
  pydevd.settrace(debugger_host,
988
+ suspend=False,
947
989
  port=int(debugger_port),
948
990
  stdoutToServer=True,
949
991
  stderrToServer=True)
@@ -796,8 +796,6 @@ RBAC_ROLES_DEPRECATED_REASON = (
796
796
  # PROVIDERS
797
797
  OCTAVIA = 'octavia'
798
798
  AMPHORAV2 = 'amphorav2'
799
- # Deprecated in Z, to be removed
800
- AMPHORAV1 = 'amphorav1'
801
799
 
802
800
  # systemctl commands
803
801
  DISABLE = 'disable'
@@ -913,6 +911,9 @@ AMPHORA_SUPPORTED_ALPN_PROTOCOLS = [lib_consts.ALPN_PROTOCOL_HTTP_2,
913
911
  lib_consts.ALPN_PROTOCOL_HTTP_1_0]
914
912
 
915
913
  # Amphora interface fields
914
+ IF_TYPE = 'if_type'
915
+ BACKEND = 'backend'
916
+ LO = 'lo'
916
917
  MTU = 'mtu'
917
918
  ADDRESSES = 'addresses'
918
919
  ROUTES = 'routes'
@@ -16,6 +16,7 @@
16
16
 
17
17
  import datetime
18
18
  import re
19
+ import typing as tp
19
20
 
20
21
  from oslo_log import log as logging
21
22
  from sqlalchemy.orm import collections
@@ -419,7 +420,8 @@ class Listener(BaseDataModel):
419
420
  tags=None, client_ca_tls_certificate_id=None,
420
421
  client_authentication=None, client_crl_container_id=None,
421
422
  allowed_cidrs=None, tls_ciphers=None, tls_versions=None,
422
- alpn_protocols=None):
423
+ alpn_protocols=None, hsts_max_age=None,
424
+ hsts_include_subdomains=None, hsts_preload=None):
423
425
  self.id = id
424
426
  self.project_id = project_id
425
427
  self.name = name
@@ -455,6 +457,10 @@ class Listener(BaseDataModel):
455
457
  self.tls_ciphers = tls_ciphers
456
458
  self.tls_versions = tls_versions
457
459
  self.alpn_protocols = alpn_protocols
460
+ self.hsts_max_age: tp.Optional[int] = hsts_max_age
461
+ self.hsts_include_subdomains: tp.Optional[bool] = (
462
+ hsts_include_subdomains)
463
+ self.hsts_preload: tp.Optional[bool] = hsts_preload
458
464
 
459
465
  def update(self, update_dict):
460
466
  for key, value in update_dict.items():