Merge "Nested-Containers: trunk subports management"
This commit is contained in:
commit
a3ed2763f8
42
README.rst
42
README.rst
@ -248,6 +248,48 @@ The bash script creates the following file if it is missing:
|
|||||||
Note the root privilege is required for creating and deleting the veth pairs
|
Note the root privilege is required for creating and deleting the veth pairs
|
||||||
with `pyroute2 <http://docs.pyroute2.org/>`_ to run.
|
with `pyroute2 <http://docs.pyroute2.org/>`_ to run.
|
||||||
|
|
||||||
|
|
||||||
|
How to try out nested-containers locally
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
1. Installing OpenStack running devstack with the desired local.conf file but
|
||||||
|
including the next to make use of OVS-firewall and enabling Trunk Ports::
|
||||||
|
|
||||||
|
[[post-config|/$Q_PLUGIN_CONF_FILE]]
|
||||||
|
|
||||||
|
[DEFAULT]
|
||||||
|
service_plugins=trunk
|
||||||
|
|
||||||
|
[securitygroup]
|
||||||
|
firewall_driver=openvswitch
|
||||||
|
|
||||||
|
2. Launch a VM with `Neutron trunk port.
|
||||||
|
<https://wiki.openstack.org/wiki/Neutron/TrunkPort>`
|
||||||
|
|
||||||
|
3. Inside the VM install kuryr and kuryr-libnetwork following the normal
|
||||||
|
installation steps (see above steps at `Installing Kuryr's libnetwork
|
||||||
|
driver`).
|
||||||
|
|
||||||
|
4. Reconfigure kuryr inside the VM to point to the neutron server and to use the
|
||||||
|
vlan driver::
|
||||||
|
- Configure `/etc/kuryr/kuryr.conf`::
|
||||||
|
|
||||||
|
[binding]
|
||||||
|
driver = kuryr.lib.binding.drivers.vlan
|
||||||
|
link_iface = eth0 # VM vNIC
|
||||||
|
|
||||||
|
[neutron]
|
||||||
|
auth_url = http://KEYSTONE_SERVER_IP:35357/v3/
|
||||||
|
username = admin
|
||||||
|
user_domain_name = Default
|
||||||
|
password = ADMIN_PASSWORD
|
||||||
|
project_name = service
|
||||||
|
project_domain_name = Default
|
||||||
|
auth_type = password
|
||||||
|
|
||||||
|
- Restart kuryr service inside the VM
|
||||||
|
|
||||||
|
|
||||||
Testing Kuryr
|
Testing Kuryr
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
|
@ -208,22 +208,6 @@ def _create_port(endpoint_id, neutron_network_id, interface_mac, fixed_ips):
|
|||||||
return rcvd_port['port']
|
return rcvd_port['port']
|
||||||
|
|
||||||
|
|
||||||
def _update_port(port, endpoint_id):
|
|
||||||
port['name'] = utils.get_neutron_port_name(endpoint_id)
|
|
||||||
try:
|
|
||||||
response_port = app.neutron.update_port(
|
|
||||||
port['id'],
|
|
||||||
{'port': {
|
|
||||||
'name': port['name'],
|
|
||||||
'device_owner': lib_const.DEVICE_OWNER,
|
|
||||||
'device_id': endpoint_id}})
|
|
||||||
except n_exceptions.NeutronClientException as ex:
|
|
||||||
app.logger.error(_LE("Error happened during updating a "
|
|
||||||
"Neutron port: %s"), ex)
|
|
||||||
raise
|
|
||||||
return response_port['port']
|
|
||||||
|
|
||||||
|
|
||||||
def _get_fixed_ips_by_interface_cidr(subnets, interface_cidrv4,
|
def _get_fixed_ips_by_interface_cidr(subnets, interface_cidrv4,
|
||||||
interface_cidrv6, fixed_ips):
|
interface_cidrv6, fixed_ips):
|
||||||
for subnet in subnets:
|
for subnet in subnets:
|
||||||
@ -273,7 +257,7 @@ def _create_or_update_port(neutron_network_id, endpoint_id,
|
|||||||
interface_mac, fixed_ips)
|
interface_mac, fixed_ips)
|
||||||
elif num_port == 1:
|
elif num_port == 1:
|
||||||
port = filtered_ports['ports'][0]
|
port = filtered_ports['ports'][0]
|
||||||
response_port = _update_port(port, endpoint_id)
|
response_port = app.driver.update_port(port, endpoint_id)
|
||||||
else:
|
else:
|
||||||
raise n_exceptions.DuplicatedResourceException(
|
raise n_exceptions.DuplicatedResourceException(
|
||||||
"Multiple ports exist for the cidrs {0} and {1}"
|
"Multiple ports exist for the cidrs {0} and {1}"
|
||||||
|
@ -49,3 +49,12 @@ class BaseNestedDriver(driver.Driver):
|
|||||||
|
|
||||||
raise exceptions.KuryrException("Cannot find a Neutron port "
|
raise exceptions.KuryrException("Cannot find a Neutron port "
|
||||||
"associated to interface name {0}".format(ifname))
|
"associated to interface name {0}".format(ifname))
|
||||||
|
|
||||||
|
def get_container_iface_name(self, neutron_port_id):
|
||||||
|
"""Returns interface name of a container in the default namespace.
|
||||||
|
|
||||||
|
:param neutron_port_id: The ID of a neutron port as string
|
||||||
|
:returns: interface name as string.
|
||||||
|
"""
|
||||||
|
_, container_iface_name = utils.get_veth_pair_names(neutron_port_id)
|
||||||
|
return container_iface_name
|
||||||
|
@ -15,8 +15,14 @@ import six
|
|||||||
|
|
||||||
from oslo_utils import importutils
|
from oslo_utils import importutils
|
||||||
|
|
||||||
|
from neutronclient.common import exceptions as n_exceptions
|
||||||
|
|
||||||
|
from kuryr.lib._i18n import _LE
|
||||||
|
from kuryr.lib import constants as lib_const
|
||||||
from kuryr.lib import exceptions
|
from kuryr.lib import exceptions
|
||||||
|
from kuryr_libnetwork import app
|
||||||
from kuryr_libnetwork import config
|
from kuryr_libnetwork import config
|
||||||
|
from kuryr_libnetwork import utils as libnet_utils
|
||||||
|
|
||||||
|
|
||||||
@six.add_metaclass(abc.ABCMeta)
|
@six.add_metaclass(abc.ABCMeta)
|
||||||
@ -106,6 +112,32 @@ class Driver(object):
|
|||||||
"""
|
"""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def update_port(self, port, endpoint_id):
|
||||||
|
"""Updates port information and performs extra driver-specific actions.
|
||||||
|
|
||||||
|
It returns the updated port dictionary after the required actions
|
||||||
|
performed depending on the binding driver.
|
||||||
|
|
||||||
|
:param port: a neutron port dictionary returned from
|
||||||
|
python-neutronclient
|
||||||
|
:param endpoint_id: the ID of the endpoint as string
|
||||||
|
:returns: the updated Neutron port id dictionary as returned by
|
||||||
|
python-neutronclient
|
||||||
|
"""
|
||||||
|
port['name'] = libnet_utils.get_neutron_port_name(endpoint_id)
|
||||||
|
try:
|
||||||
|
response_port = app.neutron.update_port(port['id'],
|
||||||
|
{'port': {
|
||||||
|
'name': port['name'],
|
||||||
|
'device_owner': lib_const.DEVICE_OWNER,
|
||||||
|
'device_id': endpoint_id
|
||||||
|
}})
|
||||||
|
except n_exceptions.NeutronClientException as ex:
|
||||||
|
app.logger.error(_LE("Error happened during updating a "
|
||||||
|
"Neutron port: %s"), ex)
|
||||||
|
raise
|
||||||
|
return response_port['port']
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.__class__.__name__
|
return self.__class__.__name__
|
||||||
|
|
||||||
|
@ -15,7 +15,6 @@ from oslo_log import log
|
|||||||
|
|
||||||
from kuryr.lib._i18n import _LE
|
from kuryr.lib._i18n import _LE
|
||||||
from kuryr.lib import binding
|
from kuryr.lib import binding
|
||||||
from kuryr.lib.binding.drivers import utils
|
|
||||||
from kuryr.lib import exceptions
|
from kuryr.lib import exceptions
|
||||||
|
|
||||||
from kuryr_libnetwork import app
|
from kuryr_libnetwork import app
|
||||||
@ -121,15 +120,6 @@ class NestedDriver(base.BaseNestedDriver):
|
|||||||
self._remove_from_allowed_address_pairs(vm_port, container_ips)
|
self._remove_from_allowed_address_pairs(vm_port, container_ips)
|
||||||
return binding.port_unbind(endpoint_id, neutron_port)
|
return binding.port_unbind(endpoint_id, neutron_port)
|
||||||
|
|
||||||
def get_container_iface_name(self, neutron_port_id):
|
|
||||||
"""Returns interface name of a container in the default namespace.
|
|
||||||
|
|
||||||
:param neutron_port_id: The ID of a neutron port as string
|
|
||||||
:returns: interface name as string
|
|
||||||
"""
|
|
||||||
_, container_iface_name = utils.get_veth_pair_names(neutron_port_id)
|
|
||||||
return container_iface_name
|
|
||||||
|
|
||||||
def _add_to_allowed_address_pairs(self, port, ip_addresses,
|
def _add_to_allowed_address_pairs(self, port, ip_addresses,
|
||||||
mac_address=None):
|
mac_address=None):
|
||||||
address_pairs = port['allowed_address_pairs']
|
address_pairs = port['allowed_address_pairs']
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
from kuryr.lib import binding
|
from kuryr.lib import binding
|
||||||
from kuryr.lib.binding.drivers import utils
|
from kuryr.lib.binding.drivers import utils
|
||||||
|
|
||||||
from kuryr_libnetwork.port_driver import driver
|
from kuryr_libnetwork.port_driver import driver
|
||||||
|
|
||||||
|
|
||||||
|
172
kuryr_libnetwork/port_driver/drivers/vlan.py
Normal file
172
kuryr_libnetwork/port_driver/drivers/vlan.py
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
# 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 neutronclient.common import exceptions as n_exceptions
|
||||||
|
from oslo_log import log
|
||||||
|
|
||||||
|
from kuryr.lib._i18n import _LE
|
||||||
|
from kuryr.lib import binding
|
||||||
|
from kuryr.lib import exceptions
|
||||||
|
from kuryr.lib import segmentation_type_drivers as seg_driver
|
||||||
|
|
||||||
|
from kuryr_libnetwork import app
|
||||||
|
from kuryr_libnetwork.port_driver import base
|
||||||
|
|
||||||
|
LOG = log.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class VlanDriver(base.BaseNestedDriver):
|
||||||
|
"""Driver for container-in-VM deployments with Trunk Ports."""
|
||||||
|
|
||||||
|
BINDING_DRIVERS = ('vlan',)
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super(VlanDriver, self).__init__()
|
||||||
|
|
||||||
|
self.port_vlan_dic = {}
|
||||||
|
self.trunk_port = self._get_port_from_host_iface(self.link_iface)
|
||||||
|
self._check_for_vlan_ids()
|
||||||
|
|
||||||
|
def _check_for_vlan_ids(self):
|
||||||
|
"""Gathers information about vlans already in use."""
|
||||||
|
for subport in self.trunk_port['trunk_details']['sub_ports']:
|
||||||
|
self.port_vlan_dic[subport['port_id']] = subport['segmentation_id']
|
||||||
|
|
||||||
|
def get_supported_bindings(self):
|
||||||
|
"""Returns a tuple of supported binding driver names for the driver.
|
||||||
|
|
||||||
|
:returns: a tuple of strings
|
||||||
|
"""
|
||||||
|
return self.BINDING_DRIVERS
|
||||||
|
|
||||||
|
def get_default_network_id(self):
|
||||||
|
"""Returns a Neutron network ID as per driver logic, if any.
|
||||||
|
|
||||||
|
:returns: the Neutron network UUID as a string
|
||||||
|
:raises: exceptions.KuryrException
|
||||||
|
"""
|
||||||
|
return None
|
||||||
|
|
||||||
|
def update_port(self, port, endpoint_id):
|
||||||
|
segmentation_id = self._get_segmentation_id(port['id'])
|
||||||
|
self._attach_subport(self.trunk_port['trunk_details']['trunk_id'],
|
||||||
|
port['id'],
|
||||||
|
segmentation_id)
|
||||||
|
return super(VlanDriver, self).update_port(port, endpoint_id)
|
||||||
|
|
||||||
|
def create_host_iface(self, endpoint_id, neutron_port, subnets,
|
||||||
|
network=None):
|
||||||
|
"""Instantiates a host interface and binds it to the host.
|
||||||
|
|
||||||
|
A host linked interface will be created for the specific Neutron port
|
||||||
|
by delegating to the pre-selected kuryr-lib driver.
|
||||||
|
This driver will attach the port to the trunk port as a subport by
|
||||||
|
using a segmentation id available.
|
||||||
|
|
||||||
|
:param endpoint_id: the ID of the endpoint as string
|
||||||
|
:param neutron_port: the container Neutron port dictionary as returned
|
||||||
|
by python-neutronclient
|
||||||
|
:param subnets: an iterable of all the Neutron subnets which the
|
||||||
|
endpoint is trying to join
|
||||||
|
:param network: the Neutron network which the endpoint is trying
|
||||||
|
to join
|
||||||
|
:returns: the tuple of stdout and stderr returned by
|
||||||
|
processutils.execute invoked
|
||||||
|
with the executable script for binding
|
||||||
|
:raises: exceptions.VethCreationFailure,
|
||||||
|
exceptions.KuryrException,
|
||||||
|
n_exceptions.NeutronClientException,
|
||||||
|
processutils.ProcessExecutionError
|
||||||
|
"""
|
||||||
|
container_ips = neutron_port['fixed_ips']
|
||||||
|
|
||||||
|
if not container_ips:
|
||||||
|
raise exceptions.KuryrException(
|
||||||
|
"Neutron port {0} does not have fixed_ips."
|
||||||
|
.format(neutron_port['id']))
|
||||||
|
|
||||||
|
vm_port = self._get_port_from_host_iface(self.link_iface)
|
||||||
|
|
||||||
|
segmentation_id = self._get_segmentation_id(neutron_port['id'])
|
||||||
|
|
||||||
|
_, _, (stdout, stderr) = binding.port_bind(
|
||||||
|
endpoint_id, neutron_port, subnets, network, vm_port,
|
||||||
|
segmentation_id)
|
||||||
|
|
||||||
|
return (stdout, stderr)
|
||||||
|
|
||||||
|
def delete_host_iface(self, endpoint_id, neutron_port):
|
||||||
|
"""Deletes a host interface after unbinding it from the host.
|
||||||
|
|
||||||
|
The host Slave interface associated to the Neutron port will be deleted
|
||||||
|
by delegating to the selected kuryr-lib driver.
|
||||||
|
This driver will also remove the subport attached to the trunk port
|
||||||
|
and will release its segmentation id
|
||||||
|
|
||||||
|
:param endpoint_id: the ID of the Docker container as string
|
||||||
|
:param neutron_port: a port dictionary returned from
|
||||||
|
python-neutronclient
|
||||||
|
:returns: the tuple of stdout and stderr returned
|
||||||
|
by processutils.execute invoked with the executable script
|
||||||
|
for unbinding
|
||||||
|
:raises: exceptions.VethDeletionFailure,
|
||||||
|
exceptions.KuryrException,
|
||||||
|
n_exceptions.NeutronClientException,
|
||||||
|
processutils.ProcessExecutionError,
|
||||||
|
"""
|
||||||
|
vm_port = self._get_port_from_host_iface(self.link_iface)
|
||||||
|
|
||||||
|
stdout, stderr = binding.port_unbind(endpoint_id, neutron_port)
|
||||||
|
|
||||||
|
subports = [{'port_id': neutron_port['id']}]
|
||||||
|
try:
|
||||||
|
app.neutron.trunk_remove_subports(
|
||||||
|
vm_port['trunk_details']['trunk_id'],
|
||||||
|
{'sub_ports': subports})
|
||||||
|
except n_exceptions.NeutronClientException as ex:
|
||||||
|
app.logger.error(_LE("Error happened during subport deletion "
|
||||||
|
"%(port_id)s: %(ex)s"),
|
||||||
|
{'port_id': neutron_port['id'], 'ex': ex})
|
||||||
|
raise
|
||||||
|
self._release_segmentation_id(neutron_port['id'])
|
||||||
|
return stdout, stderr
|
||||||
|
|
||||||
|
def _attach_subport(self, trunk_id, port_id, segmentation_id):
|
||||||
|
subport = [
|
||||||
|
{
|
||||||
|
'segmentation_id': segmentation_id,
|
||||||
|
'port_id': port_id,
|
||||||
|
'segmentation_type': 'vlan'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
try:
|
||||||
|
app.neutron.trunk_add_subports(trunk_id, {'sub_ports': subport})
|
||||||
|
except n_exceptions.NeutronClientException as ex:
|
||||||
|
app.logger.error(_LE("Error happened adding subport %(port_id)s "
|
||||||
|
"to trunk port %(trunk_id)s: %(ex)s"),
|
||||||
|
port_id, trunk_id, ex)
|
||||||
|
raise
|
||||||
|
|
||||||
|
def _get_segmentation_id(self, id):
|
||||||
|
if id in self.port_vlan_dic.keys():
|
||||||
|
return self.port_vlan_dic[id]
|
||||||
|
seg_id = seg_driver.allocate_segmentation_id(
|
||||||
|
self.port_vlan_dic.values())
|
||||||
|
self.port_vlan_dic[id] = seg_id
|
||||||
|
return seg_id
|
||||||
|
|
||||||
|
def _release_segmentation_id(self, id):
|
||||||
|
seg_driver.release_segmentation_id(id)
|
||||||
|
del self.port_vlan_dic[id]
|
||||||
|
|
||||||
|
def _get_port_vlan(self, port_id):
|
||||||
|
return self.port_vlan_dic[port_id]
|
@ -158,7 +158,8 @@ class TestKuryrBase(TestCase):
|
|||||||
neutron_subnet_v6_id=None,
|
neutron_subnet_v6_id=None,
|
||||||
neutron_subnet_v4_address="192.168.1.2",
|
neutron_subnet_v4_address="192.168.1.2",
|
||||||
neutron_subnet_v6_address="fe80::f816:3eff:fe20:57c4",
|
neutron_subnet_v6_address="fe80::f816:3eff:fe20:57c4",
|
||||||
device_owner=None):
|
device_owner=None,
|
||||||
|
neutron_trunk_id=None):
|
||||||
# The following fake response is retrieved from the Neutron doc:
|
# The following fake response is retrieved from the Neutron doc:
|
||||||
# http://developer.openstack.org/api-ref-networking-v2.html#createPort # noqa
|
# http://developer.openstack.org/api-ref-networking-v2.html#createPort # noqa
|
||||||
fake_port = {
|
fake_port = {
|
||||||
@ -188,6 +189,9 @@ class TestKuryrBase(TestCase):
|
|||||||
"subnet_id": neutron_subnet_v6_id,
|
"subnet_id": neutron_subnet_v6_id,
|
||||||
"ip_address": neutron_subnet_v6_address
|
"ip_address": neutron_subnet_v6_address
|
||||||
})
|
})
|
||||||
|
if neutron_trunk_id:
|
||||||
|
fake_port['port']['trunk_details'] = {'trunk_id': neutron_trunk_id}
|
||||||
|
|
||||||
return fake_port
|
return fake_port
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
319
kuryr_libnetwork/tests/unit/port_driver/drivers/test_vlan.py
Normal file
319
kuryr_libnetwork/tests/unit/port_driver/drivers/test_vlan.py
Normal file
@ -0,0 +1,319 @@
|
|||||||
|
# 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 oslo_utils import uuidutils
|
||||||
|
|
||||||
|
from kuryr.lib import binding
|
||||||
|
from kuryr.lib.binding.drivers import utils
|
||||||
|
from kuryr.lib import constants as lib_const
|
||||||
|
from kuryr.lib import exceptions
|
||||||
|
from kuryr.lib import segmentation_type_drivers as seg_driver
|
||||||
|
from kuryr.lib import utils as lib_utils
|
||||||
|
from kuryr_libnetwork.port_driver.drivers import vlan
|
||||||
|
from kuryr_libnetwork.tests.unit import base
|
||||||
|
from kuryr_libnetwork import utils as libnet_utils
|
||||||
|
|
||||||
|
mock_interface = mock.MagicMock()
|
||||||
|
|
||||||
|
|
||||||
|
class TestVlanDriver(base.TestKuryrBase):
|
||||||
|
"""Unit tests for the VlanDriver port driver"""
|
||||||
|
|
||||||
|
@mock.patch('kuryr_libnetwork.port_driver.drivers.vlan'
|
||||||
|
'.VlanDriver._check_for_vlan_ids')
|
||||||
|
@mock.patch('kuryr_libnetwork.port_driver.drivers.vlan'
|
||||||
|
'.VlanDriver._get_port_from_host_iface')
|
||||||
|
def test_get_supported_bindings(self, mock_trunk_port, mock_vlan_check):
|
||||||
|
mock_trunk_port.return_value = None
|
||||||
|
mock_vlan_check.return_value = None
|
||||||
|
vlan_driver = vlan.VlanDriver()
|
||||||
|
bindings = vlan_driver.get_supported_bindings()
|
||||||
|
self.assertEqual(bindings, vlan.VlanDriver.BINDING_DRIVERS)
|
||||||
|
|
||||||
|
@mock.patch('kuryr_libnetwork.config.CONF')
|
||||||
|
@mock.patch('kuryr_libnetwork.port_driver.drivers.vlan'
|
||||||
|
'.VlanDriver._check_for_vlan_ids')
|
||||||
|
@mock.patch.object(binding, 'port_bind')
|
||||||
|
@mock.patch('kuryr_libnetwork.port_driver.drivers.vlan'
|
||||||
|
'.VlanDriver._get_segmentation_id')
|
||||||
|
@mock.patch('kuryr_libnetwork.port_driver.drivers.vlan'
|
||||||
|
'.VlanDriver._get_port_from_host_iface')
|
||||||
|
def test_create_host_iface(self, mock_get_port_from_host,
|
||||||
|
mock_segmentation_id,
|
||||||
|
mock_port_bind, mock_vlan_check, mock_conf):
|
||||||
|
mock_vlan_check.return_value = None
|
||||||
|
fake_endpoint_id = lib_utils.get_hash()
|
||||||
|
fake_neutron_port_id = uuidutils.generate_uuid()
|
||||||
|
fake_neutron_net_id = uuidutils.generate_uuid()
|
||||||
|
fake_neutron_v4_subnet_id = uuidutils.generate_uuid()
|
||||||
|
fake_neutron_v6_subnet_id = uuidutils.generate_uuid()
|
||||||
|
fake_vm_port_id = uuidutils.generate_uuid()
|
||||||
|
|
||||||
|
fake_neutron_port = self._get_fake_port(
|
||||||
|
fake_endpoint_id, fake_neutron_net_id,
|
||||||
|
fake_neutron_port_id, lib_const.PORT_STATUS_ACTIVE,
|
||||||
|
fake_neutron_v4_subnet_id, fake_neutron_v6_subnet_id,
|
||||||
|
'192.168.1.3', 'fe80::f816:3eff:fe1c:36a9')['port']
|
||||||
|
fake_neutron_port['mac_address'] = 'fa:16:3e:20:57:c3'
|
||||||
|
fake_vm_port = self._get_fake_port(
|
||||||
|
fake_endpoint_id, fake_neutron_net_id,
|
||||||
|
fake_vm_port_id, lib_const.PORT_STATUS_ACTIVE,
|
||||||
|
fake_neutron_v4_subnet_id, fake_neutron_v6_subnet_id,
|
||||||
|
'192.168.1.2', 'fe80::f816:3eff:fe20:57c4')['port']
|
||||||
|
fake_vm_port['allowed_address_pairs'] = [
|
||||||
|
{'ip_address': '192.168.1.2',
|
||||||
|
'mac_address': fake_vm_port['mac_address']},
|
||||||
|
{'ip_address': 'fe80::f816:3eff:fe20:57c4',
|
||||||
|
'mac_address': fake_vm_port['mac_address']}]
|
||||||
|
|
||||||
|
fake_subnets = self._get_fake_subnets(
|
||||||
|
fake_endpoint_id, fake_neutron_net_id,
|
||||||
|
fake_neutron_v4_subnet_id, fake_neutron_v6_subnet_id)['subnets']
|
||||||
|
|
||||||
|
fake_network = mock.sentinel.binding_network
|
||||||
|
mock_conf.binding.link_iface = 'eth0'
|
||||||
|
fake_exec_response = ('fake_stdout', '')
|
||||||
|
fake_segmentation_id = 1
|
||||||
|
mock_port_bind.return_value = ('fake_host_ifname',
|
||||||
|
'fake_container_ifname', fake_exec_response)
|
||||||
|
mock_segmentation_id.return_value = fake_segmentation_id
|
||||||
|
mock_get_port_from_host.return_value = fake_vm_port
|
||||||
|
|
||||||
|
vlan_driver = vlan.VlanDriver()
|
||||||
|
|
||||||
|
response = vlan_driver.create_host_iface(fake_endpoint_id,
|
||||||
|
fake_neutron_port, fake_subnets, fake_network)
|
||||||
|
|
||||||
|
mock_get_port_from_host.assert_called_with(
|
||||||
|
mock_conf.binding.link_iface)
|
||||||
|
mock_port_bind.assert_called_with(fake_endpoint_id,
|
||||||
|
fake_neutron_port, fake_subnets, fake_network, fake_vm_port,
|
||||||
|
fake_segmentation_id)
|
||||||
|
mock_segmentation_id.assert_called_with(fake_neutron_port['id'])
|
||||||
|
|
||||||
|
self.assertEqual(response, fake_exec_response)
|
||||||
|
|
||||||
|
@mock.patch('kuryr_libnetwork.config.CONF')
|
||||||
|
@mock.patch('kuryr_libnetwork.port_driver.drivers.vlan'
|
||||||
|
'.VlanDriver._check_for_vlan_ids')
|
||||||
|
@mock.patch('kuryr_libnetwork.port_driver.drivers.vlan'
|
||||||
|
'.VlanDriver._release_segmentation_id')
|
||||||
|
@mock.patch.object(binding, 'port_unbind')
|
||||||
|
@mock.patch('kuryr_libnetwork.app.neutron.trunk_remove_subports')
|
||||||
|
@mock.patch('kuryr_libnetwork.port_driver.drivers.vlan'
|
||||||
|
'.VlanDriver._get_port_from_host_iface')
|
||||||
|
def test_delete_host_iface(self, mock_get_port_from_host,
|
||||||
|
mock_trunk_remove_subports, mock_port_unbind,
|
||||||
|
mock_release_seg_id, mock_vlan_check,
|
||||||
|
mock_conf):
|
||||||
|
mock_vlan_check.return_value = None
|
||||||
|
fake_endpoint_id = lib_utils.get_hash()
|
||||||
|
fake_neutron_port_id = uuidutils.generate_uuid()
|
||||||
|
fake_neutron_net_id = uuidutils.generate_uuid()
|
||||||
|
fake_neutron_trunk_id = uuidutils.generate_uuid()
|
||||||
|
fake_neutron_v4_subnet_id = uuidutils.generate_uuid()
|
||||||
|
fake_neutron_v6_subnet_id = uuidutils.generate_uuid()
|
||||||
|
fake_vm_port_id = uuidutils.generate_uuid()
|
||||||
|
|
||||||
|
fake_neutron_port = self._get_fake_port(
|
||||||
|
fake_endpoint_id, fake_neutron_net_id, fake_neutron_port_id,
|
||||||
|
lib_const.PORT_STATUS_ACTIVE,
|
||||||
|
fake_neutron_v4_subnet_id, fake_neutron_v6_subnet_id,
|
||||||
|
'192.168.1.3', 'fe80::f816:3eff:fe1c:36a9')['port']
|
||||||
|
fake_neutron_port['mac_address'] = 'fa:16:3e:20:57:c3'
|
||||||
|
fake_vm_port = self._get_fake_port(
|
||||||
|
fake_endpoint_id, fake_neutron_net_id,
|
||||||
|
fake_vm_port_id, lib_const.PORT_STATUS_ACTIVE,
|
||||||
|
fake_neutron_v4_subnet_id, fake_neutron_v6_subnet_id,
|
||||||
|
'192.168.1.2', 'fe80::f816:3eff:fe20:57c4',
|
||||||
|
None, fake_neutron_trunk_id)['port']
|
||||||
|
fake_vm_port['allowed_address_pairs'] = [
|
||||||
|
{'ip_address': '192.168.1.3',
|
||||||
|
'mac_address': fake_neutron_port['mac_address']},
|
||||||
|
{'ip_address': 'fe80::f816:3eff:fe1c:36a9',
|
||||||
|
'mac_address': fake_neutron_port['mac_address']}]
|
||||||
|
|
||||||
|
mock_conf.binding.link_iface = 'eth0'
|
||||||
|
fake_unbind_response = ('fake_stdout', '')
|
||||||
|
mock_get_port_from_host.return_value = fake_vm_port
|
||||||
|
mock_port_unbind.return_value = fake_unbind_response
|
||||||
|
|
||||||
|
vlan_driver = vlan.VlanDriver()
|
||||||
|
|
||||||
|
response = vlan_driver.delete_host_iface(fake_endpoint_id,
|
||||||
|
fake_neutron_port)
|
||||||
|
|
||||||
|
mock_get_port_from_host.assert_called_with(
|
||||||
|
mock_conf.binding.link_iface)
|
||||||
|
mock_port_unbind.assert_called_with(fake_endpoint_id,
|
||||||
|
fake_neutron_port)
|
||||||
|
mock_trunk_remove_subports.assert_called_with(fake_neutron_trunk_id,
|
||||||
|
{'sub_ports': [{
|
||||||
|
'port_id': fake_neutron_port_id
|
||||||
|
}]})
|
||||||
|
mock_release_seg_id.assert_called_with(fake_neutron_port_id)
|
||||||
|
|
||||||
|
self.assertEqual(response, fake_unbind_response)
|
||||||
|
|
||||||
|
@mock.patch('kuryr_libnetwork.port_driver.drivers.vlan'
|
||||||
|
'.VlanDriver._check_for_vlan_ids')
|
||||||
|
@mock.patch('kuryr_libnetwork.port_driver.drivers.vlan'
|
||||||
|
'.VlanDriver._get_port_from_host_iface')
|
||||||
|
@mock.patch.object(utils, 'get_veth_pair_names',
|
||||||
|
return_value=("fake_host_ifname", "fake_container_name"))
|
||||||
|
def test_get_container_iface_name(self, mock_get_pair_names,
|
||||||
|
mock_trunk_port, mock_vlan_check):
|
||||||
|
mock_trunk_port.return_value = None
|
||||||
|
mock_vlan_check.return_value = None
|
||||||
|
vlan_driver = vlan.VlanDriver()
|
||||||
|
fake_neutron_port_id = uuidutils.generate_uuid()
|
||||||
|
response = vlan_driver.get_container_iface_name(fake_neutron_port_id)
|
||||||
|
mock_get_pair_names.assert_called_with(fake_neutron_port_id)
|
||||||
|
self.assertEqual(response, "fake_container_name")
|
||||||
|
|
||||||
|
@mock.patch('kuryr_libnetwork.port_driver.drivers.vlan'
|
||||||
|
'.VlanDriver._check_for_vlan_ids')
|
||||||
|
@mock.patch('kuryr_libnetwork.port_driver.drivers.vlan'
|
||||||
|
'.VlanDriver._get_port_from_host_iface')
|
||||||
|
@mock.patch('kuryr_libnetwork.app.neutron.trunk_add_subports')
|
||||||
|
def test_attach_subport(self, mock_trunk_add_subports, mock_trunk_port,
|
||||||
|
mock_vlan_check):
|
||||||
|
mock_trunk_port.return_value = None
|
||||||
|
mock_vlan_check.return_value = None
|
||||||
|
|
||||||
|
fake_neutron_trunk_id = uuidutils.generate_uuid()
|
||||||
|
fake_neutron_port_id = uuidutils.generate_uuid()
|
||||||
|
fake_segmentation_id = 1
|
||||||
|
fake_subport = [
|
||||||
|
{
|
||||||
|
'segmentation_id': fake_segmentation_id,
|
||||||
|
'port_id': fake_neutron_port_id,
|
||||||
|
'segmentation_type': 'vlan'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
vlan_driver = vlan.VlanDriver()
|
||||||
|
|
||||||
|
vlan_driver._attach_subport(fake_neutron_trunk_id,
|
||||||
|
fake_neutron_port_id,
|
||||||
|
fake_segmentation_id)
|
||||||
|
mock_trunk_add_subports.assert_called_with(fake_neutron_trunk_id,
|
||||||
|
{'sub_ports': fake_subport})
|
||||||
|
|
||||||
|
@mock.patch('kuryr_libnetwork.port_driver.drivers.vlan'
|
||||||
|
'.VlanDriver._check_for_vlan_ids')
|
||||||
|
@mock.patch('kuryr_libnetwork.port_driver.drivers.vlan'
|
||||||
|
'.VlanDriver._get_port_from_host_iface')
|
||||||
|
@mock.patch.object(seg_driver, 'allocate_segmentation_id')
|
||||||
|
def test_get_segmentation_id(self, mock_alloc_seg_id, mock_trunk_port,
|
||||||
|
mock_vlan_check):
|
||||||
|
mock_trunk_port.return_value = None
|
||||||
|
mock_vlan_check.return_value = None
|
||||||
|
fake_neutron_port1_id = uuidutils.generate_uuid()
|
||||||
|
fake_neutron_port2_id = uuidutils.generate_uuid()
|
||||||
|
mock_alloc_seg_id.side_effect = [1, 2]
|
||||||
|
|
||||||
|
vlan_driver = vlan.VlanDriver()
|
||||||
|
|
||||||
|
response = vlan_driver._get_segmentation_id(fake_neutron_port1_id)
|
||||||
|
mock_alloc_seg_id.assert_called_once()
|
||||||
|
self.assertEqual(response, 1)
|
||||||
|
|
||||||
|
mock_alloc_seg_id.reset_mock()
|
||||||
|
response = vlan_driver._get_segmentation_id(fake_neutron_port1_id)
|
||||||
|
mock_alloc_seg_id.assert_not_called()
|
||||||
|
self.assertEqual(response, 1)
|
||||||
|
|
||||||
|
response = vlan_driver._get_segmentation_id(fake_neutron_port2_id)
|
||||||
|
mock_alloc_seg_id.assert_called_once()
|
||||||
|
self.assertEqual(response, 2)
|
||||||
|
|
||||||
|
@mock.patch('kuryr_libnetwork.port_driver.drivers.vlan'
|
||||||
|
'.VlanDriver._check_for_vlan_ids')
|
||||||
|
@mock.patch('kuryr_libnetwork.port_driver.drivers.vlan'
|
||||||
|
'.VlanDriver._get_port_from_host_iface')
|
||||||
|
@mock.patch('kuryr_libnetwork.app.neutron.update_port')
|
||||||
|
@mock.patch.object(libnet_utils, 'get_neutron_port_name')
|
||||||
|
@mock.patch('kuryr_libnetwork.port_driver.drivers.vlan'
|
||||||
|
'.VlanDriver._attach_subport')
|
||||||
|
@mock.patch('kuryr_libnetwork.port_driver.drivers.vlan'
|
||||||
|
'.VlanDriver._get_segmentation_id')
|
||||||
|
def test_update_port(self, mock_get_seg_id, mock_attach_subport,
|
||||||
|
mock_get_port_name, mock_update_port,
|
||||||
|
mock_get_port_from_host, mock_vlan_check):
|
||||||
|
fake_endpoint_id = lib_utils.get_hash()
|
||||||
|
fake_neutron_port_id = uuidutils.generate_uuid()
|
||||||
|
fake_neutron_net_id = uuidutils.generate_uuid()
|
||||||
|
fake_neutron_trunk_id = uuidutils.generate_uuid()
|
||||||
|
fake_neutron_v4_subnet_id = uuidutils.generate_uuid()
|
||||||
|
fake_neutron_v6_subnet_id = uuidutils.generate_uuid()
|
||||||
|
fake_vm_port_id = uuidutils.generate_uuid()
|
||||||
|
|
||||||
|
fake_neutron_port = self._get_fake_port(
|
||||||
|
fake_endpoint_id, fake_neutron_net_id,
|
||||||
|
fake_neutron_port_id, lib_const.PORT_STATUS_ACTIVE,
|
||||||
|
fake_neutron_v4_subnet_id, fake_neutron_v6_subnet_id,
|
||||||
|
'192.168.1.3', 'fe80::f816:3eff:fe1c:36a9')['port']
|
||||||
|
fake_neutron_port['mac_address'] = 'fa:16:3e:20:57:c3'
|
||||||
|
fake_vm_port = self._get_fake_port(
|
||||||
|
fake_endpoint_id, fake_neutron_net_id,
|
||||||
|
fake_vm_port_id, lib_const.PORT_STATUS_ACTIVE,
|
||||||
|
fake_neutron_v4_subnet_id, fake_neutron_v6_subnet_id,
|
||||||
|
'192.168.1.2', 'fe80::f816:3eff:fe20:57c4',
|
||||||
|
None, fake_neutron_trunk_id)['port']
|
||||||
|
fake_segmentation_id = 1
|
||||||
|
fake_port_name = 'port1'
|
||||||
|
|
||||||
|
mock_get_seg_id.return_value = fake_segmentation_id
|
||||||
|
mock_get_port_name.return_value = fake_port_name
|
||||||
|
mock_get_port_from_host.return_value = fake_vm_port
|
||||||
|
mock_vlan_check.return_value = None
|
||||||
|
|
||||||
|
vlan_driver = vlan.VlanDriver()
|
||||||
|
|
||||||
|
vlan_driver.update_port(fake_neutron_port, fake_endpoint_id)
|
||||||
|
|
||||||
|
mock_get_seg_id.assert_called_with(fake_neutron_port_id)
|
||||||
|
|
||||||
|
mock_get_port_name.assert_called_with(fake_endpoint_id)
|
||||||
|
|
||||||
|
mock_attach_subport.assert_called_with(fake_neutron_trunk_id,
|
||||||
|
fake_neutron_port_id,
|
||||||
|
fake_segmentation_id)
|
||||||
|
|
||||||
|
mock_update_port.assert_called_with(fake_neutron_port_id,
|
||||||
|
{'port': {
|
||||||
|
'name': fake_port_name,
|
||||||
|
'device_owner': lib_const.DEVICE_OWNER,
|
||||||
|
'device_id': fake_endpoint_id
|
||||||
|
}})
|
||||||
|
|
||||||
|
|
||||||
|
class TestVlanDriverFailures(base.TestKuryrFailures):
|
||||||
|
"""Unit tests for the VlanDriver port driver failures"""
|
||||||
|
|
||||||
|
@mock.patch('kuryr_libnetwork.port_driver.drivers.vlan'
|
||||||
|
'.VlanDriver._get_port_from_host_iface')
|
||||||
|
def test_create_host_iface(self, mock_get_port_from_host):
|
||||||
|
fake_endpoint_id = lib_utils.get_hash()
|
||||||
|
fake_neutron_port_id = uuidutils.generate_uuid()
|
||||||
|
fake_neutron_net_id = uuidutils.generate_uuid()
|
||||||
|
|
||||||
|
fake_neutron_port = self._get_fake_port(
|
||||||
|
fake_endpoint_id, fake_neutron_net_id,
|
||||||
|
fake_neutron_port_id, lib_const.PORT_STATUS_ACTIVE)['port']
|
||||||
|
|
||||||
|
vlan_driver = vlan.VlanDriver()
|
||||||
|
self.assertRaises(exceptions.KuryrException,
|
||||||
|
vlan_driver.create_host_iface, fake_endpoint_id,
|
||||||
|
fake_neutron_port, None)
|
@ -35,6 +35,9 @@ class TestBaseDriver(d_base.BaseNestedDriver):
|
|||||||
def get_supported_bindings(self):
|
def get_supported_bindings(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def update_port(self, neutron_port_id, endpoint_id):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
@ddt.ddt
|
@ddt.ddt
|
||||||
class TestBaseNestedDriver(base.TestKuryrBase):
|
class TestBaseNestedDriver(base.TestKuryrBase):
|
||||||
|
@ -849,7 +849,7 @@ class TestKuryr(base.TestKuryrBase):
|
|||||||
@mock.patch('kuryr_libnetwork.controllers.app.driver.create_host_iface')
|
@mock.patch('kuryr_libnetwork.controllers.app.driver.create_host_iface')
|
||||||
@mock.patch('kuryr_libnetwork.controllers.app.neutron.list_networks')
|
@mock.patch('kuryr_libnetwork.controllers.app.neutron.list_networks')
|
||||||
@mock.patch('kuryr_libnetwork.controllers.app.neutron.show_port')
|
@mock.patch('kuryr_libnetwork.controllers.app.neutron.show_port')
|
||||||
@mock.patch('kuryr_libnetwork.controllers.app.neutron.update_port')
|
@mock.patch('kuryr_libnetwork.controllers.app.driver.update_port')
|
||||||
@mock.patch('kuryr_libnetwork.controllers.app.neutron.list_ports')
|
@mock.patch('kuryr_libnetwork.controllers.app.neutron.list_ports')
|
||||||
@mock.patch('kuryr_libnetwork.controllers.app.neutron.list_subnets')
|
@mock.patch('kuryr_libnetwork.controllers.app.neutron.list_subnets')
|
||||||
@mock.patch('kuryr_libnetwork.controllers.app')
|
@mock.patch('kuryr_libnetwork.controllers.app')
|
||||||
@ -922,7 +922,7 @@ class TestKuryr(base.TestKuryrBase):
|
|||||||
fake_updated_port = fake_port_response['port']
|
fake_updated_port = fake_port_response['port']
|
||||||
fake_updated_port['name'] = utils.get_neutron_port_name(
|
fake_updated_port['name'] = utils.get_neutron_port_name(
|
||||||
fake_docker_endpoint_id)
|
fake_docker_endpoint_id)
|
||||||
mock_update_port.return_value = fake_port_response
|
mock_update_port.return_value = fake_port_response['port']
|
||||||
|
|
||||||
fake_neutron_subnets = [fake_v4_subnet['subnet'],
|
fake_neutron_subnets = [fake_v4_subnet['subnet'],
|
||||||
fake_v6_subnet['subnet']]
|
fake_v6_subnet['subnet']]
|
||||||
@ -931,7 +931,6 @@ class TestKuryr(base.TestKuryrBase):
|
|||||||
mock_create_host_iface.return_value = fake_create_iface_response
|
mock_create_host_iface.return_value = fake_create_iface_response
|
||||||
|
|
||||||
if vif_plug_is_fatal:
|
if vif_plug_is_fatal:
|
||||||
mock_vif.vif_plug_is_fatal = vif_plug_is_fatal
|
|
||||||
fake_neutron_ports_response_2 = self._get_fake_port(
|
fake_neutron_ports_response_2 = self._get_fake_port(
|
||||||
fake_docker_endpoint_id, fake_neutron_net_id,
|
fake_docker_endpoint_id, fake_neutron_net_id,
|
||||||
fake_port_id, lib_const.PORT_STATUS_ACTIVE,
|
fake_port_id, lib_const.PORT_STATUS_ACTIVE,
|
||||||
@ -958,13 +957,8 @@ class TestKuryr(base.TestKuryrBase):
|
|||||||
mock_list_subnets.assert_any_call(
|
mock_list_subnets.assert_any_call(
|
||||||
network_id=fake_neutron_net_id, cidr='fe80::/64')
|
network_id=fake_neutron_net_id, cidr='fe80::/64')
|
||||||
mock_list_ports.assert_called_with(fixed_ips=fake_fixed_ips)
|
mock_list_ports.assert_called_with(fixed_ips=fake_fixed_ips)
|
||||||
mock_update_port.assert_called_with(
|
mock_update_port.assert_called_with(fake_port_response['port'],
|
||||||
fake_updated_port['id'],
|
fake_docker_endpoint_id)
|
||||||
{'port': {
|
|
||||||
'name': fake_updated_port['name'],
|
|
||||||
'device_owner': lib_const.DEVICE_OWNER,
|
|
||||||
'device_id': fake_docker_endpoint_id
|
|
||||||
}})
|
|
||||||
mock_list_networks.assert_any_call(tags=t)
|
mock_list_networks.assert_any_call(tags=t)
|
||||||
mock_create_host_iface.assert_called_with(fake_docker_endpoint_id,
|
mock_create_host_iface.assert_called_with(fake_docker_endpoint_id,
|
||||||
fake_updated_port, fake_neutron_subnets,
|
fake_updated_port, fake_neutron_subnets,
|
||||||
|
@ -105,7 +105,7 @@ class TestKuryrEndpointCreateFailures(base.TestKuryrFailures):
|
|||||||
self.assertEqual({'Err': GivenException.message}, decoded_json)
|
self.assertEqual({'Err': GivenException.message}, decoded_json)
|
||||||
|
|
||||||
@mock.patch('kuryr_libnetwork.controllers.app.driver.create_host_iface')
|
@mock.patch('kuryr_libnetwork.controllers.app.driver.create_host_iface')
|
||||||
@mock.patch('kuryr_libnetwork.controllers.app.neutron.update_port')
|
@mock.patch('kuryr_libnetwork.controllers.app.driver.update_port')
|
||||||
@mock.patch('kuryr_libnetwork.controllers.app.neutron.list_subnets')
|
@mock.patch('kuryr_libnetwork.controllers.app.neutron.list_subnets')
|
||||||
@mock.patch('kuryr_libnetwork.controllers.app.neutron.list_ports')
|
@mock.patch('kuryr_libnetwork.controllers.app.neutron.list_ports')
|
||||||
@mock.patch('kuryr_libnetwork.controllers.app.neutron.list_networks')
|
@mock.patch('kuryr_libnetwork.controllers.app.neutron.list_networks')
|
||||||
@ -172,7 +172,7 @@ class TestKuryrEndpointCreateFailures(base.TestKuryrFailures):
|
|||||||
fake_updated_port = fake_port_response['port']
|
fake_updated_port = fake_port_response['port']
|
||||||
fake_updated_port['name'] = utils.get_neutron_port_name(
|
fake_updated_port['name'] = utils.get_neutron_port_name(
|
||||||
fake_docker_endpoint_id)
|
fake_docker_endpoint_id)
|
||||||
mock_update_port.return_value = fake_port_response
|
mock_update_port.return_value = fake_port_response['port']
|
||||||
|
|
||||||
fake_neutron_subnets = [fake_v4_subnet['subnet'],
|
fake_neutron_subnets = [fake_v4_subnet['subnet'],
|
||||||
fake_v6_subnet['subnet']]
|
fake_v6_subnet['subnet']]
|
||||||
@ -195,13 +195,8 @@ class TestKuryrEndpointCreateFailures(base.TestKuryrFailures):
|
|||||||
mock.call(cidr='fe80::/64', network_id=fake_neutron_network_id)]
|
mock.call(cidr='fe80::/64', network_id=fake_neutron_network_id)]
|
||||||
mock_list_subnets.assert_has_calls(expect_calls, any_order=True)
|
mock_list_subnets.assert_has_calls(expect_calls, any_order=True)
|
||||||
mock_list_ports.assert_called_with(fixed_ips=fake_fixed_ips)
|
mock_list_ports.assert_called_with(fixed_ips=fake_fixed_ips)
|
||||||
mock_update_port.assert_called_with(
|
mock_update_port.assert_called_with(fake_port_response['port'],
|
||||||
fake_updated_port['id'],
|
fake_docker_endpoint_id)
|
||||||
{'port': {
|
|
||||||
'name': fake_updated_port['name'],
|
|
||||||
'device_owner': lib_const.DEVICE_OWNER,
|
|
||||||
'device_id': fake_docker_endpoint_id
|
|
||||||
}})
|
|
||||||
mock_create_host_iface.assert_called_with(
|
mock_create_host_iface.assert_called_with(
|
||||||
fake_docker_endpoint_id, fake_updated_port, fake_neutron_subnets,
|
fake_docker_endpoint_id, fake_updated_port, fake_neutron_subnets,
|
||||||
fake_neutron_network['networks'][0])
|
fake_neutron_network['networks'][0])
|
||||||
|
Loading…
Reference in New Issue
Block a user