Merge "[L3 HA] Add "no_track" option to VIPs in keepalived config" into stable/rocky
This commit is contained in:
commit
cb2677ff70
|
@ -85,24 +85,28 @@ class InvalidAuthenticationTypeException(exceptions.NeutronException):
|
||||||
class KeepalivedVipAddress(object):
|
class KeepalivedVipAddress(object):
|
||||||
"""A virtual address entry of a keepalived configuration."""
|
"""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.ip_address = ip_address
|
||||||
self.interface_name = interface_name
|
self.interface_name = interface_name
|
||||||
self.scope = scope
|
self.scope = scope
|
||||||
|
self.track = track
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
return (isinstance(other, KeepalivedVipAddress) and
|
return (isinstance(other, KeepalivedVipAddress) and
|
||||||
self.ip_address == other.ip_address)
|
self.ip_address == other.ip_address)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return '[%s, %s, %s]' % (self.ip_address,
|
return '[%s, %s, %s, %s]' % (self.ip_address,
|
||||||
self.interface_name,
|
self.interface_name,
|
||||||
self.scope)
|
self.scope,
|
||||||
|
self.track)
|
||||||
|
|
||||||
def build_config(self):
|
def build_config(self):
|
||||||
result = '%s dev %s' % (self.ip_address, self.interface_name)
|
result = '%s dev %s' % (self.ip_address, self.interface_name)
|
||||||
if self.scope:
|
if self.scope:
|
||||||
result += ' scope %s' % self.scope
|
result += ' scope %s' % self.scope
|
||||||
|
if not self.track:
|
||||||
|
result += ' no_track'
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
@ -124,6 +128,7 @@ class KeepalivedVirtualRoute(object):
|
||||||
output += ' dev %s' % self.interface_name
|
output += ' dev %s' % self.interface_name
|
||||||
if self.scope:
|
if self.scope:
|
||||||
output += ' scope %s' % self.scope
|
output += ' scope %s' % self.scope
|
||||||
|
output += ' no_track'
|
||||||
return output
|
return output
|
||||||
|
|
||||||
|
|
||||||
|
@ -200,7 +205,8 @@ class KeepalivedInstance(object):
|
||||||
self.authentication = (auth_type, password)
|
self.authentication = (auth_type, password)
|
||||||
|
|
||||||
def add_vip(self, ip_cidr, interface_name, scope):
|
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:
|
if vip not in self.vips:
|
||||||
self.vips.append(vip)
|
self.vips.append(vip)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
import functools
|
import functools
|
||||||
import textwrap
|
|
||||||
|
|
||||||
import mock
|
import mock
|
||||||
import netaddr
|
import netaddr
|
||||||
|
@ -47,6 +46,39 @@ _uuid = uuidutils.generate_uuid
|
||||||
|
|
||||||
OVS_INTERFACE_DRIVER = 'neutron.agent.linux.interface.OVSInterfaceDriver'
|
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):
|
def get_ovs_bridge(br_name):
|
||||||
return ovs_lib.OVSBridge(br_name)
|
return ovs_lib.OVSBridge(br_name)
|
||||||
|
@ -432,38 +464,7 @@ class L3AgentTestFramework(base.BaseSudoTestCase):
|
||||||
router.get_floating_ips()[0]['floating_ip_address'])
|
router.get_floating_ips()[0]['floating_ip_address'])
|
||||||
default_gateway_ip = external_port['subnets'][0].get('gateway_ip')
|
default_gateway_ip = external_port['subnets'][0].get('gateway_ip')
|
||||||
extra_subnet_cidr = external_port['extra_subnets'][0].get('cidr')
|
extra_subnet_cidr = external_port['extra_subnets'][0].get('cidr')
|
||||||
return textwrap.dedent("""\
|
return 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
|
|
||||||
%(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
|
|
||||||
}
|
|
||||||
}""") % {
|
|
||||||
'email_from': keepalived.KEEPALIVED_EMAIL_FROM,
|
'email_from': keepalived.KEEPALIVED_EMAIL_FROM,
|
||||||
'router_id': keepalived.KEEPALIVED_ROUTER_ID,
|
'router_id': keepalived.KEEPALIVED_ROUTER_ID,
|
||||||
'ha_device_name': ha_device_name,
|
'ha_device_name': ha_device_name,
|
||||||
|
|
|
@ -83,16 +83,16 @@ class KeepalivedConfBaseMixin(object):
|
||||||
instance1.track_interfaces.append("eth0")
|
instance1.track_interfaces.append("eth0")
|
||||||
|
|
||||||
vip_address1 = keepalived.KeepalivedVipAddress('192.168.1.0/24',
|
vip_address1 = keepalived.KeepalivedVipAddress('192.168.1.0/24',
|
||||||
'eth1')
|
'eth1', track=False)
|
||||||
|
|
||||||
vip_address2 = keepalived.KeepalivedVipAddress('192.168.2.0/24',
|
vip_address2 = keepalived.KeepalivedVipAddress('192.168.2.0/24',
|
||||||
'eth2')
|
'eth2', track=False)
|
||||||
|
|
||||||
vip_address3 = keepalived.KeepalivedVipAddress('192.168.3.0/24',
|
vip_address3 = keepalived.KeepalivedVipAddress('192.168.3.0/24',
|
||||||
'eth2')
|
'eth2', track=False)
|
||||||
|
|
||||||
vip_address_ex = keepalived.KeepalivedVipAddress('192.168.55.0/24',
|
vip_address_ex = keepalived.KeepalivedVipAddress('192.168.55.0/24',
|
||||||
'eth10')
|
'eth10', track=False)
|
||||||
|
|
||||||
instance1.vips.append(vip_address1)
|
instance1.vips.append(vip_address1)
|
||||||
instance1.vips.append(vip_address2)
|
instance1.vips.append(vip_address2)
|
||||||
|
@ -110,7 +110,7 @@ class KeepalivedConfBaseMixin(object):
|
||||||
instance2.track_interfaces.append("eth4")
|
instance2.track_interfaces.append("eth4")
|
||||||
|
|
||||||
vip_address1 = keepalived.KeepalivedVipAddress('192.168.3.0/24',
|
vip_address1 = keepalived.KeepalivedVipAddress('192.168.3.0/24',
|
||||||
'eth6')
|
'eth6', track=False)
|
||||||
|
|
||||||
instance2.vips.append(vip_address1)
|
instance2.vips.append(vip_address1)
|
||||||
instance2.vips.append(vip_address2)
|
instance2.vips.append(vip_address2)
|
||||||
|
@ -144,13 +144,13 @@ class KeepalivedConfTestCase(base.BaseTestCase,
|
||||||
169.254.0.1/24 dev eth0
|
169.254.0.1/24 dev eth0
|
||||||
}
|
}
|
||||||
virtual_ipaddress_excluded {
|
virtual_ipaddress_excluded {
|
||||||
192.168.1.0/24 dev eth1
|
192.168.1.0/24 dev eth1 no_track
|
||||||
192.168.2.0/24 dev eth2
|
192.168.2.0/24 dev eth2 no_track
|
||||||
192.168.3.0/24 dev eth2
|
192.168.3.0/24 dev eth2 no_track
|
||||||
192.168.55.0/24 dev eth10
|
192.168.55.0/24 dev eth10 no_track
|
||||||
}
|
}
|
||||||
virtual_routes {
|
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 {
|
vrrp_instance VR_2 {
|
||||||
|
@ -167,9 +167,9 @@ class KeepalivedConfTestCase(base.BaseTestCase,
|
||||||
169.254.0.2/24 dev eth4
|
169.254.0.2/24 dev eth4
|
||||||
}
|
}
|
||||||
virtual_ipaddress_excluded {
|
virtual_ipaddress_excluded {
|
||||||
192.168.2.0/24 dev eth2
|
192.168.2.0/24 dev eth2 no_track
|
||||||
192.168.3.0/24 dev eth6
|
192.168.3.0/24 dev eth6 no_track
|
||||||
192.168.55.0/24 dev eth10
|
192.168.55.0/24 dev eth10 no_track
|
||||||
}
|
}
|
||||||
}""")
|
}""")
|
||||||
|
|
||||||
|
@ -239,11 +239,11 @@ class KeepalivedInstanceRoutesTestCase(base.BaseTestCase):
|
||||||
|
|
||||||
def test_build_config(self):
|
def test_build_config(self):
|
||||||
expected = """ virtual_routes {
|
expected = """ virtual_routes {
|
||||||
0.0.0.0/0 via 1.0.0.254 dev eth0
|
0.0.0.0/0 via 1.0.0.254 dev eth0 no_track
|
||||||
::/0 via fe80::3e97:eff:fe26:3bfa/64 dev eth1
|
::/0 via fe80::3e97:eff:fe26:3bfa/64 dev eth1 no_track
|
||||||
10.0.0.0/8 via 1.0.0.1
|
10.0.0.0/8 via 1.0.0.1 no_track
|
||||||
20.0.0.0/8 via 2.0.0.2
|
20.0.0.0/8 via 2.0.0.2 no_track
|
||||||
30.0.0.0/8 dev eth0 scope link
|
30.0.0.0/8 dev eth0 scope link no_track
|
||||||
}"""
|
}"""
|
||||||
routes = self._get_instance_routes()
|
routes = self._get_instance_routes()
|
||||||
self.assertEqual(expected, '\n'.join(routes.build_config()))
|
self.assertEqual(expected, '\n'.join(routes.build_config()))
|
||||||
|
@ -281,10 +281,10 @@ class KeepalivedInstanceTestCase(base.BaseTestCase,
|
||||||
169.254.0.1/24 dev eth0
|
169.254.0.1/24 dev eth0
|
||||||
}
|
}
|
||||||
virtual_ipaddress_excluded {
|
virtual_ipaddress_excluded {
|
||||||
192.168.1.0/24 dev eth1
|
192.168.1.0/24 dev eth1 no_track
|
||||||
}
|
}
|
||||||
virtual_routes {
|
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 {
|
vrrp_instance VR_2 {
|
||||||
|
@ -301,9 +301,9 @@ class KeepalivedInstanceTestCase(base.BaseTestCase,
|
||||||
169.254.0.2/24 dev eth4
|
169.254.0.2/24 dev eth4
|
||||||
}
|
}
|
||||||
virtual_ipaddress_excluded {
|
virtual_ipaddress_excluded {
|
||||||
192.168.2.0/24 dev eth2
|
192.168.2.0/24 dev eth2 no_track
|
||||||
192.168.3.0/24 dev eth6
|
192.168.3.0/24 dev eth6 no_track
|
||||||
192.168.55.0/24 dev eth10
|
192.168.55.0/24 dev eth10 no_track
|
||||||
}
|
}
|
||||||
}""")
|
}""")
|
||||||
|
|
||||||
|
@ -371,12 +371,13 @@ class KeepalivedVirtualRouteTestCase(base.BaseTestCase):
|
||||||
def test_virtual_route_with_dev(self):
|
def test_virtual_route_with_dev(self):
|
||||||
route = keepalived.KeepalivedVirtualRoute(n_consts.IPv4_ANY, '1.2.3.4',
|
route = keepalived.KeepalivedVirtualRoute(n_consts.IPv4_ANY, '1.2.3.4',
|
||||||
'eth0')
|
'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())
|
route.build_config())
|
||||||
|
|
||||||
def test_virtual_route_without_dev(self):
|
def test_virtual_route_without_dev(self):
|
||||||
route = keepalived.KeepalivedVirtualRoute('50.0.0.0/8', '1.2.3.4')
|
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):
|
class KeepalivedTrackScriptTestCase(base.BaseTestCase):
|
||||||
|
|
Loading…
Reference in New Issue