Some drivers, like the Open vSwitch one, may restrict the creation of a trunk from a bound port (i.e. prevents from creating trunks after a VM is already booted on the port). This limitation frees us from worrying about dataplane migrations for OVS as trunk ports and regular ports are wired differently. However, other drivers, like the Linux Bridge one, may not be affected by this limitation, and the existing rule should be relaxed to allow the operation based on whether not the driver can support it. Partially-implements: blueprint vlan-aware-vms Change-Id: Ia938eb7cc845f6f144924acdb0e333d23516fccachanges/75/351375/11
parent
04b3b4dfa8
commit
42f2ba88a5
@ -0,0 +1,59 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from neutron.services.trunk.drivers import base
|
||||
|
||||
|
||||
class FakeDriver(base.DriverBase):
|
||||
|
||||
@property
|
||||
def is_loaded(self):
|
||||
return True
|
||||
|
||||
@classmethod
|
||||
def create(cls):
|
||||
return cls('foo_name', ('foo_intfs',), ('foo_seg_types',))
|
||||
|
||||
|
||||
class FakeDriver2(base.DriverBase):
|
||||
|
||||
@property
|
||||
def is_loaded(self):
|
||||
return True
|
||||
|
||||
@classmethod
|
||||
def create(cls):
|
||||
return cls('foo_name2', ('foo_intf2',), ('foo_seg_types',))
|
||||
|
||||
|
||||
class FakeDriverCanTrunkBoundPort(base.DriverBase):
|
||||
|
||||
@property
|
||||
def is_loaded(self):
|
||||
return True
|
||||
|
||||
@classmethod
|
||||
def create(cls):
|
||||
return cls('foo_name3', ('foo_intfs',),
|
||||
('foo_seg_types',), can_trunk_bound_port=True)
|
||||
|
||||
|
||||
class FakeDriverWithAgent(base.DriverBase):
|
||||
|
||||
@property
|
||||
def is_loaded(self):
|
||||
return True
|
||||
|
||||
@classmethod
|
||||
def create(cls):
|
||||
return cls('foo_name4', ('foo_intfs',), ('foo_seg_types',), "foo_type")
|
@ -0,0 +1,69 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import mock
|
||||
|
||||
from neutron.services.trunk import utils
|
||||
from neutron.tests.unit.plugins.ml2 import test_plugin
|
||||
from neutron.tests.unit.services.trunk import fakes
|
||||
|
||||
|
||||
class UtilsTestCase(test_plugin.Ml2PluginV2TestCase):
|
||||
|
||||
def test_are_agent_types_available_on_host_returns_false(self):
|
||||
self.assertFalse(
|
||||
utils.are_agent_types_available_on_host(
|
||||
self.context, ['foo_type'], 'foo_host'))
|
||||
|
||||
def test_are_agent_types_available_on_host_returns_true(self):
|
||||
with mock.patch("neutron.db.agents_db.AgentDbMixin.get_agents") as f:
|
||||
f.return_value = ['foo_agent']
|
||||
self.assertTrue(
|
||||
utils.are_agent_types_available_on_host(
|
||||
self.context, ['foo_type'], 'foo_host'))
|
||||
|
||||
def _test_is_driver_compatible(self, driver, interface, host, agents=None):
|
||||
with mock.patch("neutron.db.agents_db.AgentDbMixin.get_agents") as f:
|
||||
f.return_value = agents or []
|
||||
return utils.is_driver_compatible(self.context,
|
||||
driver,
|
||||
interface,
|
||||
host)
|
||||
|
||||
def test_is_driver_compatible(self):
|
||||
driver = fakes.FakeDriverWithAgent.create()
|
||||
self.assertTrue(self._test_is_driver_compatible(
|
||||
driver, 'foo_intfs', 'foo_host', [{'agent_type': 'foo_type'}]))
|
||||
|
||||
def test_is_driver_compatible_agent_based_agent_mismatch(self):
|
||||
driver = fakes.FakeDriverWithAgent.create()
|
||||
self.assertFalse(self._test_is_driver_compatible(
|
||||
driver, 'foo_intfs', 'foo_host'))
|
||||
|
||||
def test_is_driver_incompatible_because_of_interface_mismatch(self):
|
||||
driver = fakes.FakeDriverWithAgent.create()
|
||||
self.assertFalse(self._test_is_driver_compatible(
|
||||
driver, 'not_my_interface', 'foo_host'))
|
||||
|
||||
def test_is_driver_compatible_agentless(self):
|
||||
driver = fakes.FakeDriver.create()
|
||||
self.assertTrue(self._test_is_driver_compatible(
|
||||
driver, 'foo_intfs', 'foo_host'))
|
||||
|
||||
def test_is_driver_compatible_multiple_drivers(self):
|
||||
driver1 = fakes.FakeDriverWithAgent.create()
|
||||
driver2 = fakes.FakeDriver2.create()
|
||||
self.assertTrue(self._test_is_driver_compatible(
|
||||
driver1, 'foo_intfs', 'foo_host', [{'agent_type': 'foo_type'}]))
|
||||
self.assertFalse(self._test_is_driver_compatible(
|
||||
driver2, 'foo_intfs', 'foo_host', [{'agent_type': 'foo_type'}]))
|
Loading…
Reference in new issue