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
|
subnet['dhcp_server_ips'] = dhcp_ips
|
||||||
return subnets
|
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):
|
def _get_aap_details(self, plugin_context, port, details):
|
||||||
pt = self._port_id_to_pt(plugin_context, port['id'])
|
|
||||||
aaps = port['allowed_address_pairs']
|
aaps = port['allowed_address_pairs']
|
||||||
if pt:
|
|
||||||
# Set the correct address ownership for this port
|
# Set the correct address ownership for this port
|
||||||
owned_addresses = self._get_owned_addresses(
|
owned_addresses = self._get_owned_addresses(
|
||||||
plugin_context, pt['port_id'])
|
plugin_context, port['id'])
|
||||||
for allowed in aaps:
|
for allowed in aaps:
|
||||||
if allowed['ip_address'] in owned_addresses:
|
if allowed['ip_address'] in owned_addresses:
|
||||||
# Signal the agent that this particular address is active
|
# Signal the agent that this particular address is active
|
||||||
@@ -1902,7 +1903,7 @@ class AIMMappingDriver(nrd.CommonNeutronBase, aim_rpc.AIMMappingRPCMixin):
|
|||||||
fips_filter = [port['id']]
|
fips_filter = [port['id']]
|
||||||
active_addrs = [a['ip_address']
|
active_addrs = [a['ip_address']
|
||||||
for a in details['allowed_address_pairs']
|
for a in details['allowed_address_pairs']
|
||||||
if a['active']]
|
if a.get('active')]
|
||||||
if active_addrs:
|
if active_addrs:
|
||||||
others = self._get_ports(
|
others = self._get_ports(
|
||||||
plugin_context,
|
plugin_context,
|
||||||
|
|||||||
@@ -110,6 +110,16 @@ class AIMMappingRPCMixin(ha_ip_db.HAIPOwnerDbMixin):
|
|||||||
LOG.exception(e)
|
LOG.exception(e)
|
||||||
return None
|
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:
|
# Things you need in order to run this Mixin:
|
||||||
# - self._core_plugin: attribute that points to the Neutron core plugin;
|
# - self._core_plugin: attribute that points to the Neutron core plugin;
|
||||||
# - self._is_port_promiscuous(context, port): define whether or not
|
# - 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
|
ksc_client.Client = self.saved_keystone_client
|
||||||
super(AIMBaseTestCase, self).tearDown()
|
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):
|
def _bind_port_to_host(self, port_id, host):
|
||||||
data = {'port': {'binding:host_id': host,
|
data = {'port': {'binding:host_id': host,
|
||||||
'device_owner': 'compute:',
|
'device_owner': 'compute:',
|
||||||
@@ -2379,6 +2390,8 @@ class TestPolicyTarget(AIMBaseTestCase):
|
|||||||
raise webob.exc.HTTPClientError(code=res.status_int)
|
raise webob.exc.HTTPClientError(code=res.status_int)
|
||||||
return self.deserialize(self.fmt, res)
|
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):
|
def _do_test_get_gbp_details(self, pre_vrf=None):
|
||||||
es1, es1_sub = self._setup_external_segment(
|
es1, es1_sub = self._setup_external_segment(
|
||||||
'es1', dn='uni/tn-t1/out-l1/instP-n1')
|
'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):
|
def test_get_gbp_details_no_pt_no_as_unrouted(self):
|
||||||
self._do_test_gbp_details_no_pt(use_as=False, routed=False)
|
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):
|
class TestPolicyTargetRollback(AIMBaseTestCase):
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user