Allow setting {provisioning,cleaning,rescuing}_network in driver_info
These values have priority over ones defined in ironic.conf. Also modify validation code to only used network UUID cached on task.network if: 1. the requested XXX_network is UUID, not name 2. the requested XXX_network is the same as the cached one. Co-Authored-By: Dmitry Tantsur <dtantsur@redhat.com> Closes-Bug: #1614876 Change-Id: I4caec34d85304fe887bcc28b7528cceceb3acfe8
This commit is contained in:
parent
6ee297f7a5
commit
95d7e602e5
@ -40,17 +40,29 @@ provisioning will happen in a multi-tenant environment (which means using the
|
|||||||
default, otherwise ``noop`` is the default.
|
default, otherwise ``noop`` is the default.
|
||||||
|
|
||||||
#. Define a provider network in the Networking service, which we shall refer to
|
#. Define a provider network in the Networking service, which we shall refer to
|
||||||
as the "provisioning" network, and add it in the ``neutron`` section of the
|
as the "provisioning" network. Using the ``neutron`` network interface
|
||||||
ironic-conductor configuration file. Using the ``neutron`` network interface
|
|
||||||
requires that ``provisioning_network`` and ``cleaning_network``
|
requires that ``provisioning_network`` and ``cleaning_network``
|
||||||
configuration options are set to valid identifiers (UUID or name) of
|
configuration options are set to valid identifiers (UUID or name) of
|
||||||
networks in the Networking service. If these options are not set correctly,
|
networks in the Networking service. If these options are not set correctly,
|
||||||
cleaning or provisioning will fail to start::
|
cleaning or provisioning will fail to start. There are two ways to set these
|
||||||
|
values:
|
||||||
|
|
||||||
[neutron]
|
- Under the ``neutron`` section of ironic configuration file:
|
||||||
...
|
|
||||||
cleaning_network=$CLEAN_UUID_OR_NAME
|
.. code-block:: ini
|
||||||
provisioning_network=$PROVISION_UUID_OR_NAME
|
|
||||||
|
[neutron]
|
||||||
|
cleaning_network = $CLEAN_UUID_OR_NAME
|
||||||
|
provisioning_network = $PROVISION_UUID_OR_NAME
|
||||||
|
|
||||||
|
- Under ``provisioning_network`` and ``cleaning_network`` keys of the node's
|
||||||
|
``driver_info`` field as ``driver_info['provisioning_network']`` and
|
||||||
|
``driver_info['cleaning_network']`` respectively.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
If these ``provisioning_network`` and ``cleaning_network`` values are
|
||||||
|
not specified in node's `driver_info` then ironic falls back to the
|
||||||
|
configuration in the ``neutron`` section.
|
||||||
|
|
||||||
Please refer to :doc:`configure-cleaning` for more information about
|
Please refer to :doc:`configure-cleaning` for more information about
|
||||||
cleaning.
|
cleaning.
|
||||||
|
@ -249,6 +249,20 @@ and may be combined if desired.
|
|||||||
|
|
||||||
See :doc:`configure-glance-images` for details.
|
See :doc:`configure-glance-images` for details.
|
||||||
|
|
||||||
|
#. Optionally you can specify the provisioning and/or cleaning network UUID
|
||||||
|
or name in the node's ``driver_info``. The ``neutron`` network interface
|
||||||
|
requires both ``provisioning_network`` and ``cleaning_network``, while
|
||||||
|
the ``flat`` network interface requires the ``cleaning_network`` to be set
|
||||||
|
either in the configuration or on the nodes. For example:
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
$ openstack baremetal node set $NODE_UUID \
|
||||||
|
--driver-info cleaning_network=$CLEAN_UUID_OR_NAME \
|
||||||
|
--driver-info provisioning_network=$PROVISION_UUID_OR_NAME
|
||||||
|
|
||||||
|
See :doc:`configure-tenant-networks` for details.
|
||||||
|
|
||||||
#. You must also inform the Bare Metal service of the network interface cards
|
#. You must also inform the Bare Metal service of the network interface cards
|
||||||
which are part of the node by creating a port with each NIC's MAC address.
|
which are part of the node by creating a port with each NIC's MAC address.
|
||||||
These MAC addresses are passed to the Networking service during instance
|
These MAC addresses are passed to the Networking service during instance
|
||||||
|
@ -568,25 +568,46 @@ class NeutronNetworkInterfaceMixin(object):
|
|||||||
_provisioning_network_uuid = None
|
_provisioning_network_uuid = None
|
||||||
_rescuing_network_uuid = None
|
_rescuing_network_uuid = None
|
||||||
|
|
||||||
def get_cleaning_network_uuid(self, context=None):
|
def get_cleaning_network_uuid(self, task):
|
||||||
if self._cleaning_network_uuid is None:
|
cleaning_network = (
|
||||||
|
task.node.driver_info.get('cleaning_network') or
|
||||||
|
CONF.neutron.cleaning_network
|
||||||
|
)
|
||||||
|
# NOTE(dtantsur): if the last used cleaning network UUID is
|
||||||
|
# the same as the new one, we can skip validating it.
|
||||||
|
if (self._cleaning_network_uuid is None or
|
||||||
|
self._cleaning_network_uuid != cleaning_network):
|
||||||
self._cleaning_network_uuid = validate_network(
|
self._cleaning_network_uuid = validate_network(
|
||||||
CONF.neutron.cleaning_network,
|
cleaning_network, _('cleaning network'),
|
||||||
_('cleaning network'), context=context)
|
context=task.context)
|
||||||
return self._cleaning_network_uuid
|
return self._cleaning_network_uuid
|
||||||
|
|
||||||
def get_provisioning_network_uuid(self, context=None):
|
def get_provisioning_network_uuid(self, task):
|
||||||
if self._provisioning_network_uuid is None:
|
provisioning_network = (
|
||||||
|
task.node.driver_info.get('provisioning_network') or
|
||||||
|
CONF.neutron.provisioning_network
|
||||||
|
)
|
||||||
|
# NOTE(dtantsur): if the last used provisioning network UUID is
|
||||||
|
# the same as the new one, we can skip validating it.
|
||||||
|
if (self._provisioning_network_uuid is None or
|
||||||
|
self._provisioning_network_uuid != provisioning_network):
|
||||||
self._provisioning_network_uuid = validate_network(
|
self._provisioning_network_uuid = validate_network(
|
||||||
CONF.neutron.provisioning_network,
|
provisioning_network, _('provisioning network'),
|
||||||
_('provisioning network'), context=context)
|
context=task.context)
|
||||||
return self._provisioning_network_uuid
|
return self._provisioning_network_uuid
|
||||||
|
|
||||||
def get_rescuing_network_uuid(self, context=None):
|
# TODO(stendulker): FlatNetwork should not use this method.
|
||||||
# TODO(stendulker): FlatNetwork should not use this method.
|
# FlatNetwork uses tenant network for rescue operation.
|
||||||
# FlatNetwork uses tenant network for rescue operation.
|
def get_rescuing_network_uuid(self, task):
|
||||||
if self._rescuing_network_uuid is None:
|
rescuing_network = (
|
||||||
|
task.node.driver_info.get('rescuing_network') or
|
||||||
|
CONF.neutron.rescuing_network
|
||||||
|
)
|
||||||
|
# NOTE(dtantsur): if the last used provisioning network UUID is
|
||||||
|
# the same as the new one, we can skip validating it.
|
||||||
|
if (self._rescuing_network_uuid is None or
|
||||||
|
self._rescuing_network_uuid != rescuing_network):
|
||||||
self._rescuing_network_uuid = validate_network(
|
self._rescuing_network_uuid = validate_network(
|
||||||
CONF.neutron.rescuing_network,
|
rescuing_network, _('rescuing network'),
|
||||||
_('rescuing network'), context=context)
|
context=task.context)
|
||||||
return self._rescuing_network_uuid
|
return self._rescuing_network_uuid
|
||||||
|
@ -51,7 +51,7 @@ class FlatNetwork(common.NeutronVIFPortIDMixin,
|
|||||||
is invalid.
|
is invalid.
|
||||||
:raises: MissingParameterValue, if some parameters are missing.
|
:raises: MissingParameterValue, if some parameters are missing.
|
||||||
"""
|
"""
|
||||||
self.get_cleaning_network_uuid(context=task.context)
|
self.get_cleaning_network_uuid(task)
|
||||||
|
|
||||||
def add_provisioning_network(self, task):
|
def add_provisioning_network(self, task):
|
||||||
"""Add the provisioning network to a node.
|
"""Add the provisioning network to a node.
|
||||||
@ -117,11 +117,10 @@ class FlatNetwork(common.NeutronVIFPortIDMixin,
|
|||||||
"""
|
"""
|
||||||
# If we have left over ports from a previous cleaning, remove them
|
# If we have left over ports from a previous cleaning, remove them
|
||||||
neutron.rollback_ports(task,
|
neutron.rollback_ports(task,
|
||||||
self.get_cleaning_network_uuid(
|
self.get_cleaning_network_uuid(task))
|
||||||
context=task.context))
|
|
||||||
LOG.info('Adding cleaning network to node %s', task.node.uuid)
|
LOG.info('Adding cleaning network to node %s', task.node.uuid)
|
||||||
vifs = neutron.add_ports_to_network(
|
vifs = neutron.add_ports_to_network(
|
||||||
task, self.get_cleaning_network_uuid(context=task.context))
|
task, self.get_cleaning_network_uuid(task))
|
||||||
for port in task.ports:
|
for port in task.ports:
|
||||||
if port.uuid in vifs:
|
if port.uuid in vifs:
|
||||||
internal_info = port.internal_info
|
internal_info = port.internal_info
|
||||||
@ -139,7 +138,7 @@ class FlatNetwork(common.NeutronVIFPortIDMixin,
|
|||||||
LOG.info('Removing ports from cleaning network for node %s',
|
LOG.info('Removing ports from cleaning network for node %s',
|
||||||
task.node.uuid)
|
task.node.uuid)
|
||||||
neutron.remove_ports_from_network(
|
neutron.remove_ports_from_network(
|
||||||
task, self.get_cleaning_network_uuid(context=task.context))
|
task, self.get_cleaning_network_uuid(task))
|
||||||
for port in task.ports:
|
for port in task.ports:
|
||||||
if 'cleaning_vif_port_id' in port.internal_info:
|
if 'cleaning_vif_port_id' in port.internal_info:
|
||||||
internal_info = port.internal_info
|
internal_info = port.internal_info
|
||||||
|
@ -57,8 +57,8 @@ class NeutronNetwork(common.NeutronVIFPortIDMixin,
|
|||||||
is invalid.
|
is invalid.
|
||||||
:raises: MissingParameterValue, if some parameters are missing.
|
:raises: MissingParameterValue, if some parameters are missing.
|
||||||
"""
|
"""
|
||||||
self.get_cleaning_network_uuid(context=task.context)
|
self.get_cleaning_network_uuid(task)
|
||||||
self.get_provisioning_network_uuid(context=task.context)
|
self.get_provisioning_network_uuid(task)
|
||||||
|
|
||||||
def add_provisioning_network(self, task):
|
def add_provisioning_network(self, task):
|
||||||
"""Add the provisioning network to a node.
|
"""Add the provisioning network to a node.
|
||||||
@ -69,11 +69,11 @@ class NeutronNetwork(common.NeutronVIFPortIDMixin,
|
|||||||
# If we have left over ports from a previous provision attempt, remove
|
# If we have left over ports from a previous provision attempt, remove
|
||||||
# them
|
# them
|
||||||
neutron.rollback_ports(
|
neutron.rollback_ports(
|
||||||
task, self.get_provisioning_network_uuid(context=task.context))
|
task, self.get_provisioning_network_uuid(task))
|
||||||
LOG.info('Adding provisioning network to node %s',
|
LOG.info('Adding provisioning network to node %s',
|
||||||
task.node.uuid)
|
task.node.uuid)
|
||||||
vifs = neutron.add_ports_to_network(
|
vifs = neutron.add_ports_to_network(
|
||||||
task, self.get_provisioning_network_uuid(context=task.context),
|
task, self.get_provisioning_network_uuid(task),
|
||||||
security_groups=CONF.neutron.provisioning_network_security_groups)
|
security_groups=CONF.neutron.provisioning_network_security_groups)
|
||||||
for port in task.ports:
|
for port in task.ports:
|
||||||
if port.uuid in vifs:
|
if port.uuid in vifs:
|
||||||
@ -91,7 +91,7 @@ class NeutronNetwork(common.NeutronVIFPortIDMixin,
|
|||||||
LOG.info('Removing provisioning network from node %s',
|
LOG.info('Removing provisioning network from node %s',
|
||||||
task.node.uuid)
|
task.node.uuid)
|
||||||
neutron.remove_ports_from_network(
|
neutron.remove_ports_from_network(
|
||||||
task, self.get_provisioning_network_uuid(context=task.context))
|
task, self.get_provisioning_network_uuid(task))
|
||||||
for port in task.ports:
|
for port in task.ports:
|
||||||
if 'provisioning_vif_port_id' in port.internal_info:
|
if 'provisioning_vif_port_id' in port.internal_info:
|
||||||
internal_info = port.internal_info
|
internal_info = port.internal_info
|
||||||
@ -107,13 +107,12 @@ class NeutronNetwork(common.NeutronVIFPortIDMixin,
|
|||||||
:returns: a dictionary in the form {port.uuid: neutron_port['id']}
|
:returns: a dictionary in the form {port.uuid: neutron_port['id']}
|
||||||
"""
|
"""
|
||||||
# If we have left over ports from a previous cleaning, remove them
|
# If we have left over ports from a previous cleaning, remove them
|
||||||
neutron.rollback_ports(task, self.get_cleaning_network_uuid(
|
neutron.rollback_ports(task, self.get_cleaning_network_uuid(task))
|
||||||
context=task.context))
|
|
||||||
LOG.info('Adding cleaning network to node %s', task.node.uuid)
|
LOG.info('Adding cleaning network to node %s', task.node.uuid)
|
||||||
security_groups = CONF.neutron.cleaning_network_security_groups
|
security_groups = CONF.neutron.cleaning_network_security_groups
|
||||||
vifs = neutron.add_ports_to_network(
|
vifs = neutron.add_ports_to_network(
|
||||||
task,
|
task,
|
||||||
self.get_cleaning_network_uuid(context=task.context),
|
self.get_cleaning_network_uuid(task),
|
||||||
security_groups=security_groups)
|
security_groups=security_groups)
|
||||||
for port in task.ports:
|
for port in task.ports:
|
||||||
if port.uuid in vifs:
|
if port.uuid in vifs:
|
||||||
@ -132,7 +131,7 @@ class NeutronNetwork(common.NeutronVIFPortIDMixin,
|
|||||||
LOG.info('Removing cleaning network from node %s',
|
LOG.info('Removing cleaning network from node %s',
|
||||||
task.node.uuid)
|
task.node.uuid)
|
||||||
neutron.remove_ports_from_network(
|
neutron.remove_ports_from_network(
|
||||||
task, self.get_cleaning_network_uuid(context=task.context))
|
task, self.get_cleaning_network_uuid(task))
|
||||||
for port in task.ports:
|
for port in task.ports:
|
||||||
if 'cleaning_vif_port_id' in port.internal_info:
|
if 'cleaning_vif_port_id' in port.internal_info:
|
||||||
internal_info = port.internal_info
|
internal_info = port.internal_info
|
||||||
@ -147,13 +146,12 @@ class NeutronNetwork(common.NeutronVIFPortIDMixin,
|
|||||||
:returns: a dictionary in the form {port.uuid: neutron_port['id']}
|
:returns: a dictionary in the form {port.uuid: neutron_port['id']}
|
||||||
"""
|
"""
|
||||||
# If we have left over ports from a previous rescue, remove them
|
# If we have left over ports from a previous rescue, remove them
|
||||||
neutron.rollback_ports(task, self.get_rescuing_network_uuid(
|
neutron.rollback_ports(task, self.get_rescuing_network_uuid(task))
|
||||||
context=task.context))
|
|
||||||
LOG.info('Adding rescuing network to node %s', task.node.uuid)
|
LOG.info('Adding rescuing network to node %s', task.node.uuid)
|
||||||
security_groups = CONF.neutron.rescuing_network_security_groups
|
security_groups = CONF.neutron.rescuing_network_security_groups
|
||||||
vifs = neutron.add_ports_to_network(
|
vifs = neutron.add_ports_to_network(
|
||||||
task,
|
task,
|
||||||
self.get_rescuing_network_uuid(context=task.context),
|
self.get_rescuing_network_uuid(task),
|
||||||
security_groups=security_groups)
|
security_groups=security_groups)
|
||||||
for port in task.ports:
|
for port in task.ports:
|
||||||
if port.uuid in vifs:
|
if port.uuid in vifs:
|
||||||
@ -172,7 +170,7 @@ class NeutronNetwork(common.NeutronVIFPortIDMixin,
|
|||||||
LOG.info('Removing rescuing network from node %s',
|
LOG.info('Removing rescuing network from node %s',
|
||||||
task.node.uuid)
|
task.node.uuid)
|
||||||
neutron.remove_ports_from_network(
|
neutron.remove_ports_from_network(
|
||||||
task, self.get_rescuing_network_uuid(context=task.context))
|
task, self.get_rescuing_network_uuid(task))
|
||||||
for port in task.ports:
|
for port in task.ports:
|
||||||
if 'rescuing_vif_port_id' in port.internal_info:
|
if 'rescuing_vif_port_id' in port.internal_info:
|
||||||
internal_info = port.internal_info
|
internal_info = port.internal_info
|
||||||
|
@ -81,6 +81,19 @@ class TestFlatInterface(db_base.DbTestCase):
|
|||||||
CONF.neutron.cleaning_network,
|
CONF.neutron.cleaning_network,
|
||||||
'cleaning network', context=task.context)
|
'cleaning network', context=task.context)
|
||||||
|
|
||||||
|
@mock.patch.object(neutron, 'validate_network', autospec=True)
|
||||||
|
def test_validate_from_node(self, validate_mock):
|
||||||
|
cleaning_network_uuid = '3aea0de6-4b92-44da-9aa0-52d134c83fdf'
|
||||||
|
driver_info = self.node.driver_info
|
||||||
|
driver_info['cleaning_network'] = cleaning_network_uuid
|
||||||
|
self.node.driver_info = driver_info
|
||||||
|
self.node.save()
|
||||||
|
with task_manager.acquire(self.context, self.node.id) as task:
|
||||||
|
self.interface.validate(task)
|
||||||
|
validate_mock.assert_called_once_with(
|
||||||
|
cleaning_network_uuid,
|
||||||
|
'cleaning network', context=task.context)
|
||||||
|
|
||||||
@mock.patch.object(neutron, 'validate_network',
|
@mock.patch.object(neutron, 'validate_network',
|
||||||
side_effect=lambda n, t, context=None: n)
|
side_effect=lambda n, t, context=None: n)
|
||||||
@mock.patch.object(neutron, 'add_ports_to_network')
|
@mock.patch.object(neutron, 'add_ports_to_network')
|
||||||
@ -101,6 +114,32 @@ class TestFlatInterface(db_base.DbTestCase):
|
|||||||
self.assertEqual('vif-port-id',
|
self.assertEqual('vif-port-id',
|
||||||
self.port.internal_info['cleaning_vif_port_id'])
|
self.port.internal_info['cleaning_vif_port_id'])
|
||||||
|
|
||||||
|
@mock.patch.object(neutron, 'validate_network',
|
||||||
|
side_effect=lambda n, t, context=None: n)
|
||||||
|
@mock.patch.object(neutron, 'add_ports_to_network')
|
||||||
|
@mock.patch.object(neutron, 'rollback_ports')
|
||||||
|
def test_add_cleaning_network_from_node(self, rollback_mock, add_mock,
|
||||||
|
validate_mock):
|
||||||
|
add_mock.return_value = {self.port.uuid: 'vif-port-id'}
|
||||||
|
# Make sure that changing the network UUID works
|
||||||
|
for cleaning_network_uuid in ['3aea0de6-4b92-44da-9aa0-52d134c83fdf',
|
||||||
|
'438be438-6aae-4fb1-bbcb-613ad7a38286']:
|
||||||
|
driver_info = self.node.driver_info
|
||||||
|
driver_info['cleaning_network'] = cleaning_network_uuid
|
||||||
|
self.node.driver_info = driver_info
|
||||||
|
self.node.save()
|
||||||
|
with task_manager.acquire(self.context, self.node.id) as task:
|
||||||
|
self.interface.add_cleaning_network(task)
|
||||||
|
rollback_mock.assert_called_with(
|
||||||
|
task, cleaning_network_uuid)
|
||||||
|
add_mock.assert_called_with(task, cleaning_network_uuid)
|
||||||
|
validate_mock.assert_called_with(
|
||||||
|
cleaning_network_uuid,
|
||||||
|
'cleaning network', context=task.context)
|
||||||
|
self.port.refresh()
|
||||||
|
self.assertEqual('vif-port-id',
|
||||||
|
self.port.internal_info['cleaning_vif_port_id'])
|
||||||
|
|
||||||
@mock.patch.object(neutron, 'validate_network',
|
@mock.patch.object(neutron, 'validate_network',
|
||||||
side_effect=lambda n, t, context=None: n)
|
side_effect=lambda n, t, context=None: n)
|
||||||
@mock.patch.object(neutron, 'remove_ports_from_network')
|
@mock.patch.object(neutron, 'remove_ports_from_network')
|
||||||
@ -115,6 +154,25 @@ class TestFlatInterface(db_base.DbTestCase):
|
|||||||
self.port.refresh()
|
self.port.refresh()
|
||||||
self.assertNotIn('cleaning_vif_port_id', self.port.internal_info)
|
self.assertNotIn('cleaning_vif_port_id', self.port.internal_info)
|
||||||
|
|
||||||
|
@mock.patch.object(neutron, 'validate_network',
|
||||||
|
side_effect=lambda n, t, context=None: n)
|
||||||
|
@mock.patch.object(neutron, 'remove_ports_from_network')
|
||||||
|
def test_remove_cleaning_network_from_node(self, remove_mock,
|
||||||
|
validate_mock):
|
||||||
|
cleaning_network_uuid = '3aea0de6-4b92-44da-9aa0-52d134c83fdf'
|
||||||
|
driver_info = self.node.driver_info
|
||||||
|
driver_info['cleaning_network'] = cleaning_network_uuid
|
||||||
|
self.node.driver_info = driver_info
|
||||||
|
self.node.save()
|
||||||
|
with task_manager.acquire(self.context, self.node.id) as task:
|
||||||
|
self.interface.remove_cleaning_network(task)
|
||||||
|
remove_mock.assert_called_once_with(task, cleaning_network_uuid)
|
||||||
|
validate_mock.assert_called_once_with(
|
||||||
|
cleaning_network_uuid,
|
||||||
|
'cleaning network', context=task.context)
|
||||||
|
self.port.refresh()
|
||||||
|
self.assertNotIn('cleaning_vif_port_id', self.port.internal_info)
|
||||||
|
|
||||||
@mock.patch.object(neutron, 'get_client')
|
@mock.patch.object(neutron, 'get_client')
|
||||||
def test_add_provisioning_network_set_binding_host_id(
|
def test_add_provisioning_network_set_binding_host_id(
|
||||||
self, client_mock):
|
self, client_mock):
|
||||||
|
@ -127,6 +127,37 @@ class NeutronInterfaceTestCase(db_base.DbTestCase):
|
|||||||
self.assertEqual(self.neutron_port['id'],
|
self.assertEqual(self.neutron_port['id'],
|
||||||
self.port.internal_info['provisioning_vif_port_id'])
|
self.port.internal_info['provisioning_vif_port_id'])
|
||||||
|
|
||||||
|
@mock.patch.object(neutron_common, 'validate_network',
|
||||||
|
side_effect=lambda n, t, context=None: n)
|
||||||
|
@mock.patch.object(neutron_common, 'rollback_ports')
|
||||||
|
@mock.patch.object(neutron_common, 'add_ports_to_network')
|
||||||
|
def test_add_provisioning_network_from_node(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']}
|
||||||
|
# Make sure that changing the network UUID works
|
||||||
|
for provisioning_network_uuid in [
|
||||||
|
'3aea0de6-4b92-44da-9aa0-52d134c83fdf',
|
||||||
|
'438be438-6aae-4fb1-bbcb-613ad7a38286']:
|
||||||
|
driver_info = self.node.driver_info
|
||||||
|
driver_info['provisioning_network'] = provisioning_network_uuid
|
||||||
|
self.node.driver_info = driver_info
|
||||||
|
self.node.save()
|
||||||
|
with task_manager.acquire(self.context, self.node.id) as task:
|
||||||
|
self.interface.add_provisioning_network(task)
|
||||||
|
rollback_mock.assert_called_with(
|
||||||
|
task, provisioning_network_uuid)
|
||||||
|
add_ports_mock.assert_called_with(
|
||||||
|
task, provisioning_network_uuid,
|
||||||
|
security_groups=[])
|
||||||
|
validate_mock.assert_called_with(
|
||||||
|
provisioning_network_uuid,
|
||||||
|
'provisioning network', context=task.context)
|
||||||
|
self.port.refresh()
|
||||||
|
self.assertEqual(self.neutron_port['id'],
|
||||||
|
self.port.internal_info['provisioning_vif_port_id'])
|
||||||
|
|
||||||
@mock.patch.object(neutron_common, 'validate_network',
|
@mock.patch.object(neutron_common, 'validate_network',
|
||||||
lambda n, t, context=None: n)
|
lambda n, t, context=None: n)
|
||||||
@mock.patch.object(neutron_common, 'rollback_ports')
|
@mock.patch.object(neutron_common, 'rollback_ports')
|
||||||
@ -169,6 +200,28 @@ class NeutronInterfaceTestCase(db_base.DbTestCase):
|
|||||||
self.port.refresh()
|
self.port.refresh()
|
||||||
self.assertNotIn('provisioning_vif_port_id', self.port.internal_info)
|
self.assertNotIn('provisioning_vif_port_id', self.port.internal_info)
|
||||||
|
|
||||||
|
@mock.patch.object(neutron_common, 'validate_network',
|
||||||
|
side_effect=lambda n, t, context=None: n)
|
||||||
|
@mock.patch.object(neutron_common, 'remove_ports_from_network')
|
||||||
|
def test_remove_provisioning_network_from_node(self, remove_ports_mock,
|
||||||
|
validate_mock):
|
||||||
|
self.port.internal_info = {'provisioning_vif_port_id': 'vif-port-id'}
|
||||||
|
self.port.save()
|
||||||
|
provisioning_network_uuid = '3aea0de6-4b92-44da-9aa0-52d134c83f9c'
|
||||||
|
driver_info = self.node.driver_info
|
||||||
|
driver_info['provisioning_network'] = provisioning_network_uuid
|
||||||
|
self.node.driver_info = driver_info
|
||||||
|
self.node.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, provisioning_network_uuid)
|
||||||
|
validate_mock.assert_called_once_with(
|
||||||
|
provisioning_network_uuid,
|
||||||
|
'provisioning network', context=task.context)
|
||||||
|
self.port.refresh()
|
||||||
|
self.assertNotIn('provisioning_vif_port_id', self.port.internal_info)
|
||||||
|
|
||||||
@mock.patch.object(neutron_common, 'validate_network',
|
@mock.patch.object(neutron_common, 'validate_network',
|
||||||
side_effect=lambda n, t, context=None: n)
|
side_effect=lambda n, t, context=None: n)
|
||||||
@mock.patch.object(neutron_common, 'rollback_ports')
|
@mock.patch.object(neutron_common, 'rollback_ports')
|
||||||
@ -188,6 +241,31 @@ class NeutronInterfaceTestCase(db_base.DbTestCase):
|
|||||||
self.assertEqual(self.neutron_port['id'],
|
self.assertEqual(self.neutron_port['id'],
|
||||||
self.port.internal_info['cleaning_vif_port_id'])
|
self.port.internal_info['cleaning_vif_port_id'])
|
||||||
|
|
||||||
|
@mock.patch.object(neutron_common, 'validate_network',
|
||||||
|
side_effect=lambda n, t, context=None: n)
|
||||||
|
@mock.patch.object(neutron_common, 'rollback_ports')
|
||||||
|
@mock.patch.object(neutron_common, 'add_ports_to_network')
|
||||||
|
def test_add_cleaning_network_from_node(self, add_ports_mock,
|
||||||
|
rollback_mock, validate_mock):
|
||||||
|
add_ports_mock.return_value = {self.port.uuid: self.neutron_port['id']}
|
||||||
|
# Make sure that changing the network UUID works
|
||||||
|
for cleaning_network_uuid in ['3aea0de6-4b92-44da-9aa0-52d134c83fdf',
|
||||||
|
'438be438-6aae-4fb1-bbcb-613ad7a38286']:
|
||||||
|
driver_info = self.node.driver_info
|
||||||
|
driver_info['cleaning_network'] = cleaning_network_uuid
|
||||||
|
self.node.driver_info = driver_info
|
||||||
|
self.node.save()
|
||||||
|
with task_manager.acquire(self.context, self.node.id) as task:
|
||||||
|
res = self.interface.add_cleaning_network(task)
|
||||||
|
rollback_mock.assert_called_with(task, cleaning_network_uuid)
|
||||||
|
self.assertEqual(res, add_ports_mock.return_value)
|
||||||
|
validate_mock.assert_called_with(
|
||||||
|
cleaning_network_uuid,
|
||||||
|
'cleaning network', context=task.context)
|
||||||
|
self.port.refresh()
|
||||||
|
self.assertEqual(self.neutron_port['id'],
|
||||||
|
self.port.internal_info['cleaning_vif_port_id'])
|
||||||
|
|
||||||
@mock.patch.object(neutron_common, 'validate_network',
|
@mock.patch.object(neutron_common, 'validate_network',
|
||||||
lambda n, t, context=None: n)
|
lambda n, t, context=None: n)
|
||||||
@mock.patch.object(neutron_common, 'rollback_ports')
|
@mock.patch.object(neutron_common, 'rollback_ports')
|
||||||
@ -227,6 +305,28 @@ class NeutronInterfaceTestCase(db_base.DbTestCase):
|
|||||||
self.port.refresh()
|
self.port.refresh()
|
||||||
self.assertNotIn('cleaning_vif_port_id', self.port.internal_info)
|
self.assertNotIn('cleaning_vif_port_id', self.port.internal_info)
|
||||||
|
|
||||||
|
@mock.patch.object(neutron_common, 'validate_network',
|
||||||
|
side_effect=lambda n, t, context=None: n)
|
||||||
|
@mock.patch.object(neutron_common, 'remove_ports_from_network')
|
||||||
|
def test_remove_cleaning_network_from_node(self, remove_ports_mock,
|
||||||
|
validate_mock):
|
||||||
|
self.port.internal_info = {'cleaning_vif_port_id': 'vif-port-id'}
|
||||||
|
self.port.save()
|
||||||
|
cleaning_network_uuid = '3aea0de6-4b92-44da-9aa0-52d134c83fdf'
|
||||||
|
driver_info = self.node.driver_info
|
||||||
|
driver_info['cleaning_network'] = cleaning_network_uuid
|
||||||
|
self.node.driver_info = driver_info
|
||||||
|
self.node.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, cleaning_network_uuid)
|
||||||
|
validate_mock.assert_called_once_with(
|
||||||
|
cleaning_network_uuid,
|
||||||
|
'cleaning network', context=task.context)
|
||||||
|
self.port.refresh()
|
||||||
|
self.assertNotIn('cleaning_vif_port_id', self.port.internal_info)
|
||||||
|
|
||||||
@mock.patch.object(neutron_common, 'validate_network',
|
@mock.patch.object(neutron_common, 'validate_network',
|
||||||
side_effect=lambda n, t, context=None: n)
|
side_effect=lambda n, t, context=None: n)
|
||||||
@mock.patch.object(neutron_common, 'rollback_ports')
|
@mock.patch.object(neutron_common, 'rollback_ports')
|
||||||
@ -258,6 +358,42 @@ class NeutronInterfaceTestCase(db_base.DbTestCase):
|
|||||||
other_port.internal_info['rescuing_vif_port_id'])
|
other_port.internal_info['rescuing_vif_port_id'])
|
||||||
self.assertNotIn('rescuing_vif_port_id', self.port.internal_info)
|
self.assertNotIn('rescuing_vif_port_id', self.port.internal_info)
|
||||||
|
|
||||||
|
@mock.patch.object(neutron_common, 'validate_network',
|
||||||
|
side_effect=lambda n, t, context=None: n)
|
||||||
|
@mock.patch.object(neutron_common, 'rollback_ports')
|
||||||
|
@mock.patch.object(neutron_common, 'add_ports_to_network')
|
||||||
|
def test_add_rescuing_network_from_node(self, add_ports_mock,
|
||||||
|
rollback_mock, validate_mock):
|
||||||
|
other_port = utils.create_test_port(
|
||||||
|
self.context, node_id=self.node.id,
|
||||||
|
address='52:54:00:cf:2d:33',
|
||||||
|
uuid=uuidutils.generate_uuid(),
|
||||||
|
extra={'vif_port_id': uuidutils.generate_uuid()})
|
||||||
|
neutron_other_port = {'id': uuidutils.generate_uuid(),
|
||||||
|
'mac_address': '52:54:00:cf:2d:33'}
|
||||||
|
add_ports_mock.return_value = {
|
||||||
|
other_port.uuid: neutron_other_port['id']}
|
||||||
|
rescuing_network_uuid = '3aea0de6-4b92-44da-9aa0-52d134c83fdf'
|
||||||
|
driver_info = self.node.driver_info
|
||||||
|
driver_info['rescuing_network'] = rescuing_network_uuid
|
||||||
|
self.node.driver_info = driver_info
|
||||||
|
self.node.save()
|
||||||
|
with task_manager.acquire(self.context, self.node.id) as task:
|
||||||
|
res = self.interface.add_rescuing_network(task)
|
||||||
|
add_ports_mock.assert_called_once_with(
|
||||||
|
task, rescuing_network_uuid,
|
||||||
|
security_groups=[])
|
||||||
|
rollback_mock.assert_called_once_with(
|
||||||
|
task, rescuing_network_uuid)
|
||||||
|
self.assertEqual(add_ports_mock.return_value, res)
|
||||||
|
validate_mock.assert_called_once_with(
|
||||||
|
rescuing_network_uuid,
|
||||||
|
'rescuing network', context=task.context)
|
||||||
|
other_port.refresh()
|
||||||
|
self.assertEqual(neutron_other_port['id'],
|
||||||
|
other_port.internal_info['rescuing_vif_port_id'])
|
||||||
|
self.assertNotIn('rescuing_vif_port_id', self.port.internal_info)
|
||||||
|
|
||||||
@mock.patch.object(neutron_common, 'validate_network',
|
@mock.patch.object(neutron_common, 'validate_network',
|
||||||
lambda n, t, context=None: n)
|
lambda n, t, context=None: n)
|
||||||
@mock.patch.object(neutron_common, 'rollback_ports')
|
@mock.patch.object(neutron_common, 'rollback_ports')
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Allows specifying the provisioning and cleaning networks on a node as
|
||||||
|
``driver_info['cleaning_network']`` and
|
||||||
|
``driver_info['provisioning_network']`` respectively. If these
|
||||||
|
values are defined in the node's driver_info at the time of
|
||||||
|
provisioning or cleaning the baremetal node, they will be used.
|
||||||
|
Otherwise, the configuration options ``cleaning_network`` and
|
||||||
|
``provisioning_network`` are used as before.
|
||||||
|
fixes:
|
||||||
|
- |
|
||||||
|
A network UUID for provisioning and cleaning network is no longer cached
|
||||||
|
locally if the requested network (either via node's ``driver_info`` or
|
||||||
|
via configuration options) is specified as a network name. Fixes the
|
||||||
|
situation when a network is re-created with the same name.
|
Loading…
Reference in New Issue
Block a user