Merge "[AIM] port the ip_address_owner_update() RPC from legacy plugin"
This commit is contained in:
@@ -1793,13 +1793,14 @@ 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'])
|
||||
plugin_context, port['id'])
|
||||
for allowed in aaps:
|
||||
if allowed['ip_address'] in owned_addresses:
|
||||
# Signal the agent that this particular address is active
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
|
||||
Reference in New Issue
Block a user