Merge "Support names for {cleaning,provisioning}_network"

This commit is contained in:
Jenkins 2016-12-02 16:54:14 +00:00 committed by Gerrit Code Review
commit ff3a8f1d7f
15 changed files with 308 additions and 104 deletions

View File

@ -587,10 +587,7 @@ function configure_ironic_networks {
}
function configure_ironic_cleaning_network {
local cleaning_network_uuid
cleaning_network_uuid=$(openstack network show "$IRONIC_CLEAN_NET_NAME" -c id -f value)
die_if_not_set $LINENO cleaning_network_uuid "Failed to get ironic cleaning network id"
iniset $IRONIC_CONF_FILE neutron cleaning_network_uuid ${cleaning_network_uuid}
iniset $IRONIC_CONF_FILE neutron cleaning_network $IRONIC_CLEAN_NET_NAME
}
function configure_ironic_provision_network {
@ -639,7 +636,7 @@ function configure_ironic_provision_network {
sudo ip addr add dev $OVS_PHYSICAL_BRIDGE $ironic_provision_network_ip/$provision_net_prefix
fi
iniset $IRONIC_CONF_FILE neutron provisioning_network_uuid $net_id
iniset $IRONIC_CONF_FILE neutron provisioning_network $IRONIC_PROVISION_NETWORK_NAME
}
function cleanup_ironic_provision_network {

View File

@ -74,14 +74,14 @@ interface as stated above):
#. Define a provider network in neutron, which we shall refer to as the
"provisioning" network, and add it in under the neutron section in
ironic-conductor configuration file. Using ``neutron`` network interface
requires that ``provisioning_network_uuid`` and ``cleaning_network_uuid``
configuration options are set to a valid neutron network UUIDs, otherwise
ironic-conductor will fail to start::
requires that ``provisioning_network`` and ``cleaning_network``
configuration options are set to a valid neutron network UUIDs or names,
otherwise cleaning or provisioning will fail to start::
[neutron]
...
cleaning_network_uuid=$CLEAN_UUID
provisioning_network_uuid=$PROVISION_UUID
cleaning_network=$CLEAN_UUID_OR_NAME
provisioning_network=$PROVISION_UUID_OR_NAME
Please refer to `Configure the Bare Metal service for cleaning`_ for more
information about cleaning.

View File

@ -1927,17 +1927,20 @@
# PEM encoded client certificate cert file (string value)
#certfile = <None>
# Neutron network UUID for the ramdisk to be booted into for
# cleaning nodes. Required for "neutron" network interface. It
# is also required if cleaning nodes when using "flat" network
# interface or "neutron" DHCP provider. (string value)
#cleaning_network_uuid = <None>
# Neutron network UUID or name for the ramdisk to be booted
# into for cleaning nodes. Required for "neutron" network
# interface. It is also required if cleaning nodes when using
# "flat" network interface or "neutron" DHCP provider. If a
# name is provided, it must be unique among all networks or
# cleaning will fail. (string value)
# Deprecated group/name - [neutron]/cleaning_network_uuid
#cleaning_network = <None>
# List of Neutron Security Group UUIDs to be applied during
# cleaning of the nodes. Optional for the "neutron" network
# interface and not used for the "flat" or "noop" network
# interfaces. If not specified, default security
# group is used. (list value)
# interfaces. If not specified, default security group is
# used. (list value)
#cleaning_network_security_groups =
# Optional domain ID to use with v3 and v2 parameters. It will
@ -1986,14 +1989,16 @@
# Neutron network UUID for the ramdisk to be booted into for
# provisioning nodes. Required for "neutron" network
# interface. (string value)
#provisioning_network_uuid = <None>
# interface. If a name is provided, it must be unique among
# all networks or deploy will fail. (string value)
# Deprecated group/name - [neutron]/provisioning_network_uuid
#provisioning_network = <None>
# List of Neutron Security Group UUIDs to be applied during
# provisioning of the nodes. Optional for the "neutron"
# network interface and not used for the "flat" or "noop"
# network interfaces. If not specified, default
# security group is used. (list value)
# network interfaces. If not specified, default security group
# is used. (list value)
#provisioning_network_security_groups =
# Client retries in the case of a failed request. (integer

View File

@ -5,7 +5,7 @@ Configure the Bare Metal service for cleaning
.. note:: If you configured the Bare Metal service to use `Node cleaning`_
(which is enabled by default), you will need to set the
``cleaning_network_uuid`` configuration option.
``cleaning_network`` configuration option.
.. _`Node cleaning`: http://docs.openstack.org/developer/ironic/deploy/cleaning.html#node-cleaning
@ -16,7 +16,7 @@ Configure the Bare Metal service for cleaning
$ neutron net-list
#. Configure the cleaning network UUID via the ``cleaning_network_uuid``
#. Configure the cleaning network UUID via the ``cleaning_network``
option in the Bare Metal service configuration file
(``/etc/ironic/ironic.conf``). In the following, replace ``NETWORK_UUID``
with the UUID you noted in the previous step:
@ -24,7 +24,7 @@ Configure the Bare Metal service for cleaning
.. code-block:: ini
[neutron]
cleaning_network_uuid = NETWORK_UUID
cleaning_network = NETWORK_UUID
#. Restart the Bare Metal service's ironic-conductor:

View File

@ -13,6 +13,7 @@
from neutronclient.common import exceptions as neutron_exceptions
from neutronclient.v2_0 import client as clientv20
from oslo_log import log
from oslo_utils import uuidutils
from ironic.common import exception
from ironic.common.i18n import _, _LE, _LI, _LW
@ -286,3 +287,65 @@ def rollback_ports(task, network_uuid):
'Failed to rollback port changes for node %(node)s '
'on network %(network)s'), {'node': task.node.uuid,
'network': network_uuid})
def validate_network(uuid_or_name, net_type=_('network')):
"""Check that the given network is present.
:param uuid_or_name: network UUID or name
:param net_type: human-readable network type for error messages
:return: network UUID
:raises: MissingParameterValue if uuid_or_name is empty
:raises: NetworkError on failure to contact Neutron
:raises: InvalidParameterValue for missing or duplicated network
"""
if not uuid_or_name:
raise exception.MissingParameterValue(
_('UUID or name of %s is not set in configuration') % net_type)
if uuidutils.is_uuid_like(uuid_or_name):
filters = {'id': uuid_or_name}
else:
filters = {'name': uuid_or_name}
try:
client = get_client()
networks = client.list_networks(fields=['id'], **filters)
except neutron_exceptions.NeutronClientException as exc:
raise exception.NetworkError(_('Could not retrieve network list: %s') %
exc)
LOG.debug('Got list of networks matching %(cond)s: %(result)s',
{'cond': filters, 'result': networks})
networks = [n['id'] for n in networks.get('networks', [])]
if not networks:
raise exception.InvalidParameterValue(
_('%(type)s with name or UUID %(uuid_or_name)s was not found') %
{'type': net_type, 'uuid_or_name': uuid_or_name})
elif len(networks) > 1:
raise exception.InvalidParameterValue(
_('More than one %(type)s was found for name %(name)s: %(nets)s') %
{'name': uuid_or_name, 'nets': ', '.join(networks),
'type': net_type})
return networks[0]
class NeutronNetworkInterfaceMixin(object):
_cleaning_network_uuid = None
_provisioning_network_uuid = None
def get_cleaning_network_uuid(self):
if self._cleaning_network_uuid is None:
self._cleaning_network_uuid = validate_network(
CONF.neutron.cleaning_network,
_('cleaning network'))
return self._cleaning_network_uuid
def get_provisioning_network_uuid(self):
if self._provisioning_network_uuid is None:
self._provisioning_network_uuid = validate_network(
CONF.neutron.provisioning_network,
_('provisioning network'))
return self._provisioning_network_uuid

