mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Ensure channels are closed on connection errors
This commit is contained in:
parent
b1b0c37871
commit
0568864435
3 changed files with 54 additions and 12 deletions
|
@ -594,14 +594,22 @@ class AsyncPubChannel:
|
|||
def _decode_payload(self, payload):
|
||||
# we need to decrypt it
|
||||
log.trace("Decoding payload: %s", payload)
|
||||
reauth = False
|
||||
if payload["enc"] == "aes":
|
||||
self._verify_master_signature(payload)
|
||||
try:
|
||||
payload["load"] = self.auth.crypticle.loads(payload["load"])
|
||||
except salt.crypt.AuthenticationError:
|
||||
yield self.auth.authenticate()
|
||||
payload["load"] = self.auth.crypticle.loads(payload["load"])
|
||||
|
||||
reauth = True
|
||||
if reauth:
|
||||
try:
|
||||
yield self.auth.authenticate()
|
||||
payload["load"] = self.auth.crypticle.loads(payload["load"])
|
||||
except salt.crypt.AuthenticationError:
|
||||
log.error(
|
||||
"Payload decryption failed even after re-authenticating with master %s",
|
||||
self.opts["master_ip"],
|
||||
)
|
||||
raise salt.ext.tornado.gen.Return(payload)
|
||||
|
||||
def __enter__(self):
|
||||
|
|
|
@ -1152,17 +1152,20 @@ class MinionManager(MinionBase):
|
|||
self.minions.append(minion)
|
||||
break
|
||||
except SaltClientError as exc:
|
||||
minion.destroy()
|
||||
failed = True
|
||||
log.error(
|
||||
"Error while bringing up minion for multi-master. Is "
|
||||
"master at %s responding?",
|
||||
"master at %s responding? The error message was %s",
|
||||
minion.opts["master"],
|
||||
exc,
|
||||
)
|
||||
last = time.time()
|
||||
if auth_wait < self.max_auth_wait:
|
||||
auth_wait += self.auth_wait
|
||||
yield salt.ext.tornado.gen.sleep(auth_wait) # TODO: log?
|
||||
except SaltMasterUnresolvableError:
|
||||
minion.destroy()
|
||||
err = (
|
||||
"Master address: '{}' could not be resolved. Invalid or"
|
||||
" unresolveable address. Set 'master' value in minion config.".format(
|
||||
|
@ -1172,6 +1175,7 @@ class MinionManager(MinionBase):
|
|||
log.error(err)
|
||||
break
|
||||
except Exception as e: # pylint: disable=broad-except
|
||||
minion.destroy()
|
||||
failed = True
|
||||
log.critical(
|
||||
"Unexpected error while connecting to %s",
|
||||
|
@ -3281,20 +3285,14 @@ class Minion(MinionBase):
|
|||
"""
|
||||
Tear down the minion
|
||||
"""
|
||||
if self._running is False:
|
||||
return
|
||||
|
||||
self._running = False
|
||||
if hasattr(self, "schedule"):
|
||||
del self.schedule
|
||||
if hasattr(self, "pub_channel") and self.pub_channel is not None:
|
||||
self.pub_channel.on_recv(None)
|
||||
if hasattr(self.pub_channel, "close"):
|
||||
self.pub_channel.close()
|
||||
del self.pub_channel
|
||||
if hasattr(self, "req_channel") and self.req_channel:
|
||||
self.pub_channel.close()
|
||||
if hasattr(self, "req_channel") and self.req_channel is not None:
|
||||
self.req_channel.close()
|
||||
self.req_channel = None
|
||||
if hasattr(self, "periodic_callbacks"):
|
||||
for cb in self.periodic_callbacks.values():
|
||||
cb.stop()
|
||||
|
|
|
@ -1119,3 +1119,39 @@ def test_load_args_and_kwargs(minion_opts):
|
|||
_args = [{"max_sleep": 40, "__kwarg__": True}]
|
||||
with pytest.raises(salt.exceptions.SaltInvocationError):
|
||||
ret = salt.minion.load_args_and_kwargs(test_mod.rand_sleep, _args)
|
||||
|
||||
|
||||
def test_connect_master_salt_client_error(minion_opts):
|
||||
"""
|
||||
Ensure minion's destory method is called on an salt client error while connecting to master.
|
||||
"""
|
||||
mm = salt.minion.MinionManager(minion_opts)
|
||||
minion = salt.minion.Minion(minion_opts)
|
||||
minion.connect_master = MagicMock(side_effect=SaltClientError)
|
||||
minion.destroy = MagicMock()
|
||||
mm._connect_minion(minion)
|
||||
minion.destroy.assert_called_once()
|
||||
|
||||
|
||||
def test_connect_master_unresolveable_error(minion_opts):
|
||||
"""
|
||||
Ensure minion's destory method is called on an unresolvable while connecting to master.
|
||||
"""
|
||||
mm = salt.minion.MinionManager(minion_opts)
|
||||
minion = salt.minion.Minion(minion_opts)
|
||||
minion.connect_master = MagicMock(side_effect=SaltMasterUnresolvableError)
|
||||
minion.destroy = MagicMock()
|
||||
mm._connect_minion(minion)
|
||||
minion.destroy.assert_called_once()
|
||||
|
||||
|
||||
def test_connect_master_general_exception_error(minion_opts):
|
||||
"""
|
||||
Ensure minion's destory method is called on an un-handled exception while connecting to master.
|
||||
"""
|
||||
mm = salt.minion.MinionManager(minion_opts)
|
||||
minion = salt.minion.Minion(minion_opts)
|
||||
minion.connect_master = MagicMock(side_effect=Exception)
|
||||
minion.destroy = MagicMock()
|
||||
mm._connect_minion(minion)
|
||||
minion.destroy.assert_called_once()
|
||||
|
|
Loading…
Add table
Reference in a new issue