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)
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:
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)
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, [])
# 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
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(),