Merge "Add option to protect available nodes from accidental deletion"
This commit is contained in:
commit
5d25189b13
@ -223,7 +223,7 @@ UPDATE_ALLOWED_STATES = (DEPLOYFAIL, INSPECTING, INSPECTFAIL, INSPECTWAIT,
|
||||
UNRESCUEFAIL)
|
||||
"""Transitional states in which we allow updating a node."""
|
||||
|
||||
DELETE_ALLOWED_STATES = (AVAILABLE, MANAGEABLE, ENROLL, ADOPTFAIL)
|
||||
DELETE_ALLOWED_STATES = (MANAGEABLE, ENROLL, ADOPTFAIL)
|
||||
"""States in which node deletion is allowed."""
|
||||
|
||||
STABLE_STATES = (ENROLL, MANAGEABLE, AVAILABLE, ACTIVE, ERROR, RESCUE)
|
||||
|
@ -2269,15 +2269,18 @@ class ConductorManager(base_manager.BaseConductorManager):
|
||||
# CLEANFAIL -> MANAGEABLE
|
||||
# INSPECTIONFAIL -> MANAGEABLE
|
||||
# DEPLOYFAIL -> DELETING
|
||||
delete_allowed_states = states.DELETE_ALLOWED_STATES
|
||||
if CONF.conductor.allow_deleting_available_nodes:
|
||||
delete_allowed_states += (states.AVAILABLE,)
|
||||
if (not node.maintenance
|
||||
and node.provision_state
|
||||
not in states.DELETE_ALLOWED_STATES):
|
||||
not in delete_allowed_states):
|
||||
msg = (_('Can not delete node "%(node)s" while it is in '
|
||||
'provision state "%(state)s". Valid provision states '
|
||||
'to perform deletion are: "%(valid_states)s", '
|
||||
'or set the node into maintenance mode') %
|
||||
{'node': node.uuid, 'state': node.provision_state,
|
||||
'valid_states': states.DELETE_ALLOWED_STATES})
|
||||
'valid_states': delete_allowed_states})
|
||||
raise exception.InvalidState(msg)
|
||||
if node.console_enabled:
|
||||
notify_utils.emit_console_notification(
|
||||
|
@ -199,6 +199,10 @@ opts = [
|
||||
'255 characters and is case insensitive. This '
|
||||
'conductor will only manage nodes with a matching '
|
||||
'"conductor_group" field set on the node.')),
|
||||
cfg.BoolOpt('allow_deleting_available_nodes',
|
||||
default=True,
|
||||
help=_('Allow deleting nodes which are in state '
|
||||
'\'available\'. Defaults to True.')),
|
||||
]
|
||||
|
||||
|
||||
|
@ -0,0 +1,12 @@
|
||||
---
|
||||
features:
|
||||
- Adds option 'allow_deleting_available_nodes' to control whether nodes in
|
||||
state 'available' should be deletable (which is and stays the default).
|
||||
Setting this option to False will remove 'available' from the list of
|
||||
states in which nodes can be deleted from ironic. It hence provides
|
||||
protection against accidental removal of nodes which are ready for
|
||||
allocation (and is meant as a safeguard for the operational effort to
|
||||
bring nodes into this state). For backwards compatibility reasons, the
|
||||
default value for this option is True. The other states in which nodes
|
||||
can be deleted from ironic ('manageable', 'enroll', and 'adoptfail')
|
||||
remain unchanged.
|
@ -5090,6 +5090,22 @@ class DestroyNodeTestCase(mgr_utils.ServiceSetUpMixin, db_base.DbTestCase):
|
||||
node.refresh()
|
||||
self.assertIsNone(node.reservation)
|
||||
|
||||
def test_destroy_node_protected_provision_state_available(self):
|
||||
CONF.set_override('allow_deleting_available_nodes',
|
||||
False, group='conductor')
|
||||
self._start_service()
|
||||
node = obj_utils.create_test_node(self.context,
|
||||
provision_state=states.AVAILABLE)
|
||||
|
||||
exc = self.assertRaises(messaging.rpc.ExpectedException,
|
||||
self.service.destroy_node,
|
||||
self.context, node.uuid)
|
||||
# Compare true exception hidden by @messaging.expected_exceptions
|
||||
self.assertEqual(exception.InvalidState, exc.exc_info[0])
|
||||
# Verify reservation was released.
|
||||
node.refresh()
|
||||
self.assertIsNone(node.reservation)
|
||||
|
||||
def test_destroy_node_protected(self):
|
||||
self._start_service()
|
||||
node = obj_utils.create_test_node(self.context,
|
||||
|
Loading…
Reference in New Issue
Block a user