Merge "Handle an older agent with agent_token" into stable/ussuri

This commit is contained in:
Zuul 2020-10-02 22:25:05 +00:00 committed by Gerrit Code Review
commit e9864fc324
3 changed files with 85 additions and 1 deletions

View File

@ -140,8 +140,28 @@ class AgentClient(object):
'res': result.get('command_result'),
'error': error,
'code': response.status_code})
if response.status_code >= http_client.BAD_REQUEST:
faultstring = result.get('faultstring')
if 'agent_token' in faultstring and agent_token:
# NOTE(TheJulia) We have an agent that is out of date.
# which means I guess grenade updates the agent image
# for upgrades... :(
if not CONF.require_agent_token:
LOG.warning('Agent command %(method)s for node %(node)s '
'failed. Expected 2xx HTTP status code, got '
'%(code)d. Error suggests an older ramdisk '
'which does not support ``agent_token``. '
'Removing the token for the next retry.',
{'method': method, 'node': node.uuid,
'code': response.status_code})
i_info = node.driver_internal_info
i_info.pop('agent_secret_token')
node.driver_internal_info = i_info
node.save()
msg = ('Node {} does not appear to support '
'agent_token and it is not required. Next retry '
'will be without the token.').format(node.uuid)
raise exception.AgentConnectionFailed(reason=msg)
LOG.error('Agent command %(method)s for node %(node)s failed. '
'Expected 2xx HTTP status code, got %(code)d.',
{'method': method, 'node': node.uuid,

View File

@ -55,6 +55,9 @@ class MockNode(object):
'instance_info': self.instance_info
}
def save(self):
pass
class TestAgentClient(base.TestCase):
def setUp(self):
@ -489,6 +492,61 @@ class TestAgentClientAttempts(base.TestCase):
params={'wait': 'false'},
timeout=60)
@mock.patch.object(retrying.time, 'sleep', autospec=True)
def test__command_succeed_after_agent_token(self, mock_sleep):
self.config(require_agent_token=False)
mock_sleep.return_value = None
error = {'faultstring': 'Unknown Argument: "agent_token"'}
response_data = {'status': 'ok'}
method = 'standby.run_image'
image_info = {'image_id': 'test_image'}
params = {'image_info': image_info}
i_info = self.node.driver_internal_info
i_info['agent_secret_token'] = 'meowmeowmeow'
self.client.session.post.side_effect = [
MockResponse(json.dumps(error),
status_code=http_client.BAD_REQUEST),
MockResponse(json.dumps(response_data)),
]
response = self.client._command(self.node, method, params)
self.assertEqual(2, self.client.session.post.call_count)
self.assertEqual(response, response_data)
self.client.session.post.assert_called_with(
self.client._get_command_url(self.node),
data=self.client._get_command_body(method, params),
params={'wait': 'false'},
timeout=60)
self.assertNotIn('agent_secret_token', self.node.driver_internal_info)
@mock.patch.object(retrying.time, 'sleep', autospec=True)
def test__command_fail_agent_token_required(self, mock_sleep):
self.config(require_agent_token=True)
mock_sleep.return_value = None
error = {'faultstring': 'Unknown Argument: "agent_token"'}
method = 'standby.run_image'
image_info = {'image_id': 'test_image'}
params = {'image_info': image_info}
i_info = self.node.driver_internal_info
i_info['agent_secret_token'] = 'meowmeowmeow'
self.client.session.post.side_effect = [
MockResponse(json.dumps(error),
status_code=http_client.BAD_REQUEST),
]
self.assertRaises(exception.AgentAPIError,
self.client._command,
self.node, method, params)
self.assertEqual(1, self.client.session.post.call_count)
self.client.session.post.assert_called_with(
self.client._get_command_url(self.node),
data=self.client._get_command_body(method, params),
params={'wait': 'false', 'agent_token': 'meowmeowmeow'},
timeout=60)
self.assertEqual(
'meowmeowmeow',
self.node.driver_internal_info.get('agent_secret_token'))
@mock.patch.object(retrying.time, 'sleep', autospec=True)
def test__command_succeed_after_one_timeout(self, mock_sleep):
mock_sleep.return_value = None

View File

@ -0,0 +1,6 @@
---
fixes:
- |
Fixes an issue with agent token handling where the agent has not been
upgraded resulting in an AgentAPIError, when the token is not required.
The conductor now retries without sending an agent token.