Merge "[L3 HA] Add "no_track" option to VIPs in keepalived config" into stable/stein

This commit is contained in:
Zuul 2020-04-23 22:15:26 +00:00 committed by Gerrit Code Review
commit 496132a156
3 changed files with 71 additions and 63 deletions

View File

@ -85,24 +85,28 @@ class InvalidAuthenticationTypeException(exceptions.NeutronException):
class KeepalivedVipAddress(object):
"""A virtual address entry of a keepalived configuration."""
def __init__(self, ip_address, interface_name, scope=None):
def __init__(self, ip_address, interface_name, scope=None, track=True):
self.ip_address = ip_address
self.interface_name = interface_name
self.scope = scope
self.track = track
def __eq__(self, other):
return (isinstance(other, KeepalivedVipAddress) and
self.ip_address == other.ip_address)
def __str__(self):
return '[%s, %s, %s]' % (self.ip_address,
self.interface_name,
self.scope)
return '[%s, %s, %s, %s]' % (self.ip_address,
self.interface_name,
self.scope,
self.track)
def build_config(self):
result = '%s dev %s' % (self.ip_address, self.interface_name)
if self.scope:
result += ' scope %s' % self.scope
if not self.track:
result += ' no_track'
return result
@ -124,6 +128,7 @@ class KeepalivedVirtualRoute(object):
output += ' dev %s' % self.interface_name
if self.scope:
output += ' scope %s' % self.scope
output += ' no_track'
return output
@ -200,7 +205,8 @@ class KeepalivedInstance(object):
self.authentication = (auth_type, password)
def add_vip(self, ip_cidr, interface_name, scope):
vip = KeepalivedVipAddress(ip_cidr, interface_name, scope)
track = interface_name in self.track_interfaces
vip = KeepalivedVipAddress(ip_cidr, interface_name, scope, track=track)
if vip not in self.vips:
self.vips.append(vip)
else:

View File

