Merge "Support names for {cleaning,provisioning}_network"
This commit is contained in:
commit
ff3a8f1d7f
@ -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 {
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 '
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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'],
|
||||
|
@ -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')
|
||||
|
@ -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:
|
||||
|
@ -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',
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
11
releasenotes/notes/net-names-b8a36aa30659ce2f.yaml
Normal file
11
releasenotes/notes/net-names-b8a36aa30659ce2f.yaml
Normal 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".
|
Loading…
x
Reference in New Issue
Block a user