Merge "[AIM] port the ip_address_owner_update() RPC from legacy plugin"
This commit is contained in:
		@@ -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,
 | 
			
		||||
 
 | 
			
		||||
@@ -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