From 36a9c13e3b1898aaeb6c21f1e0d004533b711a27 Mon Sep 17 00:00:00 2001 From: Gregory Thiemonge Date: Tue, 9 Nov 2021 10:56:39 +0100 Subject: [PATCH] Fix PortNotFound exception when updating a LB after a failover The ApplyQos task applied the qos policy on the VRRP ports of all the amphorae linked to a load balancer, including amphorae in DELETED status. It triggered an ERROR when updating a LB (with a qos policy) after a failover. Story 2009667 Task 43894 Change-Id: I876fd91fb40d9250381bbb37f8148b53692a7d8d (cherry picked from commit c3481d04a25c4e6f03ce4de720c620730188d99e) (cherry picked from commit 328ffc00cf5fc74eed6889bae2594cded1f8cd9b) (cherry picked from commit 8b28293ddbe6e74170c253b55fafee3e057c47b4) (cherry picked from commit b8d68e6e3d16dd29e3b4ba58b0cb3b54780500f7) --- octavia/controller/worker/v1/tasks/network_tasks.py | 4 ++++ octavia/controller/worker/v2/tasks/network_tasks.py | 4 ++++ octavia/tests/common/constants.py | 4 ++++ .../unit/controller/worker/v1/tasks/test_network_tasks.py | 8 +++++++- .../unit/controller/worker/v2/tasks/test_network_tasks.py | 8 +++++++- .../fix-qos-apply-after-failover-561abbd153ab88ee.yaml | 6 ++++++ 6 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 releasenotes/notes/fix-qos-apply-after-failover-561abbd153ab88ee.yaml diff --git a/octavia/controller/worker/v1/tasks/network_tasks.py b/octavia/controller/worker/v1/tasks/network_tasks.py index 53abc698b2..b071ab95db 100644 --- a/octavia/controller/worker/v1/tasks/network_tasks.py +++ b/octavia/controller/worker/v1/tasks/network_tasks.py @@ -605,6 +605,10 @@ class ApplyQos(BaseNetworkTask): if not amps_data: amps_data = loadbalancer.amphorae + amps_data = [amp + for amp in amps_data + if amp.status == constants.AMPHORA_ALLOCATED] + apply_qos = ApplyQosAmphora() for amp_data in amps_data: apply_qos._apply_qos_on_vrrp_port(loadbalancer, amp_data, diff --git a/octavia/controller/worker/v2/tasks/network_tasks.py b/octavia/controller/worker/v2/tasks/network_tasks.py index 6e715dff9c..0646cc4dcd 100644 --- a/octavia/controller/worker/v2/tasks/network_tasks.py +++ b/octavia/controller/worker/v2/tasks/network_tasks.py @@ -679,6 +679,10 @@ class ApplyQos(BaseNetworkTask): id=loadbalancer[constants.LOADBALANCER_ID]) amps_data = db_lb.amphorae + amps_data = [amp + for amp in amps_data + if amp.status == constants.AMPHORA_ALLOCATED] + apply_qos = ApplyQosAmphora() for amp_data in amps_data: apply_qos._apply_qos_on_vrrp_port(loadbalancer, amp_data.to_dict(), diff --git a/octavia/tests/common/constants.py b/octavia/tests/common/constants.py index e07e7db4d0..43ae5dd28a 100644 --- a/octavia/tests/common/constants.py +++ b/octavia/tests/common/constants.py @@ -177,8 +177,10 @@ MOCK_FLOATING_IP = {'floatingip': {'id': MOCK_FLOATING_IP_ID, MOCK_AMP_ID1 = 'amp1-id' MOCK_AMP_ID2 = 'amp2-id' +MOCK_AMP_ID3 = 'amp3-id' MOCK_AMP_COMPUTE_ID1 = 'amp1-compute-id' MOCK_AMP_COMPUTE_ID2 = 'amp2-compute-id' +MOCK_AMP_COMPUTE_ID3 = 'amp3-compute-id' MOCK_MANAGEMENT_SUBNET_ID = 'mgmt-subnet-1' MOCK_MANAGEMENT_NET_ID = 'mgmt-net-1' @@ -218,9 +220,11 @@ MOCK_VIP_SUBNET_ID = 'vip-subnet-1' MOCK_VIP_NET_ID = 'vip-net-1' MOCK_VRRP_PORT_ID1 = 'vrrp-port-1' MOCK_VRRP_PORT_ID2 = 'vrrp-port-2' +MOCK_VRRP_PORT_ID3 = 'vrrp-port-3' # These IPs become vrrp_ip MOCK_VRRP_IP1 = '55.55.55.1' MOCK_VRRP_IP2 = '55.55.55.2' +MOCK_VRRP_IP3 = '55.55.55.3' MOCK_VRRP_FIXED_IPS1 = [{'ip_address': MOCK_VRRP_IP1, 'subnet_id': MOCK_VIP_SUBNET_ID}] diff --git a/octavia/tests/unit/controller/worker/v1/tasks/test_network_tasks.py b/octavia/tests/unit/controller/worker/v1/tasks/test_network_tasks.py index 0832c0ac04..be9f6a8c05 100644 --- a/octavia/tests/unit/controller/worker/v1/tasks/test_network_tasks.py +++ b/octavia/tests/unit/controller/worker/v1/tasks/test_network_tasks.py @@ -50,11 +50,17 @@ INTERFACE = data_models.Interface(id=uuidutils.generate_uuid(), compute_id=COMPUTE_ID, fixed_ips=FIXED_IPS, port_id=PORT_ID) AMPS_DATA = [o_data_models.Amphora(id=t_constants.MOCK_AMP_ID1, + status=constants.AMPHORA_ALLOCATED, vrrp_port_id=t_constants.MOCK_VRRP_PORT_ID1, vrrp_ip=t_constants.MOCK_VRRP_IP1), o_data_models.Amphora(id=t_constants.MOCK_AMP_ID2, + status=constants.AMPHORA_ALLOCATED, vrrp_port_id=t_constants.MOCK_VRRP_PORT_ID2, - vrrp_ip=t_constants.MOCK_VRRP_IP2) + vrrp_ip=t_constants.MOCK_VRRP_IP2), + o_data_models.Amphora(id=t_constants.MOCK_AMP_ID3, + status=constants.DELETED, + vrrp_port_id=t_constants.MOCK_VRRP_PORT_ID3, + vrrp_ip=t_constants.MOCK_VRRP_IP3) ] UPDATE_DICT = {constants.TOPOLOGY: None} diff --git a/octavia/tests/unit/controller/worker/v2/tasks/test_network_tasks.py b/octavia/tests/unit/controller/worker/v2/tasks/test_network_tasks.py index b2e0eb609d..ae4e380403 100644 --- a/octavia/tests/unit/controller/worker/v2/tasks/test_network_tasks.py +++ b/octavia/tests/unit/controller/worker/v2/tasks/test_network_tasks.py @@ -52,11 +52,17 @@ INTERFACE = data_models.Interface(id=uuidutils.generate_uuid(), compute_id=COMPUTE_ID, fixed_ips=FIXED_IPS, port_id=PORT_ID) AMPS_DATA = [o_data_models.Amphora(id=t_constants.MOCK_AMP_ID1, + status=constants.AMPHORA_ALLOCATED, vrrp_port_id=t_constants.MOCK_VRRP_PORT_ID1, vrrp_ip=t_constants.MOCK_VRRP_IP1), o_data_models.Amphora(id=t_constants.MOCK_AMP_ID2, + status=constants.AMPHORA_ALLOCATED, vrrp_port_id=t_constants.MOCK_VRRP_PORT_ID2, - vrrp_ip=t_constants.MOCK_VRRP_IP2) + vrrp_ip=t_constants.MOCK_VRRP_IP2), + o_data_models.Amphora(id=t_constants.MOCK_AMP_ID3, + status=constants.DELETED, + vrrp_port_id=t_constants.MOCK_VRRP_PORT_ID3, + vrrp_ip=t_constants.MOCK_VRRP_IP3) ] UPDATE_DICT = {constants.TOPOLOGY: None} _session_mock = mock.MagicMock() diff --git a/releasenotes/notes/fix-qos-apply-after-failover-561abbd153ab88ee.yaml b/releasenotes/notes/fix-qos-apply-after-failover-561abbd153ab88ee.yaml new file mode 100644 index 0000000000..c4908fe33a --- /dev/null +++ b/releasenotes/notes/fix-qos-apply-after-failover-561abbd153ab88ee.yaml @@ -0,0 +1,6 @@ +--- +fixes: + - | + Fix a bug when updating a load balancer with a QoS policy after a failover, + Octavia attempted to update the VRRP ports of the deleted amphorae, moving + the provisioning status of the load balancer to ERROR.