to update_ha_routers_states
1.5 - Added update_ha_routers_states
1.6 - Added process_prefix_update
-
+ 1.7 - DVR support: new L3 plugin methods added.
+ - delete_agent_gateway_port
"""
def __init__(self, topic, host):
return cctxt.call(context, 'process_prefix_update',
subnets=prefix_update)
+ def delete_agent_gateway_port(self, context, fip_net):
+ """Delete Floatingip_agent_gateway_port."""
+ cctxt = self.client.prepare(version='1.7')
+ return cctxt.call(context, 'delete_agent_gateway_port',
+ host=self.host, network_id=fip_net)
+
class L3NATAgent(firewall_l3_agent.FWaaSL3AgentRpcCallback,
ha.AgentMixin,
# destroying it. The two could end up conflicting on
# creating/destroying interfaces and such. I think I'd like a
# semaphore to sync creation/deletion of this namespace.
+
+ # NOTE (Swami): Since we are deleting the namespace here we
+ # should be able to delete the floatingip agent gateway port
+ # for the provided external net since we don't need it anymore.
+ if self.fip_ns.agent_gateway_port:
+ LOG.debug('Removed last floatingip, so requesting the '
+ 'server to delete Floatingip Agent Gateway port:'
+ '%s', self.fip_ns.agent_gateway_port)
+ self.agent.plugin_rpc.delete_agent_gateway_port(
+ self.agent.context,
+ self.fip_ns.agent_gateway_port['network_id'])
self.fip_ns.delete()
self.fip_ns = None
# since it was unused. The RPC version was not changed
# 1.5 Added update_ha_routers_states
# 1.6 Added process_prefix_update to support IPv6 Prefix Delegation
- target = oslo_messaging.Target(version='1.6')
+ # 1.7 Added method delete_agent_gateway_port for DVR Routers
+ target = oslo_messaging.Target(version='1.7')
@property
def plugin(self):
subnet_id,
{'subnet': {'cidr': prefix}}))
return updated_subnets
+
+ def delete_agent_gateway_port(self, context, **kwargs):
+ """Delete Floatingip agent gateway port."""
+ network_id = kwargs.get('network_id')
+ host = kwargs.get('host')
+ admin_ctx = neutron_context.get_admin_context()
+ self.l3plugin.delete_floatingip_agent_gateway_port(
+ admin_ctx, network_id, host_id=host)
ext_net_gw_ports = self._core_plugin.get_ports(
context.elevated(), filters)
if not ext_net_gw_ports:
- self._delete_floatingip_agent_gateway_port(
+ self.delete_floatingip_agent_gateway_port(
context.elevated(), None, gw_ext_net_id)
def _create_gw_port(self, context, router_id, router, new_network,
context, fip_hostid, floatingip_db['floating_network_id']):
LOG.debug('Deleting the Agent GW Port for ext-net: '
'%s', floatingip_db['floating_network_id'])
- self._delete_floatingip_agent_gateway_port(
+ self.delete_floatingip_agent_gateway_port(
context, fip_hostid, floatingip_db['floating_network_id'])
def delete_floatingip(self, context, id):
return True
return False
- def _delete_floatingip_agent_gateway_port(
+ def delete_floatingip_agent_gateway_port(
self, context, host_id, ext_net_id):
"""Function to delete FIP gateway port with given ext_net_id."""
# delete any fip agent gw port
router_updated, internal_dev_name=internal_device_name)
self.assertFalse(sg_device)
self.assertTrue(qg_device)
+
+ def test_dvr_router_calls_delete_agent_gateway_if_last_fip(self):
+ """Test to validate delete fip if it is last fip managed by agent."""
+ self.agent.conf.agent_mode = 'dvr_snat'
+ router_info = self.generate_dvr_router_info(enable_snat=True)
+ router1 = self.manage_router(self.agent, router_info)
+ floating_agent_gw_port = (
+ router1.router[l3_constants.FLOATINGIP_AGENT_INTF_KEY])
+ self.assertTrue(floating_agent_gw_port)
+ fip_ns = router1.fip_ns.get_name()
+ router1.fip_ns.agent_gw_port = floating_agent_gw_port
+ self.assertTrue(self._namespace_exists(router1.ns_name))
+ self.assertTrue(self._namespace_exists(fip_ns))
+ self._assert_dvr_floating_ips(router1)
+ self._assert_dvr_snat_gateway(router1)
+ router1.router[l3_constants.FLOATINGIP_KEY] = []
+ rpc_mock = mock.patch.object(
+ self.agent.plugin_rpc, 'delete_agent_gateway_port').start()
+ self.agent._process_updated_router(router1.router)
+ self.assertTrue(rpc_mock.called)
+ rpc_mock.assert_called_once_with(
+ self.agent.context,
+ floating_agent_gw_port[0]['network_id'])
+ self.assertFalse(self._namespace_exists(fip_ns))
network_id, port = (
self.setup_create_agent_gw_port_for_network())
- self.l3_plugin._delete_floatingip_agent_gateway_port(
+ self.l3_plugin.delete_floatingip_agent_gateway_port(
self.context, "", network_id)
self.assertIsNone(
self.l3_plugin._get_agent_gw_ports_exist_for_network(
'interface_driver': self.mock_driver}
def _create_router(self, router=None, **kwargs):
- agent_conf = mock.Mock()
+ agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)
self.router_id = _uuid()
if not router:
router = mock.MagicMock()
- return dvr_router.DvrLocalRouter(mock.sentinel.agent,
- mock.sentinel.myhost,
+ return dvr_router.DvrLocalRouter(agent,
+ HOSTNAME,
self.router_id,
router,
- agent_conf,
- mock.sentinel.interface_driver,
+ self.conf,
+ mock.Mock(),
**kwargs)
def test_get_floating_ips_dvr(self):
router = mock.MagicMock()
- router.get.return_value = [{'host': mock.sentinel.myhost},
+ router.get.return_value = [{'host': HOSTNAME},
{'host': mock.sentinel.otherhost}]
ri = self._create_router(router)
fips = ri.get_floating_ips()
- self.assertEqual([{'host': mock.sentinel.myhost}], fips)
+ self.assertEqual([{'host': HOSTNAME}], fips)
@mock.patch.object(ip_lib, 'send_ip_addr_adv_notif')
@mock.patch.object(ip_lib, 'IPDevice')
ri.rtr_fip_subnet = lla.LinkLocalAddressPair('15.1.2.3/32')
_, fip_to_rtr = ri.rtr_fip_subnet.get_pair()
fip_ns = ri.fip_ns
-
- ri.floating_ip_removed_dist(fip_cidr)
-
- self.assertTrue(fip_ns.destroyed)
- mIPWrapper().del_veth.assert_called_once_with(
- fip_ns.get_int_device_name(router['id']))
- mIPDevice().route.delete_gateway.assert_called_once_with(
- str(fip_to_rtr.ip), table=16)
- fip_ns.unsubscribe.assert_called_once_with(ri.router_id)
+ with mock.patch.object(self.plugin_api,
+ 'delete_agent_gateway_port') as del_fip_gw:
+ ri.floating_ip_removed_dist(fip_cidr)
+ self.assertTrue(del_fip_gw.called)
+ self.assertTrue(fip_ns.destroyed)
+ mIPWrapper().del_veth.assert_called_once_with(
+ fip_ns.get_int_device_name(router['id']))
+ mIPDevice().route.delete_gateway.assert_called_once_with(
+ str(fip_to_rtr.ip), table=16)
+ fip_ns.unsubscribe.assert_called_once_with(ri.router_id)
def _test_add_floating_ip(self, ri, fip, is_failure):
ri._add_fip_addr_to_device = mock.Mock(return_value=is_failure)
self.ctx,
port['id'])
- def test_prevent__delete_floatingip_agent_gateway_port(self):
+ def test_prevent_delete_floatingip_agent_gateway_port(self):
port = {
'id': 'my_port_id',
'fixed_ips': mock.ANY,
'_check_fips_availability_on_host_ext_net') as cfips,\
mock.patch.object(
self.mixin,
- '_delete_floatingip_agent_gateway_port') as dfips:
+ 'delete_floatingip_agent_gateway_port') as dfips:
gfips.return_value = floatingip
gvm.return_value = 'my-host'
cfips.return_value = True
plugin = mock.Mock()
gp.return_value = plugin
plugin.get_ports.return_value = ports
- self.mixin._delete_floatingip_agent_gateway_port(
+ self.mixin.delete_floatingip_agent_gateway_port(
self.ctx, port_host, 'ext_network_id')
plugin.get_ports.assert_called_with(self.ctx, filters={
'network_id': ['ext_network_id'],
plugin.ipam.delete_port.assert_called_with(
self.ctx, 'my_new_port_id')
- def test__delete_floatingip_agent_gateway_port_without_host_id(self):
+ def test_delete_floatingip_agent_gateway_port_without_host_id(self):
self._helper_delete_floatingip_agent_gateway_port(None)
- def test__delete_floatingip_agent_gateway_port_with_host_id(self):
+ def test_delete_floatingip_agent_gateway_port_with_host_id(self):
self._helper_delete_floatingip_agent_gateway_port(
'foo_host')
'delete_csnat_router_interface_ports') as del_csnat_port,\
mock.patch.object(
self.mixin,
- '_delete_floatingip_agent_gateway_port') as del_agent_gw_port:
+ 'delete_floatingip_agent_gateway_port') as del_agent_gw_port:
plugin = mock.Mock()
gp.return_value = plugin
plugin.get_ports.return_value = port