Beispiel #1
0
 def test_plug_interface(self):
     segment = amb.NetworkSegment(p_const.TYPE_VLAN, "physnet-1", "1")
     with mock.patch.object(self.lbm, "add_tap_interface") as add_tap:
         self.lbm.plug_interface("123", segment, "tap234",
                                 constants.DEVICE_OWNER_NETWORK_PREFIX)
         add_tap.assert_called_with("123", p_const.TYPE_VLAN, "physnet-1",
                                    "1", "tap234",
                                    constants.DEVICE_OWNER_NETWORK_PREFIX)
    def test_treat_devices_added_updated_admin_state_up_true(self):
        agent = self.agent
        mock_details = {
            'device': 'dev123',
            'port_id': 'port123',
            'network_id': 'net123',
            'admin_state_up': True,
            'network_type': 'vlan',
            'segmentation_id': 100,
            'physical_network': 'physnet1',
            'device_owner': constants.DEVICE_OWNER_NETWORK_PREFIX
        }
        mock_port_data = {
            'port_id': mock_details['port_id'],
            'device': mock_details['device']
        }
        agent.ext_manager = mock.Mock()
        agent.plugin_rpc = mock.Mock()
        agent.plugin_rpc.get_devices_details_list.return_value = [mock_details]
        agent.mgr = mock.Mock()
        agent.mgr.plug_interface.return_value = True
        agent.mgr.ensure_port_admin_state = mock.Mock()
        mock_segment = amb.NetworkSegment(mock_details['network_type'],
                                          mock_details['physical_network'],
                                          mock_details['segmentation_id'])

        with mock.patch(
                'neutron.plugins.ml2.drivers.agent.'
                '_agent_manager_base.NetworkSegment',
                return_value=mock_segment):
            resync_needed = agent.treat_devices_added_updated(set(['tap1']))

            self.assertFalse(resync_needed)
            agent.rpc_callbacks.add_network.assert_called_with(
                'net123', mock_segment)
            agent.mgr.plug_interface.assert_called_with(
                'net123', mock_segment, 'dev123',
                constants.DEVICE_OWNER_NETWORK_PREFIX)
            self.assertTrue(agent.plugin_rpc.update_device_up.called)
            self.assertTrue(agent.ext_manager.handle_port.called)
            self.assertIn(mock_port_data,
                          agent.network_ports[mock_details['network_id']])
Beispiel #3
0
    def _process_device_if_exists(self, device_details):
        # ignore exceptions from devices that disappear because they will
        # be handled as removed in the next iteration
        device = device_details['device']
        with self._ignore_missing_device_exceptions(device):
            LOG.debug("Port %s added", device)

            if 'port_id' in device_details:
                LOG.info(_LI("Port %(device)s updated. Details: %(details)s"),
                         {
                             'device': device,
                             'details': device_details
                         })
                if self.prevent_arp_spoofing:
                    self.mgr.setup_arp_spoofing_protection(
                        device, device_details)

                segment = amb.NetworkSegment(
                    device_details.get('network_type'),
                    device_details['physical_network'],
                    device_details.get('segmentation_id'),
                    device_details.get('mtu'))
                network_id = device_details['network_id']
                self.rpc_callbacks.add_network(network_id, segment)
                interface_plugged = self.mgr.plug_interface(
                    network_id, segment, device,
                    device_details['device_owner'])
                # REVISIT(scheuran): Changed the way how ports admin_state_up
                # is implemented.
                #
                # Old lb implementation:
                # - admin_state_up: ensure that tap is plugged into bridge
                # - admin_state_down: remove tap from bridge
                # New lb implementation:
                # - admin_state_up: set tap device state to up
                # - admin_state_down: set tap device state to down
                #
                # However both approaches could result in races with
                # nova/libvirt and therefore to an invalid system state in the
                # scenario, where an instance is booted with a port configured
                # with admin_state_up = False:
                #
                # Libvirt does the following actions in exactly
                # this order (see libvirt virnetdevtap.c)
                #     1) Create the tap device, set its MAC and MTU
                #     2) Plug the tap into the bridge
                #     3) Set the tap online
                #
                # Old lb implementation:
                #   A race could occur, if the lb agent removes the tap device
                #   right after step 1). Then libvirt will add it to the bridge
                #   again in step 2).
                # New lb implementation:
                #   The race could occur if the lb-agent sets the taps device
                #   state to down right after step 2). In step 3) libvirt
                #   might set it to up again.
                #
                # This is not an issue if an instance is booted with a port
                # configured with admin_state_up = True. Libvirt would just
                # set the tap device up again.
                #
                # This refactoring is recommended for the following reasons:
                # 1) An existing race with libvirt caused by the behavior of
                #    the old implementation. See Bug #1312016
                # 2) The new code is much more readable
                if interface_plugged:
                    self.mgr.ensure_port_admin_state(
                        device, device_details['admin_state_up'])
                # update plugin about port status if admin_state is up
                if device_details['admin_state_up']:
                    if interface_plugged:
                        self.plugin_rpc.update_device_up(
                            self.context, device, self.agent_id, cfg.CONF.host)
                    else:
                        self.plugin_rpc.update_device_down(
                            self.context, device, self.agent_id, cfg.CONF.host)
                self._update_network_ports(device_details['network_id'],
                                           device_details['port_id'],
                                           device_details['device'])
                self.ext_manager.handle_port(self.context, device_details)
                registry.notify(local_resources.PORT_DEVICE,
                                events.AFTER_UPDATE,
                                self,
                                context=self.context,
                                device_details=device_details)
            else:
                LOG.info(_LI("Device %s not defined on plugin"), device)
Beispiel #4
0
import mock
from neutron_lib.agent import topics
from neutron_lib.utils import helpers
from oslo_config import cfg
from oslo_service import service

from neutron.agent.linux import ip_lib
from neutron.common import config as common_config
from neutron.plugins.ml2.drivers.agent import _agent_manager_base as amb
from neutron.plugins.ml2.drivers.macvtap.agent import macvtap_neutron_agent
from neutron.plugins.ml2.drivers.macvtap import macvtap_common
from neutron.tests import base

INTERFACE_MAPPINGS = {'physnet1': 'eth1'}
NETWORK_ID = 'net-id123'
NETWORK_SEGMENT_VLAN = amb.NetworkSegment('vlan', 'physnet1', 1)
NETWORK_SEGMENT_FLAT = amb.NetworkSegment('flat', 'physnet1', None)


class TestMacvtapRPCCallbacks(base.BaseTestCase):
    def setUp(self):
        super(TestMacvtapRPCCallbacks, self).setUp()

        agent = mock.Mock()
        agent.mgr = mock.Mock()
        agent.mgr.interface_mappings = INTERFACE_MAPPINGS
        self.rpc = macvtap_neutron_agent.MacvtapRPCCallBack(
            mock.Mock(), agent, mock.Mock())

    def test_network_delete_vlan(self):
        self.rpc.network_map = {NETWORK_ID: NETWORK_SEGMENT_VLAN}
 def test_add_network(self):
     segment = amb.NetworkSegment('vlan', 'physnet1', 100)
     network_id = "foo"
     self.rpc_callbacks.add_network(network_id, segment)
     self.assertEqual(segment, self.rpc_callbacks.network_map[network_id])