Ensure OVN-LB is properly configured upon LS removal from LR
If an ovn-lb is created (VIP and members) in a LS (neutron network) that has 2 subnets (IPv4 + IPv6), and this LS is connected to a LR, removing the LS from the LR leads to the removal of the ovn-lb from the LS and consequently to remove it from the OVN SB DB as it is not associated to any datapath This is a problem on the _find_ls_for_lr function that looks for all the LR ports, and get the network name from them, therefore, even though the port for the LS got deleted, there is still another port from the other subnet pointing to the same network (LS), which is the culprit to delete the ovn-lb from that LS. With this patch, the VIP IP version is consider so that the router ports that belongs to the other subnet are not considered and the ovn-lb is not therefore removed from the LS. (manually cherry picked from commitchanges/62/862362/1512b2c83b5
) Closes-Bug: #1992363 Change-Id: I7b6dd9a31020d942d391726662e9b5ed9d76dc1f (cherry picked from commit512b2c83b5
)
parent
99ca59276f
commit
da84037045
|
@ -785,7 +785,9 @@ class OvnProviderHelper(object):
|
|||
self.ovn_nbdb_api.lr_lb_del(ovn_lr.uuid, ovn_lb.uuid,
|
||||
if_exists=True)
|
||||
)
|
||||
for net in self._find_ls_for_lr(ovn_lr):
|
||||
lb_vip = netaddr.IPNetwork(
|
||||
ovn_lb.external_ids.get(ovn_const.LB_EXT_IDS_VIP_KEY))
|
||||
for net in self._find_ls_for_lr(ovn_lr, ip_version=lb_vip.version):
|
||||
commands.append(self.ovn_nbdb_api.ls_lb_del(
|
||||
net, ovn_lb.uuid, if_exists=True))
|
||||
return commands
|
||||
|
@ -796,7 +798,9 @@ class OvnProviderHelper(object):
|
|||
self.ovn_nbdb_api.lr_lb_add(ovn_lr.uuid, ovn_lb.uuid,
|
||||
may_exist=True)
|
||||
)
|
||||
for net in self._find_ls_for_lr(ovn_lr):
|
||||
lb_vip = netaddr.IPNetwork(
|
||||
ovn_lb.external_ids.get(ovn_const.LB_EXT_IDS_VIP_KEY))
|
||||
for net in self._find_ls_for_lr(ovn_lr, ip_version=lb_vip.version):
|
||||
commands.append(self.ovn_nbdb_api.ls_lb_add(
|
||||
net, ovn_lb.uuid, may_exist=True))
|
||||
|
||||
|
@ -851,11 +855,13 @@ class OvnProviderHelper(object):
|
|||
return self._del_lb_to_lr_association(ovn_lb, ovn_lr, lr_ref)
|
||||
return self._add_lb_to_lr_association(ovn_lb, ovn_lr, lr_ref)
|
||||
|
||||
def _find_ls_for_lr(self, router):
|
||||
def _find_ls_for_lr(self, router, ip_version):
|
||||
ls = []
|
||||
for port in router.ports:
|
||||
if port.gateway_chassis:
|
||||
continue
|
||||
if netaddr.IPNetwork(port.networks[0]).version != ip_version:
|
||||
continue
|
||||
port_network_name = port.external_ids.get(
|
||||
ovn_const.OVN_NETWORK_NAME_EXT_ID_KEY)
|
||||
if port_network_name:
|
||||
|
|
|
@ -1118,7 +1118,8 @@ class TestOvnProviderHelper(TestOvnOctaviaBase):
|
|||
ext_ids={
|
||||
ovn_const.LB_EXT_IDS_LR_REF_KEY: "neutron-%s" % net_id,
|
||||
ovn_const.LB_EXT_IDS_LS_REFS_KEY:
|
||||
'{\"neutron-%s\": 1}' % net_id})
|
||||
'{\"neutron-%s\": 1}' % net_id,
|
||||
ovn_const.LB_EXT_IDS_VIP_KEY: self.vip_address})
|
||||
self.ref_lb2 = MockedLB(
|
||||
uuid=uuidutils.generate_uuid(),
|
||||
admin_state_up=True,
|
||||
|
@ -1131,7 +1132,8 @@ class TestOvnProviderHelper(TestOvnOctaviaBase):
|
|||
ext_ids={
|
||||
ovn_const.LB_EXT_IDS_LR_REF_KEY: "neutron-%s" % net_id,
|
||||
ovn_const.LB_EXT_IDS_LS_REFS_KEY:
|
||||
'{\"neutron-%s\": 1}' % net_id})
|
||||
'{\"neutron-%s\": 1}' % net_id,
|
||||
ovn_const.LB_EXT_IDS_VIP_KEY: self.vip_address})
|
||||
# TODO(mjozefcz): Consider using FakeOVNRouter.
|
||||
self.router = fakes.FakeOvsdbRow.create_one_ovsdb_row(
|
||||
attrs={'load_balancer': [self.ref_lb1],
|
||||
|
@ -3010,36 +3012,59 @@ class TestOvnProviderHelper(TestOvnOctaviaBase):
|
|||
p1 = fakes.FakeOVNPort.create_one_port(attrs={
|
||||
'gateway_chassis': [],
|
||||
'external_ids': {
|
||||
ovn_const.OVN_NETWORK_NAME_EXT_ID_KEY: 'foo1'}})
|
||||
ovn_const.OVN_NETWORK_NAME_EXT_ID_KEY: 'foo1'},
|
||||
'networks': ["10.0.0.1/24"]})
|
||||
p2 = fakes.FakeOVNPort.create_one_port(attrs={
|
||||
'gateway_chassis': [],
|
||||
'external_ids': {
|
||||
ovn_const.OVN_NETWORK_NAME_EXT_ID_KEY: 'foo2'}})
|
||||
ovn_const.OVN_NETWORK_NAME_EXT_ID_KEY: 'foo2'},
|
||||
'networks': ["10.0.10.1/24"]})
|
||||
self.router.ports.append(p1)
|
||||
self.router.ports.append(p2)
|
||||
res = self.helper._find_ls_for_lr(self.router)
|
||||
res = self.helper._find_ls_for_lr(self.router, n_const.IP_VERSION_4)
|
||||
self.assertListEqual(['neutron-foo1', 'neutron-foo2'], res)
|
||||
|
||||
def test__find_ls_for_lr_net_not_found(self):
|
||||
p1 = fakes.FakeOVNPort.create_one_port(attrs={
|
||||
'gateway_chassis': [],
|
||||
'external_ids': {
|
||||
ovn_const.OVN_NETWORK_NAME_EXT_ID_KEY: 'foo1'}})
|
||||
ovn_const.OVN_NETWORK_NAME_EXT_ID_KEY: 'foo1'},
|
||||
'networks': ["10.0.0.1/24"]})
|
||||
p2 = fakes.FakeOVNPort.create_one_port(attrs={
|
||||
'gateway_chassis': [],
|
||||
'external_ids': {}})
|
||||
'external_ids': {},
|
||||
'networks': ["10.0.10.1/24"]})
|
||||
self.router.ports.append(p2)
|
||||
self.router.ports.append(p1)
|
||||
res = self.helper._find_ls_for_lr(self.router)
|
||||
res = self.helper._find_ls_for_lr(self.router, n_const.IP_VERSION_4)
|
||||
self.assertListEqual(['neutron-foo1'], res)
|
||||
|
||||
def test__find_ls_for_lr_different_ip_version(self):
|
||||
p1 = fakes.FakeOVNPort.create_one_port(attrs={
|
||||
'gateway_chassis': [],
|
||||
'external_ids': {
|
||||
ovn_const.OVN_NETWORK_NAME_EXT_ID_KEY: 'foo1'},
|
||||
'networks': ["10.0.0.1/24"]})
|
||||
p2 = fakes.FakeOVNPort.create_one_port(attrs={
|
||||
'gateway_chassis': [],
|
||||
'external_ids': {
|
||||
ovn_const.OVN_NETWORK_NAME_EXT_ID_KEY: 'foo2'},
|
||||
'networks': ["fdaa:4ad8:e8fb::/64"]})
|
||||
self.router.ports.append(p2)
|
||||
self.router.ports.append(p1)
|
||||
res = self.helper._find_ls_for_lr(self.router, n_const.IP_VERSION_4)
|
||||
self.assertListEqual(['neutron-foo1'], res)
|
||||
res = self.helper._find_ls_for_lr(self.router, n_const.IP_VERSION_6)
|
||||
self.assertListEqual(['neutron-foo2'], res)
|
||||
|
||||
def test__find_ls_for_lr_gw_port(self):
|
||||
p1 = fakes.FakeOVNPort.create_one_port(attrs={
|
||||
'gateway_chassis': ['foo-gw-chassis'],
|
||||
'external_ids': {
|
||||
ovn_const.OVN_NETWORK_NAME_EXT_ID_KEY: 'foo1'}})
|
||||
ovn_const.OVN_NETWORK_NAME_EXT_ID_KEY: 'foo1'},
|
||||
'networks': ["10.0.0.1/24"]})
|
||||
self.router.ports.append(p1)
|
||||
result = self.helper._find_ls_for_lr(self.router)
|
||||
result = self.helper._find_ls_for_lr(self.router, n_const.IP_VERSION_4)
|
||||
self.assertListEqual([], result)
|
||||
|
||||
@mock.patch.object(
|
||||
|
|
Loading…
Reference in New Issue