Merge "Add logic to support baremetal inspection"
This commit is contained in:
commit
5ce5c003e8
@ -4468,6 +4468,74 @@ class OperatorCloud(OpenStackCloud):
|
|||||||
except ironic_exceptions.ClientException:
|
except ironic_exceptions.ClientException:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def inspect_machine(self, name_or_id, wait=False, timeout=3600):
|
||||||
|
"""Inspect a Barmetal machine
|
||||||
|
|
||||||
|
Engages the Ironic node inspection behavior in order to collect
|
||||||
|
metadata about the baremetal machine.
|
||||||
|
|
||||||
|
:param name_or_id: String representing machine name or UUID value in
|
||||||
|
order to identify the machine.
|
||||||
|
|
||||||
|
:param wait: Boolean value controlling if the method is to wait for
|
||||||
|
the desired state to be reached or a failure to occur.
|
||||||
|
|
||||||
|
:param timeout: Integer value, defautling to 3600 seconds, for the$
|
||||||
|
wait state to reach completion.
|
||||||
|
|
||||||
|
:returns: Dictonary representing the current state of the machine
|
||||||
|
upon exit of the method.
|
||||||
|
"""
|
||||||
|
|
||||||
|
return_to_available = False
|
||||||
|
|
||||||
|
machine = self.get_machine(name_or_id)
|
||||||
|
if not machine:
|
||||||
|
raise OpenStackCloudException(
|
||||||
|
"Machine inspection failed to find: %s." % name_or_id)
|
||||||
|
|
||||||
|
# NOTE(TheJulia): If in available state, we can do this, however
|
||||||
|
# We need to to move the host back to m
|
||||||
|
if "available" in machine['provision_state']:
|
||||||
|
return_to_available = True
|
||||||
|
# NOTE(TheJulia): Changing available machine to managedable state
|
||||||
|
# and due to state transitions we need to until that transition has
|
||||||
|
# completd.
|
||||||
|
self.node_set_provision_state(machine['uuid'], 'manage',
|
||||||
|
wait=True, timeout=timeout)
|
||||||
|
elif ("manage" not in machine['provision_state'] and
|
||||||
|
"inspect failed" not in machine['provision_state']):
|
||||||
|
raise OpenStackCloudException(
|
||||||
|
"Machine must be in 'manage' or 'available' state to "
|
||||||
|
"engage inspection: Machine: %s State: %s"
|
||||||
|
% (machine['uuid'], machine['provision_state']))
|
||||||
|
try:
|
||||||
|
machine = self.node_set_provision_state(machine['uuid'], 'inspect')
|
||||||
|
if wait:
|
||||||
|
for count in _utils._iterate_timeout(
|
||||||
|
timeout,
|
||||||
|
"Timeout waiting for node transition to "
|
||||||
|
"target state of 'inpection'"):
|
||||||
|
machine = self.get_machine(name_or_id)
|
||||||
|
|
||||||
|
if "inspect failed" in machine['provision_state']:
|
||||||
|
raise OpenStackCloudException(
|
||||||
|
"Inspection of node %s failed, last error: %s"
|
||||||
|
% (machine['uuid'], machine['last_error']))
|
||||||
|
|
||||||
|
if "manageable" in machine['provision_state']:
|
||||||
|
break
|
||||||
|
|
||||||
|
if return_to_available:
|
||||||
|
machine = self.node_set_provision_state(
|
||||||
|
machine['uuid'], 'provide', wait=wait, timeout=timeout)
|
||||||
|
|
||||||
|
return(machine)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
raise OpenStackCloudException(
|
||||||
|
"Error inspecting machine: %s" % e)
|
||||||
|
|
||||||
def register_machine(self, nics, wait=False, timeout=3600,
|
def register_machine(self, nics, wait=False, timeout=3600,
|
||||||
lock_timeout=600, **kwargs):
|
lock_timeout=600, **kwargs):
|
||||||
"""Register Baremetal with Ironic
|
"""Register Baremetal with Ironic
|
||||||
|
@ -363,6 +363,180 @@ class TestShadeOperator(base.TestCase):
|
|||||||
'00000000-0000-0000-0000-000000000000',
|
'00000000-0000-0000-0000-000000000000',
|
||||||
expected_patch)
|
expected_patch)
|
||||||
|
|
||||||
|
@mock.patch.object(shade.OperatorCloud, 'ironic_client')
|
||||||
|
def test_inspect_machine_fail_active(self, mock_client):
|
||||||
|
|
||||||
|
machine_uuid = '00000000-0000-0000-0000-000000000000'
|
||||||
|
|
||||||
|
class active_machine:
|
||||||
|
uuid = machine_uuid
|
||||||
|
provision_state = "active"
|
||||||
|
|
||||||
|
mock_client.node.get.return_value = active_machine
|
||||||
|
self.assertRaises(
|
||||||
|
shade.OpenStackCloudException,
|
||||||
|
self.cloud.inspect_machine,
|
||||||
|
machine_uuid,
|
||||||
|
wait=True,
|
||||||
|
timeout=0.001)
|
||||||
|
|
||||||
|
@mock.patch.object(shade.OperatorCloud, 'ironic_client')
|
||||||
|
def test_inspect_machine_failed(self, mock_client):
|
||||||
|
|
||||||
|
machine_uuid = '00000000-0000-0000-0000-000000000000'
|
||||||
|
|
||||||
|
class inspect_failed_machine:
|
||||||
|
uuid = machine_uuid
|
||||||
|
provision_state = "inspect failed"
|
||||||
|
last_error = "kaboom"
|
||||||
|
|
||||||
|
mock_client.node.get.return_value = inspect_failed_machine
|
||||||
|
self.cloud.inspect_machine(machine_uuid)
|
||||||
|
self.assertTrue(mock_client.node.set_provision_state.called)
|
||||||
|
self.assertEqual(
|
||||||
|
mock_client.node.set_provision_state.call_count, 1)
|
||||||
|
|
||||||
|
@mock.patch.object(shade.OperatorCloud, 'ironic_client')
|
||||||
|
def test_inspect_machine_managable(self, mock_client):
|
||||||
|
|
||||||
|
machine_uuid = '00000000-0000-0000-0000-000000000000'
|
||||||
|
|
||||||
|
class manageable_machine:
|
||||||
|
uuid = machine_uuid
|
||||||
|
provision_state = "manageable"
|
||||||
|
|
||||||
|
mock_client.node.get.return_value = manageable_machine
|
||||||
|
self.cloud.inspect_machine(machine_uuid)
|
||||||
|
self.assertEqual(
|
||||||
|
mock_client.node.set_provision_state.call_count, 1)
|
||||||
|
|
||||||
|
@mock.patch.object(shade.OperatorCloud, 'ironic_client')
|
||||||
|
def test_inspect_machine_available(self, mock_client):
|
||||||
|
|
||||||
|
machine_uuid = '00000000-0000-0000-0000-000000000000'
|
||||||
|
|
||||||
|
class available_machine:
|
||||||
|
uuid = machine_uuid
|
||||||
|
provision_state = "available"
|
||||||
|
|
||||||
|
class manageable_machine:
|
||||||
|
uuid = machine_uuid
|
||||||
|
provision_state = "manageable"
|
||||||
|
|
||||||
|
class inspecting_machine:
|
||||||
|
uuid = machine_uuid
|
||||||
|
provision_state = "inspecting"
|
||||||
|
|
||||||
|
mock_client.node.get.side_effect = iter([
|
||||||
|
available_machine,
|
||||||
|
available_machine,
|
||||||
|
manageable_machine,
|
||||||
|
manageable_machine,
|
||||||
|
inspecting_machine])
|
||||||
|
self.cloud.inspect_machine(machine_uuid)
|
||||||
|
self.assertTrue(mock_client.node.set_provision_state.called)
|
||||||
|
self.assertEqual(
|
||||||
|
mock_client.node.set_provision_state.call_count, 3)
|
||||||
|
|
||||||
|
@mock.patch.object(shade.OperatorCloud, 'ironic_client')
|
||||||
|
def test_inspect_machine_available_wait(self, mock_client):
|
||||||
|
|
||||||
|
machine_uuid = '00000000-0000-0000-0000-000000000000'
|
||||||
|
|
||||||
|
class available_machine:
|
||||||
|
uuid = machine_uuid
|
||||||
|
provision_state = "available"
|
||||||
|
|
||||||
|
class manageable_machine:
|
||||||
|
uuid = machine_uuid
|
||||||
|
provision_state = "manageable"
|
||||||
|
|
||||||
|
class inspecting_machine:
|
||||||
|
uuid = machine_uuid
|
||||||
|
provision_state = "inspecting"
|
||||||
|
|
||||||
|
mock_client.node.get.side_effect = iter([
|
||||||
|
available_machine,
|
||||||
|
available_machine,
|
||||||
|
manageable_machine,
|
||||||
|
inspecting_machine,
|
||||||
|
manageable_machine,
|
||||||
|
available_machine,
|
||||||
|
available_machine])
|
||||||
|
expected_return_value = dict(
|
||||||
|
uuid=machine_uuid,
|
||||||
|
provision_state="available"
|
||||||
|
)
|
||||||
|
|
||||||
|
return_value = self.cloud.inspect_machine(
|
||||||
|
machine_uuid, wait=True, timeout=0.001)
|
||||||
|
self.assertTrue(mock_client.node.set_provision_state.called)
|
||||||
|
self.assertEqual(
|
||||||
|
mock_client.node.set_provision_state.call_count, 3)
|
||||||
|
self.assertDictEqual(expected_return_value, return_value)
|
||||||
|
|
||||||
|
@mock.patch.object(shade.OperatorCloud, 'ironic_client')
|
||||||
|
def test_inspect_machine_wait(self, mock_client):
|
||||||
|
|
||||||
|
machine_uuid = '00000000-0000-0000-0000-000000000000'
|
||||||
|
|
||||||
|
class manageable_machine:
|
||||||
|
uuid = machine_uuid
|
||||||
|
provision_state = "manageable"
|
||||||
|
|
||||||
|
class inspecting_machine:
|
||||||
|
uuid = machine_uuid
|
||||||
|
provision_state = "inspecting"
|
||||||
|
|
||||||
|
expected_return_value = dict(
|
||||||
|
uuid=machine_uuid,
|
||||||
|
provision_state="manageable"
|
||||||
|
)
|
||||||
|
mock_client.node.get.side_effect = iter([
|
||||||
|
manageable_machine,
|
||||||
|
inspecting_machine,
|
||||||
|
inspecting_machine,
|
||||||
|
manageable_machine,
|
||||||
|
manageable_machine])
|
||||||
|
|
||||||
|
return_value = self.cloud.inspect_machine(
|
||||||
|
machine_uuid, wait=True, timeout=0.001)
|
||||||
|
self.assertDictEqual(expected_return_value, return_value)
|
||||||
|
|
||||||
|
@mock.patch.object(shade.OperatorCloud, 'ironic_client')
|
||||||
|
def test_inspect_machine_inspect_failed(self, mock_client):
|
||||||
|
|
||||||
|
machine_uuid = '00000000-0000-0000-0000-000000000000'
|
||||||
|
|
||||||
|
class manageable_machine:
|
||||||
|
uuid = machine_uuid
|
||||||
|
provision_state = "manageable"
|
||||||
|
last_error = None
|
||||||
|
|
||||||
|
class inspecting_machine:
|
||||||
|
uuid = machine_uuid
|
||||||
|
provision_state = "inspecting"
|
||||||
|
last_error = None
|
||||||
|
|
||||||
|
class inspect_failed_machine:
|
||||||
|
uuid = machine_uuid
|
||||||
|
provision_state = "inspect failed"
|
||||||
|
last_error = "kaboom"
|
||||||
|
|
||||||
|
mock_client.node.get.side_effect = iter([
|
||||||
|
manageable_machine,
|
||||||
|
inspecting_machine,
|
||||||
|
inspect_failed_machine])
|
||||||
|
self.assertRaises(
|
||||||
|
shade.OpenStackCloudException,
|
||||||
|
self.cloud.inspect_machine,
|
||||||
|
machine_uuid,
|
||||||
|
wait=True,
|
||||||
|
timeout=0.001)
|
||||||
|
self.assertEqual(
|
||||||
|
mock_client.node.set_provision_state.call_count, 1)
|
||||||
|
self.assertEqual(mock_client.node.get.call_count, 3)
|
||||||
|
|
||||||
@mock.patch.object(shade.OperatorCloud, 'ironic_client')
|
@mock.patch.object(shade.OperatorCloud, 'ironic_client')
|
||||||
def test_register_machine(self, mock_client):
|
def test_register_machine(self, mock_client):
|
||||||
class fake_node:
|
class fake_node:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user