Merge pull request #47415 from kstreee/fix-local-client-tgt-bug

Fixes a bug of rest_tornado's 'local' client, complement fix of #46326
This commit is contained in:
Nicole Thomas 2018-05-01 17:11:24 -04:00 committed by GitHub
commit 56235032f4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 14 deletions

View file

@ -429,6 +429,9 @@ class BaseSaltAPIHandler(tornado.web.RequestHandler): # pylint: disable=W0223
'runner_async': None, # empty, since we use the same client as `runner`
}
if not hasattr(self, 'ckminions'):
self.ckminions = salt.utils.minions.CkMinions(self.application.opts)
@property
def token(self):
'''
@ -921,7 +924,8 @@ class SaltAPIHandler(BaseSaltAPIHandler): # pylint: disable=W0223
chunk['jid'] = salt.utils.jid.gen_jid()
# Subscribe returns from minions before firing a job
future_minion_map = self.subscribe_minion_returns(chunk['jid'], chunk['tgt'])
minions = set(self.ckminions.check_minions(chunk['tgt'], chunk.get('tgt_type', 'glob')))
future_minion_map = self.subscribe_minion_returns(chunk['jid'], minions)
f_call = self._format_call_run_job_async(chunk)
# fire a job off
@ -940,9 +944,9 @@ class SaltAPIHandler(BaseSaltAPIHandler): # pylint: disable=W0223
pass
raise tornado.gen.Return('No minions matched the target. No command was sent, no jid was assigned.')
syndic_min_wait = None
# wait syndic a while to avoid missing published events
if self.application.opts['order_masters']:
syndic_min_wait = tornado.gen.sleep(self.application.opts['syndic_wait'])
yield tornado.gen.sleep(self.application.opts['syndic_wait'])
# To ensure job_not_running and all_return are terminated by each other, communicate using a future
is_finished = Future()
@ -952,10 +956,6 @@ class SaltAPIHandler(BaseSaltAPIHandler): # pylint: disable=W0223
f_call['kwargs']['tgt_type'],
is_finished)
# if we have a min_wait, do that
if syndic_min_wait is not None:
yield syndic_min_wait
minion_returns_future = self.sanitize_minion_returns(future_minion_map, pub_data['minions'], is_finished)
yield job_not_running_future
@ -992,7 +992,7 @@ class SaltAPIHandler(BaseSaltAPIHandler): # pylint: disable=W0223
chunk_ret = {}
while True:
f = yield Any(future_minion_map.keys() + [is_finished])
f = yield Any(list(future_minion_map.keys()) + [is_finished])
try:
# When finished entire routine, cleanup other futures and return result
if f is is_finished:

View file

@ -53,6 +53,7 @@ class TestSaltAPIHandler(_SaltnadoIntegrationTestCase):
application = self.build_tornado_app(urls)
application.event_listener = saltnado.EventListener({}, self.opts)
self.application = application
return application
def test_root(self):
@ -89,8 +90,6 @@ class TestSaltAPIHandler(_SaltnadoIntegrationTestCase):
self.assertEqual(response.code, 302)
self.assertEqual(response.headers['Location'], '/login')
# Local client tests
@skipIf(True, 'to be re-enabled when #23623 is merged')
def test_simple_local_post(self):
'''
Test a basic API of /
@ -108,7 +107,8 @@ class TestSaltAPIHandler(_SaltnadoIntegrationTestCase):
request_timeout=30,
)
response_obj = json_loads(response.body)
self.assertEqual(response_obj['return'], [{'minion': True, 'sub_minion': True}])
self.assertEqual(len(response_obj['return']), 1)
self.assertEqual(response_obj['return'][0], {'minion': True, 'sub_minion': True})
def test_simple_local_post_no_tgt(self):
'''
@ -129,8 +129,6 @@ class TestSaltAPIHandler(_SaltnadoIntegrationTestCase):
response_obj = json_loads(response.body)
self.assertEqual(response_obj['return'], ["No minions matched the target. No command was sent, no jid was assigned."])
# local client request body test
@skipIf(True, 'Undetermined race condition in test. Temporarily disabled.')
def test_simple_local_post_only_dictionary_request(self):
'''
Test a basic API of /
@ -148,7 +146,8 @@ class TestSaltAPIHandler(_SaltnadoIntegrationTestCase):
request_timeout=30,
)
response_obj = json_loads(response.body)
self.assertEqual(response_obj['return'], [{'minion': True, 'sub_minion': True}])
self.assertEqual(len(response_obj['return']), 1)
self.assertEqual(response_obj['return'][0], {'minion': True, 'sub_minion': True})
def test_simple_local_post_invalid_request(self):
'''
@ -263,6 +262,28 @@ class TestSaltAPIHandler(_SaltnadoIntegrationTestCase):
response_obj = json_loads(response.body)
self.assertEqual(response_obj['return'], [{}])
def test_simple_local_post_only_dictionary_request_with_order_masters(self):
'''
Test a basic API of /
'''
low = {'client': 'local',
'tgt': '*',
'fun': 'test.ping',
}
response = self.fetch('/',
method='POST',
body=salt.utils.json.dumps(low),
headers={'Content-Type': self.content_type_map['json'],
saltnado.AUTH_TOKEN_HEADER: self.token['token']},
connect_timeout=30,
request_timeout=30,
)
response_obj = salt.utils.json.loads(response.body)
self.application.opts['order_masters'] = []
self.application.opts['syndic_wait'] = 5
self.assertEqual(response_obj['return'], [{'minion': True, 'sub_minion': True}])
# runner tests
def test_simple_local_runner_post(self):
low = [{'client': 'runner',