We have some news to share for the request index beta feature. We’ve added more options to sort your requests, counters to the individual filters and documentation for the search functionality. Checkout the blog post for more details.

File make-_auth-calls-visible-with-master-stats-696.patch of Package venv-salt-minion

From 32099b97c2fa549cb050d3ae618b5200c07328c8 Mon Sep 17 00:00:00 2001
From: Victor Zhestkov <vzhestkov@suse.com>
Date: Fri, 21 Feb 2025 11:59:00 +0100
Subject: [PATCH] Make `_auth` calls visible with master stats (#696)

* Put _auth calls to the master stats

* Add _auth master stats tests

* test small fix
---
 salt/channel/server.py                    |  9 ++++--
 salt/master.py                            |  5 ++++
 tests/pytests/unit/channel/__init__.py    |  0
 tests/pytests/unit/channel/test_server.py | 34 +++++++++++++++++++++++
 tests/pytests/unit/test_master.py         | 25 +++++++++++++++++
 5 files changed, 70 insertions(+), 3 deletions(-)
 create mode 100644 tests/pytests/unit/channel/__init__.py
 create mode 100644 tests/pytests/unit/channel/test_server.py

diff --git a/salt/channel/server.py b/salt/channel/server.py
index f1b6f701a9..59da3a2dc2 100644
--- a/salt/channel/server.py
+++ b/salt/channel/server.py
@@ -9,6 +9,7 @@ import hashlib
 import logging
 import os
 import shutil
+import time
 
 import salt.crypt
 import salt.ext.tornado.gen
@@ -149,9 +150,11 @@ class ReqServerChannel:
         # intercept the "_auth" commands, since the main daemon shouldn't know
         # anything about our key auth
         if payload["enc"] == "clear" and payload.get("load", {}).get("cmd") == "_auth":
-            raise salt.ext.tornado.gen.Return(
-                self._auth(payload["load"], sign_messages)
-            )
+            start = time.time()
+            ret = self._auth(payload["load"], sign_messages)
+            if self.opts.get("master_stats", False):
+                yield self.payload_handler({"cmd": "_auth", "_start": start})
+            raise salt.ext.tornado.gen.Return(ret)
 
         nonce = None
         if version > 1:
diff --git a/salt/master.py b/salt/master.py
index 49cfb68860..c0cd9a366b 100644
--- a/salt/master.py
+++ b/salt/master.py
@@ -1036,6 +1036,11 @@ class MWorker(salt.utils.process.SignalHandlingProcess):
 
         :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 == "aes":
diff --git a/tests/pytests/unit/channel/__init__.py b/tests/pytests/unit/channel/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/tests/pytests/unit/channel/test_server.py b/tests/pytests/unit/channel/test_server.py
new file mode 100644
index 0000000000..3fa5d94bea
--- /dev/null
+++ b/tests/pytests/unit/channel/test_server.py
@@ -0,0 +1,34 @@
+import time
+
+import pytest
+
+import salt.channel.server as server
+import salt.ext.tornado.gen
+from tests.support.mock import MagicMock, patch
+
+
+def test__auth_cmd_stats_passing():
+    req_server_channel = server.ReqServerChannel({"master_stats": True}, None)
+
+    fake_ret = {"enc": "clear", "load": b"FAKELOAD"}
+
+    def _auth_mock(*_, **__):
+        time.sleep(0.03)
+        return fake_ret
+
+    future = salt.ext.tornado.gen.Future()
+    future.set_result({})
+
+    with patch.object(req_server_channel, "_auth", _auth_mock):
+        req_server_channel.payload_handler = MagicMock(return_value=future)
+        req_server_channel.handle_message(
+            {"enc": "clear", "load": {"cmd": "_auth", "id": "minion"}}
+        )
+        cur_time = time.time()
+        req_server_channel.payload_handler.assert_called_once()
+        assert req_server_channel.payload_handler.call_args[0][0]["cmd"] == "_auth"
+        auth_call_duration = (
+            cur_time - req_server_channel.payload_handler.call_args[0][0]["_start"]
+        )
+        assert auth_call_duration >= 0.03
+        assert auth_call_duration < 0.05
diff --git a/tests/pytests/unit/test_master.py b/tests/pytests/unit/test_master.py
index 679229066d..7fccb24d73 100644
--- a/tests/pytests/unit/test_master.py
+++ b/tests/pytests/unit/test_master.py
@@ -282,3 +282,28 @@ def test_syndic_return_cache_dir_creation_traversal(encrypted_requests):
     )
     assert not (cachedir / "syndics").exists()
     assert not (cachedir / "mamajama").exists()
+
+
+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:
+        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
+        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()
-- 
2.48.1

openSUSE Build Service is sponsored by