]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Fix KeyError except on router_info in FW Agent
authorSridar Kandaswamy <skandasw@cisco.com>
Mon, 10 Mar 2014 06:31:28 +0000 (23:31 -0700)
committerSridar Kandaswamy <skandasw@cisco.com>
Fri, 14 Mar 2014 20:26:53 +0000 (13:26 -0700)
The workflow of creating a firewall when a router without any i/f is present in that tenant
causes a KeyError on the FWAgent. The issue occurs as such routers are present in the list of
routers returned by get_routers() but are not populated in the router_info dict. Adding a check
before accessing the dict to prevent the exception. When an i/f is added to such routers -
_router_added processing in the l3agent will populate the router_info dict and the FWAgent
also picks this up in that context.

Change-Id: I5ea22e88a46e62372a0462e9cb958a08dd9f4c7d
Closes-Bug: #1289643

neutron/services/firewall/agents/l3reference/firewall_l3_agent.py
neutron/tests/unit/services/firewall/agents/l3reference/test_firewall_l3_agent.py

index f3158c28059cd7fb0ff895ff730313fee8736f4e..a3646c6bbf1c573df02af2022fb30253b7a5a76b 100644 (file)
@@ -97,6 +97,10 @@ class FWaaSL3AgentRpcCallback(api.FWaaSAgentRpcCallbackMixin):
         router_info_list = []
         # Pick up namespaces for Tenant Routers
         for rid in router_ids:
+            # for routers without an interface - get_routers returns
+            # the router - but this is not yet populated in router_info
+            if rid not in self.router_info:
+                continue
             if self.router_info[rid].use_namespaces:
                 router_ns = self.router_info[rid].ns_name()
                 if router_ns in local_ns_list:
index 9d7f4079b89a0c0213608522de4268d3725294ca..0034381056a6a94eb1e0311624af52adad3a6bd9 100644 (file)
@@ -360,3 +360,33 @@ class TestFwaasL3AgentRpcCallback(base.BaseTestCase):
     def test_get_router_info_list_tenant_without_namespace_router_with(self):
         self._get_router_info_list_without_namespace_helper(
             router_use_namespaces=True)
+
+    def _get_router_info_list_router_without_router_info_helper(self,
+                                                                rtr_with_ri):
+        self.conf.set_override('use_namespaces', True)
+        # ri.router with associated router_info (ri)
+        # rtr2 has no router_info
+        ri = self._prepare_router_data(use_namespaces=True)
+        rtr2 = {'id': str(uuid.uuid4()), 'tenant_id': ri.router['tenant_id']}
+        routers = [rtr2]
+        self.api.router_info = {}
+        ri_expected = []
+        if rtr_with_ri:
+            self.api.router_info[ri.router_id] = ri
+            routers.append(ri.router)
+            ri_expected.append(ri)
+        with mock.patch.object(ip_lib.IPWrapper,
+                               'get_namespaces') as mock_get_namespaces:
+            mock_get_namespaces.return_value = ri.ns_name()
+            router_info_list = self.api._get_router_info_list_for_tenant(
+                routers,
+                ri.router['tenant_id'])
+            self.assertEqual(ri_expected, router_info_list)
+
+    def test_get_router_info_list_router_without_router_info(self):
+        self._get_router_info_list_router_without_router_info_helper(
+            rtr_with_ri=False)
+
+    def test_get_router_info_list_two_routers_one_without_router_info(self):
+        self._get_router_info_list_router_without_router_info_helper(
+            rtr_with_ri=True)