Merge "DVR: Fix Duplicate IPtables rule detected warning message in l3agent"
This commit is contained in:
commit
043763891c
|
@ -74,4 +74,5 @@ class AgentMixin(object):
|
|||
"""Delete fip namespace after external network removed."""
|
||||
fip_ns = self.get_fip_ns(ext_net_id)
|
||||
if fip_ns.agent_gateway_port and not fip_ns.destroyed:
|
||||
fip_ns.unsubscribe(ext_net_id)
|
||||
fip_ns.delete()
|
||||
|
|
|
@ -80,13 +80,13 @@ class FipNamespace(namespaces.Namespace):
|
|||
def has_subscribers(self):
|
||||
return len(self._subscribers) != 0
|
||||
|
||||
def subscribe(self, router_id):
|
||||
def subscribe(self, external_net_id):
|
||||
is_first = not self.has_subscribers()
|
||||
self._subscribers.add(router_id)
|
||||
self._subscribers.add(external_net_id)
|
||||
return is_first
|
||||
|
||||
def unsubscribe(self, router_id):
|
||||
self._subscribers.discard(router_id)
|
||||
def unsubscribe(self, external_net_id):
|
||||
self._subscribers.discard(external_net_id)
|
||||
return not self.has_subscribers()
|
||||
|
||||
def allocate_rule_priority(self, floating_ip):
|
||||
|
|
|
@ -133,7 +133,6 @@ class DvrLocalRouter(dvr_router_base.DvrRouterBase):
|
|||
self.fip_ns.local_subnets.release(self.router_id)
|
||||
self.rtr_fip_subnet = None
|
||||
ns_ip.del_veth(fip_2_rtr_name)
|
||||
self.fip_ns.unsubscribe(self.router_id)
|
||||
# NOTE (Swami): The fg interface and the namespace will be deleted
|
||||
# when the external gateway port is removed. This will be
|
||||
# initiated from the server through an RPC call.
|
||||
|
@ -429,7 +428,7 @@ class DvrLocalRouter(dvr_router_base.DvrRouterBase):
|
|||
"plugin: %s", fip_agent_port)
|
||||
is_first = False
|
||||
if floating_ips:
|
||||
is_first = self.fip_ns.subscribe(self.router_id)
|
||||
is_first = self.fip_ns.subscribe(ex_gw_port['network_id'])
|
||||
if is_first and not fip_agent_port:
|
||||
LOG.debug("No FloatingIP agent gateway port possibly due to "
|
||||
"late binding of the private port to the host, "
|
||||
|
@ -448,7 +447,7 @@ class DvrLocalRouter(dvr_router_base.DvrRouterBase):
|
|||
self.fip_ns.create_gateway_port(fip_agent_port)
|
||||
|
||||
if (self.fip_ns.agent_gateway_port and
|
||||
(self.dist_fip_count == 0 or is_first)):
|
||||
(self.dist_fip_count == 0)):
|
||||
self.fip_ns.create_rtr_2_fip_link(self)
|
||||
|
||||
# kicks the FW Agent to add rules for the IR namespace if
|
||||
|
|
|
@ -19,7 +19,6 @@ import mock
|
|||
import netaddr
|
||||
|
||||
from neutron.agent.l3 import agent as neutron_l3_agent
|
||||
from neutron.agent.l3 import dvr_fip_ns
|
||||
from neutron.agent.l3 import dvr_snat_ns
|
||||
from neutron.agent.l3 import namespaces
|
||||
from neutron.agent.linux import ip_lib
|
||||
|
@ -677,8 +676,12 @@ class TestDvrRouter(framework.L3AgentTestFramework):
|
|||
|
||||
def _assert_fip_namespace_deleted(self, ext_gateway_port):
|
||||
ext_net_id = ext_gateway_port['network_id']
|
||||
fip_ns = self.agent.get_fip_ns(ext_net_id)
|
||||
fip_ns.unsubscribe = mock.Mock()
|
||||
self.agent.fipnamespace_delete_on_ext_net(
|
||||
self.agent.context, ext_net_id)
|
||||
self._assert_interfaces_deleted_from_ovs()
|
||||
fip_ns_name = dvr_fip_ns.FipNamespace._get_ns_name(ext_net_id)
|
||||
fip_ns_name = fip_ns.get_name()
|
||||
self.assertFalse(self._namespace_exists(fip_ns_name))
|
||||
self.assertTrue(fip_ns.destroyed)
|
||||
self.assertTrue(fip_ns.unsubscribe.called)
|
||||
|
|
|
@ -889,6 +889,72 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework):
|
|||
ri.add_floating_ip.assert_called_once_with(
|
||||
floating_ips[0], mock.sentinel.interface_name, device)
|
||||
|
||||
@mock.patch.object(lla.LinkLocalAllocator, '_write')
|
||||
def test_create_dvr_fip_interfaces_if_fipnamespace_exist(self, lla_write):
|
||||
fake_network_id = _uuid()
|
||||
subnet_id = _uuid()
|
||||
fake_floatingips = {'floatingips': [
|
||||
{'id': _uuid(),
|
||||
'floating_ip_address': '20.0.0.3',
|
||||
'fixed_ip_address': '192.168.0.1',
|
||||
'floating_network_id': _uuid(),
|
||||
'port_id': _uuid(),
|
||||
'host': HOSTNAME}]}
|
||||
agent_gateway_port = (
|
||||
[{'fixed_ips': [
|
||||
{'ip_address': '20.0.0.30',
|
||||
'prefixlen': 24,
|
||||
'subnet_id': subnet_id}],
|
||||
'subnets': [
|
||||
{'id': subnet_id,
|
||||
'gateway_ip': '20.0.0.1'}],
|
||||
'id': _uuid(),
|
||||
'network_id': fake_network_id,
|
||||
'mac_address': 'ca:fe:de:ad:be:ef'}]
|
||||
)
|
||||
|
||||
router = l3_test_common.prepare_router_data(enable_snat=True)
|
||||
router[l3_constants.FLOATINGIP_KEY] = fake_floatingips['floatingips']
|
||||
router[l3_constants.FLOATINGIP_AGENT_INTF_KEY] = agent_gateway_port
|
||||
router['distributed'] = True
|
||||
agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
|
||||
ri = dvr_router.DvrEdgeRouter(
|
||||
agent, HOSTNAME, router['id'], router, **self.ri_kwargs)
|
||||
ext_gw_port = ri.router.get('gw_port')
|
||||
ri.fip_ns = agent.get_fip_ns(ext_gw_port['network_id'])
|
||||
ri.dist_fip_count = 0
|
||||
agent.process_router_add = mock.Mock()
|
||||
ri.fip_ns.create_rtr_2_fip_link = mock.Mock()
|
||||
with mock.patch.object(ri, 'get_floating_ips') as fips, \
|
||||
mock.patch.object(ri.fip_ns,
|
||||
'create') as create_fip, \
|
||||
mock.patch.object(ri, 'get_floating_agent_gw_interface'
|
||||
) as fip_gw_port:
|
||||
fips.return_value = fake_floatingips
|
||||
fip_gw_port.return_value = agent_gateway_port[0]
|
||||
ri.create_dvr_fip_interfaces(ext_gw_port)
|
||||
self.assertTrue(fip_gw_port.called)
|
||||
self.assertTrue(fips.called)
|
||||
self.assertTrue(create_fip.called)
|
||||
self.assertEqual(agent_gateway_port[0],
|
||||
ri.fip_ns.agent_gateway_port)
|
||||
# Now let us associate the fip to the router
|
||||
ri.floating_ip_added_dist(fips, "192.168.0.1/32")
|
||||
self.assertEqual(1, ri.dist_fip_count)
|
||||
# Now let us disassociate the fip from the router
|
||||
ri.floating_ip_removed_dist("192.168.0.1/32")
|
||||
self.assertEqual(0, ri.dist_fip_count)
|
||||
# Calling create_dvr_fip_interfaces again to make sure
|
||||
# that the fip namespace create is not called again.
|
||||
# If the create is not called again, that would contain
|
||||
# the duplicate rules configuration in the fip namespace.
|
||||
ri.create_dvr_fip_interfaces(ext_gw_port)
|
||||
self.assertTrue(fip_gw_port.called)
|
||||
self.assertTrue(fips.called)
|
||||
create_fip.assert_called_once_with()
|
||||
self.assertEqual(2, agent.process_router_add.call_count)
|
||||
self.assertEqual(2, ri.fip_ns.create_rtr_2_fip_link.call_count)
|
||||
|
||||
@mock.patch.object(lla.LinkLocalAllocator, '_write')
|
||||
def test_create_dvr_fip_interfaces_for_late_binding(self, lla_write):
|
||||
fake_network_id = _uuid()
|
||||
|
@ -1020,7 +1086,7 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework):
|
|||
ri.fip_ns.subscribe = mock.Mock(return_value=True)
|
||||
ri.fip_ns.agent_router_gateway = mock.Mock()
|
||||
ri.rtr_fip_subnet = None
|
||||
ri.dist_fip_count = 1
|
||||
ri.dist_fip_count = 0
|
||||
|
||||
with mock.patch.object(ri, 'get_floating_ips') as fips,\
|
||||
mock.patch.object(ri, 'get_floating_agent_gw_interface'
|
||||
|
|
|
@ -39,23 +39,23 @@ class TestDvrFipNs(base.BaseTestCase):
|
|||
use_ipv6=True)
|
||||
|
||||
def test_subscribe(self):
|
||||
is_first = self.fip_ns.subscribe(mock.sentinel.router_id)
|
||||
is_first = self.fip_ns.subscribe(mock.sentinel.external_net_id)
|
||||
self.assertTrue(is_first)
|
||||
|
||||
def test_subscribe_not_first(self):
|
||||
self.fip_ns.subscribe(mock.sentinel.router_id)
|
||||
is_first = self.fip_ns.subscribe(mock.sentinel.router_id2)
|
||||
self.fip_ns.subscribe(mock.sentinel.external_net_id)
|
||||
is_first = self.fip_ns.subscribe(mock.sentinel.external_net_id2)
|
||||
self.assertFalse(is_first)
|
||||
|
||||
def test_unsubscribe(self):
|
||||
self.fip_ns.subscribe(mock.sentinel.router_id)
|
||||
is_last = self.fip_ns.unsubscribe(mock.sentinel.router_id)
|
||||
self.fip_ns.subscribe(mock.sentinel.external_net_id)
|
||||
is_last = self.fip_ns.unsubscribe(mock.sentinel.external_net_id)
|
||||
self.assertTrue(is_last)
|
||||
|
||||
def test_unsubscribe_not_last(self):
|
||||
self.fip_ns.subscribe(mock.sentinel.router_id)
|
||||
self.fip_ns.subscribe(mock.sentinel.router_id2)
|
||||
is_last = self.fip_ns.unsubscribe(mock.sentinel.router_id2)
|
||||
self.fip_ns.subscribe(mock.sentinel.external_net_id)
|
||||
self.fip_ns.subscribe(mock.sentinel.external_net_id2)
|
||||
is_last = self.fip_ns.unsubscribe(mock.sentinel.external_net_id2)
|
||||
self.assertFalse(is_last)
|
||||
|
||||
def test_allocate_rule_priority(self):
|
||||
|
|
|
@ -251,7 +251,6 @@ class TestDvrRouterOperations(base.BaseTestCase):
|
|||
mIPRule().rule.delete.assert_called_with(
|
||||
ip=str(netaddr.IPNetwork(fip_cidr).ip), table=16, priority=FIP_PRI)
|
||||
mIPDevice().route.delete_route.assert_called_with(fip_cidr, str(s.ip))
|
||||
self.assertFalse(ri.fip_ns.unsubscribe.called)
|
||||
ri.fip_ns.local_subnets.allocate.assert_not_called()
|
||||
|
||||
ri.dist_fip_count = 1
|
||||
|
@ -266,7 +265,7 @@ class TestDvrRouterOperations(base.BaseTestCase):
|
|||
fip_ns.get_int_device_name(router['id']))
|
||||
mIPDevice().route.delete_gateway.assert_called_once_with(
|
||||
str(fip_to_rtr.ip), table=16)
|
||||
fip_ns.unsubscribe.assert_called_once_with(ri.router_id)
|
||||
self.assertFalse(ri.fip_ns.unsubscribe.called)
|
||||
ri.fip_ns.local_subnets.allocate.assert_called_once_with(ri.router_id)
|
||||
|
||||
def _test_add_floating_ip(self, ri, fip, is_failure):
|
||||
|
|
Loading…
Reference in New Issue