Merge "Move some LogicalSwitchChassisEvent methods out" into stable/2024.1

This commit is contained in:
Zuul 2024-11-20 12:34:15 +00:00 committed by Gerrit Code Review
commit d9ea437d61
7 changed files with 151 additions and 82 deletions

View File

@ -18,3 +18,18 @@ def get_from_external_ids(row, key):
return row.external_ids[key]
except (AttributeError, KeyError):
pass
def ip_matches_in_row(row, ip, key):
"""Return True if given ip is in external_ids under given key.
Return also True if passed ip is None and key is not present.
Return None if external_ids is not present in row.
Otherwise return False
"""
try:
return ip == row.external_ids.get(key)
except AttributeError:
pass

View File

@ -0,0 +1,42 @@
# Copyright 2024 Red Hat, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from ovn_bgp_agent import constants
from ovn_bgp_agent.drivers.openstack.utils import common as common_utils
from ovn_bgp_agent.drivers.openstack.utils import driver_utils
def get_vips(lb):
"""Return a set of vips from a Load_Balancer row
Note: As LB VIP contains a port (e.g., '192.168.1.1:80'), the port part
is removed.
"""
return {driver_utils.remove_port_from_ip(ipport)
for ipport in getattr(lb, 'vips', {})}
def get_diff_ip_from_vips(new, old):
"""Return a set of IPs that are present in 'new' but not in 'old'"""
return get_vips(new) - get_vips(old)
def is_vip(row, ip):
return common_utils.ip_matches_in_row(
row, ip, constants.OVN_LB_VIP_IP_EXT_ID_KEY)
def is_fip(row, ip):
return common_utils.ip_matches_in_row(
row, ip, constants.OVN_LB_VIP_FIP_EXT_ID_KEY)

View File

@ -49,33 +49,6 @@ class OVNLBEvent(Event):
super().__init__(bgp_agent, events, table)
self.event_name = self.__class__.__name__
def _get_ip_from_vips(self, row):
return [driver_utils.remove_port_from_ip(ipport)
for ipport in getattr(row, 'vips', {}).keys()]
def _get_diff_ip_from_vips(self, new, old):
"""Returns a list of IPs that are present in 'new' but not in 'old'
Note: As LB VIP contains a port (e.g., '192.168.1.1:80'), the port part
is removed before comparison.
"""
return list(set(self._get_ip_from_vips(new)) -
set(self._get_ip_from_vips(old)))
def _is_vip_or_fip(self, row, ip, key):
try:
return ip == row.external_ids.get(key)
except AttributeError:
pass
def _is_vip(self, row, ip):
return self._is_vip_or_fip(row, ip, constants.OVN_LB_VIP_IP_EXT_ID_KEY)
def _is_fip(self, row, ip):
return self._is_vip_or_fip(row,
ip,
constants.OVN_LB_VIP_FIP_EXT_ID_KEY)
class LogicalSwitchChassisEvent(Event):
def __init__(self, bgp_agent, events):

View File

@ -18,6 +18,7 @@ from oslo_log import log as logging
from ovn_bgp_agent import constants
from ovn_bgp_agent.drivers.openstack.utils import common as common_utils
from ovn_bgp_agent.drivers.openstack.utils import driver_utils
from ovn_bgp_agent.drivers.openstack.utils import loadbalancer as lb_utils
from ovn_bgp_agent.drivers.openstack.utils import port as port_utils
from ovn_bgp_agent.drivers.openstack.utils import router as router_utils
from ovn_bgp_agent.drivers.openstack.watchers import base_watcher
@ -728,12 +729,12 @@ class OVNLBCreateEvent(base_watcher.OVNLBEvent):
def _run(self, event, row, old):
# vips field grows
diff = self._get_diff_ip_from_vips(row, old)
diff = lb_utils.get_diff_ip_from_vips(row, old)
for ip in diff:
with _SYNC_STATE_LOCK.read_lock():
if self._is_vip(row, ip):
if lb_utils.is_vip(row, ip):
self.agent.expose_ovn_lb_vip(row)
elif self._is_fip(row, ip):
elif lb_utils.is_fip(row, ip):
self.agent.expose_ovn_lb_fip(row)
# router set ext-gw
@ -792,23 +793,23 @@ class OVNLBDeleteEvent(base_watcher.OVNLBEvent):
def _run(self, event, row, old):
# DELETE event need drop all
if event == self.ROW_DELETE:
diff = self._get_ip_from_vips(row)
diff = lb_utils.get_vips(row)
for ip in diff:
with _SYNC_STATE_LOCK.read_lock():
if self._is_vip(row, ip):
if lb_utils.is_vip(row, ip):
self.agent.withdraw_ovn_lb_vip(row)
elif self._is_fip(row, ip):
elif lb_utils.is_fip(row, ip):
self.agent.withdraw_ovn_lb_fip(row)
return
# UPDATE event
# vips field decrease
diff = self._get_diff_ip_from_vips(old, row)
diff = lb_utils.get_diff_ip_from_vips(old, row)
for ip in diff:
with _SYNC_STATE_LOCK.read_lock():
if self._is_vip(old, ip):
if lb_utils.is_vip(old, ip):
self.agent.withdraw_ovn_lb_vip(old)
elif self._is_fip(old, ip):
elif lb_utils.is_fip(old, ip):
self.agent.withdraw_ovn_lb_fip(old)
# router unset ext-gw

