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.
- octavia/amphorae/backends/agent/api_server/osutils.py +1 -0
- octavia/amphorae/backends/agent/api_server/plug.py +21 -7
- octavia/amphorae/backends/agent/api_server/templates/amphora-netns.systemd.j2 +2 -2
- octavia/amphorae/backends/agent/api_server/util.py +21 -0
- octavia/amphorae/backends/health_daemon/health_daemon.py +9 -3
- octavia/amphorae/backends/health_daemon/health_sender.py +2 -0
- octavia/amphorae/backends/utils/interface.py +14 -6
- octavia/amphorae/backends/utils/interface_file.py +6 -3
- octavia/amphorae/backends/utils/keepalivedlvs_query.py +8 -9
- octavia/amphorae/drivers/driver_base.py +1 -2
- octavia/amphorae/drivers/haproxy/rest_api_driver.py +11 -25
- octavia/amphorae/drivers/health/heartbeat_udp.py +34 -24
- octavia/amphorae/drivers/keepalived/jinja/jinja_cfg.py +3 -12
- octavia/amphorae/drivers/noop_driver/driver.py +3 -5
- octavia/api/common/pagination.py +4 -4
- octavia/api/drivers/amphora_driver/v2/driver.py +11 -5
- octavia/api/drivers/driver_agent/driver_get.py +22 -14
- octavia/api/drivers/driver_agent/driver_updater.py +8 -4
- octavia/api/drivers/utils.py +4 -2
- octavia/api/healthcheck/healthcheck_plugins.py +4 -2
- octavia/api/root_controller.py +4 -1
- octavia/api/v2/controllers/amphora.py +35 -38
- octavia/api/v2/controllers/availability_zone_profiles.py +43 -33
- octavia/api/v2/controllers/availability_zones.py +22 -18
- octavia/api/v2/controllers/flavor_profiles.py +37 -28
- octavia/api/v2/controllers/flavors.py +19 -15
- octavia/api/v2/controllers/health_monitor.py +44 -33
- octavia/api/v2/controllers/l7policy.py +52 -40
- octavia/api/v2/controllers/l7rule.py +68 -55
- octavia/api/v2/controllers/listener.py +88 -61
- octavia/api/v2/controllers/load_balancer.py +52 -34
- octavia/api/v2/controllers/member.py +63 -52
- octavia/api/v2/controllers/pool.py +55 -42
- octavia/api/v2/controllers/quotas.py +5 -3
- octavia/api/v2/types/listener.py +15 -0
- octavia/cmd/octavia_worker.py +0 -3
- octavia/cmd/status.py +1 -4
- octavia/common/clients.py +25 -45
- octavia/common/config.py +64 -22
- octavia/common/constants.py +3 -2
- octavia/common/data_models.py +7 -1
- octavia/common/jinja/haproxy/combined_listeners/jinja_cfg.py +12 -1
- octavia/common/jinja/haproxy/combined_listeners/templates/macros.j2 +5 -2
- octavia/common/jinja/lvs/jinja_cfg.py +4 -2
- octavia/common/keystone.py +58 -5
- octavia/common/validate.py +35 -0
- octavia/compute/drivers/noop_driver/driver.py +6 -0
- octavia/controller/healthmanager/health_manager.py +3 -6
- octavia/controller/housekeeping/house_keeping.py +36 -37
- octavia/controller/worker/amphora_rate_limit.py +5 -4
- octavia/controller/worker/task_utils.py +57 -41
- octavia/controller/worker/v2/controller_worker.py +160 -103
- octavia/controller/worker/v2/flows/listener_flows.py +3 -0
- octavia/controller/worker/v2/flows/load_balancer_flows.py +9 -14
- octavia/controller/worker/v2/tasks/amphora_driver_tasks.py +152 -91
- octavia/controller/worker/v2/tasks/compute_tasks.py +4 -2
- octavia/controller/worker/v2/tasks/database_tasks.py +542 -400
- octavia/controller/worker/v2/tasks/network_tasks.py +119 -79
- octavia/db/api.py +26 -23
- octavia/db/base_models.py +2 -2
- octavia/db/healthcheck.py +2 -1
- octavia/db/migration/alembic_migrations/versions/632152d2d32e_add_http_strict_transport_security_.py +42 -0
- octavia/db/models.py +12 -2
- octavia/db/prepare.py +2 -0
- octavia/db/repositories.py +462 -482
- octavia/hacking/checks.py +1 -1
- octavia/network/base.py +0 -14
- octavia/network/drivers/neutron/allowed_address_pairs.py +92 -135
- octavia/network/drivers/neutron/base.py +65 -77
- octavia/network/drivers/neutron/utils.py +69 -85
- octavia/network/drivers/noop_driver/driver.py +0 -7
- octavia/statistics/drivers/update_db.py +10 -10
- octavia/tests/common/constants.py +91 -84
- octavia/tests/common/sample_data_models.py +13 -1
- octavia/tests/fixtures.py +32 -0
- octavia/tests/functional/amphorae/backend/agent/api_server/test_server.py +9 -10
- octavia/tests/functional/api/drivers/driver_agent/test_driver_agent.py +260 -15
- octavia/tests/functional/api/test_root_controller.py +3 -28
- octavia/tests/functional/api/v2/base.py +5 -3
- octavia/tests/functional/api/v2/test_amphora.py +18 -5
- octavia/tests/functional/api/v2/test_availability_zone_profiles.py +1 -0
- octavia/tests/functional/api/v2/test_listener.py +51 -19
- octavia/tests/functional/api/v2/test_load_balancer.py +10 -1
- octavia/tests/functional/db/base.py +31 -16
- octavia/tests/functional/db/test_models.py +27 -28
- octavia/tests/functional/db/test_repositories.py +407 -50
- octavia/tests/unit/amphorae/backends/agent/api_server/test_amphora_info.py +2 -0
- octavia/tests/unit/amphorae/backends/agent/api_server/test_osutils.py +1 -1
- octavia/tests/unit/amphorae/backends/agent/api_server/test_plug.py +54 -6
- octavia/tests/unit/amphorae/backends/agent/api_server/test_util.py +35 -0
- octavia/tests/unit/amphorae/backends/health_daemon/test_health_daemon.py +8 -0
- octavia/tests/unit/amphorae/backends/health_daemon/test_health_sender.py +18 -0
- octavia/tests/unit/amphorae/backends/utils/test_interface.py +81 -0
- octavia/tests/unit/amphorae/backends/utils/test_interface_file.py +2 -0
- octavia/tests/unit/amphorae/backends/utils/test_keepalivedlvs_query.py +129 -5
- octavia/tests/unit/amphorae/drivers/haproxy/test_rest_api_driver_1_0.py +42 -20
- octavia/tests/unit/amphorae/drivers/health/test_heartbeat_udp.py +18 -20
- octavia/tests/unit/amphorae/drivers/keepalived/jinja/test_jinja_cfg.py +4 -4
- octavia/tests/unit/amphorae/drivers/noop_driver/test_driver.py +4 -1
- octavia/tests/unit/api/drivers/driver_agent/test_driver_get.py +3 -3
- octavia/tests/unit/api/drivers/driver_agent/test_driver_updater.py +11 -13
- octavia/tests/unit/base.py +6 -0
- octavia/tests/unit/cmd/test_interface.py +2 -2
- octavia/tests/unit/cmd/test_status.py +2 -2
- octavia/tests/unit/common/jinja/haproxy/combined_listeners/test_jinja_cfg.py +152 -1
- octavia/tests/unit/common/sample_configs/sample_configs_combined.py +10 -3
- octavia/tests/unit/common/test_clients.py +0 -39
- octavia/tests/unit/common/test_keystone.py +54 -0
- octavia/tests/unit/common/test_validate.py +67 -0
- octavia/tests/unit/controller/healthmanager/test_health_manager.py +8 -22
- octavia/tests/unit/controller/housekeeping/test_house_keeping.py +3 -64
- octavia/tests/unit/controller/worker/test_amphora_rate_limit.py +1 -1
- octavia/tests/unit/controller/worker/test_task_utils.py +44 -24
- octavia/tests/unit/controller/worker/v2/flows/test_load_balancer_flows.py +0 -1
- octavia/tests/unit/controller/worker/v2/tasks/test_amphora_driver_tasks.py +49 -26
- octavia/tests/unit/controller/worker/v2/tasks/test_database_tasks.py +399 -196
- octavia/tests/unit/controller/worker/v2/tasks/test_database_tasks_quota.py +37 -64
- octavia/tests/unit/controller/worker/v2/tasks/test_network_tasks.py +3 -14
- octavia/tests/unit/controller/worker/v2/test_controller_worker.py +2 -2
- octavia/tests/unit/network/drivers/neutron/test_allowed_address_pairs.py +456 -561
- octavia/tests/unit/network/drivers/neutron/test_base.py +181 -194
- octavia/tests/unit/network/drivers/neutron/test_utils.py +14 -30
- octavia/tests/unit/statistics/drivers/test_update_db.py +7 -5
- {octavia-12.0.0.0rc2.data → octavia-13.0.0.0rc1.data}/data/share/octavia/README.rst +1 -1
- {octavia-12.0.0.0rc2.dist-info → octavia-13.0.0.0rc1.dist-info}/AUTHORS +4 -0
- {octavia-12.0.0.0rc2.dist-info → octavia-13.0.0.0rc1.dist-info}/METADATA +4 -4
- {octavia-12.0.0.0rc2.dist-info → octavia-13.0.0.0rc1.dist-info}/RECORD +141 -189
- {octavia-12.0.0.0rc2.dist-info → octavia-13.0.0.0rc1.dist-info}/entry_points.txt +1 -2
- octavia-13.0.0.0rc1.dist-info/pbr.json +1 -0
- octavia/api/drivers/amphora_driver/v1/__init__.py +0 -11
- octavia/api/drivers/amphora_driver/v1/driver.py +0 -547
- octavia/controller/queue/v1/__init__.py +0 -11
- octavia/controller/queue/v1/consumer.py +0 -64
- octavia/controller/queue/v1/endpoints.py +0 -160
- octavia/controller/worker/v1/__init__.py +0 -11
- octavia/controller/worker/v1/controller_worker.py +0 -1157
- octavia/controller/worker/v1/flows/__init__.py +0 -11
- octavia/controller/worker/v1/flows/amphora_flows.py +0 -610
- octavia/controller/worker/v1/flows/health_monitor_flows.py +0 -105
- octavia/controller/worker/v1/flows/l7policy_flows.py +0 -94
- octavia/controller/worker/v1/flows/l7rule_flows.py +0 -100
- octavia/controller/worker/v1/flows/listener_flows.py +0 -128
- octavia/controller/worker/v1/flows/load_balancer_flows.py +0 -692
- octavia/controller/worker/v1/flows/member_flows.py +0 -230
- octavia/controller/worker/v1/flows/pool_flows.py +0 -127
- octavia/controller/worker/v1/tasks/__init__.py +0 -11
- octavia/controller/worker/v1/tasks/amphora_driver_tasks.py +0 -453
- octavia/controller/worker/v1/tasks/cert_task.py +0 -51
- octavia/controller/worker/v1/tasks/compute_tasks.py +0 -335
- octavia/controller/worker/v1/tasks/database_tasks.py +0 -2756
- octavia/controller/worker/v1/tasks/lifecycle_tasks.py +0 -173
- octavia/controller/worker/v1/tasks/model_tasks.py +0 -41
- octavia/controller/worker/v1/tasks/network_tasks.py +0 -970
- octavia/controller/worker/v1/tasks/retry_tasks.py +0 -74
- octavia/tests/unit/api/drivers/amphora_driver/v1/__init__.py +0 -11
- octavia/tests/unit/api/drivers/amphora_driver/v1/test_driver.py +0 -824
- octavia/tests/unit/controller/queue/v1/__init__.py +0 -11
- octavia/tests/unit/controller/queue/v1/test_consumer.py +0 -61
- octavia/tests/unit/controller/queue/v1/test_endpoints.py +0 -189
- octavia/tests/unit/controller/worker/v1/__init__.py +0 -11
- octavia/tests/unit/controller/worker/v1/flows/__init__.py +0 -11
- octavia/tests/unit/controller/worker/v1/flows/test_amphora_flows.py +0 -474
- octavia/tests/unit/controller/worker/v1/flows/test_health_monitor_flows.py +0 -72
- octavia/tests/unit/controller/worker/v1/flows/test_l7policy_flows.py +0 -67
- octavia/tests/unit/controller/worker/v1/flows/test_l7rule_flows.py +0 -67
- octavia/tests/unit/controller/worker/v1/flows/test_listener_flows.py +0 -91
- octavia/tests/unit/controller/worker/v1/flows/test_load_balancer_flows.py +0 -431
- octavia/tests/unit/controller/worker/v1/flows/test_member_flows.py +0 -106
- octavia/tests/unit/controller/worker/v1/flows/test_pool_flows.py +0 -77
- octavia/tests/unit/controller/worker/v1/tasks/__init__.py +0 -11
- octavia/tests/unit/controller/worker/v1/tasks/test_amphora_driver_tasks.py +0 -792
- octavia/tests/unit/controller/worker/v1/tasks/test_cert_task.py +0 -46
- octavia/tests/unit/controller/worker/v1/tasks/test_compute_tasks.py +0 -634
- octavia/tests/unit/controller/worker/v1/tasks/test_database_tasks.py +0 -2615
- octavia/tests/unit/controller/worker/v1/tasks/test_database_tasks_quota.py +0 -415
- octavia/tests/unit/controller/worker/v1/tasks/test_lifecycle_tasks.py +0 -401
- octavia/tests/unit/controller/worker/v1/tasks/test_model_tasks.py +0 -44
- octavia/tests/unit/controller/worker/v1/tasks/test_network_tasks.py +0 -1788
- octavia/tests/unit/controller/worker/v1/tasks/test_retry_tasks.py +0 -47
- octavia/tests/unit/controller/worker/v1/test_controller_worker.py +0 -2096
- octavia-12.0.0.0rc2.dist-info/pbr.json +0 -1
- {octavia-12.0.0.0rc2.data → octavia-13.0.0.0rc1.data}/data/share/octavia/LICENSE +0 -0
- {octavia-12.0.0.0rc2.data → octavia-13.0.0.0rc1.data}/data/share/octavia/diskimage-create/README.rst +0 -0
- {octavia-12.0.0.0rc2.data → octavia-13.0.0.0rc1.data}/data/share/octavia/diskimage-create/diskimage-create.sh +0 -0
- {octavia-12.0.0.0rc2.data → octavia-13.0.0.0rc1.data}/data/share/octavia/diskimage-create/image-tests.sh +0 -0
- {octavia-12.0.0.0rc2.data → octavia-13.0.0.0rc1.data}/data/share/octavia/diskimage-create/requirements.txt +0 -0
- {octavia-12.0.0.0rc2.data → octavia-13.0.0.0rc1.data}/data/share/octavia/diskimage-create/test-requirements.txt +0 -0
- {octavia-12.0.0.0rc2.data → octavia-13.0.0.0rc1.data}/data/share/octavia/diskimage-create/tox.ini +0 -0
- {octavia-12.0.0.0rc2.data → octavia-13.0.0.0rc1.data}/data/share/octavia/diskimage-create/version.txt +0 -0
- {octavia-12.0.0.0rc2.data → octavia-13.0.0.0rc1.data}/scripts/octavia-wsgi +0 -0
- {octavia-12.0.0.0rc2.dist-info → octavia-13.0.0.0rc1.dist-info}/LICENSE +0 -0
- {octavia-12.0.0.0rc2.dist-info → octavia-13.0.0.0rc1.dist-info}/WHEEL +0 -0
- {octavia-12.0.0.0rc2.dist-info → octavia-13.0.0.0rc1.dist-info}/top_level.txt +0 -0
@@ -55,16 +55,10 @@ class CalculateAmphoraDelta(BaseNetworkTask):
|
|
55
55
|
|
56
56
|
default_provides = constants.DELTA
|
57
57
|
|
58
|
-
# TODO(gthiemonge) ensure we no longer need vrrp_port
|
59
58
|
def execute(self, loadbalancer, amphora, availability_zone):
|
60
59
|
LOG.debug("Calculating network delta for amphora id: %s",
|
61
60
|
amphora.get(constants.ID))
|
62
61
|
|
63
|
-
vip_subnet_to_net_map = {
|
64
|
-
loadbalancer[constants.VIP_SUBNET_ID]:
|
65
|
-
loadbalancer[constants.VIP_NETWORK_ID]
|
66
|
-
}
|
67
|
-
|
68
62
|
# Figure out what networks we want
|
69
63
|
# seed with lb network(s)
|
70
64
|
if (availability_zone and
|
@@ -74,15 +68,15 @@ class CalculateAmphoraDelta(BaseNetworkTask):
|
|
74
68
|
else:
|
75
69
|
management_nets = CONF.controller_worker.amp_boot_network_list
|
76
70
|
|
77
|
-
|
78
|
-
|
71
|
+
session = db_apis.get_session()
|
72
|
+
with session.begin():
|
73
|
+
db_lb = self.loadbalancer_repo.get(
|
74
|
+
session, id=loadbalancer[constants.LOADBALANCER_ID])
|
79
75
|
|
80
|
-
desired_subnet_to_net_map = {
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
desired_subnet_to_net_map[subnet_id] = mgmt_net_id
|
85
|
-
desired_subnet_to_net_map.update(vip_subnet_to_net_map)
|
76
|
+
desired_subnet_to_net_map = {
|
77
|
+
loadbalancer[constants.VIP_SUBNET_ID]:
|
78
|
+
loadbalancer[constants.VIP_NETWORK_ID]
|
79
|
+
}
|
86
80
|
|
87
81
|
for pool in db_lb.pools:
|
88
82
|
for member in pool.members:
|
@@ -101,7 +95,12 @@ class CalculateAmphoraDelta(BaseNetworkTask):
|
|
101
95
|
nics = self.network_driver.get_plugged_networks(
|
102
96
|
amphora[constants.COMPUTE_ID])
|
103
97
|
# we don't have two nics in the same network
|
104
|
-
|
98
|
+
# Don't include the nics connected to the management network, we don't
|
99
|
+
# want to update these interfaces.
|
100
|
+
network_to_nic_map = {
|
101
|
+
nic.network_id: nic
|
102
|
+
for nic in nics
|
103
|
+
if nic.network_id not in management_nets}
|
105
104
|
|
106
105
|
plugged_network_ids = set(network_to_nic_map)
|
107
106
|
|
@@ -183,8 +182,10 @@ class CalculateDelta(BaseNetworkTask):
|
|
183
182
|
|
184
183
|
calculate_amp = CalculateAmphoraDelta()
|
185
184
|
deltas = {}
|
186
|
-
|
187
|
-
|
185
|
+
session = db_apis.get_session()
|
186
|
+
with session.begin():
|
187
|
+
db_lb = self.loadbalancer_repo.get(
|
188
|
+
session, id=loadbalancer[constants.LOADBALANCER_ID])
|
188
189
|
for amphora in filter(
|
189
190
|
lambda amp: amp.status == constants.AMPHORA_ALLOCATED,
|
190
191
|
db_lb.amphorae):
|
@@ -317,8 +318,10 @@ class HandleNetworkDelta(BaseNetworkTask):
|
|
317
318
|
|
318
319
|
def execute(self, amphora, delta):
|
319
320
|
"""Handle network plugging based off deltas."""
|
320
|
-
|
321
|
-
|
321
|
+
session = db_apis.get_session()
|
322
|
+
with session.begin():
|
323
|
+
db_amp = self.amphora_repo.get(session,
|
324
|
+
id=amphora.get(constants.ID))
|
322
325
|
updated_ports = {}
|
323
326
|
for nic in delta[constants.ADD_NICS]:
|
324
327
|
subnet_id = nic[constants.FIXED_IPS][0][constants.SUBNET_ID]
|
@@ -432,8 +435,10 @@ class HandleNetworkDeltas(BaseNetworkTask):
|
|
432
435
|
|
433
436
|
def execute(self, deltas, loadbalancer):
|
434
437
|
"""Handle network plugging based off deltas."""
|
435
|
-
|
436
|
-
|
438
|
+
session = db_apis.get_session()
|
439
|
+
with session.begin():
|
440
|
+
db_lb = self.loadbalancer_repo.get(
|
441
|
+
session, id=loadbalancer[constants.LOADBALANCER_ID])
|
437
442
|
amphorae = {amp.id: amp for amp in db_lb.amphorae}
|
438
443
|
|
439
444
|
updated_ports = {}
|
@@ -481,9 +486,11 @@ class PlugVIP(BaseNetworkTask):
|
|
481
486
|
|
482
487
|
LOG.debug("Plumbing VIP for loadbalancer id: %s",
|
483
488
|
loadbalancer[constants.LOADBALANCER_ID])
|
484
|
-
|
485
|
-
|
486
|
-
|
489
|
+
session = db_apis.get_session()
|
490
|
+
with session.begin():
|
491
|
+
db_lb = self.loadbalancer_repo.get(
|
492
|
+
session,
|
493
|
+
id=loadbalancer[constants.LOADBALANCER_ID])
|
487
494
|
amps_data = self.network_driver.plug_vip(db_lb,
|
488
495
|
db_lb.vip)
|
489
496
|
return [amp.to_dict() for amp in amps_data]
|
@@ -496,9 +503,11 @@ class PlugVIP(BaseNetworkTask):
|
|
496
503
|
LOG.warning("Unable to plug VIP for loadbalancer id %s",
|
497
504
|
loadbalancer[constants.LOADBALANCER_ID])
|
498
505
|
|
499
|
-
|
500
|
-
|
501
|
-
|
506
|
+
session = db_apis.get_session()
|
507
|
+
with session.begin():
|
508
|
+
db_lb = self.loadbalancer_repo.get(
|
509
|
+
session,
|
510
|
+
id=loadbalancer[constants.LOADBALANCER_ID])
|
502
511
|
try:
|
503
512
|
# Make sure we have the current port IDs for cleanup
|
504
513
|
for amp_data in result:
|
@@ -524,8 +533,10 @@ class UpdateVIPSecurityGroup(BaseNetworkTask):
|
|
524
533
|
|
525
534
|
LOG.debug("Setting up VIP SG for load balancer id: %s",
|
526
535
|
loadbalancer_id)
|
527
|
-
|
528
|
-
|
536
|
+
session = db_apis.get_session()
|
537
|
+
with session.begin():
|
538
|
+
db_lb = self.loadbalancer_repo.get(
|
539
|
+
session, id=loadbalancer_id)
|
529
540
|
|
530
541
|
sg_id = self.network_driver.update_vip_sg(db_lb, db_lb.vip)
|
531
542
|
LOG.info("Set up VIP SG %s for load balancer %s complete",
|
@@ -557,11 +568,13 @@ class PlugVIPAmphora(BaseNetworkTask):
|
|
557
568
|
|
558
569
|
LOG.debug("Plumbing VIP for amphora id: %s",
|
559
570
|
amphora.get(constants.ID))
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
571
|
+
session = db_apis.get_session()
|
572
|
+
with session.begin():
|
573
|
+
db_amp = self.amphora_repo.get(session,
|
574
|
+
id=amphora.get(constants.ID))
|
575
|
+
db_subnet = self.network_driver.get_subnet(subnet[constants.ID])
|
576
|
+
db_lb = self.loadbalancer_repo.get(
|
577
|
+
session, id=loadbalancer[constants.LOADBALANCER_ID])
|
565
578
|
amp_data = self.network_driver.plug_aap_port(
|
566
579
|
db_lb, db_lb.vip, db_amp, db_subnet)
|
567
580
|
return amp_data.to_dict()
|
@@ -576,14 +589,17 @@ class PlugVIPAmphora(BaseNetworkTask):
|
|
576
589
|
loadbalancer[constants.LOADBALANCER_ID])
|
577
590
|
|
578
591
|
try:
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
592
|
+
session = db_apis.get_session()
|
593
|
+
with session.begin():
|
594
|
+
db_amp = self.amphora_repo.get(session,
|
595
|
+
id=amphora.get(constants.ID))
|
596
|
+
db_amp.vrrp_port_id = result[constants.VRRP_PORT_ID]
|
597
|
+
db_amp.ha_port_id = result[constants.HA_PORT_ID]
|
598
|
+
db_subnet = self.network_driver.get_subnet(
|
599
|
+
subnet[constants.ID])
|
600
|
+
db_lb = self.loadbalancer_repo.get(
|
601
|
+
session,
|
602
|
+
id=loadbalancer[constants.LOADBALANCER_ID])
|
587
603
|
|
588
604
|
self.network_driver.unplug_aap_port(db_lb.vip,
|
589
605
|
db_amp, db_subnet)
|
@@ -600,9 +616,11 @@ class UnplugVIP(BaseNetworkTask):
|
|
600
616
|
|
601
617
|
LOG.debug("Unplug vip on amphora")
|
602
618
|
try:
|
603
|
-
|
604
|
-
|
605
|
-
|
619
|
+
session = db_apis.get_session()
|
620
|
+
with session.begin():
|
621
|
+
db_lb = self.loadbalancer_repo.get(
|
622
|
+
session,
|
623
|
+
id=loadbalancer[constants.LOADBALANCER_ID])
|
606
624
|
self.network_driver.unplug_vip(db_lb, db_lb.vip)
|
607
625
|
except Exception:
|
608
626
|
LOG.exception("Unable to unplug vip from load balancer %s",
|
@@ -621,8 +639,10 @@ class AllocateVIP(BaseNetworkTask):
|
|
621
639
|
loadbalancer[constants.VIP_SUBNET_ID],
|
622
640
|
loadbalancer[constants.VIP_ADDRESS],
|
623
641
|
loadbalancer[constants.LOADBALANCER_ID])
|
624
|
-
|
625
|
-
|
642
|
+
session = db_apis.get_session()
|
643
|
+
with session.begin():
|
644
|
+
db_lb = self.loadbalancer_repo.get(
|
645
|
+
session, id=loadbalancer[constants.LOADBALANCER_ID])
|
626
646
|
vip, additional_vips = self.network_driver.allocate_vip(db_lb)
|
627
647
|
LOG.info("Allocated vip with port id %s, subnet id %s, ip address %s "
|
628
648
|
"for load balancer %s",
|
@@ -682,10 +702,12 @@ class DeallocateVIP(BaseNetworkTask):
|
|
682
702
|
# will need access to the load balancer that the vip is/was attached
|
683
703
|
# to. However the data model serialization for the vip does not give a
|
684
704
|
# backref to the loadbalancer if accessed through the loadbalancer.
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
705
|
+
session = db_apis.get_session()
|
706
|
+
with session.begin():
|
707
|
+
db_lb = self.loadbalancer_repo.get(
|
708
|
+
session, id=loadbalancer[constants.LOADBALANCER_ID])
|
709
|
+
vip = db_lb.vip
|
710
|
+
vip.load_balancer = db_lb
|
689
711
|
self.network_driver.deallocate_vip(vip)
|
690
712
|
|
691
713
|
|
@@ -693,8 +715,10 @@ class UpdateVIP(BaseNetworkTask):
|
|
693
715
|
"""Task to update a VIP."""
|
694
716
|
|
695
717
|
def execute(self, listeners):
|
696
|
-
|
697
|
-
|
718
|
+
session = db_apis.get_session()
|
719
|
+
with session.begin():
|
720
|
+
loadbalancer = self.loadbalancer_repo.get(
|
721
|
+
session, id=listeners[0][constants.LOADBALANCER_ID])
|
698
722
|
|
699
723
|
LOG.debug("Updating VIP of load_balancer %s.", loadbalancer.id)
|
700
724
|
|
@@ -705,8 +729,10 @@ class UpdateVIPForDelete(BaseNetworkTask):
|
|
705
729
|
"""Task to update a VIP for listener delete flows."""
|
706
730
|
|
707
731
|
def execute(self, loadbalancer_id):
|
708
|
-
|
709
|
-
|
732
|
+
session = db_apis.get_session()
|
733
|
+
with session.begin():
|
734
|
+
loadbalancer = self.loadbalancer_repo.get(
|
735
|
+
session, id=loadbalancer_id)
|
710
736
|
LOG.debug("Updating VIP for listener delete on load_balancer %s.",
|
711
737
|
loadbalancer.id)
|
712
738
|
self.network_driver.update_vip(loadbalancer, for_delete=True)
|
@@ -717,10 +743,12 @@ class GetAmphoraNetworkConfigs(BaseNetworkTask):
|
|
717
743
|
|
718
744
|
def execute(self, loadbalancer, amphora=None):
|
719
745
|
LOG.debug("Retrieving vip network details.")
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
746
|
+
session = db_apis.get_session()
|
747
|
+
with session.begin():
|
748
|
+
db_amp = self.amphora_repo.get(session,
|
749
|
+
id=amphora.get(constants.ID))
|
750
|
+
db_lb = self.loadbalancer_repo.get(
|
751
|
+
session, id=loadbalancer[constants.LOADBALANCER_ID])
|
724
752
|
db_configs = self.network_driver.get_network_configs(
|
725
753
|
db_lb, amphora=db_amp)
|
726
754
|
provider_dict = {}
|
@@ -734,9 +762,11 @@ class GetAmphoraNetworkConfigsByID(BaseNetworkTask):
|
|
734
762
|
|
735
763
|
def execute(self, loadbalancer_id, amphora_id=None):
|
736
764
|
LOG.debug("Retrieving vip network details.")
|
737
|
-
|
738
|
-
|
739
|
-
|
765
|
+
session = db_apis.get_session()
|
766
|
+
with session.begin():
|
767
|
+
loadbalancer = self.loadbalancer_repo.get(session,
|
768
|
+
id=loadbalancer_id)
|
769
|
+
amphora = self.amphora_repo.get(session, id=amphora_id)
|
740
770
|
db_configs = self.network_driver.get_network_configs(loadbalancer,
|
741
771
|
amphora=amphora)
|
742
772
|
provider_dict = {}
|
@@ -750,8 +780,10 @@ class GetAmphoraeNetworkConfigs(BaseNetworkTask):
|
|
750
780
|
|
751
781
|
def execute(self, loadbalancer_id):
|
752
782
|
LOG.debug("Retrieving vip network details.")
|
753
|
-
|
754
|
-
|
783
|
+
session = db_apis.get_session()
|
784
|
+
with session.begin():
|
785
|
+
db_lb = self.loadbalancer_repo.get(
|
786
|
+
session, id=loadbalancer_id)
|
755
787
|
db_configs = self.network_driver.get_network_configs(db_lb)
|
756
788
|
provider_dict = {}
|
757
789
|
for amp_id, amp_conf in db_configs.items():
|
@@ -763,8 +795,10 @@ class FailoverPreparationForAmphora(BaseNetworkTask):
|
|
763
795
|
"""Task to prepare an amphora for failover."""
|
764
796
|
|
765
797
|
def execute(self, amphora):
|
766
|
-
|
767
|
-
|
798
|
+
session = db_apis.get_session()
|
799
|
+
with session.begin():
|
800
|
+
db_amp = self.amphora_repo.get(session,
|
801
|
+
id=amphora[constants.ID])
|
768
802
|
LOG.debug("Prepare amphora %s for failover.", amphora[constants.ID])
|
769
803
|
|
770
804
|
self.network_driver.failover_preparation(db_amp)
|
@@ -799,8 +833,10 @@ class PlugPorts(BaseNetworkTask):
|
|
799
833
|
"""Task to plug neutron ports into a compute instance."""
|
800
834
|
|
801
835
|
def execute(self, amphora, ports):
|
802
|
-
|
803
|
-
|
836
|
+
session = db_apis.get_session()
|
837
|
+
with session.begin():
|
838
|
+
db_amp = self.amphora_repo.get(session,
|
839
|
+
id=amphora[constants.ID])
|
804
840
|
for port in ports:
|
805
841
|
LOG.debug('Plugging port ID: %(port_id)s into compute instance: '
|
806
842
|
'%(compute_id)s.',
|
@@ -816,15 +852,17 @@ class ApplyQos(BaseNetworkTask):
|
|
816
852
|
is_revert=False, request_qos_id=None):
|
817
853
|
"""Call network driver to apply QoS Policy on the vrrp ports."""
|
818
854
|
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
855
|
+
session = db_apis.get_session()
|
856
|
+
with session.begin():
|
857
|
+
if not amps_data:
|
858
|
+
db_lb = self.loadbalancer_repo.get(
|
859
|
+
session,
|
860
|
+
id=loadbalancer[constants.LOADBALANCER_ID])
|
861
|
+
amps_data = db_lb.amphorae
|
824
862
|
|
825
|
-
|
826
|
-
|
827
|
-
|
863
|
+
amps_data = [amp
|
864
|
+
for amp in amps_data
|
865
|
+
if amp.status == constants.AMPHORA_ALLOCATED]
|
828
866
|
|
829
867
|
apply_qos = ApplyQosAmphora()
|
830
868
|
for amp_data in amps_data:
|
@@ -833,9 +871,11 @@ class ApplyQos(BaseNetworkTask):
|
|
833
871
|
|
834
872
|
def execute(self, loadbalancer, amps_data=None, update_dict=None):
|
835
873
|
"""Apply qos policy on the vrrp ports which are related with vip."""
|
836
|
-
|
837
|
-
|
838
|
-
|
874
|
+
session = db_apis.get_session()
|
875
|
+
with session.begin():
|
876
|
+
db_lb = self.loadbalancer_repo.get(
|
877
|
+
session,
|
878
|
+
id=loadbalancer[constants.LOADBALANCER_ID])
|
839
879
|
|
840
880
|
qos_policy_id = db_lb.vip.qos_policy_id
|
841
881
|
if not qos_policy_id and (
|
octavia/db/api.py
CHANGED
@@ -12,15 +12,13 @@
|
|
12
12
|
# License for the specific language governing permissions and limitations
|
13
13
|
# under the License.
|
14
14
|
|
15
|
-
import contextlib
|
16
15
|
import time
|
17
16
|
|
18
17
|
from sqlalchemy.sql.expression import select
|
19
18
|
|
20
19
|
from oslo_config import cfg
|
21
|
-
from oslo_db.sqlalchemy import
|
20
|
+
from oslo_db.sqlalchemy import enginefacade
|
22
21
|
from oslo_log import log as logging
|
23
|
-
from oslo_utils import excutils
|
24
22
|
|
25
23
|
LOG = logging.getLogger(__name__)
|
26
24
|
_FACADE = None
|
@@ -29,32 +27,37 @@ _FACADE = None
|
|
29
27
|
def _create_facade_lazily():
|
30
28
|
global _FACADE
|
31
29
|
if _FACADE is None:
|
32
|
-
_FACADE =
|
33
|
-
|
30
|
+
_FACADE = True
|
31
|
+
enginefacade.configure(sqlite_fk=True, expire_on_commit=True)
|
32
|
+
|
33
|
+
|
34
|
+
def _get_transaction_context(reader=False):
|
35
|
+
_create_facade_lazily()
|
36
|
+
# TODO(gthiemonge) Create and use new functions to get read-only sessions
|
37
|
+
if reader:
|
38
|
+
context = enginefacade.reader
|
39
|
+
else:
|
40
|
+
context = enginefacade.writer
|
41
|
+
return context
|
42
|
+
|
43
|
+
|
44
|
+
def _get_sessionmaker(reader=False):
|
45
|
+
context = _get_transaction_context(reader)
|
46
|
+
return context.get_sessionmaker()
|
34
47
|
|
35
48
|
|
36
49
|
def get_engine():
|
37
|
-
|
38
|
-
return
|
50
|
+
context = _get_transaction_context()
|
51
|
+
return context.get_engine()
|
39
52
|
|
40
53
|
|
41
|
-
def get_session(
|
54
|
+
def get_session():
|
42
55
|
"""Helper method to grab session."""
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
@contextlib.contextmanager
|
49
|
-
def get_lock_session():
|
50
|
-
"""Context manager for using a locking (not auto-commit) session."""
|
51
|
-
lock_session = get_session(autocommit=False)
|
52
|
-
try:
|
53
|
-
yield lock_session
|
54
|
-
lock_session.commit()
|
55
|
-
except Exception:
|
56
|
-
with excutils.save_and_reraise_exception():
|
57
|
-
lock_session.rollback()
|
56
|
+
return _get_sessionmaker()()
|
57
|
+
|
58
|
+
|
59
|
+
def session():
|
60
|
+
return _get_sessionmaker()
|
58
61
|
|
59
62
|
|
60
63
|
def wait_for_connection(exit_event):
|
octavia/db/base_models.py
CHANGED
@@ -16,8 +16,8 @@ from oslo_db.sqlalchemy import models
|
|
16
16
|
from oslo_utils import strutils
|
17
17
|
from oslo_utils import uuidutils
|
18
18
|
import sqlalchemy as sa
|
19
|
-
from sqlalchemy.ext import declarative
|
20
19
|
from sqlalchemy.orm import collections
|
20
|
+
from sqlalchemy.orm import declarative_base
|
21
21
|
|
22
22
|
|
23
23
|
class OctaviaBase(models.ModelBase):
|
@@ -189,7 +189,7 @@ class TagMixin(object):
|
|
189
189
|
self._tags = new_tags
|
190
190
|
|
191
191
|
|
192
|
-
BASE =
|
192
|
+
BASE = declarative_base(cls=OctaviaBase)
|
193
193
|
|
194
194
|
|
195
195
|
class Tags(BASE):
|
octavia/db/healthcheck.py
CHANGED
@@ -12,6 +12,7 @@
|
|
12
12
|
# License for the specific language governing permissions and limitations
|
13
13
|
# under the License.
|
14
14
|
from oslo_log import log as logging
|
15
|
+
from sqlalchemy import text
|
15
16
|
|
16
17
|
from octavia.i18n import _
|
17
18
|
|
@@ -28,7 +29,7 @@ def check_database_connection(session):
|
|
28
29
|
:returns: True if the connection check is successful, False if not.
|
29
30
|
"""
|
30
31
|
try:
|
31
|
-
session.execute('SELECT 1;')
|
32
|
+
session.execute(text('SELECT 1;'))
|
32
33
|
return True, None
|
33
34
|
except Exception as e:
|
34
35
|
message = _('Database health check failed due to: {err}.').format(
|
octavia/db/migration/alembic_migrations/versions/632152d2d32e_add_http_strict_transport_security_.py
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
2
|
+
# not use this file except in compliance with the License. You may obtain
|
3
|
+
# a copy of the License at
|
4
|
+
#
|
5
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
6
|
+
#
|
7
|
+
# Unless required by applicable law or agreed to in writing, software
|
8
|
+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
9
|
+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
10
|
+
# License for the specific language governing permissions and limitations
|
11
|
+
# under the License.
|
12
|
+
|
13
|
+
"""Add HTTP Strict Transport Security support
|
14
|
+
|
15
|
+
Revision ID: 632152d2d32e
|
16
|
+
Revises: 0995c26fc506
|
17
|
+
Create Date: 2023-04-19 13:36:44.015581
|
18
|
+
|
19
|
+
"""
|
20
|
+
|
21
|
+
from alembic import op
|
22
|
+
import sqlalchemy as sa
|
23
|
+
|
24
|
+
|
25
|
+
# revision identifiers, used by Alembic.
|
26
|
+
revision = '632152d2d32e'
|
27
|
+
down_revision = '0995c26fc506'
|
28
|
+
|
29
|
+
|
30
|
+
def upgrade():
|
31
|
+
op.add_column(
|
32
|
+
'listener',
|
33
|
+
sa.Column('hsts_max_age', sa.Integer, nullable=True)
|
34
|
+
)
|
35
|
+
op.add_column(
|
36
|
+
'listener',
|
37
|
+
sa.Column('hsts_include_subdomains', sa.Boolean, nullable=True)
|
38
|
+
)
|
39
|
+
op.add_column(
|
40
|
+
'listener',
|
41
|
+
sa.Column('hsts_preload', sa.Boolean, nullable=True)
|
42
|
+
)
|
octavia/db/models.py
CHANGED
@@ -19,6 +19,7 @@ from oslo_db.sqlalchemy import models
|
|
19
19
|
import sqlalchemy as sa
|
20
20
|
from sqlalchemy.ext import orderinglist
|
21
21
|
from sqlalchemy import orm
|
22
|
+
from sqlalchemy.orm import Mapped
|
22
23
|
from sqlalchemy.orm import validates
|
23
24
|
from sqlalchemy.sql import func
|
24
25
|
from sqlalchemy_utils import ScalarListType
|
@@ -353,7 +354,8 @@ class Pool(base_models.BASE, base_models.IdMixin, base_models.ProjectMixin,
|
|
353
354
|
"SessionPersistence", uselist=False, cascade="delete",
|
354
355
|
back_populates="pool")
|
355
356
|
_default_listeners = orm.relationship("Listener", uselist=True,
|
356
|
-
back_populates="default_pool"
|
357
|
+
back_populates="default_pool",
|
358
|
+
cascade_backrefs=False)
|
357
359
|
l7policies = orm.relationship("L7Policy", uselist=True,
|
358
360
|
back_populates="redirect_pool")
|
359
361
|
_tags = orm.relationship(
|
@@ -453,6 +455,7 @@ class LoadBalancer(base_models.BASE, base_models.IdMixin,
|
|
453
455
|
sa.ForeignKey("availability_zone.name",
|
454
456
|
name="fk_load_balancer_availability_zone_name"),
|
455
457
|
nullable=True)
|
458
|
+
flavor: Mapped["Flavor"] = orm.relationship("Flavor")
|
456
459
|
|
457
460
|
def __str__(self):
|
458
461
|
return (f"LoadBalancer(id={self.id!r}, name={self.name!r}, "
|
@@ -573,7 +576,8 @@ class Listener(base_models.BASE, base_models.IdMixin,
|
|
573
576
|
load_balancer = orm.relationship("LoadBalancer", uselist=False,
|
574
577
|
back_populates="listeners")
|
575
578
|
default_pool = orm.relationship("Pool", uselist=False,
|
576
|
-
back_populates="_default_listeners"
|
579
|
+
back_populates="_default_listeners",
|
580
|
+
cascade_backrefs=False)
|
577
581
|
sni_containers = orm.relationship(
|
578
582
|
'SNI', cascade='all,delete-orphan',
|
579
583
|
uselist=True, backref=orm.backref('listener', uselist=False))
|
@@ -599,6 +603,9 @@ class Listener(base_models.BASE, base_models.IdMixin,
|
|
599
603
|
tls_ciphers = sa.Column(sa.String(2048), nullable=True)
|
600
604
|
tls_versions = sa.Column(ScalarListType(), nullable=True)
|
601
605
|
alpn_protocols = sa.Column(ScalarListType(), nullable=True)
|
606
|
+
hsts_max_age = sa.Column(sa.Integer, nullable=True)
|
607
|
+
hsts_include_subdomains = sa.Column(sa.Boolean, nullable=True)
|
608
|
+
hsts_preload = sa.Column(sa.Boolean, nullable=True)
|
602
609
|
|
603
610
|
_tags = orm.relationship(
|
604
611
|
'Tags',
|
@@ -907,6 +914,7 @@ class Flavor(base_models.BASE,
|
|
907
914
|
sa.ForeignKey("flavor_profile.id",
|
908
915
|
name="fk_flavor_flavor_profile_id"),
|
909
916
|
nullable=False)
|
917
|
+
flavor_profile: Mapped["FlavorProfile"] = orm.relationship("FlavorProfile")
|
910
918
|
|
911
919
|
|
912
920
|
class AvailabilityZoneProfile(base_models.BASE, base_models.IdMixin,
|
@@ -942,6 +950,8 @@ class AvailabilityZone(base_models.BASE,
|
|
942
950
|
sa.ForeignKey("availability_zone_profile.id",
|
943
951
|
name="fk_az_az_profile_id"),
|
944
952
|
nullable=False)
|
953
|
+
availability_zone_profile: Mapped["AvailabilityZoneProfile"] = (
|
954
|
+
orm.relationship("AvailabilityZoneProfile"))
|
945
955
|
|
946
956
|
|
947
957
|
class ClientAuthenticationMode(base_models.BASE):
|
octavia/db/prepare.py
CHANGED
@@ -169,6 +169,8 @@ def create_pool(pool_dict, lb_id=None):
|
|
169
169
|
|
170
170
|
|
171
171
|
def create_member(member_dict, pool_id, has_health_monitor=False):
|
172
|
+
if not member_dict.get('id'):
|
173
|
+
member_dict['id'] = uuidutils.generate_uuid()
|
172
174
|
member_dict['pool_id'] = pool_id
|
173
175
|
member_dict[constants.PROVISIONING_STATUS] = constants.PENDING_CREATE
|
174
176
|
if has_health_monitor:
|