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
@@ -28,7 +28,6 @@ from octavia.common import constants
28
28
  from octavia.common import data_models
29
29
  from octavia.common import exceptions
30
30
  from octavia.common import validate
31
- from octavia.db import api as db_api
32
31
  from octavia.db import prepare as db_prepare
33
32
 
34
33
 
@@ -47,8 +46,9 @@ class L7RuleController(base.BaseController):
47
46
  def get(self, id, fields=None):
48
47
  """Gets a single l7rule's details."""
49
48
  context = pecan_request.context.get('octavia_context')
50
- db_l7rule = self._get_db_l7rule(context.session, id,
51
- show_deleted=False)
49
+ with context.session.begin():
50
+ db_l7rule = self._get_db_l7rule(context.session, id,
51
+ show_deleted=False)
52
52
 
53
53
  self._auth_validate_action(context, db_l7rule.project_id,
54
54
  constants.RBAC_GET_ONE)
@@ -66,15 +66,17 @@ class L7RuleController(base.BaseController):
66
66
  pcontext = pecan_request.context
67
67
  context = pcontext.get('octavia_context')
68
68
 
69
- l7policy = self._get_db_l7policy(context.session, self.l7policy_id,
70
- show_deleted=False)
69
+ with context.session.begin():
70
+ l7policy = self._get_db_l7policy(context.session, self.l7policy_id,
71
+ show_deleted=False)
71
72
 
72
- self._auth_validate_action(context, l7policy.project_id,
73
- constants.RBAC_GET_ALL)
73
+ self._auth_validate_action(context, l7policy.project_id,
74
+ constants.RBAC_GET_ALL)
74
75
 
75
- db_l7rules, links = self.repositories.l7rule.get_all_API_list(
76
- context.session, show_deleted=False, l7policy_id=self.l7policy_id,
77
- pagination_helper=pcontext.get(constants.PAGINATION_HELPER))
76
+ db_l7rules, links = self.repositories.l7rule.get_all_API_list(
77
+ context.session, show_deleted=False,
78
+ l7policy_id=self.l7policy_id,
79
+ pagination_helper=pcontext.get(constants.PAGINATION_HELPER))
78
80
  result = self._convert_db_to_type(
79
81
  db_l7rules, [l7rule_types.L7RuleResponse])
80
82
  if fields is not None:
@@ -109,7 +111,9 @@ class L7RuleController(base.BaseController):
109
111
 
110
112
  def _validate_create_l7rule(self, lock_session, l7rule_dict):
111
113
  try:
112
- return self.repositories.l7rule.create(lock_session, **l7rule_dict)
114
+ ret = self.repositories.l7rule.create(lock_session, **l7rule_dict)
115
+ lock_session.flush()
116
+ return ret
113
117
  except odb_exceptions.DBDuplicateEntry as e:
114
118
  raise exceptions.IDAlreadyExists() from e
115
119
  except odb_exceptions.DBReferenceError as e:
@@ -125,30 +129,33 @@ class L7RuleController(base.BaseController):
125
129
  l7rule = rule_.rule
126
130
  context = pecan_request.context.get('octavia_context')
127
131
 
128
- db_l7policy = self._get_db_l7policy(context.session, self.l7policy_id,
129
- show_deleted=False)
130
- load_balancer_id, listener_id = self._get_listener_and_loadbalancer_id(
131
- db_l7policy)
132
- l7rule.project_id, provider = self._get_lb_project_id_provider(
133
- context.session, load_balancer_id)
134
- self._auth_validate_action(context, l7rule.project_id,
135
- constants.RBAC_POST)
132
+ with context.session.begin():
133
+ db_l7policy = self._get_db_l7policy(context.session,
134
+ self.l7policy_id,
135
+ show_deleted=False)
136
+ load_balancer_id, listener_id = (
137
+ self._get_listener_and_loadbalancer_id(db_l7policy))
138
+ l7rule.project_id, provider = self._get_lb_project_id_provider(
139
+ context.session, load_balancer_id)
136
140
 
137
- try:
138
- validate.l7rule_data(l7rule)
139
- except Exception as e:
140
- raise exceptions.L7RuleValidation(error=e)
141
+ self._auth_validate_action(context, l7rule.project_id,
142
+ constants.RBAC_POST)
143
+
144
+ try:
145
+ validate.l7rule_data(l7rule)
146
+ except Exception as e:
147
+ raise exceptions.L7RuleValidation(error=e)
141
148
 
