]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Get rid of rpc to fetch fip agent port on agent.
authorSwaminathan Vasudevan <swaminathan.vasudevan@hp.com>
Fri, 6 Feb 2015 23:59:06 +0000 (15:59 -0800)
committerCarl Baldwin <carl.baldwin@hp.com>
Wed, 18 Feb 2015 17:58:16 +0000 (17:58 +0000)
This patch is dependent on the plugin side patch
Change-Id: Ieaa79c8bf2b1e03bc352f9252ce22286703e3715
for retrieving the fip agent port from the
router_update message.

This would reduce the wait time substantially.

Change-Id: I47bc43bab4bff59d14e2cdbce9f8b47826d392d9
Related-Bug: #1415522

neutron/agent/l3/agent.py
neutron/tests/functional/agent/test_l3_agent.py
neutron/tests/unit/test_l3_agent.py

index c39e52ad95c5673b15dbb05ac502ce778d6c221d..c21edd69384cba0f940d840d552c56c6eff1b85b 100644 (file)
@@ -580,8 +580,10 @@ class L3NATAgent(firewall_l3_agent.FWaaSL3AgentRpcCallback,
                 ri, ex_gw_port)
             fip_statuses = self._configure_fip_addresses(ri, interface_name)
 
-        except (n_exc.FloatingIpSetupException, n_exc.IpTablesApplyException):
+        except (n_exc.FloatingIpSetupException,
+                n_exc.IpTablesApplyException) as e:
                 # All floating IPs must be put in error state
+                LOG.exception(e)
                 fip_statuses = self._put_fips_in_error_state(ri)
 
         self._update_fip_statuses(ri, existing_floating_ips, fip_statuses)
