Merge "[AIM] port the ip_address_owner_update() RPC from legacy plugin"

This commit is contained in:
Jenkins
2017-02-06 19:39:03 +00:00
committed by Gerrit Code Review
3 changed files with 77 additions and 11 deletions

View File

@@ -1793,18 +1793,19 @@ class AIMMappingDriver(nrd.CommonNeutronBase, aim_rpc.AIMMappingRPCMixin):
subnet['dhcp_server_ips'] = dhcp_ips
return subnets
def _send_port_update_notification(self, plugin_context, port):
self.aim_mech_driver._notify_port_update(plugin_context, port)
def _get_aap_details(self, plugin_context, port, details):
pt = self._port_id_to_pt(plugin_context, port['id'])
aaps = port['allowed_address_pairs']
if pt:
# Set the correct address ownership for this port
owned_addresses = self._get_owned_addresses(
plugin_context, pt['port_id'])
for allowed in aaps:
if allowed['ip_address'] in owned_addresses:
# Signal the agent that this particular address is active
# on its port
allowed['active'] = True
# Set the correct address ownership for this port
owned_addresses = self._get_owned_addresses(
plugin_context, port['id'])
for allowed in aaps:
if allowed['ip_address'] in owned_addresses:
# Signal the agent that this particular address is active
# on its port
allowed['active'] = True
return aaps
def _get_port_vrf(self, plugin_context, port, details):
@@ -1902,7 +1903,7 @@ class AIMMappingDriver(nrd.CommonNeutronBase, aim_rpc.AIMMappingRPCMixin):
fips_filter = [port['id']]
active_addrs = [a['ip_address']
for a in details['allowed_address_pairs']
if a['active']]
if a.get('active')]
if active_addrs:
others = self._get_ports(
plugin_context,

View File

@@ -110,6 +110,16 @@ class AIMMappingRPCMixin(ha_ip_db.HAIPOwnerDbMixin):
LOG.exception(e)
return None
# Child class needs to support:
# - self._send_port_update_notification(context, port)
def ip_address_owner_update(self, context, **kwargs):
if not kwargs.get('ip_owner_info'):
return
ports_to_update = self.update_ip_owner(kwargs['ip_owner_info'])
for p in ports_to_update:
LOG.debug("APIC ownership update for port %s", p)
self._send_port_update_notification(context, p)
# Things you need in order to run this Mixin:
# - self._core_plugin: attribute that points to the Neutron core plugin;
# - self._is_port_promiscuous(context, port): define whether or not

View File

@@ -177,6 +177,17 @@ class AIMBaseTestCase(test_nr_base.CommonNeutronBaseTestCase,
ksc_client.Client = self.saved_keystone_client
super(AIMBaseTestCase, self).tearDown()
def _check_call_list(self, expected, observed, check_all=True):
for call in expected:
self.assertTrue(call in observed,
msg='Call not found, expected:\n%s\nobserved:'
'\n%s' % (str(call), str(observed)))
observed.remove(call)
if check_all:
self.assertFalse(
len(observed),
msg='There are more calls than expected: %s' % str(observed))
def _bind_port_to_host(self, port_id, host):
data = {'port': {'binding:host_id': host,
'device_owner': 'compute:',
@@ -2379,6 +2390,8 @@ class TestPolicyTarget(AIMBaseTestCase):
raise webob.exc.HTTPClientError(code=res.status_int)
return self.deserialize(self.fmt, res)
# TODO(Kent): we should also add the ML2 related UTs for
# get_gbp_details(). Its missing completely....
def _do_test_get_gbp_details(self, pre_vrf=None):
es1, es1_sub = self._setup_external_segment(
'es1', dn='uni/tn-t1/out-l1/instP-n1')
@@ -2600,6 +2613,48 @@ class TestPolicyTarget(AIMBaseTestCase):
def test_get_gbp_details_no_pt_no_as_unrouted(self):
self._do_test_gbp_details_no_pt(use_as=False, routed=False)
def test_ip_address_owner_update(self):
l3p = self.create_l3_policy(name='myl3')['l3_policy']
l2p = self.create_l2_policy(name='myl2',
l3_policy_id=l3p['id'])['l2_policy']
ptg = self.create_policy_target_group(
name="ptg1", l2_policy_id=l2p['id'])['policy_target_group']
net_id = l2p['network_id']
pt1 = self.create_policy_target(
name="pt1", policy_target_group_id=ptg['id'])['policy_target']
pt2 = self.create_policy_target(name="pt2",
policy_target_group_id=ptg['id'])['policy_target']
self._bind_port_to_host(pt1['port_id'], 'h1')
self._bind_port_to_host(pt2['port_id'], 'h2')
ip_owner_info = {'port': pt1['port_id'], 'ip_address_v4': '1.2.3.4'}
self.driver.aim_mech_driver._notify_port_update = mock.Mock()
# set new owner
self.driver.ip_address_owner_update(self._context,
ip_owner_info=ip_owner_info, host='h1')
obj = self.driver.ha_ip_handler.get_port_for_ha_ipaddress(
'1.2.3.4', net_id)
self.assertEqual(pt1['port_id'], obj['port_id'])
self.driver.aim_mech_driver._notify_port_update.assert_called_with(
mock.ANY, pt1['port_id'])
# update existing owner
self.driver.aim_mech_driver._notify_port_update.reset_mock()
ip_owner_info['port'] = pt2['port_id']
self.driver.ip_address_owner_update(self._context,
ip_owner_info=ip_owner_info, host='h2')
obj = self.driver.ha_ip_handler.get_port_for_ha_ipaddress(
'1.2.3.4', net_id)
self.assertEqual(pt2['port_id'], obj['port_id'])
exp_calls = [
mock.call(mock.ANY, pt1['port_id']),
mock.call(mock.ANY, pt2['port_id'])]
self._check_call_list(exp_calls,
self.driver.aim_mech_driver._notify_port_update.call_args_list)
class TestPolicyTargetRollback(AIMBaseTestCase):