Doublecheck node provision state on receiving data from ramdisk
Change-Id: I888be685ee5b44fa257c5c9ab3f4548e0d9e5532 Closes-Bug: #1437298
This commit is contained in:
parent
6eec990919
commit
eafa4ea94b
|
@ -29,8 +29,6 @@ CONF = cfg.CONF
|
||||||
|
|
||||||
|
|
||||||
LOG = logging.getLogger("ironic_discoverd.introspect")
|
LOG = logging.getLogger("ironic_discoverd.introspect")
|
||||||
# See http://specs.openstack.org/openstack/ironic-specs/specs/kilo/new-ironic-state-machine.html # noqa
|
|
||||||
VALID_STATES = {'enroll', 'manageable', 'inspecting', 'inspectfail'}
|
|
||||||
PASSWORD_ACCEPTED_CHARS = set(string.ascii_letters + string.digits)
|
PASSWORD_ACCEPTED_CHARS = set(string.ascii_letters + string.digits)
|
||||||
PASSWORD_MAX_LENGTH = 20 # IPMI v2.0
|
PASSWORD_MAX_LENGTH = 20 # IPMI v2.0
|
||||||
|
|
||||||
|
@ -84,16 +82,7 @@ def introspect(uuid, new_ipmi_credentials=None):
|
||||||
raise utils.Error(_("Cannot get node %(node)s: %(exc)s") %
|
raise utils.Error(_("Cannot get node %(node)s: %(exc)s") %
|
||||||
{'node': uuid, 'exc': exc})
|
{'node': uuid, 'exc': exc})
|
||||||
|
|
||||||
if not node.maintenance:
|
utils.check_provision_state(node)
|
||||||
provision_state = node.provision_state
|
|
||||||
if provision_state and provision_state.lower() not in VALID_STATES:
|
|
||||||
msg = _('Refusing to introspect node %(node)s with provision state'
|
|
||||||
' "%(state)s" and maintenance mode off')
|
|
||||||
raise utils.Error(msg % {'node': node.uuid,
|
|
||||||
'state': provision_state})
|
|
||||||
else:
|
|
||||||
LOG.info(_LI('Node %s is in maintenance mode, skipping'
|
|
||||||
' provision states check'), node.uuid)
|
|
||||||
|
|
||||||
if new_ipmi_credentials:
|
if new_ipmi_credentials:
|
||||||
new_ipmi_credentials = (
|
new_ipmi_credentials = (
|
||||||
|
|
|
@ -87,6 +87,9 @@ def _run_post_hooks(node, ports, node_info):
|
||||||
|
|
||||||
|
|
||||||
def _process_node(ironic, node, node_info, cached_node):
|
def _process_node(ironic, node, node_info, cached_node):
|
||||||
|
# NOTE(dtantsur): repeat the check in case something changed
|
||||||
|
utils.check_provision_state(node)
|
||||||
|
|
||||||
ports = {}
|
ports = {}
|
||||||
for mac in (node_info.get('macs') or ()):
|
for mac in (node_info.get('macs') or ()):
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -345,6 +345,11 @@ class TestProcessNode(BaseTest):
|
||||||
return process._process_node(self.cli, self.node, self.data,
|
return process._process_node(self.cli, self.node, self.data,
|
||||||
self.cached_node)
|
self.cached_node)
|
||||||
|
|
||||||
|
def test_wrong_provision_state(self, filters_mock, post_hook_mock):
|
||||||
|
self.node.provision_state = 'active'
|
||||||
|
self.assertRaises(utils.Error, self.call)
|
||||||
|
self.assertFalse(post_hook_mock.called)
|
||||||
|
|
||||||
@mock.patch.object(node_cache.NodeInfo, 'finished', autospec=True)
|
@mock.patch.object(node_cache.NodeInfo, 'finished', autospec=True)
|
||||||
def test_ok(self, finished_mock, filters_mock, post_hook_mock):
|
def test_ok(self, finished_mock, filters_mock, post_hook_mock):
|
||||||
self.call()
|
self.call()
|
||||||
|
|
|
@ -22,10 +22,13 @@ from keystonemiddleware import auth_token
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
import six
|
import six
|
||||||
|
|
||||||
from ironic_discoverd.common.i18n import _, _LE, _LW
|
from ironic_discoverd.common.i18n import _, _LE, _LI, _LW
|
||||||
|
|
||||||
CONF = cfg.CONF
|
CONF = cfg.CONF
|
||||||
|
|
||||||
|
# See http://specs.openstack.org/openstack/ironic-specs/specs/kilo/new-ironic-state-machine.html # noqa
|
||||||
|
VALID_STATES = {'enroll', 'manageable', 'inspecting', 'inspectfail'}
|
||||||
|
|
||||||
|
|
||||||
LOG = logging.getLogger('ironic_discoverd.utils')
|
LOG = logging.getLogger('ironic_discoverd.utils')
|
||||||
RETRY_COUNT = 12
|
RETRY_COUNT = 12
|
||||||
|
@ -118,6 +121,18 @@ def retry_on_conflict(call, *args, **kwargs):
|
||||||
raise RuntimeError('unreachable code') # pragma: no cover
|
raise RuntimeError('unreachable code') # pragma: no cover
|
||||||
|
|
||||||
|
|
||||||
|
def check_provision_state(node):
|
||||||
|
if not node.maintenance:
|
||||||
|
provision_state = node.provision_state
|
||||||
|
if provision_state and provision_state.lower() not in VALID_STATES:
|
||||||
|
msg = _('Refusing to introspect node %(node)s with provision state'
|
||||||
|
' "%(state)s" and maintenance mode off')
|
||||||
|
raise Error(msg % {'node': node.uuid, 'state': provision_state})
|
||||||
|
else:
|
||||||
|
LOG.info(_LI('Node %s is in maintenance mode, skipping'
|
||||||
|
' provision states check'), node.uuid)
|
||||||
|
|
||||||
|
|
||||||
def capabilities_to_dict(caps):
|
def capabilities_to_dict(caps):
|
||||||
"""Convert the Node's capabilities into a dictionary."""
|
"""Convert the Node's capabilities into a dictionary."""
|
||||||
if not caps:
|
if not caps:
|
||||||
|
|
Loading…
Reference in New Issue