Merge "Handle an older agent with agent_token" into stable/ussuri
This commit is contained in:
commit
e9864fc324
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
Loading…
Reference in New Issue