]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Don't update floating IP status if no change
authorKevin Benton <blak111@gmail.com>
Fri, 17 Apr 2015 11:03:38 +0000 (04:03 -0700)
committerKevin Benton <blak111@gmail.com>
Sat, 30 May 2015 04:04:32 +0000 (21:04 -0700)
The floating IP status was going through all of the
status update code every time the L3 agent sent in
an update, even if the status didn't change.

This patch skips sending updates to the server if the
agent doesn't change the status.

Change-Id: Ic3736bed3dc3e4ccb91f4acfabbf033949e09ce0
Partial-Bug: #1445412

neutron/agent/l3/agent.py
neutron/agent/l3/router_info.py
neutron/tests/unit/agent/l3/test_agent.py
neutron/tests/unit/agent/l3/test_router_info.py

index 2c1c1696ee834f850e3c3016f21b1c734681e32b..03f40d61c94592197c41ef543af8b487288d72d8 100644 (file)
@@ -29,6 +29,7 @@ from neutron.agent.l3 import ha_router
 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
@@ -348,6 +349,11 @@ class L3NATAgent(firewall_l3_agent.FWaaSL3AgentRpcCallback,
         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(
index 3f0d801a660600fd7b433755f51bce31f29d06a8..adb668bc3dba14f109e27fb067e78878c093e29e 100644 (file)
@@ -30,6 +30,7 @@ INTERNAL_DEV_PREFIX = namespaces.INTERNAL_DEV_PREFIX
 EXTERNAL_DEV_PREFIX = namespaces.EXTERNAL_DEV_PREFIX
 
 EXTERNAL_INGRESS_MARK_MASK = '0xffffffff'
+FLOATINGIP_STATUS_NOCHANGE = object()
 
 
 class RouterInfo(object):
@@ -247,6 +248,10 @@ 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))
index bdf62fbbd9909aa14bcc659161815566ab288678..6c1057c9010b9b9c68d88bef8f28c5e607c9b7e0 100644 (file)
@@ -231,6 +231,7 @@ def prepare_router_data(ip_version=4, enable_snat=None, num_internal_ports=1,
         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'}]
 
@@ -1274,6 +1275,7 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework):
             {'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}]}
@@ -1690,6 +1692,27 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework):
             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(
@@ -1701,6 +1724,7 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework):
                 {'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'],
index 04aa55748c3e494b3d3973055a39d8f829fa1dfd..5e60aa12c8fe54d9869079c7e699393d338eee95 100644 (file)
@@ -283,7 +283,8 @@ class TestFloatingIpWithMockDevice(BasicRouterTestCaseFramework):
         fip = {
             'id': fip_id, 'port_id': _uuid(),
             'floating_ip_address': '15.1.2.3',
-            'fixed_ip_address': '192.168.0.2'
+            'fixed_ip_address': '192.168.0.2',
+            'status': 'DOWN'
         }
         ri = self._create_router()
         ri.add_floating_ip = mock.Mock(