]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Move the assignment of existing_floating_ips before try block
authorYalei Wang <yalei.wang@intel.com>
Wed, 21 Jan 2015 09:48:56 +0000 (17:48 +0800)
committerBrian Haley <brian.haley@hp.com>
Tue, 24 Feb 2015 21:55:58 +0000 (16:55 -0500)
In function _process_external() in agent/l3/agent.py, the call to
iptables_manager.defer_apply() may throw an exception, making a
later call to _update_fip_statuses() use an un-initialized value.
This will throw its own UnboundLocalError, with the result being
no iptables rules will be applied.

Added tests to cover both the defer_apply() code exception
processing, as well as this new case where we might jump to
_update_fip_statuses() without having done any work on floating
IP addresses.

Change-Id: I0045effc9319772127758be4aacca02ab5c236cd
Closes-Bug: #1413111

neutron/agent/l3/agent.py
neutron/agent/linux/iptables_manager.py
neutron/tests/unit/test_iptables_manager.py
neutron/tests/unit/test_l3_agent.py

index 4935614bc3cd12652c5d5b84e6b4edc865ad8c8e..642efca823b33729664c4c165f62b60ec8083b74 100644 (file)
@@ -533,6 +533,7 @@ class L3NATAgent(firewall_l3_agent.FWaaSL3AgentRpcCallback,
                 ri.disable_keepalived()
 
     def _process_external(self, ri):
+        existing_floating_ips = ri.floating_ips
         try:
             with ri.iptables_manager.defer_apply():
                 self._process_external_gateway(ri)
@@ -543,7 +544,6 @@ class L3NATAgent(firewall_l3_agent.FWaaSL3AgentRpcCallback,
                     return
 
                 # Process SNAT/DNAT rules and addresses for floating IPs
-                existing_floating_ips = ri.floating_ips
                 if ri.router['distributed']:
                     self.create_dvr_fip_interfaces(ri, ex_gw_port)
                 ri.process_snat_dnat_for_fip()
index 5adf1d227cec00af53c8bd62ffe8f229bd0a8c73..9efbd3879c8b796eed7be4381070f816b523e76a 100644 (file)
@@ -384,8 +384,9 @@ class IptablesManager(object):
             try:
                 self.defer_apply_off()
             except Exception:
-                raise n_exc.IpTablesApplyException('Failure applying ip '
-                                                   'tables rules')
+                msg = _LE('Failure applying iptables rules')
+                LOG.exception(msg)
+                raise n_exc.IpTablesApplyException(msg)
 
     def defer_apply_on(self):
         self.iptables_apply_deferred = True
index e0017a459ae0b57ba1b64cd716aa08c793260e4e..564e46186c1470fef524327abee69cd549abe070 100644 (file)
@@ -18,10 +18,12 @@ import sys
 
 import mock
 from oslo_config import cfg
+import testtools
 
 from neutron.agent.common import config as a_cfg
 from neutron.agent.linux import iptables_comments as ic
 from neutron.agent.linux import iptables_manager
+from neutron.common import exceptions as n_exc
 from neutron.tests import base
 from neutron.tests import tools
 
@@ -247,6 +249,12 @@ class IptablesManagerStateFulTestCase(base.BaseTestCase):
         self.assertEqual(iptables_manager.get_chain_name(name, wrap=True),
                          name[:11])
 
+    def test_defer_apply_with_exception(self):
+        self.iptables._apply = mock.Mock(side_effect=Exception)
+        with testtools.ExpectedException(n_exc.IpTablesApplyException):
+            with self.iptables.defer_apply():
+                pass
+
     def _extend_with_ip6tables_filter(self, expected_calls, filter_dump):
         expected_calls.insert(2, (
             mock.call(['ip6tables-save', '-c'],
index 200febe44ad6d66f57b466bdb274d135428fa181..0bccd1d6ff9d4f445d0c34f41fa646e8bfc9a68e 100644 (file)
@@ -1290,6 +1290,30 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework):
                 mock.ANY, ri.router_id,
                 {fip_id: l3_constants.FLOATINGIP_STATUS_ERROR})
 
+    def test_process_external_iptables_exception(self):
+        agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
+        with mock.patch.object(
+            agent.plugin_rpc,
+            'update_floatingip_statuses') as mock_update_fip_status:
+            fip_id = _uuid()
+            router = prepare_router_data(num_internal_ports=1)
+            router[l3_constants.FLOATINGIP_KEY] = [
+                {'id': fip_id,
+                 'floating_ip_address': '8.8.8.8',
+                 'fixed_ip_address': '7.7.7.7',
+                 'port_id': router[l3_constants.INTERFACE_KEY][0]['id']}]
+
+            ri = l3router.RouterInfo(router['id'], router, **self.ri_kwargs)
+            ri.iptables_manager._apply = mock.Mock(side_effect=Exception)
+            agent._process_external(ri)
+            # Assess the call for putting the floating IP into Error
+            # was performed
+            mock_update_fip_status.assert_called_once_with(
+                mock.ANY, ri.router_id,
+                {fip_id: l3_constants.FLOATINGIP_STATUS_ERROR})
+
+            self.assertEqual(ri.iptables_manager._apply.call_count, 1)
+
     def test_handle_router_snat_rules_distributed_without_snat_manager(self):
         ri = dvr_router.DvrRouter(
             HOSTNAME,