Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog/67746.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add `_auth` calls to the master stats
8 changes: 7 additions & 1 deletion salt/channel/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,13 @@ async def handle_message(self, payload):
payload["enc"] == "clear"
and payload.get("load", {}).get("cmd") == "_auth"
):
return self._auth(payload["load"], sign_messages, version)
# Store time at the beginning of serving _auth call
# to calculate duration of the call with master_stats
start = time.time()
ret = self._auth(payload["load"], sign_messages, version)
if self.opts.get("master_stats", False):
await self.payload_handler({"cmd": "_auth", "_start": start})
return ret

# Take the payload_handler function that was registered when we created the channel
# and call it, returning control to the caller until it completes
Expand Down
5 changes: 5 additions & 0 deletions salt/master.py
Original file line number Diff line number Diff line change
Expand Up @@ -1203,6 +1203,11 @@ async def _handle_payload(self, payload):

:param dict payload: The payload route to the appropriate handler
"""
if payload.get("cmd") == "_auth":
if self.opts["master_stats"]:
self.stats["_auth"]["runs"] += 1
self._post_stats(payload["_start"], "_auth")
return
key = payload["enc"]
load = payload["load"]
if key == "clear":
Expand Down
39 changes: 39 additions & 0 deletions tests/pytests/unit/channel/test_server.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import ctypes
import multiprocessing
import time
import uuid

import pytest
Expand Down Expand Up @@ -553,3 +554,41 @@ async def test_handle_message_exceptions(temp_salt_master):
{"version": 3, "enc": "clear", "load": {}}
)
assert ret == "Server-side exception handling payload"


async def test__auth_cmd_stats_passing(auth_master_opts):
opts = auth_master_opts.copy()
opts.update(
{
"master_stats": True,
}
)
req = server.ReqServerChannel(opts, None)

fake_ret = {"enc": "clear", "load": b"FAKELOAD"}

def _auth_mock(*_, **__):
time.sleep(0.03)
return fake_ret

with patch.object(req, "_auth", _auth_mock), patch(
"salt.channel.server.ReqServerChannel.payload_handler",
AsyncMock(return_value=(None, {"fun": "send"})),
create=True,
) as payload_handler:
ret = await req.handle_message(
{
"enc": "clear",
"version": 3,
"load": {
"cmd": "_auth",
"id": "minion",
},
}
)
cur_time = time.time()
payload_handler.assert_called_once()
assert payload_handler.call_args[0][0]["cmd"] == "_auth"
auth_call_duration = cur_time - payload_handler.call_args[0][0]["_start"]
assert auth_call_duration >= 0.03
assert auth_call_duration < 0.05
25 changes: 25 additions & 0 deletions tests/pytests/unit/test_master.py
Original file line number Diff line number Diff line change
Expand Up @@ -1259,3 +1259,28 @@ def test_on_demand_not_allowed(not_allowed_funcs, tmp_path, caplog):
"The following ext_pillar modules are not allowed for on-demand pillar data: git."
in caplog.text
)


async def test_collect__auth_to_master_stats():
"""
Check if master stats is collecting _auth calls while not calling neither _handle_aes nor _handle_clear
"""
opts = {
"master_stats": True,
"master_stats_event_iter": 10,
}
req_channel_mock = MagicMock()
mworker = salt.master.MWorker(opts, {}, {}, [req_channel_mock])
with patch.object(mworker, "_handle_aes") as handle_aes_mock, patch.object(
mworker, "_handle_clear"
) as handle_clear_mock:
await mworker._handle_payload({"cmd": "_auth", "_start": time.time() - 0.02})
assert mworker.stats["_auth"]["runs"] == 1
assert mworker.stats["_auth"]["mean"] >= 0.02
assert mworker.stats["_auth"]["mean"] < 0.04
await mworker._handle_payload({"cmd": "_auth", "_start": time.time() - 0.02})
assert mworker.stats["_auth"]["runs"] == 2
assert mworker.stats["_auth"]["mean"] >= 0.02
assert mworker.stats["_auth"]["mean"] < 0.04
handle_aes_mock.assert_not_called()
handle_clear_mock.assert_not_called()
Loading