diff --git a/releasenotes/notes/handle-failed-actions-cac0abd02ed67a51.yaml b/releasenotes/notes/handle-failed-actions-cac0abd02ed67a51.yaml new file mode 100644 index 000000000..7765f889c --- /dev/null +++ b/releasenotes/notes/handle-failed-actions-cac0abd02ed67a51.yaml @@ -0,0 +1,5 @@ +--- +fixes: + - The result of Mistral actions will now be checked, and if they've failed, + an exception will be raised. See + https://bugs.launchpad.net/tripleo/+bug/1686811 diff --git a/tripleoclient/exceptions.py b/tripleoclient/exceptions.py index 58f08742d..a87988fcc 100644 --- a/tripleoclient/exceptions.py +++ b/tripleoclient/exceptions.py @@ -78,3 +78,12 @@ class PlanCreationError(Exception): class PlanExportError(Exception): """Plan export failed""" + + +class WorkflowActionError(Exception): + """Workflow action failed""" + msg_format = "Action {} execution failed: {}" + + def __init__(self, message, action='', output=''): + message = message.format(action, output) + super(WorkflowActionError, self).__init__(message) diff --git a/tripleoclient/tests/workflows/test_base.py b/tripleoclient/tests/workflows/test_base.py index c2961336a..c1248b313 100644 --- a/tripleoclient/tests/workflows/test_base.py +++ b/tripleoclient/tests/workflows/test_base.py @@ -58,3 +58,25 @@ class TestBaseWorkflows(utils.TestCommand): self.assertTrue(mistral.executions.get.called) websocket.wait_for_messages.assert_called_with(timeout=None) + + def test_call_action_success(self): + mistral = mock.Mock() + action = 'test-action' + + result = mock.Mock() + result.output = '{"result":"test-result"}' + mistral.action_executions.create = mock.Mock(return_value=result) + + self.assertEqual(base.call_action(mistral, action), "test-result") + + def test_call_action_fail(self): + mistral = mock.Mock() + action = 'test-action' + + result = mock.Mock() + result.output = '{"result":"test-result"}' + result.state = 'ERROR' + mistral.action_executions.create = mock.Mock(return_value=result) + + self.assertRaises(exceptions.WorkflowActionError, + base.call_action, mistral, action) diff --git a/tripleoclient/workflows/base.py b/tripleoclient/workflows/base.py index 7f91796b5..7592a69fc 100644 --- a/tripleoclient/workflows/base.py +++ b/tripleoclient/workflows/base.py @@ -25,7 +25,11 @@ def call_action(workflow_client, action, **input_): save_result=True, run_sync=True) # Parse the JSON output. Mistral client should do this for us really. - return json.loads(result.output)['result'] + output = json.loads(result.output)['result'] + + if result.state == 'ERROR': + raise exceptions.WorkflowActionError(action, output) + return output def start_workflow(workflow_client, identifier, workflow_input):