summaryrefslogtreecommitdiff
path: root/ironic
diff options
context:
space:
mode:
authorJulia Kreger <juliaashleykreger@gmail.com>2020-04-22 08:42:29 -0700
committerJulia Kreger <juliaashleykreger@gmail.com>2020-04-24 09:55:09 -0700
commitbfeef067aac7572bb914396db4553da5c013403f (patch)
tree7a48829f2bff7760260d77c58e042bf0dc5066e4 /ironic
parentb49319137181cee00342175395bc93eac87e0033 (diff)
downloadironic-bfeef067aac7572bb914396db4553da5c013403f.tar.gz
Fix agent_client handling of embedded errors
The agent_client may get a general "command_error" field returned to it upon commands and the agent may not properly sinal that the command failed because we are reliant upon the same data elsewhere in the ironic/agent interaction. This resulted in the case where the embedded error signaled that the error was method compatability as opposed to the actual method command error. This could cause higher level failures and prevent fallback logic from detecting that we could try a different command. We now consider the error type, and raise the appropriate exception to signal that the issue may be an API compatability issue. Change-Id: Ia2f63bd853632e1d7138901cf23fde1e261fc4d6
Diffstat (limited to 'ironic')
-rw-r--r--ironic/drivers/modules/agent_client.py17
-rw-r--r--ironic/tests/unit/drivers/modules/test_agent_client.py21
2 files changed, 37 insertions, 1 deletions
diff --git a/ironic/drivers/modules/agent_client.py b/ironic/drivers/modules/agent_client.py
index 4c17403b9..feb4ebc88 100644
--- a/ironic/drivers/modules/agent_client.py
+++ b/ironic/drivers/modules/agent_client.py
@@ -127,11 +127,18 @@ class AgentClient(object):
LOG.error(msg)
raise exception.IronicException(msg)
+ error = result.get('command_error')
+ exc_type = None
+ if error:
+ # if an error, we should see if a type field exists. This type
+ # field may signal an exception that is compatability based.
+ exc_type = error.get('type')
+
LOG.debug('Agent command %(method)s for node %(node)s returned '
'result %(res)s, error %(error)s, HTTP status code %(code)d',
{'node': node.uuid, 'method': method,
'res': result.get('command_result'),
- 'error': result.get('command_error'),
+ 'error': error,
'code': response.status_code})
if response.status_code >= http_client.BAD_REQUEST:
@@ -142,6 +149,14 @@ class AgentClient(object):
raise exception.AgentAPIError(node=node.uuid,
status=response.status_code,
error=result.get('faultstring'))
+ if exc_type == 'TypeError':
+ LOG.error('Agent command %(method)s for node %(node)s failed. '
+ 'Internal %(exc_type)s error detected: Error %(error)s',
+ {'method': method, 'node': node.uuid,
+ 'exc_type': exc_type, 'error': error})
+ raise exception.AgentAPIError(node=node.uuid,
+ status=error.get('code'),
+ error=result.get('faultstring'))
return result
diff --git a/ironic/tests/unit/drivers/modules/test_agent_client.py b/ironic/tests/unit/drivers/modules/test_agent_client.py
index 65bb58172..1bea74188 100644
--- a/ironic/tests/unit/drivers/modules/test_agent_client.py
+++ b/ironic/tests/unit/drivers/modules/test_agent_client.py
@@ -178,6 +178,27 @@ class TestAgentClient(base.TestCase):
params={'wait': 'false'},
timeout=60)
+ def test__command_error_code_okay_error_typeerror_embedded(self):
+ response_text = ('{"faultstring": "you dun goofd", '
+ '"command_error": {"type": "TypeError"}}')
+ self.client.session.post.return_value = MockResponse(
+ response_text)
+ method = 'standby.run_image'
+ image_info = {'image_id': 'test_image'}
+ params = {'image_info': image_info}
+
+ url = self.client._get_command_url(self.node)
+ body = self.client._get_command_body(method, params)
+
+ self.assertRaises(exception.AgentAPIError,
+ self.client._command,
+ self.node, method, params)
+ self.client.session.post.assert_called_once_with(
+ url,
+ data=body,
+ params={'wait': 'false'},
+ timeout=60)
+
def test_get_commands_status(self):
with mock.patch.object(self.client.session, 'get',
autospec=True) as mock_get: