Merge "Revert "DVR: Remove control plane arp updates for DVR"" into stable/ussuri
This commit is contained in:
commit
5489a10d70
@ -13,6 +13,7 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
import collections
|
import collections
|
||||||
|
|
||||||
|
import netaddr
|
||||||
from neutron_lib.api.definitions import external_net as extnet_apidef
|
from neutron_lib.api.definitions import external_net as extnet_apidef
|
||||||
from neutron_lib.api.definitions import l3 as l3_apidef
|
from neutron_lib.api.definitions import l3 as l3_apidef
|
||||||
from neutron_lib.api.definitions import portbindings
|
from neutron_lib.api.definitions import portbindings
|
||||||
@ -50,6 +51,7 @@ from neutron.db import models_v2
|
|||||||
from neutron.extensions import _admin_state_down_before_update_lib
|
from neutron.extensions import _admin_state_down_before_update_lib
|
||||||
from neutron.ipam import utils as ipam_utils
|
from neutron.ipam import utils as ipam_utils
|
||||||
from neutron.objects import agent as ag_obj
|
from neutron.objects import agent as ag_obj
|
||||||
|
from neutron.objects import base as base_obj
|
||||||
from neutron.objects import l3agent as rb_obj
|
from neutron.objects import l3agent as rb_obj
|
||||||
from neutron.objects import router as l3_obj
|
from neutron.objects import router as l3_obj
|
||||||
|
|
||||||
@ -475,6 +477,17 @@ class DVRResourceOperationHandler(object):
|
|||||||
fixed_ip_address))
|
fixed_ip_address))
|
||||||
if not addr_pair_active_service_port_list:
|
if not addr_pair_active_service_port_list:
|
||||||
return
|
return
|
||||||
|
self._inherit_service_port_and_arp_update(
|
||||||
|
context, addr_pair_active_service_port_list[0])
|
||||||
|
|
||||||
|
def _inherit_service_port_and_arp_update(self, context, service_port):
|
||||||
|
"""Function inherits port host bindings for allowed_address_pair."""
|
||||||
|
service_port_dict = self.l3plugin._core_plugin._make_port_dict(
|
||||||
|
service_port)
|
||||||
|
address_pair_list = service_port_dict.get('allowed_address_pairs')
|
||||||
|
for address_pair in address_pair_list:
|
||||||
|
self.update_arp_entry_for_dvr_service_port(context,
|
||||||
|
service_port_dict)
|
||||||
|
|
||||||
@registry.receives(resources.ROUTER_INTERFACE, [events.BEFORE_CREATE])
|
@registry.receives(resources.ROUTER_INTERFACE, [events.BEFORE_CREATE])
|
||||||
@db_api.retry_if_session_inactive()
|
@db_api.retry_if_session_inactive()
|
||||||
@ -1111,6 +1124,21 @@ class _DVRAgentInterfaceMixin(object):
|
|||||||
self._populate_mtu_and_subnets_for_ports(context, [agent_port])
|
self._populate_mtu_and_subnets_for_ports(context, [agent_port])
|
||||||
return agent_port
|
return agent_port
|
||||||
|
|
||||||
|
def _generate_arp_table_and_notify_agent(self, context, fixed_ip,
|
||||||
|
mac_address, notifier):
|
||||||
|
"""Generates the arp table entry and notifies the l3 agent."""
|
||||||
|
ip_address = fixed_ip['ip_address']
|
||||||
|
subnet = fixed_ip['subnet_id']
|
||||||
|
arp_table = {'ip_address': ip_address,
|
||||||
|
'mac_address': mac_address,
|
||||||
|
'subnet_id': subnet}
|
||||||
|
filters = {'fixed_ips': {'subnet_id': [subnet]},
|
||||||
|
'device_owner': [const.DEVICE_OWNER_DVR_INTERFACE]}
|
||||||
|
ports = self._core_plugin.get_ports(context, filters=filters)
|
||||||
|
routers = [port['device_id'] for port in ports]
|
||||||
|
for router_id in routers:
|
||||||
|
notifier(context, router_id, arp_table)
|
||||||
|
|
||||||
def _get_subnet_id_for_given_fixed_ip(self, context, fixed_ip, port_dict):
|
def _get_subnet_id_for_given_fixed_ip(self, context, fixed_ip, port_dict):
|
||||||
"""Returns the subnet_id that matches the fixedip on a network."""
|
"""Returns the subnet_id that matches the fixedip on a network."""
|
||||||
filters = {'network_id': [port_dict['network_id']]}
|
filters = {'network_id': [port_dict['network_id']]}
|
||||||
@ -1119,6 +1147,78 @@ class _DVRAgentInterfaceMixin(object):
|
|||||||
if ipam_utils.check_subnet_ip(subnet['cidr'], fixed_ip):
|
if ipam_utils.check_subnet_ip(subnet['cidr'], fixed_ip):
|
||||||
return subnet['id']
|
return subnet['id']
|
||||||
|
|
||||||
|
def _get_allowed_address_pair_fixed_ips(self, context, port_dict):
|
||||||
|
"""Returns all fixed_ips associated with the allowed_address_pair."""
|
||||||
|
aa_pair_fixed_ips = []
|
||||||
|
if port_dict.get('allowed_address_pairs'):
|
||||||
|
for address_pair in port_dict['allowed_address_pairs']:
|
||||||
|
aap_ip_cidr = address_pair['ip_address'].split("/")
|
||||||
|
if len(aap_ip_cidr) == 1 or int(aap_ip_cidr[1]) == 32:
|
||||||
|
subnet_id = self._get_subnet_id_for_given_fixed_ip(
|
||||||
|
context, aap_ip_cidr[0], port_dict)
|
||||||
|
if subnet_id is not None:
|
||||||
|
fixed_ip = {'subnet_id': subnet_id,
|
||||||
|
'ip_address': aap_ip_cidr[0]}
|
||||||
|
aa_pair_fixed_ips.append(fixed_ip)
|
||||||
|
else:
|
||||||
|
LOG.debug("Subnet does not match for the given "
|
||||||
|
"fixed_ip %s for arp update", aap_ip_cidr[0])
|
||||||
|
return aa_pair_fixed_ips
|
||||||
|
|
||||||
|
def update_arp_entry_for_dvr_service_port(self, context, port_dict):
|
||||||
|
"""Notify L3 agents of ARP table entry for dvr service port.
|
||||||
|
|
||||||
|
When a dvr service port goes up, look for the DVR router on
|
||||||
|
the port's subnet, and send the ARP details to all
|
||||||
|
L3 agents hosting the router to add it.
|
||||||
|
If there are any allowed_address_pairs associated with the port
|
||||||
|
those fixed_ips should also be updated in the ARP table.
|
||||||
|
"""
|
||||||
|
fixed_ips = port_dict['fixed_ips']
|
||||||
|
if not fixed_ips:
|
||||||
|
return
|
||||||
|
allowed_address_pair_fixed_ips = (
|
||||||
|
self._get_allowed_address_pair_fixed_ips(context, port_dict))
|
||||||
|
changed_fixed_ips = fixed_ips + allowed_address_pair_fixed_ips
|
||||||
|
for fixed_ip in changed_fixed_ips:
|
||||||
|
self._generate_arp_table_and_notify_agent(
|
||||||
|
context, fixed_ip, port_dict['mac_address'],
|
||||||
|
self.l3_rpc_notifier.add_arp_entry)
|
||||||
|
|
||||||
|
def delete_arp_entry_for_dvr_service_port(self, context, port_dict,
|
||||||
|
fixed_ips_to_delete=None):
|
||||||
|
"""Notify L3 agents of ARP table entry for dvr service port.
|
||||||
|
|
||||||
|
When a dvr service port goes down, look for the DVR
|
||||||
|
router on the port's subnet, and send the ARP details to all
|
||||||
|
L3 agents hosting the router to delete it.
|
||||||
|
If there are any allowed_address_pairs associated with the
|
||||||
|
port, those fixed_ips should be removed from the ARP table.
|
||||||
|
"""
|
||||||
|
fixed_ips = port_dict['fixed_ips']
|
||||||
|
if not fixed_ips:
|
||||||
|
return
|
||||||
|
if not fixed_ips_to_delete:
|
||||||
|
allowed_address_pair_fixed_ips = (
|
||||||
|
self._get_allowed_address_pair_fixed_ips(context, port_dict))
|
||||||
|
fixed_ips_to_delete = fixed_ips + allowed_address_pair_fixed_ips
|
||||||
|
for fixed_ip in fixed_ips_to_delete:
|
||||||
|
self._generate_arp_table_and_notify_agent(
|
||||||
|
context, fixed_ip, port_dict['mac_address'],
|
||||||
|
self.l3_rpc_notifier.del_arp_entry)
|
||||||
|
|
||||||
|
def _get_address_pair_active_port_with_fip(
|
||||||
|
self, context, port_dict, port_addr_pair_ip):
|
||||||
|
port_valid_state = (port_dict['admin_state_up'] or
|
||||||
|
port_dict['status'] == const.PORT_STATUS_ACTIVE)
|
||||||
|
if not port_valid_state:
|
||||||
|
return
|
||||||
|
fips = l3_obj.FloatingIP.get_objects(
|
||||||
|
context, _pager=base_obj.Pager(limit=1),
|
||||||
|
fixed_ip_address=netaddr.IPAddress(port_addr_pair_ip))
|
||||||
|
return self._core_plugin.get_port(
|
||||||
|
context, fips[0].fixed_port_id) if fips else None
|
||||||
|
|
||||||
|
|
||||||
class L3_NAT_with_dvr_db_mixin(_DVRAgentInterfaceMixin,
|
class L3_NAT_with_dvr_db_mixin(_DVRAgentInterfaceMixin,
|
||||||
DVRResourceOperationHandler,
|
DVRResourceOperationHandler,
|
||||||
|
@ -518,6 +518,19 @@ class L3_DVRsch_db_mixin(l3agent_sch_db.L3AgentSchedulerDbMixin):
|
|||||||
return any([r in dvr_routers for r in related_routers])
|
return any([r in dvr_routers for r in related_routers])
|
||||||
|
|
||||||
|
|
||||||
|
def _dvr_handle_unbound_allowed_addr_pair_add(
|
||||||
|
plugin, context, port, allowed_address_pair):
|
||||||
|
plugin.update_arp_entry_for_dvr_service_port(context, port)
|
||||||
|
|
||||||
|
|
||||||
|
def _dvr_handle_unbound_allowed_addr_pair_del(
|
||||||
|
plugin, context, port, allowed_address_pair):
|
||||||
|
aa_fixed_ips = plugin._get_allowed_address_pair_fixed_ips(context, port)
|
||||||
|
if aa_fixed_ips:
|
||||||
|
plugin.delete_arp_entry_for_dvr_service_port(
|
||||||
|
context, port, fixed_ips_to_delete=aa_fixed_ips)
|
||||||
|
|
||||||
|
|
||||||
def _notify_l3_agent_new_port(resource, event, trigger, **kwargs):
|
def _notify_l3_agent_new_port(resource, event, trigger, **kwargs):
|
||||||
LOG.debug('Received %(resource)s %(event)s', {
|
LOG.debug('Received %(resource)s %(event)s', {
|
||||||
'resource': resource,
|
'resource': resource,
|
||||||
@ -530,6 +543,7 @@ def _notify_l3_agent_new_port(resource, event, trigger, **kwargs):
|
|||||||
l3plugin = directory.get_plugin(plugin_constants.L3)
|
l3plugin = directory.get_plugin(plugin_constants.L3)
|
||||||
context = kwargs['context']
|
context = kwargs['context']
|
||||||
l3plugin.dvr_handle_new_service_port(context, port)
|
l3plugin.dvr_handle_new_service_port(context, port)
|
||||||
|
l3plugin.update_arp_entry_for_dvr_service_port(context, port)
|
||||||
|
|
||||||
|
|
||||||
def _notify_port_delete(event, resource, trigger, **kwargs):
|
def _notify_port_delete(event, resource, trigger, **kwargs):
|
||||||
@ -537,6 +551,14 @@ def _notify_port_delete(event, resource, trigger, **kwargs):
|
|||||||
port = kwargs['port']
|
port = kwargs['port']
|
||||||
get_related_hosts_info = kwargs.get("get_related_hosts_info", True)
|
get_related_hosts_info = kwargs.get("get_related_hosts_info", True)
|
||||||
l3plugin = directory.get_plugin(plugin_constants.L3)
|
l3plugin = directory.get_plugin(plugin_constants.L3)
|
||||||
|
if port:
|
||||||
|
port_host = port.get(portbindings.HOST_ID)
|
||||||
|
allowed_address_pairs_list = port.get('allowed_address_pairs')
|
||||||
|
if allowed_address_pairs_list and port_host:
|
||||||
|
for address_pair in allowed_address_pairs_list:
|
||||||
|
_dvr_handle_unbound_allowed_addr_pair_del(
|
||||||
|
l3plugin, context, port, address_pair)
|
||||||
|
l3plugin.delete_arp_entry_for_dvr_service_port(context, port)
|
||||||
removed_routers = l3plugin.get_dvr_routers_to_remove(
|
removed_routers = l3plugin.get_dvr_routers_to_remove(
|
||||||
context, port, get_related_hosts_info)
|
context, port, get_related_hosts_info)
|
||||||
for info in removed_routers:
|
for info in removed_routers:
|
||||||
@ -625,7 +647,32 @@ def _notify_l3_agent_port_update(resource, event, trigger, **kwargs):
|
|||||||
context, new_port,
|
context, new_port,
|
||||||
dest_host=dest_host,
|
dest_host=dest_host,
|
||||||
router_id=fip_router_id)
|
router_id=fip_router_id)
|
||||||
|
l3plugin.update_arp_entry_for_dvr_service_port(
|
||||||
|
context, new_port)
|
||||||
return
|
return
|
||||||
|
# Check for allowed_address_pairs and port state
|
||||||
|
new_port_host = new_port.get(portbindings.HOST_ID)
|
||||||
|
allowed_address_pairs_list = new_port.get('allowed_address_pairs')
|
||||||
|
if allowed_address_pairs_list and new_port_host:
|
||||||
|
new_port_state = new_port.get('admin_state_up')
|
||||||
|
original_port_state = original_port.get('admin_state_up')
|
||||||
|
if new_port_state:
|
||||||
|
# Case were we activate the port from inactive state,
|
||||||
|
# or the same port has additional address_pairs added.
|
||||||
|
for address_pair in allowed_address_pairs_list:
|
||||||
|
_dvr_handle_unbound_allowed_addr_pair_add(
|
||||||
|
l3plugin, context, new_port, address_pair)
|
||||||
|
return
|
||||||
|
elif original_port_state:
|
||||||
|
# Case were we deactivate the port from active state.
|
||||||
|
for address_pair in allowed_address_pairs_list:
|
||||||
|
_dvr_handle_unbound_allowed_addr_pair_del(
|
||||||
|
l3plugin, context, original_port, address_pair)
|
||||||
|
return
|
||||||
|
|
||||||
|
if kwargs.get('mac_address_updated') or is_fixed_ips_changed:
|
||||||
|
l3plugin.update_arp_entry_for_dvr_service_port(
|
||||||
|
context, new_port)
|
||||||
|
|
||||||
|
|
||||||
def subscribe():
|
def subscribe():
|
||||||
|
@ -1024,6 +1024,145 @@ class L3DvrTestCase(L3DvrTestCaseBase):
|
|||||||
floatingips = router_sync_info[0][constants.FLOATINGIP_KEY]
|
floatingips = router_sync_info[0][constants.FLOATINGIP_KEY]
|
||||||
self.assertTrue(floatingips[0][constants.DVR_SNAT_BOUND])
|
self.assertTrue(floatingips[0][constants.DVR_SNAT_BOUND])
|
||||||
|
|
||||||
|
def test_allowed_addr_pairs_delayed_fip_and_update_arp_entry(self):
|
||||||
|
HOST1 = 'host1'
|
||||||
|
helpers.register_l3_agent(
|
||||||
|
host=HOST1, agent_mode=constants.L3_AGENT_MODE_DVR)
|
||||||
|
HOST2 = 'host2'
|
||||||
|
helpers.register_l3_agent(
|
||||||
|
host=HOST2, agent_mode=constants.L3_AGENT_MODE_DVR)
|
||||||
|
router = self._create_router(ha=False)
|
||||||
|
private_net1 = self._make_network(self.fmt, 'net1', True)
|
||||||
|
test_allocation_pools = [{'start': '10.1.0.2',
|
||||||
|
'end': '10.1.0.20'}]
|
||||||
|
fixed_vrrp_ip = [{'ip_address': '10.1.0.201'}]
|
||||||
|
kwargs = {'arg_list': (extnet_apidef.EXTERNAL,),
|
||||||
|
extnet_apidef.EXTERNAL: True}
|
||||||
|
ext_net = self._make_network(self.fmt, '', True, **kwargs)
|
||||||
|
self._make_subnet(
|
||||||
|
self.fmt, ext_net, '10.20.0.1', '10.20.0.0/24',
|
||||||
|
ip_version=constants.IP_VERSION_4, enable_dhcp=True)
|
||||||
|
self.l3_plugin.schedule_router(self.context,
|
||||||
|
router['id'],
|
||||||
|
candidates=[self.l3_agent])
|
||||||
|
|
||||||
|
# Set gateway to router
|
||||||
|
self.l3_plugin._update_router_gw_info(
|
||||||
|
self.context, router['id'],
|
||||||
|
{'network_id': ext_net['network']['id']})
|
||||||
|
private_subnet1 = self._make_subnet(
|
||||||
|
self.fmt,
|
||||||
|
private_net1,
|
||||||
|
'10.1.0.1',
|
||||||
|
cidr='10.1.0.0/24',
|
||||||
|
ip_version=constants.IP_VERSION_4,
|
||||||
|
allocation_pools=test_allocation_pools,
|
||||||
|
enable_dhcp=True)
|
||||||
|
vrrp_port = self._make_port(
|
||||||
|
self.fmt,
|
||||||
|
private_net1['network']['id'],
|
||||||
|
fixed_ips=fixed_vrrp_ip)
|
||||||
|
allowed_address_pairs = [
|
||||||
|
{'ip_address': '10.1.0.201',
|
||||||
|
'mac_address': vrrp_port['port']['mac_address']}]
|
||||||
|
with self.port(
|
||||||
|
subnet=private_subnet1,
|
||||||
|
device_owner=DEVICE_OWNER_COMPUTE) as int_port,\
|
||||||
|
self.port(subnet=private_subnet1,
|
||||||
|
device_owner=DEVICE_OWNER_COMPUTE) as int_port2:
|
||||||
|
self.l3_plugin.add_router_interface(
|
||||||
|
self.context, router['id'],
|
||||||
|
{'subnet_id': private_subnet1['subnet']['id']})
|
||||||
|
router_handle = (
|
||||||
|
self.l3_plugin.list_active_sync_routers_on_active_l3_agent(
|
||||||
|
self.context, self.l3_agent['host'], [router['id']]))
|
||||||
|
self.assertEqual(self.l3_agent['host'],
|
||||||
|
router_handle[0]['gw_port_host'])
|
||||||
|
with mock.patch.object(self.l3_plugin,
|
||||||
|
'_l3_rpc_notifier') as l3_notifier:
|
||||||
|
vm_port = self.core_plugin.update_port(
|
||||||
|
self.context, int_port['port']['id'],
|
||||||
|
{'port': {portbindings.HOST_ID: HOST1}})
|
||||||
|
vm_port_mac = vm_port['mac_address']
|
||||||
|
vm_port_fixed_ips = vm_port['fixed_ips']
|
||||||
|
vm_port_subnet_id = vm_port_fixed_ips[0]['subnet_id']
|
||||||
|
vm_arp_table = {
|
||||||
|
'ip_address': vm_port_fixed_ips[0]['ip_address'],
|
||||||
|
'mac_address': vm_port_mac,
|
||||||
|
'subnet_id': vm_port_subnet_id}
|
||||||
|
vm_port2 = self.core_plugin.update_port(
|
||||||
|
self.context, int_port2['port']['id'],
|
||||||
|
{'port': {portbindings.HOST_ID: HOST2}})
|
||||||
|
# Now update the VM port with the allowed_address_pair
|
||||||
|
self.core_plugin.update_port(
|
||||||
|
self.context, vm_port['id'],
|
||||||
|
{'port': {
|
||||||
|
'allowed_address_pairs': allowed_address_pairs}})
|
||||||
|
self.core_plugin.update_port(
|
||||||
|
self.context, vm_port2['id'],
|
||||||
|
{'port': {
|
||||||
|
'allowed_address_pairs': allowed_address_pairs}})
|
||||||
|
self.assertEqual(
|
||||||
|
2, l3_notifier.routers_updated_on_host.call_count)
|
||||||
|
updated_vm_port1 = self.core_plugin.get_port(
|
||||||
|
self.context, vm_port['id'])
|
||||||
|
updated_vm_port2 = self.core_plugin.get_port(
|
||||||
|
self.context, vm_port2['id'])
|
||||||
|
expected_allowed_address_pairs = updated_vm_port1.get(
|
||||||
|
'allowed_address_pairs')
|
||||||
|
self.assertEqual(expected_allowed_address_pairs,
|
||||||
|
allowed_address_pairs)
|
||||||
|
expected_allowed_address_pairs_2 = updated_vm_port2.get(
|
||||||
|
'allowed_address_pairs')
|
||||||
|
self.assertEqual(expected_allowed_address_pairs_2,
|
||||||
|
allowed_address_pairs)
|
||||||
|
# Now the VRRP port is attached to the VM port. At this
|
||||||
|
# point, the VRRP port should not have inherited the
|
||||||
|
# port host bindings from the parent VM port.
|
||||||
|
cur_vrrp_port_db = self.core_plugin.get_port(
|
||||||
|
self.context, vrrp_port['port']['id'])
|
||||||
|
self.assertNotEqual(
|
||||||
|
cur_vrrp_port_db[portbindings.HOST_ID], HOST1)
|
||||||
|
self.assertNotEqual(
|
||||||
|
cur_vrrp_port_db[portbindings.HOST_ID], HOST2)
|
||||||
|
# Next we can try to associate the floatingip to the
|
||||||
|
# VRRP port that is already attached to the VM port
|
||||||
|
floating_ip = {'floating_network_id': ext_net['network']['id'],
|
||||||
|
'router_id': router['id'],
|
||||||
|
'port_id': vrrp_port['port']['id'],
|
||||||
|
'tenant_id': vrrp_port['port']['tenant_id']}
|
||||||
|
floating_ip = self.l3_plugin.create_floatingip(
|
||||||
|
self.context, {'floatingip': floating_ip})
|
||||||
|
|
||||||
|
post_update_vrrp_port_db = self.core_plugin.get_port(
|
||||||
|
self.context, vrrp_port['port']['id'])
|
||||||
|
vrrp_port_fixed_ips = post_update_vrrp_port_db['fixed_ips']
|
||||||
|
vrrp_port_subnet_id = vrrp_port_fixed_ips[0]['subnet_id']
|
||||||
|
vrrp_arp_table1 = {
|
||||||
|
'ip_address': vrrp_port_fixed_ips[0]['ip_address'],
|
||||||
|
'mac_address': vm_port_mac,
|
||||||
|
'subnet_id': vrrp_port_subnet_id}
|
||||||
|
|
||||||
|
expected_calls = [
|
||||||
|
mock.call(self.context,
|
||||||
|
router['id'], vm_arp_table),
|
||||||
|
mock.call(self.context,
|
||||||
|
router['id'], vrrp_arp_table1)]
|
||||||
|
l3_notifier.add_arp_entry.assert_has_calls(
|
||||||
|
expected_calls)
|
||||||
|
expected_routers_updated_calls = [
|
||||||
|
mock.call(self.context, mock.ANY, HOST1),
|
||||||
|
mock.call(self.context, mock.ANY, HOST2),
|
||||||
|
mock.call(self.context, mock.ANY, 'host0')]
|
||||||
|
l3_notifier.routers_updated_on_host.assert_has_calls(
|
||||||
|
expected_routers_updated_calls, any_order=True)
|
||||||
|
self.assertFalse(l3_notifier.routers_updated.called)
|
||||||
|
router_info = (
|
||||||
|
self.l3_plugin.list_active_sync_routers_on_active_l3_agent(
|
||||||
|
self.context, self.l3_agent['host'], [router['id']]))
|
||||||
|
floatingips = router_info[0][constants.FLOATINGIP_KEY]
|
||||||
|
self.assertTrue(floatingips[0][constants.DVR_SNAT_BOUND])
|
||||||
|
|
||||||
def test_dvr_gateway_host_binding_is_set(self):
|
def test_dvr_gateway_host_binding_is_set(self):
|
||||||
router = self._create_router(ha=False)
|
router = self._create_router(ha=False)
|
||||||
private_net1 = self._make_network(self.fmt, 'net1', True)
|
private_net1 = self._make_network(self.fmt, 'net1', True)
|
||||||
@ -1058,6 +1197,110 @@ class L3DvrTestCase(L3DvrTestCaseBase):
|
|||||||
self.assertEqual(self.l3_agent['host'],
|
self.assertEqual(self.l3_agent['host'],
|
||||||
router_handle[0]['gw_port_host'])
|
router_handle[0]['gw_port_host'])
|
||||||
|
|
||||||
|
def test_allowed_address_pairs_update_arp_entry(self):
|
||||||
|
HOST1 = 'host1'
|
||||||
|
helpers.register_l3_agent(
|
||||||
|
host=HOST1, agent_mode=constants.L3_AGENT_MODE_DVR)
|
||||||
|
router = self._create_router(ha=False)
|
||||||
|
private_net1 = self._make_network(self.fmt, 'net1', True)
|
||||||
|
test_allocation_pools = [{'start': '10.1.0.2',
|
||||||
|
'end': '10.1.0.20'}]
|
||||||
|
fixed_vrrp_ip = [{'ip_address': '10.1.0.201'}]
|
||||||
|
kwargs = {'arg_list': (extnet_apidef.EXTERNAL,),
|
||||||
|
extnet_apidef.EXTERNAL: True}
|
||||||
|
ext_net = self._make_network(self.fmt, '', True, **kwargs)
|
||||||
|
self._make_subnet(
|
||||||
|
self.fmt, ext_net, '10.20.0.1', '10.20.0.0/24',
|
||||||
|
ip_version=constants.IP_VERSION_4, enable_dhcp=True)
|
||||||
|
self.l3_plugin.schedule_router(self.context,
|
||||||
|
router['id'],
|
||||||
|
candidates=[self.l3_agent])
|
||||||
|
# Set gateway to router
|
||||||
|
self.l3_plugin._update_router_gw_info(
|
||||||
|
self.context, router['id'],
|
||||||
|
{'network_id': ext_net['network']['id']})
|
||||||
|
private_subnet1 = self._make_subnet(
|
||||||
|
self.fmt,
|
||||||
|
private_net1,
|
||||||
|
'10.1.0.1',
|
||||||
|
cidr='10.1.0.0/24',
|
||||||
|
ip_version=constants.IP_VERSION_4,
|
||||||
|
allocation_pools=test_allocation_pools,
|
||||||
|
enable_dhcp=True)
|
||||||
|
vrrp_port = self._make_port(
|
||||||
|
self.fmt,
|
||||||
|
private_net1['network']['id'],
|
||||||
|
fixed_ips=fixed_vrrp_ip)
|
||||||
|
allowed_address_pairs = [
|
||||||
|
{'ip_address': '10.1.0.201',
|
||||||
|
'mac_address': vrrp_port['port']['mac_address']}]
|
||||||
|
with self.port(
|
||||||
|
subnet=private_subnet1,
|
||||||
|
device_owner=DEVICE_OWNER_COMPUTE) as int_port:
|
||||||
|
self.l3_plugin.add_router_interface(
|
||||||
|
self.context, router['id'],
|
||||||
|
{'subnet_id': private_subnet1['subnet']['id']})
|
||||||
|
router_handle = (
|
||||||
|
self.l3_plugin.list_active_sync_routers_on_active_l3_agent(
|
||||||
|
self.context, self.l3_agent['host'], [router['id']]))
|
||||||
|
self.assertEqual(self.l3_agent['host'],
|
||||||
|
router_handle[0]['gw_port_host'])
|
||||||
|
with mock.patch.object(self.l3_plugin,
|
||||||
|
'_l3_rpc_notifier') as l3_notifier:
|
||||||
|
vm_port = self.core_plugin.update_port(
|
||||||
|
self.context, int_port['port']['id'],
|
||||||
|
{'port': {portbindings.HOST_ID: HOST1}})
|
||||||
|
vm_port_mac = vm_port['mac_address']
|
||||||
|
vm_port_fixed_ips = vm_port['fixed_ips']
|
||||||
|
vm_port_subnet_id = vm_port_fixed_ips[0]['subnet_id']
|
||||||
|
vm_arp_table = {
|
||||||
|
'ip_address': vm_port_fixed_ips[0]['ip_address'],
|
||||||
|
'mac_address': vm_port_mac,
|
||||||
|
'subnet_id': vm_port_subnet_id}
|
||||||
|
self.assertEqual(1, l3_notifier.add_arp_entry.call_count)
|
||||||
|
floating_ip = {'floating_network_id': ext_net['network']['id'],
|
||||||
|
'router_id': router['id'],
|
||||||
|
'port_id': vrrp_port['port']['id'],
|
||||||
|
'tenant_id': vrrp_port['port']['tenant_id']}
|
||||||
|
floating_ip = self.l3_plugin.create_floatingip(
|
||||||
|
self.context, {'floatingip': floating_ip})
|
||||||
|
vrrp_port_db = self.core_plugin.get_port(
|
||||||
|
self.context, vrrp_port['port']['id'])
|
||||||
|
self.assertNotEqual(vrrp_port_db[portbindings.HOST_ID], HOST1)
|
||||||
|
# Now update the VM port with the allowed_address_pair
|
||||||
|
self.core_plugin.update_port(
|
||||||
|
self.context, vm_port['id'],
|
||||||
|
{'port': {
|
||||||
|
'allowed_address_pairs': allowed_address_pairs}})
|
||||||
|
updated_vm_port = self.core_plugin.get_port(
|
||||||
|
self.context, vm_port['id'])
|
||||||
|
expected_allowed_address_pairs = updated_vm_port.get(
|
||||||
|
'allowed_address_pairs')
|
||||||
|
self.assertEqual(expected_allowed_address_pairs,
|
||||||
|
allowed_address_pairs)
|
||||||
|
cur_vrrp_port_db = self.core_plugin.get_port(
|
||||||
|
self.context, vrrp_port['port']['id'])
|
||||||
|
vrrp_port_fixed_ips = cur_vrrp_port_db['fixed_ips']
|
||||||
|
vrrp_port_subnet_id = vrrp_port_fixed_ips[0]['subnet_id']
|
||||||
|
vrrp_arp_table1 = {
|
||||||
|
'ip_address': vrrp_port_fixed_ips[0]['ip_address'],
|
||||||
|
'mac_address': vm_port_mac,
|
||||||
|
'subnet_id': vrrp_port_subnet_id}
|
||||||
|
|
||||||
|
expected_calls = [
|
||||||
|
mock.call(self.context,
|
||||||
|
router['id'], vm_arp_table),
|
||||||
|
mock.call(self.context,
|
||||||
|
router['id'], vrrp_arp_table1)]
|
||||||
|
l3_notifier.add_arp_entry.assert_has_calls(
|
||||||
|
expected_calls)
|
||||||
|
expected_routers_updated_calls = [
|
||||||
|
mock.call(self.context, mock.ANY, HOST1),
|
||||||
|
mock.call(self.context, mock.ANY, 'host0')]
|
||||||
|
l3_notifier.routers_updated_on_host.assert_has_calls(
|
||||||
|
expected_routers_updated_calls)
|
||||||
|
self.assertFalse(l3_notifier.routers_updated.called)
|
||||||
|
|
||||||
def test_update_vm_port_host_router_update(self):
|
def test_update_vm_port_host_router_update(self):
|
||||||
# register l3 agents in dvr mode in addition to existing dvr_snat agent
|
# register l3 agents in dvr mode in addition to existing dvr_snat agent
|
||||||
HOST1 = 'host1'
|
HOST1 = 'host1'
|
||||||
|
@ -1136,6 +1136,72 @@ class L3DvrTestCase(test_db_base_plugin_v2.NeutronDbPluginV2TestCase):
|
|||||||
port=mock.ANY,
|
port=mock.ANY,
|
||||||
interface_info=interface_info)
|
interface_info=interface_info)
|
||||||
|
|
||||||
|
def test__generate_arp_table_and_notify_agent(self):
|
||||||
|
fixed_ip = {
|
||||||
|
'ip_address': '1.2.3.4',
|
||||||
|
'subnet_id': _uuid()}
|
||||||
|
mac_address = "00:11:22:33:44:55"
|
||||||
|
expected_arp_table = {
|
||||||
|
'ip_address': fixed_ip['ip_address'],
|
||||||
|
'subnet_id': fixed_ip['subnet_id'],
|
||||||
|
'mac_address': mac_address}
|
||||||
|
notifier = mock.Mock()
|
||||||
|
ports = [{'id': _uuid(), 'device_id': 'router_1'},
|
||||||
|
{'id': _uuid(), 'device_id': 'router_2'}]
|
||||||
|
with mock.patch.object(self.core_plugin, "get_ports",
|
||||||
|
return_value=ports):
|
||||||
|
self.mixin._generate_arp_table_and_notify_agent(
|
||||||
|
self.ctx, fixed_ip, mac_address, notifier)
|
||||||
|
notifier.assert_has_calls([
|
||||||
|
mock.call(self.ctx, "router_1", expected_arp_table),
|
||||||
|
mock.call(self.ctx, "router_2", expected_arp_table)])
|
||||||
|
|
||||||
|
def _test_update_arp_entry_for_dvr_service_port(
|
||||||
|
self, device_owner, action):
|
||||||
|
router_dict = {'name': 'test_router', 'admin_state_up': True,
|
||||||
|
'distributed': True}
|
||||||
|
router = self._create_router(router_dict)
|
||||||
|
plugin = mock.Mock()
|
||||||
|
directory.add_plugin(plugin_constants.CORE, plugin)
|
||||||
|
l3_notify = self.mixin.l3_rpc_notifier = mock.Mock()
|
||||||
|
port = {
|
||||||
|
'id': 'my_port_id',
|
||||||
|
'fixed_ips': [
|
||||||
|
{'subnet_id': '51edc9e0-24f9-47f2-8e1e-2a41cb691323',
|
||||||
|
'ip_address': '10.0.0.11'},
|
||||||
|
{'subnet_id': '2b7c8a07-6f8e-4937-8701-f1d5da1a807c',
|
||||||
|
'ip_address': '10.0.0.21'},
|
||||||
|
{'subnet_id': '48534187-f077-4e81-93ff-81ec4cc0ad3b',
|
||||||
|
'ip_address': 'fd45:1515:7e0:0:f816:3eff:fe1a:1111'}],
|
||||||
|
'mac_address': 'my_mac',
|
||||||
|
'device_owner': device_owner
|
||||||
|
}
|
||||||
|
dvr_port = {
|
||||||
|
'id': 'dvr_port_id',
|
||||||
|
'fixed_ips': mock.ANY,
|
||||||
|
'device_owner': const.DEVICE_OWNER_DVR_INTERFACE,
|
||||||
|
'device_id': router['id']
|
||||||
|
}
|
||||||
|
plugin.get_ports.return_value = [dvr_port]
|
||||||
|
if action == 'add':
|
||||||
|
self.mixin.update_arp_entry_for_dvr_service_port(
|
||||||
|
self.ctx, port)
|
||||||
|
self.assertEqual(3, l3_notify.add_arp_entry.call_count)
|
||||||
|
elif action == 'del':
|
||||||
|
self.mixin.delete_arp_entry_for_dvr_service_port(
|
||||||
|
self.ctx, port)
|
||||||
|
self.assertEqual(3, l3_notify.del_arp_entry.call_count)
|
||||||
|
|
||||||
|
def test_update_arp_entry_for_dvr_service_port_added(self):
|
||||||
|
action = 'add'
|
||||||
|
device_owner = const.DEVICE_OWNER_LOADBALANCER
|
||||||
|
self._test_update_arp_entry_for_dvr_service_port(device_owner, action)
|
||||||
|
|
||||||
|
def test_update_arp_entry_for_dvr_service_port_deleted(self):
|
||||||
|
action = 'del'
|
||||||
|
device_owner = const.DEVICE_OWNER_LOADBALANCER
|
||||||
|
self._test_update_arp_entry_for_dvr_service_port(device_owner, action)
|
||||||
|
|
||||||
def test_add_router_interface_csnat_ports_failure(self):
|
def test_add_router_interface_csnat_ports_failure(self):
|
||||||
router_dict = {'name': 'test_router', 'admin_state_up': True,
|
router_dict = {'name': 'test_router', 'admin_state_up': True,
|
||||||
'distributed': True}
|
'distributed': True}
|
||||||
|
@ -841,12 +841,20 @@ class L3DvrSchedulerTestCase(L3SchedulerBaseMixin,
|
|||||||
'device_owner': DEVICE_OWNER_COMPUTE,
|
'device_owner': DEVICE_OWNER_COMPUTE,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
port = kwargs.get('original_port')
|
||||||
l3plugin = mock.Mock()
|
l3plugin = mock.Mock()
|
||||||
directory.add_plugin(plugin_constants.L3, l3plugin)
|
directory.add_plugin(plugin_constants.L3, l3plugin)
|
||||||
l3_dvrscheduler_db._notify_l3_agent_port_update(
|
l3_dvrscheduler_db._notify_l3_agent_port_update(
|
||||||
'port', 'after_update', mock.ANY, **kwargs)
|
'port', 'after_update', mock.ANY, **kwargs)
|
||||||
l3plugin._get_allowed_address_pair_fixed_ips.return_value = (
|
l3plugin._get_allowed_address_pair_fixed_ips.return_value = (
|
||||||
['10.1.0.21'])
|
['10.1.0.21'])
|
||||||
|
self.assertFalse(
|
||||||
|
l3plugin.update_arp_entry_for_dvr_service_port.called)
|
||||||
|
l3plugin.delete_arp_entry_for_dvr_service_port.\
|
||||||
|
assert_called_once_with(
|
||||||
|
self.adminContext,
|
||||||
|
port,
|
||||||
|
fixed_ips_to_delete=mock.ANY)
|
||||||
|
|
||||||
def test__notify_l3_agent_update_port_with_allowed_address_pairs(self):
|
def test__notify_l3_agent_update_port_with_allowed_address_pairs(self):
|
||||||
port_id = uuidutils.generate_uuid()
|
port_id = uuidutils.generate_uuid()
|
||||||
@ -874,6 +882,8 @@ class L3DvrSchedulerTestCase(L3SchedulerBaseMixin,
|
|||||||
directory.add_plugin(plugin_constants.L3, l3plugin)
|
directory.add_plugin(plugin_constants.L3, l3plugin)
|
||||||
l3_dvrscheduler_db._notify_l3_agent_port_update(
|
l3_dvrscheduler_db._notify_l3_agent_port_update(
|
||||||
'port', 'after_update', mock.ANY, **kwargs)
|
'port', 'after_update', mock.ANY, **kwargs)
|
||||||
|
self.assertTrue(
|
||||||
|
l3plugin.update_arp_entry_for_dvr_service_port.called)
|
||||||
|
|
||||||
def test__notify_l3_agent_when_unbound_port_migrates_to_bound_host(self):
|
def test__notify_l3_agent_when_unbound_port_migrates_to_bound_host(self):
|
||||||
port_id = 'fake-port'
|
port_id = 'fake-port'
|
||||||
@ -929,6 +939,8 @@ class L3DvrSchedulerTestCase(L3SchedulerBaseMixin,
|
|||||||
directory.add_plugin(plugin_constants.L3, l3plugin)
|
directory.add_plugin(plugin_constants.L3, l3plugin)
|
||||||
l3_dvrscheduler_db._notify_l3_agent_port_update(
|
l3_dvrscheduler_db._notify_l3_agent_port_update(
|
||||||
'port', 'after_update', plugin, **kwargs)
|
'port', 'after_update', plugin, **kwargs)
|
||||||
|
self.assertFalse(
|
||||||
|
l3plugin.update_arp_entry_for_dvr_service_port.called)
|
||||||
self.assertFalse(
|
self.assertFalse(
|
||||||
l3plugin.dvr_handle_new_service_port.called)
|
l3plugin.dvr_handle_new_service_port.called)
|
||||||
self.assertFalse(l3plugin.remove_router_from_l3_agent.called)
|
self.assertFalse(l3plugin.remove_router_from_l3_agent.called)
|
||||||
@ -946,6 +958,9 @@ class L3DvrSchedulerTestCase(L3SchedulerBaseMixin,
|
|||||||
directory.add_plugin(plugin_constants.L3, l3plugin)
|
directory.add_plugin(plugin_constants.L3, l3plugin)
|
||||||
l3_dvrscheduler_db._notify_l3_agent_new_port(
|
l3_dvrscheduler_db._notify_l3_agent_new_port(
|
||||||
'port', 'after_create', mock.ANY, **kwargs)
|
'port', 'after_create', mock.ANY, **kwargs)
|
||||||
|
l3plugin.update_arp_entry_for_dvr_service_port.\
|
||||||
|
assert_called_once_with(
|
||||||
|
self.adminContext, kwargs.get('port'))
|
||||||
l3plugin.dvr_handle_new_service_port.assert_called_once_with(
|
l3plugin.dvr_handle_new_service_port.assert_called_once_with(
|
||||||
self.adminContext, kwargs.get('port'))
|
self.adminContext, kwargs.get('port'))
|
||||||
|
|
||||||
@ -961,6 +976,8 @@ class L3DvrSchedulerTestCase(L3SchedulerBaseMixin,
|
|||||||
directory.add_plugin(plugin_constants.L3, l3plugin)
|
directory.add_plugin(plugin_constants.L3, l3plugin)
|
||||||
l3_dvrscheduler_db._notify_l3_agent_new_port(
|
l3_dvrscheduler_db._notify_l3_agent_new_port(
|
||||||
'port', 'after_create', mock.ANY, **kwargs)
|
'port', 'after_create', mock.ANY, **kwargs)
|
||||||
|
self.assertFalse(
|
||||||
|
l3plugin.update_arp_entry_for_dvr_service_port.called)
|
||||||
self.assertFalse(
|
self.assertFalse(
|
||||||
l3plugin.dvr_handle_new_service_port.called)
|
l3plugin.dvr_handle_new_service_port.called)
|
||||||
|
|
||||||
@ -987,6 +1004,9 @@ class L3DvrSchedulerTestCase(L3SchedulerBaseMixin,
|
|||||||
l3plugin.dvr_handle_new_service_port.assert_called_once_with(
|
l3plugin.dvr_handle_new_service_port.assert_called_once_with(
|
||||||
self.adminContext, kwargs.get('port'),
|
self.adminContext, kwargs.get('port'),
|
||||||
dest_host='vm-host2', router_id=None)
|
dest_host='vm-host2', router_id=None)
|
||||||
|
l3plugin.update_arp_entry_for_dvr_service_port.\
|
||||||
|
assert_called_once_with(
|
||||||
|
self.adminContext, kwargs.get('port'))
|
||||||
|
|
||||||
def test__notify_l3_agent_update_port_no_action(self):
|
def test__notify_l3_agent_update_port_no_action(self):
|
||||||
kwargs = {
|
kwargs = {
|
||||||
@ -1005,6 +1025,8 @@ class L3DvrSchedulerTestCase(L3SchedulerBaseMixin,
|
|||||||
l3_dvrscheduler_db._notify_l3_agent_port_update(
|
l3_dvrscheduler_db._notify_l3_agent_port_update(
|
||||||
'port', 'after_update', mock.ANY, **kwargs)
|
'port', 'after_update', mock.ANY, **kwargs)
|
||||||
|
|
||||||
|
self.assertFalse(
|
||||||
|
l3plugin.update_arp_entry_for_dvr_service_port.called)
|
||||||
self.assertFalse(
|
self.assertFalse(
|
||||||
l3plugin.dvr_handle_new_service_port.called)
|
l3plugin.dvr_handle_new_service_port.called)
|
||||||
self.assertFalse(l3plugin.remove_router_from_l3_agent.called)
|
self.assertFalse(l3plugin.remove_router_from_l3_agent.called)
|
||||||
@ -1029,6 +1051,10 @@ class L3DvrSchedulerTestCase(L3SchedulerBaseMixin,
|
|||||||
directory.add_plugin(plugin_constants.L3, l3plugin)
|
directory.add_plugin(plugin_constants.L3, l3plugin)
|
||||||
l3_dvrscheduler_db._notify_l3_agent_port_update(
|
l3_dvrscheduler_db._notify_l3_agent_port_update(
|
||||||
'port', 'after_update', mock.ANY, **kwargs)
|
'port', 'after_update', mock.ANY, **kwargs)
|
||||||
|
|
||||||
|
l3plugin.update_arp_entry_for_dvr_service_port.\
|
||||||
|
assert_called_once_with(
|
||||||
|
self.adminContext, kwargs.get('port'))
|
||||||
self.assertFalse(l3plugin.dvr_handle_new_service_port.called)
|
self.assertFalse(l3plugin.dvr_handle_new_service_port.called)
|
||||||
|
|
||||||
def test__notify_l3_agent_update_port_with_ip_update(self):
|
def test__notify_l3_agent_update_port_with_ip_update(self):
|
||||||
@ -1053,6 +1079,9 @@ class L3DvrSchedulerTestCase(L3SchedulerBaseMixin,
|
|||||||
l3_dvrscheduler_db._notify_l3_agent_port_update(
|
l3_dvrscheduler_db._notify_l3_agent_port_update(
|
||||||
'port', 'after_update', mock.ANY, **kwargs)
|
'port', 'after_update', mock.ANY, **kwargs)
|
||||||
|
|
||||||
|
l3plugin.update_arp_entry_for_dvr_service_port.\
|
||||||
|
assert_called_once_with(
|
||||||
|
self.adminContext, kwargs.get('port'))
|
||||||
self.assertFalse(l3plugin.dvr_handle_new_service_port.called)
|
self.assertFalse(l3plugin.dvr_handle_new_service_port.called)
|
||||||
|
|
||||||
def test__notify_l3_agent_update_port_without_ip_change(self):
|
def test__notify_l3_agent_update_port_without_ip_change(self):
|
||||||
@ -1074,6 +1103,7 @@ class L3DvrSchedulerTestCase(L3SchedulerBaseMixin,
|
|||||||
l3_dvrscheduler_db._notify_l3_agent_port_update(
|
l3_dvrscheduler_db._notify_l3_agent_port_update(
|
||||||
'port', 'after_update', mock.ANY, **kwargs)
|
'port', 'after_update', mock.ANY, **kwargs)
|
||||||
|
|
||||||
|
self.assertFalse(l3plugin.update_arp_entry_for_dvr_service_port.called)
|
||||||
self.assertFalse(l3plugin.dvr_handle_new_service_port.called)
|
self.assertFalse(l3plugin.dvr_handle_new_service_port.called)
|
||||||
|
|
||||||
def test__notify_l3_agent_port_binding_change(self):
|
def test__notify_l3_agent_port_binding_change(self):
|
||||||
@ -1159,10 +1189,15 @@ class L3DvrSchedulerTestCase(L3SchedulerBaseMixin,
|
|||||||
if routers_to_remove:
|
if routers_to_remove:
|
||||||
(l3plugin.l3_rpc_notifier.router_removed_from_agent.
|
(l3plugin.l3_rpc_notifier.router_removed_from_agent.
|
||||||
assert_called_once_with(mock.ANY, 'foo_id', source_host))
|
assert_called_once_with(mock.ANY, 'foo_id', source_host))
|
||||||
|
self.assertEqual(
|
||||||
|
1,
|
||||||
|
l3plugin.delete_arp_entry_for_dvr_service_port.call_count)
|
||||||
if fip and is_distributed and not (routers_to_remove and
|
if fip and is_distributed and not (routers_to_remove and
|
||||||
fip['router_id'] is routers_to_remove[0]['router_id']):
|
fip['router_id'] is routers_to_remove[0]['router_id']):
|
||||||
(l3plugin.l3_rpc_notifier.routers_updated_on_host.
|
(l3plugin.l3_rpc_notifier.routers_updated_on_host.
|
||||||
assert_called_once_with(mock.ANY, ['router_id'], source_host))
|
assert_called_once_with(mock.ANY, ['router_id'], source_host))
|
||||||
|
self.assertEqual(
|
||||||
|
1, l3plugin.update_arp_entry_for_dvr_service_port.call_count)
|
||||||
l3plugin.dvr_handle_new_service_port.assert_called_once_with(
|
l3plugin.dvr_handle_new_service_port.assert_called_once_with(
|
||||||
self.adminContext, kwargs.get('port'),
|
self.adminContext, kwargs.get('port'),
|
||||||
dest_host=None, router_id=router_id)
|
dest_host=None, router_id=router_id)
|
||||||
@ -1203,6 +1238,12 @@ class L3DvrSchedulerTestCase(L3SchedulerBaseMixin,
|
|||||||
l3_dvrscheduler_db._notify_l3_agent_port_update(
|
l3_dvrscheduler_db._notify_l3_agent_port_update(
|
||||||
'port', 'after_update', plugin, **kwargs)
|
'port', 'after_update', plugin, **kwargs)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
1, l3plugin.delete_arp_entry_for_dvr_service_port.call_count)
|
||||||
|
l3plugin.delete_arp_entry_for_dvr_service_port.\
|
||||||
|
assert_called_once_with(
|
||||||
|
self.adminContext, mock.ANY)
|
||||||
|
|
||||||
self.assertFalse(
|
self.assertFalse(
|
||||||
l3plugin.dvr_handle_new_service_port.called)
|
l3plugin.dvr_handle_new_service_port.called)
|
||||||
(l3plugin.l3_rpc_notifier.router_removed_from_agent.
|
(l3plugin.l3_rpc_notifier.router_removed_from_agent.
|
||||||
@ -1236,6 +1277,9 @@ class L3DvrSchedulerTestCase(L3SchedulerBaseMixin,
|
|||||||
l3plugin.get_dvr_routers_to_remove.return_value = removed_routers
|
l3plugin.get_dvr_routers_to_remove.return_value = removed_routers
|
||||||
l3_dvrscheduler_db._notify_port_delete(
|
l3_dvrscheduler_db._notify_port_delete(
|
||||||
'port', 'after_delete', plugin, **kwargs)
|
'port', 'after_delete', plugin, **kwargs)
|
||||||
|
l3plugin.delete_arp_entry_for_dvr_service_port.\
|
||||||
|
assert_called_once_with(
|
||||||
|
self.adminContext, mock.ANY)
|
||||||
(l3plugin.l3_rpc_notifier.router_removed_from_agent.
|
(l3plugin.l3_rpc_notifier.router_removed_from_agent.
|
||||||
assert_called_once_with(mock.ANY, 'foo_id', 'foo_host'))
|
assert_called_once_with(mock.ANY, 'foo_id', 'foo_host'))
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user