View File

@ -36,3 +36,33 @@ class TestGetFromExternalIds(test_base.TestCase):
row = test_utils.create_row(external_ids={})
self.assertIsNone(common.get_from_external_ids(row, 'key'))
class TestIpMatchesInRow(test_base.TestCase):
def test_ip_is_in_row(self):
ip = 'ip'
key = 'key'
row = test_utils.create_row(external_ids={key: ip})
self.assertTrue(common.ip_matches_in_row(row, ip, key))
def test_external_ids_missing_returns_none(self):
ip = 'ip'
key = 'key'
row = test_utils.create_row()
self.assertIsNone(common.ip_matches_in_row(row, ip, key))
def test_key_missing(self):
ip = 'ip'
key = 'key'
row = test_utils.create_row(external_ids={})
self.assertFalse(common.ip_matches_in_row(row, ip, key))
def test_key_missing_but_ip_is_none(self):
ip = None
key = 'key'
row = test_utils.create_row(external_ids={})
self.assertTrue(common.ip_matches_in_row(row, ip, key))

View File

@ -0,0 +1,54 @@
# Copyright 2024 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from ovn_bgp_agent import constants
from ovn_bgp_agent.drivers.openstack.utils import loadbalancer as lb_utils
from ovn_bgp_agent.tests import base as test_base
from ovn_bgp_agent.tests import utils as test_utils
class TestGetVipsFromLb(test_base.TestCase):
def test_get_vips(self):
vips = {'192.168.1.50:80': '192.168.1.100:80',
'172.24.4.5:80': '192.168.1.100:80'}
expected_vip_set = {"192.168.1.50", "172.24.4.5"}
row = test_utils.create_row(vips=vips)
observed = lb_utils.get_vips(row)
self.assertSetEqual(expected_vip_set, observed)
def test_get_vips_not_present(self):
row = test_utils.create_row()
observed = lb_utils.get_vips(row)
self.assertSetEqual(set(), observed)
class TestIsVip(test_base.TestCase):
def test_is_vip(self):
ip = 'ip'
row = test_utils.create_row(
external_ids={constants.OVN_LB_VIP_IP_EXT_ID_KEY: ip})
self.assertTrue(lb_utils.is_vip(row, ip))
class TestIsFip(test_base.TestCase):
def test_is_fip(self):
ip = 'ip'
row = test_utils.create_row(
external_ids={constants.OVN_LB_VIP_FIP_EXT_ID_KEY: ip})
self.assertTrue(lb_utils.is_fip(row, ip))

View File

@ -21,52 +21,6 @@ from ovn_bgp_agent.tests import base as test_base
from ovn_bgp_agent.tests import utils
class FakeOVNLBEvent(base_watcher.OVNLBEvent):
def run(self):
pass
class TestOVNLBEvent(test_base.TestCase):
def setUp(self):
super(TestOVNLBEvent, self).setUp()
self.ovnlb_event = FakeOVNLBEvent(
mock.Mock(), [mock.Mock()])
def test__is_vip(self):
row = utils.create_row(
external_ids={constants.OVN_LB_VIP_IP_EXT_ID_KEY: '192.168.1.50',
constants.OVN_LB_VIP_FIP_EXT_ID_KEY: '172.24.4.5'},
vips={'192.168.1.50:80': '192.168.1.100:80',
'172.24.4.5:80': '192.168.1.100:80'})
self.assertFalse(self.ovnlb_event._is_vip(row, '172.24.4.5'))
self.assertTrue(self.ovnlb_event._is_vip(row, '192.168.1.50'))
row = utils.create_row(external_ids={})
self.assertFalse(self.ovnlb_event._is_vip(row, '172.24.4.5'))
self.assertFalse(self.ovnlb_event._is_vip(row, '192.168.1.50'))
def test__is_fip(self):
row = utils.create_row(
external_ids={constants.OVN_LB_VIP_IP_EXT_ID_KEY: '192.168.1.50',
constants.OVN_LB_VIP_FIP_EXT_ID_KEY: '172.24.4.5'},
vips={'192.168.1.50:80': '192.168.1.100:80',
'172.24.4.5:80': '192.168.1.100:80'})
self.assertTrue(self.ovnlb_event._is_fip(row, '172.24.4.5'))
self.assertFalse(self.ovnlb_event._is_fip(row, '192.168.1.50'))
row = utils.create_row(external_ids={})
self.assertFalse(self.ovnlb_event._is_fip(row, '172.24.4.5'))
self.assertFalse(self.ovnlb_event._is_fip(row, '192.168.1.50'))
def test__get_ip_from_vips(self):
row = utils.create_row(
external_ids={constants.OVN_LB_VIP_IP_EXT_ID_KEY: '192.168.1.50',
constants.OVN_LB_VIP_FIP_EXT_ID_KEY: '172.24.4.5'},
vips={'192.168.1.50:80': '192.168.1.100:80',
'172.24.4.5:80': '192.168.1.100:80'})
self.assertEqual(self.ovnlb_event._get_ip_from_vips(row),
['192.168.1.50', '172.24.4.5'])
class FakeLSPChassisEvent(base_watcher.LSPChassisEvent):
def run(self):
pass