142
- self._check_l7policy_max_rules(context.session)
149
+ self._check_l7policy_max_rules(context.session)
143
150
 
144
151
  # Load the driver early as it also provides validation
145
152
  driver = driver_factory.get_driver(provider)
146
153
 
147
- lock_session = db_api.get_session(autocommit=False)
154
+ context.session.begin()
148
155
  try:
149
156
  if self.repositories.check_quota_met(
150
157
  context.session,
151
- lock_session,
158
+ context.session,
152
159
  data_models.L7Rule,
153
160
  l7rule.project_id):
154
161
  raise exceptions.QuotaException(
@@ -157,9 +164,10 @@ class L7RuleController(base.BaseController):
157
164
  l7rule_dict = db_prepare.create_l7rule(
158
165
  l7rule.to_dict(render_unsets=True), self.l7policy_id)
159
166
 
160
- self._test_lb_listener_policy_statuses(lock_session)
167
+ self._test_lb_listener_policy_statuses(context.session)
161
168
 
162
- db_l7rule = self._validate_create_l7rule(lock_session, l7rule_dict)
169
+ db_l7rule = self._validate_create_l7rule(context.session,
170
+ l7rule_dict)
163
171
 
164
172
  # Prepare the data for the driver data model
165
173
  provider_l7rule = (
@@ -171,12 +179,13 @@ class L7RuleController(base.BaseController):
171
179
  driver_utils.call_provider(
172
180
  driver.name, driver.l7rule_create, provider_l7rule)
173
181
 
174
- lock_session.commit()
182
+ context.session.commit()
175
183
  except Exception:
176
184
  with excutils.save_and_reraise_exception():
177
- lock_session.rollback()
185
+ context.session.rollback()
178
186
 
179
- db_l7rule = self._get_db_l7rule(context.session, db_l7rule.id)
187
+ with context.session.begin():
188
+ db_l7rule = self._get_db_l7rule(context.session, db_l7rule.id)
180
189
  result = self._convert_db_to_type(db_l7rule,
181
190
  l7rule_types.L7RuleResponse)
182
191
  return l7rule_types.L7RuleRootResponse(rule=result)
@@ -198,14 +207,16 @@ class L7RuleController(base.BaseController):
198
207
  """Updates a l7rule."""
199
208
  l7rule = l7rule_.rule
200
209
  context = pecan_request.context.get('octavia_context')
201
- db_l7rule = self._get_db_l7rule(context.session, id,
202
- show_deleted=False)
203
- db_l7policy = self._get_db_l7policy(context.session, self.l7policy_id,
210
+ with context.session.begin():
211
+ db_l7rule = self._get_db_l7rule(context.session, id,
204
212
  show_deleted=False)
205
- load_balancer_id, listener_id = self._get_listener_and_loadbalancer_id(
206
- db_l7policy)
207
- project_id, provider = self._get_lb_project_id_provider(
208
- context.session, load_balancer_id)
213
+ db_l7policy = self._get_db_l7policy(context.session,
214
+ self.l7policy_id,
215
+ show_deleted=False)
216
+ load_balancer_id, listener_id = (
217
+ self._get_listener_and_loadbalancer_id(db_l7policy))
218
+ project_id, provider = self._get_lb_project_id_provider(
219
+ context.session, load_balancer_id)
209
220
 
210
221
  self._auth_validate_action(context, project_id, constants.RBAC_PUT)
211
222
 
@@ -225,9 +236,8 @@ class L7RuleController(base.BaseController):
225
236
  # Load the driver early as it also provides validation
226
237
  driver = driver_factory.get_driver(provider)
227
238
 
228
- with db_api.get_lock_session() as lock_session:
229
-
230
- self._test_lb_listener_policy_statuses(lock_session)
239
+ with context.session.begin():
240
+ self._test_lb_listener_policy_statuses(context.session)
231
241
 
232
242
  # Prepare the data for the driver data model
233
243
  l7rule_dict = l7rule.to_dict(render_unsets=False)
@@ -250,12 +260,14 @@ class L7RuleController(base.BaseController):
250
260
  # Update the database to reflect what the driver just accepted
251
261
  l7rule.provisioning_status = constants.PENDING_UPDATE
252
262
  db_l7rule_dict = l7rule.to_dict(render_unsets=False)
253
- self.repositories.l7rule.update(lock_session, id, **db_l7rule_dict)
263
+ self.repositories.l7rule.update(context.session, id,
264
+ **db_l7rule_dict)
254
265
 
255
266
  # Force SQL alchemy to query the DB, otherwise we get inconsistent
256
267
  # results
257
268
  context.session.expire_all()
258
- db_l7rule = self._get_db_l7rule(context.session, id)
269
+ with context.session.begin():
270
+ db_l7rule = self._get_db_l7rule(context.session, id)
259
271
  result = self._convert_db_to_type(db_l7rule,
260
272
  l7rule_types.L7RuleResponse)
261
273
  return l7rule_types.L7RuleRootResponse(rule=result)
@@ -264,15 +276,17 @@ class L7RuleController(base.BaseController):
264
276
  def delete(self, id):
265
277
  """Deletes a l7rule."""
266
278
  context = pecan_request.context.get('octavia_context')
267
- db_l7rule = self._get_db_l7rule(context.session, id,
268
- show_deleted=False)
269
-
270
- db_l7policy = self._get_db_l7policy(context.session, self.l7policy_id,
279
+ with context.session.begin():
280
+ db_l7rule = self._get_db_l7rule(context.session, id,
271
281
  show_deleted=False)
272
- load_balancer_id, listener_id = self._get_listener_and_loadbalancer_id(
273
- db_l7policy)
274
- project_id, provider = self._get_lb_project_id_provider(
275
- context.session, load_balancer_id)
282
+
283
+ db_l7policy = self._get_db_l7policy(context.session,
284
+ self.l7policy_id,
285
+ show_deleted=False)
286
+ load_balancer_id, listener_id = (
287
+ self._get_listener_and_loadbalancer_id(db_l7policy))
288
+ project_id, provider = self._get_lb_project_id_provider(
289
+ context.session, load_balancer_id)
276
290
 
277
291
  self._auth_validate_action(context, project_id, constants.RBAC_DELETE)
278
292
 
@@ -282,12 +296,11 @@ class L7RuleController(base.BaseController):
282
296
  # Load the driver early as it also provides validation
283
297
  driver = driver_factory.get_driver(provider)
284
298
 
285
- with db_api.get_lock_session() as lock_session:
286
-
287
- self._test_lb_listener_policy_statuses(lock_session)
299
+ with context.session.begin():
300
+ self._test_lb_listener_policy_statuses(context.session)
288
301
 
289
302
  self.repositories.l7rule.update(
290
- lock_session, db_l7rule.id,
303
+ context.session, db_l7rule.id,
291
304
  provisioning_status=constants.PENDING_DELETE)
292
305
 
293
306
  LOG.info("Sending delete L7 Rule %s to provider %s", id,
@@ -35,7 +35,6 @@ from octavia.common import exceptions
35
35
  from octavia.common import stats
36
36
  from octavia.common import utils as common_utils
37
37
  from octavia.common import validate
38
- from octavia.db import api as db_api
39
38
  from octavia.db import prepare as db_prepare
40
39
  from octavia.i18n import _
41
40
 
@@ -55,8 +54,9 @@ class ListenersController(base.BaseController):
55
54
  def get_one(self, id, fields=None):
56
55
  """Gets a single listener's details."""
57
56
  context = pecan_request.context.get('octavia_context')
58
- db_listener = self._get_db_listener(context.session, id,
59
- show_deleted=False)
57
+ with context.session.begin():
58
+ db_listener = self._get_db_listener(context.session, id,
59
+ show_deleted=False)
60
60
 
61
61
  if not db_listener:
62
62
  raise exceptions.NotFound(resource=data_models.Listener._name(),
@@ -80,10 +80,11 @@ class ListenersController(base.BaseController):
80
80
 
81
81
  query_filter = self._auth_get_all(context, project_id)
82
82
 
83
- db_listeners, links = self.repositories.listener.get_all_API_list(
84
- context.session, show_deleted=False,
85
- pagination_helper=pcontext.get(constants.PAGINATION_HELPER),
86
- **query_filter)
83
+ with context.session.begin():
84
+ db_listeners, links = self.repositories.listener.get_all_API_list(
85
+ context.session, show_deleted=False,
86
+ pagination_helper=pcontext.get(constants.PAGINATION_HELPER),
87
+ **query_filter)
87
88
  result = self._convert_db_to_type(
88
89
  db_listeners, [listener_types.ListenerResponse])
89
90
  if fields is not None:
@@ -156,14 +157,18 @@ class ListenersController(base.BaseController):
156
157
  value=headers,
157
158
  option='%s protocol listener.' % listener_protocol)
158
159
 
159
- def _validate_cidr_compatible_with_vip(self, vip, allowed_cidrs):
160
+ def _validate_cidr_compatible_with_vip(self, vips, allowed_cidrs):
160
161
  for cidr in allowed_cidrs:
161
- # Check if CIDR IP version matches VIP IP version
162
- if common_utils.is_cidr_ipv6(cidr) != common_utils.is_ipv6(vip):
163
- msg = _("CIDR %(cidr)s IP version incompatible with VIP "
164
- "%(vip)s IP version.")
162
+ for vip in vips:
163
+ # Check if CIDR IP version matches VIP IP version
164
+ if (common_utils.is_cidr_ipv6(cidr) ==
165
+ common_utils.is_ipv6(vip)):
166
+ break
167
+ else:
168
+ msg = _("CIDR %(cidr)s IP version incompatible with all VIPs "
169
+ "%(vips)s IP version.")
165
170
  raise exceptions.ValidationException(
166
- detail=msg % {'cidr': cidr, 'vip': vip})
171
+ detail=msg % {'cidr': cidr, 'vips': vips})
167
172
 
168
173
  def _validate_create_listener(self, lock_session, listener_dict):
169
174
  """Validate listener for wrong protocol or duplicate listeners
@@ -306,10 +311,11 @@ class ListenersController(base.BaseController):
306
311
  # Validate allowed CIDRs
307
312
  allowed_cidrs = listener_dict.get('allowed_cidrs', []) or []
308
313
  lb_id = listener_dict.get('load_balancer_id')
309
- vip_db = self.repositories.vip.get(
310
- lock_session, load_balancer_id=lb_id)
311
- vip_address = vip_db.ip_address
312
- self._validate_cidr_compatible_with_vip(vip_address, allowed_cidrs)
314
+ lb_db = self.repositories.load_balancer.get(
315
+ lock_session, id=lb_id)
316
+ vip_addresses = [lb_db.vip.ip_address]
317
+ vip_addresses.extend([vip.ip_address for vip in lb_db.additional_vips])
318
+ self._validate_cidr_compatible_with_vip(vip_addresses, allowed_cidrs)
313
319
 
314
320
  if _can_tls_offload:
315
321
  # Validate TLS version list
@@ -319,15 +325,19 @@ class ListenersController(base.BaseController):
319
325
  # Validate ALPN protocol list
320
326
  validate.check_alpn_protocols(listener_dict['alpn_protocols'])
321
327
 
328
+ validate.check_hsts_options(listener_dict)
329
+
322
330
  try:
323
331
  db_listener = self.repositories.listener.create(
324
332
  lock_session, **listener_dict)
333
+ lock_session.flush()
325
334
  if sni_containers:
326
335
  for container in sni_containers:
327
336
  sni_dict = {'listener_id': db_listener.id,
328
337
  'tls_container_id': container.get(
329
338
  'tls_container_id')}
330
339
  self.repositories.sni.create(lock_session, **sni_dict)
340
+ lock_session.flush()
331
341
  # DB listener needs to be refreshed
332
342
  db_listener = self.repositories.listener.get(
333
343
  lock_session, id=db_listener.id)
@@ -340,7 +350,6 @@ class ListenersController(base.BaseController):
340
350
  except odb_exceptions.DBError as e:
341
351
  raise exceptions.InvalidOption(value=listener_dict.get('protocol'),
342
352
  option='protocol') from e
343
- return None
344
353
 
345
354
  @wsme_pecan.wsexpose(listener_types.ListenerRootResponse,
346
355
  body=listener_types.ListenerRootPOST, status_code=201)
@@ -350,8 +359,9 @@ class ListenersController(base.BaseController):
350
359
  context = pecan_request.context.get('octavia_context')
351
360
 
352
361
  load_balancer_id = listener.loadbalancer_id
353
- listener.project_id, provider = self._get_lb_project_id_provider(
354
- context.session, load_balancer_id)
362
+ with context.session.begin():
363
+ listener.project_id, provider = self._get_lb_project_id_provider(
364
+ context.session, load_balancer_id)
355
365
 
356
366
  self._auth_validate_action(context, listener.project_id,
357
367
  constants.RBAC_POST)
@@ -359,11 +369,11 @@ class ListenersController(base.BaseController):
359
369
  # Load the driver early as it also provides validation
360
370
  driver = driver_factory.get_driver(provider)
361
371
 
362
- lock_session = db_api.get_session(autocommit=False)
372
+ context.session.begin()
363
373
  try:
364
374
  if self.repositories.check_quota_met(
365
375
  context.session,
366
- lock_session,
376
+ context.session,
367
377
  data_models.Listener,
368
378
  listener.project_id):
369
379
  raise exceptions.QuotaException(
@@ -382,10 +392,10 @@ class ListenersController(base.BaseController):
382
392
  listener.protocol)
383
393
 
384
394
  self._test_lb_and_listener_statuses(
385
- lock_session, lb_id=load_balancer_id)
395
+ context.session, lb_id=load_balancer_id)
386
396
 
387
397
  db_listener = self._validate_create_listener(
388
- lock_session, listener_dict)
398
+ context.session, listener_dict)
389
399
 
390
400
  # Prepare the data for the driver data model
391
401
  provider_listener = (
@@ -403,12 +413,14 @@ class ListenersController(base.BaseController):
403
413
  driver_utils.call_provider(
404
414
  driver.name, driver.listener_create, provider_listener)
405
415
 
406
- lock_session.commit()
416
+ context.session.commit()
407
417
  except Exception:
408
418
  with excutils.save_and_reraise_exception():
409
- lock_session.rollback()
419
+ context.session.rollback()
410
420
 
411
- db_listener = self._get_db_listener(context.session, db_listener.id)
421
+ with context.session.begin():
422
+ db_listener = self._get_db_listener(context.session,
423
+ db_listener.id)
412
424
  result = self._convert_db_to_type(db_listener,
413
425
  listener_types.ListenerResponse)
414
426
  return listener_types.ListenerRootResponse(listener=result)
@@ -525,9 +537,13 @@ class ListenersController(base.BaseController):
525
537
 
526
538
  # Validate allowed CIDRs
527
539
  if (listener.allowed_cidrs and listener.allowed_cidrs != wtypes.Unset):
528
- vip_address = db_listener.load_balancer.vip.ip_address
540
+ vip_addresses = [db_listener.load_balancer.vip.ip_address]
541
+ vip_addresses.extend(
542
+ [vip.ip_address
543
+ for vip in db_listener.load_balancer.additional_vips]
544
+ )
529
545
  self._validate_cidr_compatible_with_vip(
530
- vip_address, listener.allowed_cidrs)
546
+ vip_addresses, listener.allowed_cidrs)
531
547
 
532
548
  # Check TLS cipher prohibit list
533
549
  if listener.tls_ciphers:
@@ -548,6 +564,8 @@ class ListenersController(base.BaseController):
548
564
  # Validate ALPN protocol list
549
565
  validate.check_alpn_protocols(listener.alpn_protocols)
550
566
 
567
+ validate.check_hsts_options_put(listener, db_listener)
568
+
551
569
  def _set_default_on_none(self, listener):
552
570
  """Reset settings to their default values if None/null was passed in
553
571
 
@@ -583,19 +601,24 @@ class ListenersController(base.BaseController):
583
601
  if listener.alpn_protocols is None:
584
602
  listener.alpn_protocols = (
585
603
  CONF.api_settings.default_listener_alpn_protocols)
604
+ if listener.hsts_include_subdomains is None:
605
+ listener.hsts_include_subdomains = False
606
+ if listener.hsts_preload is None:
607
+ listener.hsts_preload = False
586
608
 
587
609
  @wsme_pecan.wsexpose(listener_types.ListenerRootResponse, wtypes.text,
588
610
  body=listener_types.ListenerRootPUT, status_code=200)
589
- def put(self, id, listener_):
611
+ def put(self, id, listener_: listener_types.ListenerRootPUT):
590
612
  """Updates a listener on a load balancer."""
591
613
  listener = listener_.listener
592
614
  context = pecan_request.context.get('octavia_context')
593
- db_listener = self._get_db_listener(context.session, id,
594
- show_deleted=False)
595
- load_balancer_id = db_listener.load_balancer_id
615
+ with context.session.begin():
616
+ db_listener = self._get_db_listener(context.session, id,
617
+ show_deleted=False)
618
+ load_balancer_id = db_listener.load_balancer_id
596
619
 
597
- project_id, provider = self._get_lb_project_id_provider(
598
- context.session, load_balancer_id)
620
+ project_id, provider = self._get_lb_project_id_provider(
621
+ context.session, load_balancer_id)
599
622
 
600
623
  self._auth_validate_action(context, project_id, constants.RBAC_PUT)
601
624
 
@@ -607,14 +630,16 @@ class ListenersController(base.BaseController):
607
630
  if db_listener.protocol == lib_consts.PROTOCOL_PROMETHEUS:
608
631
  raise exceptions.ListenerNoChildren(
609
632
  protocol=lib_consts.PROTOCOL_PROMETHEUS)
610
- self._validate_pool(context.session, load_balancer_id,
611
- listener.default_pool_id, db_listener.protocol)
633
+ with context.session.begin():
634
+ self._validate_pool(context.session, load_balancer_id,
635
+ listener.default_pool_id,
636
+ db_listener.protocol)
612
637
 
613
638
  # Load the driver early as it also provides validation
614
639
  driver = driver_factory.get_driver(provider)
615
640
 
616
- with db_api.get_lock_session() as lock_session:
617
- self._test_lb_and_listener_statuses(lock_session,
641
+ with context.session.begin():
642
+ self._test_lb_and_listener_statuses(context.session,
618
643
  load_balancer_id, id=id)
619
644
 
620
645
  # Prepare the data for the driver data model
@@ -639,12 +664,13 @@ class ListenersController(base.BaseController):
639
664
 
640
665
  # Update the database to reflect what the driver just accepted
641
666
  self.repositories.listener.update(
642
- lock_session, id, **listener.to_dict(render_unsets=False))
667
+ context.session, id, **listener.to_dict(render_unsets=False))
643
668
 
644
669
  # Force SQL alchemy to query the DB, otherwise we get inconsistent
645
670
  # results
646
671
  context.session.expire_all()
647
- db_listener = self._get_db_listener(context.session, id)
672
+ with context.session.begin():
673
+ db_listener = self._get_db_listener(context.session, id)
648
674
  result = self._convert_db_to_type(db_listener,
649
675
  listener_types.ListenerResponse)
650
676
  return listener_types.ListenerRootResponse(listener=result)
@@ -653,22 +679,22 @@ class ListenersController(base.BaseController):
653
679
  def delete(self, id):
654
680
  """Deletes a listener from a load balancer."""
655
681
  context = pecan_request.context.get('octavia_context')
656
- db_listener = self._get_db_listener(context.session, id,
657
- show_deleted=False)
658
- load_balancer_id = db_listener.load_balancer_id
682
+ with context.session.begin():
683
+ db_listener = self._get_db_listener(context.session, id,
684
+ show_deleted=False)
685
+ load_balancer_id = db_listener.load_balancer_id
659
686
 
660
- project_id, provider = self._get_lb_project_id_provider(
661
- context.session, load_balancer_id)
687
+ project_id, provider = self._get_lb_project_id_provider(
688
+ context.session, load_balancer_id)
662
689
 
663
690
  self._auth_validate_action(context, project_id, constants.RBAC_DELETE)
664
691
 
665
692
  # Load the driver early as it also provides validation
666
693
  driver = driver_factory.get_driver(provider)
667
694
 
668
- with db_api.get_lock_session() as lock_session:
669
-
695
+ with context.session.begin():
670
696
  self._test_lb_and_listener_statuses(
671
- lock_session, load_balancer_id,
697
+ context.session, load_balancer_id,
672
698
  id=id, listener_status=constants.PENDING_DELETE)
673
699
 
674
700
  LOG.info("Sending delete Listener %s to provider %s", id,
@@ -702,18 +728,19 @@ class StatisticsController(base.BaseController, stats.StatsMixin):
702
728
  status_code=200)
703
729
  def get(self):
704
730
  context = pecan_request.context.get('octavia_context')
705
- db_listener = self._get_db_listener(context.session, self.id,
706
- show_deleted=False)
707
- if not db_listener:
708
- LOG.info("Listener %s not found.", id)
709
- raise exceptions.NotFound(
710
- resource=data_models.Listener._name(),
711
- id=id)
712
-
713
- self._auth_validate_action(context, db_listener.project_id,
714
- constants.RBAC_GET_STATS)
715
-
716
- listener_stats = self.get_listener_stats(context.session, self.id)
731
+ with context.session.begin():
732
+ db_listener = self._get_db_listener(context.session, self.id,
733
+ show_deleted=False)
734
+ if not db_listener:
735
+ LOG.info("Listener %s not found.", id)
736
+ raise exceptions.NotFound(
737
+ resource=data_models.Listener._name(),
738
+ id=id)
739
+
740
+ self._auth_validate_action(context, db_listener.project_id,
741
+ constants.RBAC_GET_STATS)
742
+
743
+ listener_stats = self.get_listener_stats(context.session, self.id)
717
744
 
718
745
  result = self._convert_db_to_type(
719
746
  listener_stats, listener_types.ListenerStatisticsResponse)