@@ -665,17 +667,18 @@ class L3NATAgent(firewall_l3_agent.FWaaSL3AgentRpcCallback,
 
     def create_dvr_fip_interfaces(self, ri, ex_gw_port):
         floating_ips = self.get_floating_ips(ri)
+        fip_agent_port = self.get_floating_agent_gw_interface(
+            ri, ex_gw_port['network_id'])
+        LOG.debug("FloatingIP agent gateway port received from the plugin: "
+                  "%s", fip_agent_port)
         if floating_ips:
             is_first = ri.fip_ns.subscribe(ri.router_id)
-            if is_first:
-                agent_gateway_port = (
-                    self.plugin_rpc.get_agent_gateway_port(
-                        self.context, ex_gw_port['network_id']))
-                if 'subnet' not in agent_gateway_port:
+            if is_first and fip_agent_port:
+                if 'subnet' not in fip_agent_port:
                     LOG.error(_LE('Missing subnet/agent_gateway_port'))
                 else:
-                    self._set_subnet_info(agent_gateway_port)
-                    ri.fip_ns.create_gateway_port(agent_gateway_port)
+                    self._set_subnet_info(fip_agent_port)
+                    ri.fip_ns.create_gateway_port(fip_agent_port)
 
         if ri.fip_ns.agent_gateway_port and floating_ips:
             if ri.dist_fip_count == 0:
@@ -802,6 +805,12 @@ class L3NATAgent(firewall_l3_agent.FWaaSL3AgentRpcCallback,
             floating_ips = [i for i in floating_ips if i['host'] == self.host]
         return floating_ips
 
+    def get_floating_agent_gw_interface(self, ri, ext_net_id):
+        """Filter Floating Agent GW port for the external network."""
+        fip_ports = ri.router.get(l3_constants.FLOATINGIP_AGENT_INTF_KEY, [])
+        return next(
+            (p for p in fip_ports if p['network_id'] == ext_net_id), None)
+
     def external_gateway_added(self, ri, ex_gw_port, interface_name):
         if ri.router['distributed']:
             ip_wrapr = ip_lib.IPWrapper(self.root_helper, namespace=ri.ns_name)
index af3961904aa7e0d65b703dbea532f1e55471797e..a018d320195618e72ebb27ca5b8293d14c5a9247 100755 (executable)
@@ -638,12 +638,42 @@ class TestDvrRouter(L3AgentTestFramework):
         floating_ip['port_id'] = internal_ports[0]['id']
         floating_ip['status'] = 'ACTIVE'
 
-        if not enable_snat:
-            return router
-
         self._add_snat_port_info_to_router(router, internal_ports)
+        # FIP has a dependency on external gateway. So we need to create
+        # the snat_port info and fip_agent_gw_port_info irrespective of
+        # the agent type the dvr supports. The namespace creation is
+        # dependent on the agent_type.
+        external_gw_port = router['gw_port']
+        self._add_fip_agent_gw_port_info_to_router(router, external_gw_port)
         return router
 
+    def _add_fip_agent_gw_port_info_to_router(self, router, external_gw_port):
+        # Add fip agent gateway port information to the router_info
+        fip_gw_port_list = router.get(
+            l3_constants.FLOATINGIP_AGENT_INTF_KEY, [])
+        if not fip_gw_port_list and external_gw_port:
+            # Get values from external gateway port
+            fixed_ip = external_gw_port['fixed_ips'][0]
+            float_subnet = external_gw_port['subnet']
+            port_ip = fixed_ip['ip_address']
+            # Pick an ip address which is not the same as port_ip
+            fip_gw_port_ip = str(netaddr.IPAddress(port_ip) + 5)
+            # Add floatingip agent gateway port info to router
+            router[l3_constants.FLOATINGIP_AGENT_INTF_KEY] = [
+                {'subnet':
+                    {'cidr': float_subnet['cidr'],
+                        'gateway_ip': float_subnet['gateway_ip'],
+                        'id': fixed_ip['subnet_id']},
+                    'network_id': external_gw_port['network_id'],
+                    'device_owner': 'network:floatingip_agent_gateway',
+                    'mac_address': 'fa:16:3e:80:8d:89',
+                    'binding:host_id': self.agent.conf.host,
+                    'fixed_ips': [{'subnet_id': fixed_ip['subnet_id'],
+                                    'ip_address': fip_gw_port_ip}],
+                    'id': _uuid(),
+                    'device_id': _uuid()}
+            ]
+
     def _add_snat_port_info_to_router(self, router, internal_ports):
         # Add snat port information to the router
         snat_port_list = router.get(l3_constants.SNAT_ROUTER_INTF_KEY, [])
@@ -731,14 +761,19 @@ class TestDvrRouter(L3AgentTestFramework):
         # is created with the ip address of the external gateway port
         floating_ips = router.router[l3_constants.FLOATINGIP_KEY]
         self.assertTrue(floating_ips)
+        # We need to fetch the floatingip agent gateway port info
+        # from the router_info
+        floating_agent_gw_port = (
+            router.router[l3_constants.FLOATINGIP_AGENT_INTF_KEY])
+        self.assertTrue(floating_agent_gw_port)
 
-        external_port = self.agent._get_ex_gw_port(router)
+        external_gw_port = floating_agent_gw_port[0]
         fip_ns = self.agent.get_fip_ns(floating_ips[0]['floating_network_id'])
         fip_ns_name = fip_ns.get_name()
         fg_port_created_succesfully = ip_lib.device_exists_with_ip_mac(
-            fip_ns.get_ext_device_name(external_port['id']),
-            external_port['ip_cidr'],
-            external_port['mac_address'],
+            fip_ns.get_ext_device_name(external_gw_port['id']),
+            external_gw_port['ip_cidr'],
+            external_gw_port['mac_address'],
             fip_ns_name, self.root_helper)
         self.assertTrue(fg_port_created_succesfully)
         # Check fpr-router device has been created
index 7b486e66fb0125fafc390bbd2acbf17cf8d1029b..5cd7f31db888b105bbabd4d4e4bdf5ee4f1c3b21 100644 (file)
@@ -883,6 +883,77 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework):
         for chain, rule in rules:
             nat.add_rule.assert_any_call(chain, rule, tag='floating_ip')
 
+    def test_get_floating_agent_gw_interfaces(self):
+        fake_network_id = _uuid()
+        agent_gateway_port = (
+            [{'fixed_ips': [{'ip_address': '20.0.0.30',
+             'subnet_id': _uuid()}],
+             'subnet': {'gateway_ip': '20.0.0.1'},
+             'id': _uuid(),
+             'binding:host_id': 'myhost',
+             'device_owner': 'network:floatingip_agent_gateway',
+             'network_id': fake_network_id,
+             'mac_address': 'ca:fe:de:ad:be:ef',
+             'ip_cidr': '20.0.0.30/24'}]
+        )
+
+        router = prepare_router_data(enable_snat=True)
+        router[l3_constants.FLOATINGIP_AGENT_INTF_KEY] = agent_gateway_port
+        router['distributed'] = True
+        ri = dvr_router.DvrRouter(router['id'], router, **self.ri_kwargs)
+        agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
+        self.assertEqual(
+            agent_gateway_port[0],
+            agent.get_floating_agent_gw_interface(ri, fake_network_id))
+
+    def test_create_dvr_fip_interfaces(self):
+        fake_network_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',
+             'subnet_id': _uuid()}],
+             'subnet': {'gateway_ip': '20.0.0.1'},
+             'id': _uuid(),
+             'network_id': fake_network_id,
+             'mac_address': 'ca:fe:de:ad:be:ef',
+             'ip_cidr': '20.0.0.30/24'}]
+        )
+
+        router = 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
+        ri = dvr_router.DvrRouter(router['id'], router, **self.ri_kwargs)
+
+        agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
+        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
+        ri.fip_ns.subscribe = mock.Mock()
+
+        with contextlib.nested(mock.patch.object(agent,
+                                                 'get_floating_ips'),
+                               mock.patch.object(
+                                   agent, 'get_floating_agent_gw_interface'),
+                               mock.patch.object(
+                                   agent, '_set_subnet_info')
+                               ) as (fips,
+                                     fip_gw_port,
+                                     sub_info):
+            fips.return_value = fake_floatingips
+            fip_gw_port.return_value = agent_gateway_port[0]
+            agent.create_dvr_fip_interfaces(ri, ext_gw_port)
+            self.assertTrue(fip_gw_port.called)
+            self.assertTrue(fips.called)
+            self.assertEqual(ri.fip_ns.agent_gateway_port,
+                             agent_gateway_port[0])
+
     def test_process_router_cent_floating_ip_add(self):
         fake_floatingips = {'floatingips': [
             {'id': _uuid(),