@ -15,7 +15,6 @@
import copy
import functools
import textwrap
import mock
import netaddr
@ -48,6 +47,39 @@ _uuid = uuidutils.generate_uuid
OVS_INTERFACE_DRIVER = 'neutron.agent.linux.interface.OVSInterfaceDriver'
KEEPALIVED_CONFIG = """\
global_defs {
notification_email_from %(email_from)s
router_id %(router_id)s
}
vrrp_instance VR_1 {
state BACKUP
interface %(ha_device_name)s
virtual_router_id 1
priority 50
garp_master_delay 60
nopreempt
advert_int 2
track_interface {
%(ha_device_name)s
}
virtual_ipaddress {
169.254.0.1/24 dev %(ha_device_name)s
}
virtual_ipaddress_excluded {
%(floating_ip_cidr)s dev %(ex_device_name)s no_track
%(external_device_cidr)s dev %(ex_device_name)s no_track
%(internal_device_cidr)s dev %(internal_device_name)s no_track
%(ex_port_ipv6)s dev %(ex_device_name)s scope link no_track
%(int_port_ipv6)s dev %(internal_device_name)s scope link no_track
}
virtual_routes {
0.0.0.0/0 via %(default_gateway_ip)s dev %(ex_device_name)s no_track
8.8.8.0/24 via 19.4.4.4 no_track
%(extra_subnet_cidr)s dev %(ex_device_name)s scope link no_track
}
}"""
def get_ovs_bridge(br_name):
return ovs_lib.OVSBridge(br_name)
@ -443,38 +475,7 @@ class L3AgentTestFramework(base.BaseSudoTestCase):
router.get_floating_ips()[0]['floating_ip_address'])
default_gateway_ip = external_port['subnets'][0].get('gateway_ip')
extra_subnet_cidr = external_port['extra_subnets'][0].get('cidr')
return textwrap.dedent("""\
global_defs {
notification_email_from %(email_from)s
router_id %(router_id)s
}
vrrp_instance VR_1 {
state BACKUP
interface %(ha_device_name)s
virtual_router_id 1
priority 50
garp_master_delay 60
nopreempt
advert_int 2
track_interface {
%(ha_device_name)s
}
virtual_ipaddress {
169.254.0.1/24 dev %(ha_device_name)s
}
virtual_ipaddress_excluded {
%(floating_ip_cidr)s dev %(ex_device_name)s
%(external_device_cidr)s dev %(ex_device_name)s
%(internal_device_cidr)s dev %(internal_device_name)s
%(ex_port_ipv6)s dev %(ex_device_name)s scope link
%(int_port_ipv6)s dev %(internal_device_name)s scope link
}
virtual_routes {
0.0.0.0/0 via %(default_gateway_ip)s dev %(ex_device_name)s
8.8.8.0/24 via 19.4.4.4
%(extra_subnet_cidr)s dev %(ex_device_name)s scope link
}
}""") % {
return KEEPALIVED_CONFIG % {
'email_from': keepalived.KEEPALIVED_EMAIL_FROM,
'router_id': keepalived.KEEPALIVED_ROUTER_ID,
'ha_device_name': ha_device_name,

View File

@ -83,16 +83,16 @@ class KeepalivedConfBaseMixin(object):
instance1.track_interfaces.append("eth0")
vip_address1 = keepalived.KeepalivedVipAddress('192.168.1.0/24',
'eth1')
'eth1', track=False)
vip_address2 = keepalived.KeepalivedVipAddress('192.168.2.0/24',
'eth2')
'eth2', track=False)
vip_address3 = keepalived.KeepalivedVipAddress('192.168.3.0/24',
'eth2')
'eth2', track=False)
vip_address_ex = keepalived.KeepalivedVipAddress('192.168.55.0/24',
'eth10')
'eth10', track=False)
instance1.vips.append(vip_address1)
instance1.vips.append(vip_address2)
@ -110,7 +110,7 @@ class KeepalivedConfBaseMixin(object):
instance2.track_interfaces.append("eth4")
vip_address1 = keepalived.KeepalivedVipAddress('192.168.3.0/24',
'eth6')
'eth6', track=False)
instance2.vips.append(vip_address1)
instance2.vips.append(vip_address2)
@ -144,13 +144,13 @@ class KeepalivedConfTestCase(base.BaseTestCase,
169.254.0.1/24 dev eth0
}
virtual_ipaddress_excluded {
192.168.1.0/24 dev eth1
192.168.2.0/24 dev eth2
192.168.3.0/24 dev eth2
192.168.55.0/24 dev eth10
192.168.1.0/24 dev eth1 no_track
192.168.2.0/24 dev eth2 no_track
192.168.3.0/24 dev eth2 no_track
192.168.55.0/24 dev eth10 no_track
}
virtual_routes {
0.0.0.0/0 via 192.168.1.1 dev eth1
0.0.0.0/0 via 192.168.1.1 dev eth1 no_track
}
}
vrrp_instance VR_2 {
@ -167,9 +167,9 @@ class KeepalivedConfTestCase(base.BaseTestCase,
169.254.0.2/24 dev eth4
}
virtual_ipaddress_excluded {
192.168.2.0/24 dev eth2
192.168.3.0/24 dev eth6
192.168.55.0/24 dev eth10
192.168.2.0/24 dev eth2 no_track
192.168.3.0/24 dev eth6 no_track
192.168.55.0/24 dev eth10 no_track
}
}""")
@ -239,11 +239,11 @@ class KeepalivedInstanceRoutesTestCase(base.BaseTestCase):
def test_build_config(self):
expected = """ virtual_routes {
0.0.0.0/0 via 1.0.0.254 dev eth0
::/0 via fe80::3e97:eff:fe26:3bfa/64 dev eth1
10.0.0.0/8 via 1.0.0.1
20.0.0.0/8 via 2.0.0.2
30.0.0.0/8 dev eth0 scope link
0.0.0.0/0 via 1.0.0.254 dev eth0 no_track
::/0 via fe80::3e97:eff:fe26:3bfa/64 dev eth1 no_track
10.0.0.0/8 via 1.0.0.1 no_track
20.0.0.0/8 via 2.0.0.2 no_track
30.0.0.0/8 dev eth0 scope link no_track
}"""
routes = self._get_instance_routes()
self.assertEqual(expected, '\n'.join(routes.build_config()))
@ -281,10 +281,10 @@ class KeepalivedInstanceTestCase(base.BaseTestCase,
169.254.0.1/24 dev eth0
}
virtual_ipaddress_excluded {
192.168.1.0/24 dev eth1
192.168.1.0/24 dev eth1 no_track
}
virtual_routes {
0.0.0.0/0 via 192.168.1.1 dev eth1
0.0.0.0/0 via 192.168.1.1 dev eth1 no_track
}
}
vrrp_instance VR_2 {
@ -301,9 +301,9 @@ class KeepalivedInstanceTestCase(base.BaseTestCase,
169.254.0.2/24 dev eth4
}
virtual_ipaddress_excluded {
192.168.2.0/24 dev eth2
192.168.3.0/24 dev eth6
192.168.55.0/24 dev eth10
192.168.2.0/24 dev eth2 no_track
192.168.3.0/24 dev eth6 no_track
192.168.55.0/24 dev eth10 no_track
}
}""")
@ -371,12 +371,13 @@ class KeepalivedVirtualRouteTestCase(base.BaseTestCase):
def test_virtual_route_with_dev(self):
route = keepalived.KeepalivedVirtualRoute(n_consts.IPv4_ANY, '1.2.3.4',
'eth0')
self.assertEqual('0.0.0.0/0 via 1.2.3.4 dev eth0',
self.assertEqual('0.0.0.0/0 via 1.2.3.4 dev eth0 no_track',
route.build_config())
def test_virtual_route_without_dev(self):
route = keepalived.KeepalivedVirtualRoute('50.0.0.0/8', '1.2.3.4')
self.assertEqual('50.0.0.0/8 via 1.2.3.4', route.build_config())
self.assertEqual('50.0.0.0/8 via 1.2.3.4 no_track',
route.build_config())
class KeepalivedTrackScriptTestCase(base.BaseTestCase):