from neutron.agent.l3 import legacy_router
from neutron.agent.l3 import namespace_manager
from neutron.agent.l3 import namespaces
+from neutron.agent.l3 import router_info as rinf
from neutron.agent.l3 import router_processing_queue as queue
from neutron.agent.linux import external_process
from neutron.agent.linux import ip_lib
ri.floating_ips = set(fip_statuses.keys())
for fip_id in existing_floating_ips - ri.floating_ips:
fip_statuses[fip_id] = l3_constants.FLOATINGIP_STATUS_DOWN
+ # filter out statuses that didn't change
+ fip_statuses = {f: stat for f, stat in fip_statuses.items()
+ if stat != rinf.FLOATINGIP_STATUS_NOCHANGE}
+ if not fip_statuses:
+ return
LOG.debug('Sending floating ip statuses: %s', fip_statuses)
# Update floating IP status on the neutron server
self.plugin_rpc.update_floatingip_statuses(
EXTERNAL_DEV_PREFIX = namespaces.EXTERNAL_DEV_PREFIX
EXTERNAL_INGRESS_MARK_MASK = '0xffffffff'
+FLOATINGIP_STATUS_NOCHANGE = object()
class RouterInfo(object):
{'id': fip['id'],
'status': fip_statuses.get(fip['id'])})
+ # mark the status as not changed. we can't remove it because
+ # that's how the caller determines that it was removed
+ if fip_statuses[fip['id']] == fip['status']:
+ fip_statuses[fip['id']] = FLOATINGIP_STATUS_NOCHANGE
fips_to_remove = (
ip_cidr for ip_cidr in existing_cidrs - new_cidrs
if common_utils.is_cidr_host(ip_cidr))
router[l3_constants.FLOATINGIP_KEY] = [{
'id': _uuid(),
'port_id': _uuid(),
+ 'status': 'DOWN',
'floating_ip_address': '19.4.4.2',
'fixed_ip_address': '10.0.0.1'}]
{'id': _uuid(),
'floating_ip_address': '15.1.2.3',
'fixed_ip_address': '192.168.0.1',
+ 'status': 'DOWN',
'floating_network_id': _uuid(),
'port_id': _uuid(),
'host': HOSTNAME}]}
self.assertNotIn(
router[l3_constants.INTERFACE_KEY][0], ri.internal_ports)
+ def test_process_router_floatingip_nochange(self):
+ agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
+ with mock.patch.object(
+ agent.plugin_rpc, 'update_floatingip_statuses'
+ ) as mock_update_fip_status:
+ router = prepare_router_data(num_internal_ports=1)
+ fip1 = {'id': _uuid(), 'floating_ip_address': '8.8.8.8',
+ 'fixed_ip_address': '7.7.7.7', 'status': 'ACTIVE',
+ 'port_id': router[l3_constants.INTERFACE_KEY][0]['id']}
+ fip2 = copy.copy(fip1)
+ fip2.update({'id': _uuid(), 'status': 'DOWN'})
+ router[l3_constants.FLOATINGIP_KEY] = [fip1, fip2]
+
+ ri = legacy_router.LegacyRouter(router['id'], router,
+ **self.ri_kwargs)
+ ri.external_gateway_added = mock.Mock()
+ ri.process(agent)
+ # make sure only the one that went from DOWN->ACTIVE was sent
+ mock_update_fip_status.assert_called_once_with(
+ mock.ANY, ri.router_id, {fip2['id']: 'ACTIVE'})
+
def test_process_router_floatingip_disabled(self):
agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
with mock.patch.object(
{'id': fip_id,
'floating_ip_address': '8.8.8.8',
'fixed_ip_address': '7.7.7.7',
+ 'status': 'DOWN',
'port_id': router[l3_constants.INTERFACE_KEY][0]['id']}]
ri = legacy_router.LegacyRouter(router['id'],