Skip to content

Commit 78cc93d

Browse files
fix TACACS Local Accounting test: fixed a check on presence of accounting log about a command executed by TACACS user (#6354)
TACACS Local Accounting tests check if the commands executed by TACACS users are logged locally in DUT. The tests execute a grep command using a TACACS user and then check presence of the corresponding accounting log in syslog using sed utility. The code fragment demonstrating it: ssh_run_command(rw_user_client, "grep") # Verify syslog have user command record. check_local_log_exist(rw_user_client, tacacs_creds, "grep") The issue is that check_local_log_exist calls sed to query for accounting logs and this query command itself is logged too so tests pass even when the initial command is not logged. Currently the test catches this log: INFO audisp-tacplus: Audisp-tacplus: Accounting: user: test_rwuser, tty: (none), host: mytestbed-1-dut, command: /usr/bin/bash -c sudo sed -nE '/INFO audisp-tacplus: Accounting: user: test_rwuser,.*, command: .*grep,/P' /var/log/syslog, type: 2, task ID: 29318\n" instead of: INFO audisp-tacplus: Audisp-tacplus: Accounting: user: test_rwuser, tty: (none), host: mytestbed-1-dut, command: /usr/bin/grep, type: 2, task ID: 13871 The consequences of the issue are: the tests do not check accounting log entries to adhere to an expected pattern Since sed command happens to be logged too, tests match the search pattern used in sed command itself, instead of matching a separate accounting log adheres to an expected pattern. The matched fragment is made bold below: INFO audisp-tacplus: Audisp-tacplus: Accounting: user: test_rwuser, tty: (none), host: mytestbed-1-dut, command: /usr/bin/bash -c sudo sed -nE '/INFO audisp-tacplus: Accounting: user: test_rwuser,.*, command: .*grep,/P' /var/log/syslog, type: 2, task ID: 29318\n" tests may fail occasionally when some small logging delays take place the scenarios documented by test code become confusing since the actual accounting log being matched is different than that's intended by tests. Expected to match an accounting log for grep command but matched a log for log query command itself.
1 parent a39bbcf commit 78cc93d

File tree

1 file changed

+30
-19
lines changed

1 file changed

+30
-19
lines changed

tests/tacacs/test_accounting.py

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -53,34 +53,44 @@ def check_tacacs_server_no_other_user_log(ptfhost, tacacs_creds):
5353
logger.info(res["stdout_lines"])
5454
pytest_assert(len(res["stdout_lines"]) == 0)
5555

56-
def check_local_log_exist(rw_user_client, tacacs_creds, command):
57-
username = tacacs_creds['tacacs_rw_user']
56+
def check_local_log_exist(duthost, tacacs_creds, command):
5857
"""
5958
Find logs run by tacacs_rw_user from syslog:
6059
Find logs match following format: "INFO audisp-tacplus: Accounting: user: tacacs_rw_user,.*, command: .*command,"
6160
Print matched logs with /P command.
6261
"""
63-
sed_command = "sudo sed -nE '/INFO audisp-tacplus: Accounting: user: {0},.*, command: .*{1},/P' /var/log/syslog".format(username, command)
64-
exit_code, stdout, stderr = ssh_run_command(rw_user_client, sed_command)
65-
pytest_assert(exit_code == 0)
66-
logger.info(sed_command) # lgtm [py/clear-text-logging-sensitive-data]
67-
logger.info(stdout)
68-
pytest_assert(len(stdout) > 0)
6962

70-
def check_local_no_other_user_log(rw_user_client, tacacs_creds):
7163
username = tacacs_creds['tacacs_rw_user']
64+
expected_log_pattern = "INFO audisp-tacplus.+Accounting: user: {0},.*, command: .*{1},".format(username, command)
65+
sed_command = "sudo sed -nE '/{}/P' /var/log/syslog".format(expected_log_pattern)
66+
output = duthost.shell(sed_command)
67+
exit_code, stdout_lines = output['rc'], output['stdout_lines']
68+
69+
# exclude logs of the sed command produced by Ansible
70+
stdout_lines = list(filter(lambda line: 'sudo sed' not in line, stdout_lines))
71+
logger.info("Searched for accounting logs with the command: %s", sed_command) # lgtm [py/clear-text-logging-sensitive-data]
72+
logger.info("Found logs: %s", stdout_lines)
73+
74+
pytest_assert(exit_code == 0)
75+
pytest_assert(stdout_lines, 'Failed to find an expected log message by pattern: ' + expected_log_pattern)
76+
77+
def check_local_no_other_user_log(duthost, tacacs_creds):
7278
"""
7379
Find logs not run by tacacs_rw_user from syslog:
7480
Remove all tacacs_rw_user's log with /D command, which will match following format: "INFO audisp-tacplus: Accounting: user: tacacs_rw_user"
7581
Find all other user's log, which will match following format: "INFO audisp-tacplus: Accounting: user:"
7682
Print matched logs with /P command, which are not run by tacacs_rw_user.
7783
"""
84+
85+
username = tacacs_creds['tacacs_rw_user']
7886
sed_command = "sudo sed -nE '/INFO audisp-tacplus: Accounting: user: {0},/D;/INFO audisp-tacplus: Accounting: user:/P' /var/log/syslog".format(username)
79-
exit_code, stdout, stderr = ssh_run_command(rw_user_client, sed_command)
87+
output = duthost.shell(sed_command)
88+
exit_code, stdout = output['rc'], output['stdout']
89+
8090
pytest_assert(exit_code == 0)
81-
logger.info(sed_command) # lgtm [py/clear-text-logging-sensitive-data]
82-
logger.info(stdout)
83-
pytest_assert(len(stdout) == 0)
91+
logger.info("Searched for accounting logs with the command: %s", sed_command) # lgtm [py/clear-text-logging-sensitive-data]
92+
logger.info("Found logs: %s", stdout)
93+
pytest_assert(len(stdout) == 0, "Expected to find no accounting logs but found" + stdout)
8494

8595
@pytest.fixture
8696
def rw_user_client(duthosts, enum_rand_one_per_hwsku_hostname, tacacs_creds):
@@ -178,9 +188,10 @@ def test_accounting_local_only(ptfhost, duthosts, enum_rand_one_per_hwsku_hostna
178188
ssh_run_command(rw_user_client, "grep")
179189

180190
# Verify syslog have user command record.
181-
check_local_log_exist(rw_user_client, tacacs_creds, "grep")
191+
check_local_log_exist(duthost, tacacs_creds, "grep")
192+
182193
# Verify syslog not have any command record which not run by user.
183-
check_local_no_other_user_log(rw_user_client, tacacs_creds)
194+
check_local_no_other_user_log(duthost, tacacs_creds)
184195

185196
def test_accounting_tacacs_and_local(ptfhost, duthosts, enum_rand_one_per_hwsku_hostname, tacacs_creds, check_tacacs, rw_user_client):
186197
duthost = duthosts[enum_rand_one_per_hwsku_hostname]
@@ -191,10 +202,10 @@ def test_accounting_tacacs_and_local(ptfhost, duthosts, enum_rand_one_per_hwsku_
191202

192203
# Verify TACACS+ server and syslog have user command record.
193204
check_tacacs_server_log_exist(ptfhost, tacacs_creds, "grep")
194-
check_local_log_exist(rw_user_client, tacacs_creds, "grep")
205+
check_local_log_exist(duthost, tacacs_creds, "grep")
195206
# Verify TACACS+ server and syslog not have any command record which not run by user.
196207
check_tacacs_server_no_other_user_log(ptfhost, tacacs_creds)
197-
check_local_no_other_user_log(rw_user_client, tacacs_creds)
208+
check_local_no_other_user_log(duthost, tacacs_creds)
198209

199210
def test_accounting_tacacs_and_local_all_tacacs_server_down(ptfhost, duthosts, enum_rand_one_per_hwsku_hostname, tacacs_creds, check_tacacs, rw_user_client):
200211
duthost = duthosts[enum_rand_one_per_hwsku_hostname]
@@ -211,9 +222,9 @@ def test_accounting_tacacs_and_local_all_tacacs_server_down(ptfhost, duthosts, e
211222
ssh_run_command(rw_user_client, "grep")
212223

213224
# Verify syslog have user command record.
214-
check_local_log_exist(rw_user_client, tacacs_creds, "grep")
225+
check_local_log_exist(duthost, tacacs_creds, "grep")
215226
# Verify syslog not have any command record which not run by user.
216-
check_local_no_other_user_log(rw_user_client, tacacs_creds)
227+
check_local_no_other_user_log(duthost, tacacs_creds)
217228

218229
# Cleanup UT.
219230
start_tacacs_server(ptfhost)

0 commit comments

Comments
 (0)