View File

@ -44,16 +44,20 @@ opts = [
'neutron. Running neutron in noauth mode (related to '
'but not affected by this setting) is insecure and '
'should only be used for testing.')),
cfg.StrOpt('cleaning_network_uuid',
help=_('Neutron network UUID for the ramdisk to be booted '
'into for cleaning nodes. Required for "neutron" '
cfg.StrOpt('cleaning_network',
help=_('Neutron network UUID or name for the ramdisk to be '
'booted into for cleaning nodes. Required for "neutron" '
'network interface. It is also required if cleaning '
'nodes when using "flat" network interface or "neutron" '
'DHCP provider.')),
cfg.StrOpt('provisioning_network_uuid',
'DHCP provider. If a name is provided, it must be '
'unique among all networks or cleaning will fail.'),
deprecated_name='cleaning_network_uuid'),
cfg.StrOpt('provisioning_network',
help=_('Neutron network UUID for the ramdisk to be booted '
'into for provisioning nodes. Required for "neutron" '
'network interface.')),
'network interface. If a name is provided, it must be '
'unique among all networks or deploy will fail.'),
deprecated_name='provisioning_network_uuid'),
cfg.ListOpt('provisioning_network_security_groups',
default=[],
help=_('List of Neutron Security Group UUIDs to be '

View File

@ -16,10 +16,8 @@ Flat network interface. Useful for shared, flat networks.
from oslo_config import cfg
from oslo_log import log
from oslo_utils import uuidutils
from ironic.common import exception
from ironic.common.i18n import _, _LI, _LW
from ironic.common.i18n import _LI, _LW
from ironic.common import neutron
from ironic.drivers import base
@ -29,22 +27,32 @@ LOG = log.getLogger(__name__)
CONF = cfg.CONF
class FlatNetwork(base.NetworkInterface):
class FlatNetwork(neutron.NeutronNetworkInterfaceMixin, base.NetworkInterface):
"""Flat network interface."""
def __init__(self):
cleaning_net = CONF.neutron.cleaning_network_uuid
cleaning_net = CONF.neutron.cleaning_network
# TODO(vdrok): Switch to DriverLoadError in Ocata
if not uuidutils.is_uuid_like(cleaning_net):
if not cleaning_net:
LOG.warning(_LW(
'Please specify a valid UUID for '
'[neutron]/cleaning_network_uuid configuration option so that '
'Please specify a valid UUID or name for '
'[neutron]/cleaning_network configuration option so that '
'this interface is able to perform cleaning. It will be '
'required starting with the Ocata release, and if not '
'specified then, the conductor service will fail to start if '
'"flat" is in the list of values for '
'[DEFAULT]enabled_network_interfaces configuration option.'))
def validate(self, task):
"""Validates the network interface.
:param task: a TaskManager instance.
:raises: InvalidParameterValue, if the network interface configuration
is invalid.
:raises: MissingParameterValue, if some parameters are missing.
"""
self.get_cleaning_network_uuid()
def add_provisioning_network(self, task):
"""Add the provisioning network to a node.
@ -84,15 +92,11 @@ class FlatNetwork(base.NetworkInterface):
:returns: a dictionary in the form {port.uuid: neutron_port['id']}
:raises: NetworkError, InvalidParameterValue
"""
if not uuidutils.is_uuid_like(CONF.neutron.cleaning_network_uuid):
raise exception.InvalidParameterValue(_(
'You must provide a valid cleaning network UUID in '
'[neutron]cleaning_network_uuid configuration option.'))
# If we have left over ports from a previous cleaning, remove them
neutron.rollback_ports(task, CONF.neutron.cleaning_network_uuid)
neutron.rollback_ports(task, self.get_cleaning_network_uuid())
LOG.info(_LI('Adding cleaning network to node %s'), task.node.uuid)
vifs = neutron.add_ports_to_network(
task, CONF.neutron.cleaning_network_uuid, is_flat=True)
task, self.get_cleaning_network_uuid(), is_flat=True)
for port in task.ports:
if port.uuid in vifs:
internal_info = port.internal_info
@ -109,8 +113,8 @@ class FlatNetwork(base.NetworkInterface):
"""
LOG.info(_LI('Removing ports from cleaning network for node %s'),
task.node.uuid)
neutron.remove_ports_from_network(
task, CONF.neutron.cleaning_network_uuid)
neutron.remove_ports_from_network(task,
self.get_cleaning_network_uuid())
for port in task.ports:
if 'cleaning_vif_port_id' in port.internal_info:
internal_info = port.internal_info

View File

@ -17,7 +17,6 @@
from neutronclient.common import exceptions as neutron_exceptions
from oslo_config import cfg
from oslo_log import log
from oslo_utils import uuidutils
from ironic.common import exception
from ironic.common.i18n import _, _LI
@ -30,25 +29,36 @@ LOG = log.getLogger(__name__)
CONF = cfg.CONF
class NeutronNetwork(base.NetworkInterface):
class NeutronNetwork(neutron.NeutronNetworkInterfaceMixin,
base.NetworkInterface):
"""Neutron v2 network interface"""
def __init__(self):
failures = []
cleaning_net = CONF.neutron.cleaning_network_uuid
if not uuidutils.is_uuid_like(cleaning_net):
failures.append('cleaning_network_uuid=%s' % cleaning_net)
cleaning_net = CONF.neutron.cleaning_network
if not cleaning_net:
failures.append('cleaning_network')
provisioning_net = CONF.neutron.provisioning_network_uuid
if not uuidutils.is_uuid_like(provisioning_net):
failures.append('provisioning_network_uuid=%s' % provisioning_net)
provisioning_net = CONF.neutron.provisioning_network
if not provisioning_net:
failures.append('provisioning_network')
if failures:
raise exception.DriverLoadError(
driver=self.__class__.__name__,
reason=(_('The following [neutron] group configuration '
'options are incorrect, they must be valid UUIDs: '
'%s') % ', '.join(failures)))
'options are missing: %s') % ', '.join(failures)))
def validate(self, task):
"""Validates the network interface.
:param task: a TaskManager instance.
:raises: InvalidParameterValue, if the network interface configuration
is invalid.
:raises: MissingParameterValue, if some parameters are missing.
"""
self.get_cleaning_network_uuid()
self.get_provisioning_network_uuid()
def add_provisioning_network(self, task):
"""Add the provisioning network to a node.
@ -58,11 +68,11 @@ class NeutronNetwork(base.NetworkInterface):
"""
# If we have left over ports from a previous provision attempt, remove
# them
neutron.rollback_ports(task, CONF.neutron.provisioning_network_uuid)
neutron.rollback_ports(task, self.get_provisioning_network_uuid())
LOG.info(_LI('Adding provisioning network to node %s'),
task.node.uuid)
vifs = neutron.add_ports_to_network(
task, CONF.neutron.provisioning_network_uuid,
task, self.get_provisioning_network_uuid(),
security_groups=CONF.neutron.provisioning_network_security_groups)
for port in task.ports:
if port.uuid in vifs:
@ -80,7 +90,7 @@ class NeutronNetwork(base.NetworkInterface):
LOG.info(_LI('Removing provisioning network from node %s'),
task.node.uuid)
neutron.remove_ports_from_network(
task, CONF.neutron.provisioning_network_uuid)
task, self.get_provisioning_network_uuid())
for port in task.ports:
if 'provisioning_vif_port_id' in port.internal_info:
internal_info = port.internal_info
@ -96,11 +106,11 @@ class NeutronNetwork(base.NetworkInterface):
:returns: a dictionary in the form {port.uuid: neutron_port['id']}
"""
# If we have left over ports from a previous cleaning, remove them
neutron.rollback_ports(task, CONF.neutron.cleaning_network_uuid)
neutron.rollback_ports(task, self.get_cleaning_network_uuid())
LOG.info(_LI('Adding cleaning network to node %s'), task.node.uuid)
security_groups = CONF.neutron.cleaning_network_security_groups
vifs = neutron.add_ports_to_network(task,
CONF.neutron.cleaning_network_uuid,
self.get_cleaning_network_uuid(),
security_groups=security_groups)
for port in task.ports:
if port.uuid in vifs:
@ -118,8 +128,8 @@ class NeutronNetwork(base.NetworkInterface):
"""
LOG.info(_LI('Removing cleaning network from node %s'),
task.node.uuid)
neutron.remove_ports_from_network(
task, CONF.neutron.cleaning_network_uuid)
neutron.remove_ports_from_network(task,
self.get_cleaning_network_uuid())
for port in task.ports:
if 'cleaning_vif_port_id' in port.internal_info:
internal_info = port.internal_info

View File

@ -119,9 +119,9 @@ class TestCase(testtools.TestCase):
self.config(use_stderr=False,
fatal_exception_format_errors=True,
tempdir=tempfile.tempdir)
self.config(cleaning_network_uuid=uuidutils.generate_uuid(),
self.config(cleaning_network=uuidutils.generate_uuid(),
group='neutron')
self.config(provisioning_network_uuid=uuidutils.generate_uuid(),
self.config(provisioning_network=uuidutils.generate_uuid(),
group='neutron')
self.config(enabled_drivers=['fake'])
self.config(enabled_network_interfaces=['flat', 'noop', 'neutron'],

View File

@ -447,3 +447,69 @@ class TestNeutronNetworkActions(db_base.DbTestCase):
with task_manager.acquire(self.context, self.node.uuid) as task:
neutron.rollback_ports(task, self.network_uuid)
self.assertTrue(log_mock.exception.called)
@mock.patch.object(neutron, 'get_client', autospec=True)
class TestValidateNetwork(base.TestCase):
def setUp(self):
super(TestValidateNetwork, self).setUp()
self.uuid = uuidutils.generate_uuid()
def test_by_uuid(self, client_mock):
net_mock = client_mock.return_value.list_networks
net_mock.return_value = {
'networks': [
{'id': self.uuid},
]
}
self.assertEqual(self.uuid, neutron.validate_network(self.uuid))
net_mock.assert_called_once_with(fields=['id'],
id=self.uuid)
def test_by_name(self, client_mock):
net_mock = client_mock.return_value.list_networks
net_mock.return_value = {
'networks': [
{'id': self.uuid},
]
}
self.assertEqual(self.uuid, neutron.validate_network('name'))
net_mock.assert_called_once_with(fields=['id'],
name='name')
def test_not_found(self, client_mock):
net_mock = client_mock.return_value.list_networks
net_mock.return_value = {
'networks': []
}
self.assertRaisesRegex(exception.InvalidParameterValue,
'was not found',
neutron.validate_network, self.uuid)
net_mock.assert_called_once_with(fields=['id'],
id=self.uuid)
def test_failure(self, client_mock):
net_mock = client_mock.return_value.list_networks
net_mock.side_effect = neutron_client_exc.NeutronClientException('foo')
self.assertRaisesRegex(exception.NetworkError, 'foo',
neutron.validate_network, 'name')
net_mock.assert_called_once_with(fields=['id'],
name='name')
def test_duplicate(self, client_mock):
net_mock = client_mock.return_value.list_networks
net_mock.return_value = {
'networks': [{'id': self.uuid},
{'id': 'uuid2'}]
}
self.assertRaisesRegex(exception.InvalidParameterValue,
'More than one network',
neutron.validate_network, 'name')
net_mock.assert_called_once_with(fields=['id'],
name='name')

View File

@ -2579,7 +2579,8 @@ class MiscTestCase(mgr_utils.ServiceSetUpMixin, mgr_utils.CommonMixIn,
target_raid_config = {'logical_disks': [{'size_gb': 1,
'raid_level': '1'}]}
node = obj_utils.create_test_node(
self.context, driver='fake', target_raid_config=target_raid_config)
self.context, driver='fake', target_raid_config=target_raid_config,
network_interface='noop')
ret = self.service.validate_driver_interfaces(self.context,
node.uuid)
expected = {'console': {'result': True},
@ -2596,7 +2597,8 @@ class MiscTestCase(mgr_utils.ServiceSetUpMixin, mgr_utils.CommonMixIn,
@mock.patch.object(images, 'is_whole_disk_image')
def test_validate_driver_interfaces_validation_fail(self, mock_iwdi):
mock_iwdi.return_value = False
node = obj_utils.create_test_node(self.context, driver='fake')
node = obj_utils.create_test_node(self.context, driver='fake',
network_interface='noop')
with mock.patch(
'ironic.drivers.modules.fake.FakeDeploy.validate'
) as deploy:

View File

@ -37,7 +37,7 @@ class TestNeutron(db_base.DbTestCase):
super(TestNeutron, self).setUp()
mgr_utils.mock_the_extension_manager(driver='fake')
self.config(
cleaning_network_uuid='00000000-0000-0000-0000-000000000000',
cleaning_network='00000000-0000-0000-0000-000000000000',
group='neutron')
self.config(enabled_drivers=['fake'])
self.config(dhcp_provider='neutron',

View File

@ -14,7 +14,6 @@ import mock
from oslo_config import cfg
from oslo_utils import uuidutils
from ironic.common import exception
from ironic.common import neutron
from ironic.conductor import task_manager
from ironic.drivers.modules.network import flat as flat_interface
@ -40,43 +39,48 @@ class TestFlatInterface(db_base.DbTestCase):
@mock.patch.object(flat_interface, 'LOG')
def test_init_incorrect_cleaning_net(self, mock_log):
self.config(cleaning_network_uuid=None, group='neutron')
self.config(cleaning_network=None, group='neutron')
flat_interface.FlatNetwork()
self.assertTrue(mock_log.warning.called)
@mock.patch.object(neutron, 'validate_network', autospec=True)
def test_validate(self, validate_mock):
with task_manager.acquire(self.context, self.node.id) as task:
self.interface.validate(task)
validate_mock.assert_called_once_with(CONF.neutron.cleaning_network,
'cleaning network')
@mock.patch.object(neutron, 'validate_network',
side_effect=lambda n, t: n)
@mock.patch.object(neutron, 'add_ports_to_network')
@mock.patch.object(neutron, 'rollback_ports')
def test_add_cleaning_network(self, rollback_mock, add_mock):
def test_add_cleaning_network(self, rollback_mock, add_mock,
validate_mock):
add_mock.return_value = {self.port.uuid: 'vif-port-id'}
with task_manager.acquire(self.context, self.node.id) as task:
self.interface.add_cleaning_network(task)
rollback_mock.assert_called_once_with(
task, CONF.neutron.cleaning_network_uuid)
task, CONF.neutron.cleaning_network)
add_mock.assert_called_once_with(
task, CONF.neutron.cleaning_network_uuid, is_flat=True)
task, CONF.neutron.cleaning_network, is_flat=True)
validate_mock.assert_called_once_with(
CONF.neutron.cleaning_network,
'cleaning network')
self.port.refresh()
self.assertEqual('vif-port-id',
self.port.internal_info['cleaning_vif_port_id'])
@mock.patch.object(neutron, 'add_ports_to_network')
@mock.patch.object(neutron, 'rollback_ports')
def test_add_cleaning_network_no_cleaning_net_uuid(self, rollback_mock,
add_mock):
with task_manager.acquire(self.context, self.node.id) as task:
# This has to go after acquire, or acquire will raise
# DriverLoadError.
self.config(cleaning_network_uuid='abc', group='neutron')
self.assertRaises(exception.InvalidParameterValue,
self.interface.add_cleaning_network, task)
self.assertFalse(rollback_mock.called)
self.assertFalse(add_mock.called)
@mock.patch.object(neutron, 'validate_network',
side_effect=lambda n, t: n)
@mock.patch.object(neutron, 'remove_ports_from_network')
def test_remove_cleaning_network(self, remove_mock):
def test_remove_cleaning_network(self, remove_mock, validate_mock):
with task_manager.acquire(self.context, self.node.id) as task:
self.interface.remove_cleaning_network(task)
remove_mock.assert_called_once_with(
task, CONF.neutron.cleaning_network_uuid)
task, CONF.neutron.cleaning_network)
validate_mock.assert_called_once_with(
CONF.neutron.cleaning_network,
'cleaning network')
self.port.refresh()
self.assertNotIn('cleaning_vif_port_id', self.port.internal_info)

View File

@ -47,30 +47,48 @@ class NeutronInterfaceTestCase(db_base.DbTestCase):
'mac_address': '52:54:00:cf:2d:32'}
def test_init_incorrect_provisioning_net(self):
self.config(provisioning_network_uuid=None, group='neutron')
self.config(provisioning_network=None, group='neutron')
self.assertRaises(exception.DriverLoadError, neutron.NeutronNetwork)
self.config(provisioning_network_uuid=uuidutils.generate_uuid(),
self.config(provisioning_network=uuidutils.generate_uuid(),
group='neutron')
self.config(cleaning_network_uuid='asdf', group='neutron')
self.config(cleaning_network=None, group='neutron')
self.assertRaises(exception.DriverLoadError, neutron.NeutronNetwork)
@mock.patch.object(neutron_common, 'validate_network', autospec=True)
def test_validate(self, validate_mock):
with task_manager.acquire(self.context, self.node.id) as task:
self.interface.validate(task)
self.assertEqual([mock.call(CONF.neutron.cleaning_network,
'cleaning network'),
mock.call(CONF.neutron.provisioning_network,
'provisioning network')],
validate_mock.call_args_list)
@mock.patch.object(neutron_common, 'validate_network',
side_effect=lambda n, t: n)
@mock.patch.object(neutron_common, 'rollback_ports')
@mock.patch.object(neutron_common, 'add_ports_to_network')
def test_add_provisioning_network(self, add_ports_mock, rollback_mock):
def test_add_provisioning_network(self, add_ports_mock, rollback_mock,
validate_mock):
self.port.internal_info = {'provisioning_vif_port_id': 'vif-port-id'}
self.port.save()
add_ports_mock.return_value = {self.port.uuid: self.neutron_port['id']}
with task_manager.acquire(self.context, self.node.id) as task:
self.interface.add_provisioning_network(task)
rollback_mock.assert_called_once_with(
task, CONF.neutron.provisioning_network_uuid)
task, CONF.neutron.provisioning_network)
add_ports_mock.assert_called_once_with(
task, CONF.neutron.provisioning_network_uuid,
task, CONF.neutron.provisioning_network,
security_groups=[])
validate_mock.assert_called_once_with(
CONF.neutron.provisioning_network,
'provisioning network')
self.port.refresh()
self.assertEqual(self.neutron_port['id'],
self.port.internal_info['provisioning_vif_port_id'])
@mock.patch.object(neutron_common, 'validate_network',
lambda n, t: n)
@mock.patch.object(neutron_common, 'rollback_ports')
@mock.patch.object(neutron_common, 'add_ports_to_network')
def test_add_provisioning_network_with_sg(self, add_ports_mock,
@ -85,39 +103,53 @@ class NeutronInterfaceTestCase(db_base.DbTestCase):
with task_manager.acquire(self.context, self.node.id) as task:
self.interface.add_provisioning_network(task)
rollback_mock.assert_called_once_with(
task, CONF.neutron.provisioning_network_uuid)
task, CONF.neutron.provisioning_network)
add_ports_mock.assert_called_once_with(
task, CONF.neutron.provisioning_network_uuid,
task, CONF.neutron.provisioning_network,
security_groups=(
CONF.neutron.provisioning_network_security_groups))
self.port.refresh()
self.assertEqual(self.neutron_port['id'],
self.port.internal_info['provisioning_vif_port_id'])
@mock.patch.object(neutron_common, 'validate_network',
side_effect=lambda n, t: n)
@mock.patch.object(neutron_common, 'remove_ports_from_network')
def test_remove_provisioning_network(self, remove_ports_mock):
def test_remove_provisioning_network(self, remove_ports_mock,
validate_mock):
self.port.internal_info = {'provisioning_vif_port_id': 'vif-port-id'}
self.port.save()
with task_manager.acquire(self.context, self.node.id) as task:
self.interface.remove_provisioning_network(task)
remove_ports_mock.assert_called_once_with(
task, CONF.neutron.provisioning_network_uuid)
task, CONF.neutron.provisioning_network)
validate_mock.assert_called_once_with(
CONF.neutron.provisioning_network,
'provisioning network')
self.port.refresh()
self.assertNotIn('provisioning_vif_port_id', self.port.internal_info)
@mock.patch.object(neutron_common, 'validate_network',
side_effect=lambda n, t: n)
@mock.patch.object(neutron_common, 'rollback_ports')
@mock.patch.object(neutron_common, 'add_ports_to_network')
def test_add_cleaning_network(self, add_ports_mock, rollback_mock):
def test_add_cleaning_network(self, add_ports_mock, rollback_mock,
validate_mock):
add_ports_mock.return_value = {self.port.uuid: self.neutron_port['id']}
with task_manager.acquire(self.context, self.node.id) as task:
res = self.interface.add_cleaning_network(task)
rollback_mock.assert_called_once_with(
task, CONF.neutron.cleaning_network_uuid)
task, CONF.neutron.cleaning_network)
self.assertEqual(res, add_ports_mock.return_value)
validate_mock.assert_called_once_with(
CONF.neutron.cleaning_network,
'cleaning network')
self.port.refresh()
self.assertEqual(self.neutron_port['id'],
self.port.internal_info['cleaning_vif_port_id'])
@mock.patch.object(neutron_common, 'validate_network',
lambda n, t: n)
@mock.patch.object(neutron_common, 'rollback_ports')
@mock.patch.object(neutron_common, 'add_ports_to_network')
def test_add_cleaning_network_with_sg(self, add_ports_mock, rollback_mock):
@ -129,23 +161,29 @@ class NeutronInterfaceTestCase(db_base.DbTestCase):
with task_manager.acquire(self.context, self.node.id) as task:
res = self.interface.add_cleaning_network(task)
add_ports_mock.assert_called_once_with(
task, CONF.neutron.cleaning_network_uuid,
task, CONF.neutron.cleaning_network,
security_groups=CONF.neutron.cleaning_network_security_groups)
rollback_mock.assert_called_once_with(
task, CONF.neutron.cleaning_network_uuid)
task, CONF.neutron.cleaning_network)
self.assertEqual(res, add_ports_mock.return_value)
self.port.refresh()
self.assertEqual(self.neutron_port['id'],
self.port.internal_info['cleaning_vif_port_id'])
@mock.patch.object(neutron_common, 'validate_network',
side_effect=lambda n, t: n)
@mock.patch.object(neutron_common, 'remove_ports_from_network')
def test_remove_cleaning_network(self, remove_ports_mock):
def test_remove_cleaning_network(self, remove_ports_mock,
validate_mock):
self.port.internal_info = {'cleaning_vif_port_id': 'vif-port-id'}
self.port.save()
with task_manager.acquire(self.context, self.node.id) as task:
self.interface.remove_cleaning_network(task)
remove_ports_mock.assert_called_once_with(
task, CONF.neutron.cleaning_network_uuid)
task, CONF.neutron.cleaning_network)
validate_mock.assert_called_once_with(
CONF.neutron.cleaning_network,
'cleaning network')
self.port.refresh()
self.assertNotIn('cleaning_vif_port_id', self.port.internal_info)

View File

@ -0,0 +1,11 @@
---
features:
- Names can now be used instead of UUIDs for "cleaning_network" and
"provisioning_network" options (former "cleaning_network_uuid" and
"provisioning_network_uuid"). Care has to be taken to ensure that the
names are unique among all networks in this case. Note that mapping between
a name and a UUID is cached for the lifetime of the conductor.
deprecations:
- Configuration options "[neutron]cleaning_network_uuid" and
"[neutron]provisioning_network_uuid" were deprecated in favor of new
"[neutron]cleaning_network" and "[neutron]provisioning_network".