-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
utils: added password_with_output function to capture ssh output #72
Conversation
2c99d8a
to
fb49ab4
Compare
I don't know how I feel about this, yet. Using expect to issue a double SSH connection. This is what the test is looking like.
|
I don't like it, taking it out of "ready for review" |
eeab4f6
to
0115da9
Compare
I removed the gssapi stuff for now and just made this PR about capturing the ssh output for some test cases. |
0291205
to
ffd73ea
Compare
|
Is this ready for review? |
Yup. |
f77db47
to
3d149c0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is much better! Thanks for taking into account the feedback.
6ad9871
to
89d3d82
Compare
I had to fix the return type on the password function, @ikerexxe that has been updated. |
Ack. But since we are doing this, I would like to add one more thing to the return value, to avoid changing it later again. It should return (expect return code, spawned command return code, stdout, stderr). I also added next-actions/pytest-mh@ee357a9 so we can capture only the ssh output. Please, consider the following change: diff --git a/sssd_test_framework/utils/authentication.py b/sssd_test_framework/utils/authentication.py
index 8727791..aaa0b68 100644
--- a/sssd_test_framework/utils/authentication.py
+++ b/sssd_test_framework/utils/authentication.py
@@ -413,7 +413,7 @@ class SSHAuthenticationUtils(MultihostUtility[MultihostHost]):
self.opts = "-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no"
"""SSH CLI options."""
- def password_with_output(self, username: str, password: str) -> tuple[int, str, str]:
+ def password_with_output(self, username: str, password: str) -> tuple[int, int, str, str]:
"""
SSH to the remote host and authenticate the user with password and captures standard output and error.
@@ -421,16 +421,34 @@ class SSHAuthenticationUtils(MultihostUtility[MultihostHost]):
:type username: str
:param password: User password.
:type password: str
- :return: Tuple containing [return code, standard out, standard error].
- :rtype: Tuple[int, str, str]
+ :return: Tuple containing [except return code, command exit code, stdout, stderr].
+ :rtype: Tuple[int, int, str, str]
"""
result = self.host.ssh.expect_nobody(
rf"""
+ # Disable debug output
+ exp_internal 0
+
+ proc exitmsg {{ msg code }} {{
+ # Send EOF, if we are in the prompt
+ send \x04;
+
+ # Wait for the exit code
+ lassign [wait] pid spawnid os_error_flag rc
+
+ puts ""
+ puts "expect result: $msg"
+ puts "expect exit code: $code"
+ puts "expect spawn exit code: $rc"
+ exit $code
+ }}
+
# It takes some time to get authentication failure
set timeout {DEFAULT_AUTHENTICATION_TIMEOUT}
set prompt "\n.*\[#\$>\] $"
log_user 1
+ log_file /tmp/expect.log
spawn ssh {self.opts} \
-o PreferredAuthentications=password \
@@ -439,27 +457,35 @@ class SSHAuthenticationUtils(MultihostUtility[MultihostHost]):
expect {{
"password:" {{send "{password}\n"}}
- timeout {{puts "expect result: Unexpected output"; exit 201}}
- eof {{puts "expect result: Unexpected end of file"; exit 202}}
+ timeout {{exitmsg "Unexpected output" 201}}
+ eof {{exitmsg "Unexpected end of file" 202}}
}}
expect {{
- -re $prompt {{puts "expect result: Password authentication successful"; exit 0}}
- "{username}@localhost: Permission denied" {{puts "expect result: Authentication failure"; exit 1}}
- "Connection closed by UNKNOWN port 65535" {{puts "expect result: Connection closed"; exit 2}}
- timeout {{puts "expect result: Unexpected output"; exit 201}}
- eof {{puts "expect result: Unexpected end of file"; exit 202}}
+ -re $prompt {{exitmsg "Password authentication successful" 0}}
+ "{username}@localhost: Permission denied" {{exitmsg "Authentication failure" 1}}
+ "Connection closed by UNKNOWN port 65535" {{exitmsg "Connection closed" 2}}
+ timeout {{exitmsg "Unexpected output" 201}}
+ eof {{exitmsg "Unexpected end of file" 202}}
}}
- puts "expect result: Unexpected code path"
- exit 203
- """
+ exitmsg "Unexpected code path" 203
+ """,
+ verbose=False,
)
if result.rc > 200:
raise ExpectScriptError(result.rc)
- return result.rc, result.stdout, result.stderr
+ expect_data = result.stdout_lines[-3:]
+
+ # Get command exit code.
+ cmdrc = int(expect_data[2].split(":")[1].strip())
+
+ # Alter stdout, first line is spawned command, the last three are our expect output.
+ stdout = "\n".join(result.stdout_lines[1:-3])
+
+ return result.rc, cmdrc, stdout, result.stderr
def password(self, username: str, password: str) -> bool:
"""
@@ -472,7 +498,7 @@ class SSHAuthenticationUtils(MultihostUtility[MultihostHost]):
:return: True if authentication was successful, False otherwise.
:rtype: bool
"""
- rc, _, _ = self.password_with_output(username, password)
+ rc, _, _, _ = self.password_with_output(username, password)
return rc == 0
def password_expired(self, username: str, password: str, new_password: str) -> bool: |
@pbrezina That's fine with me, I applied your patch. |
@ikerexxe Do you want to look at latest changes? |
No need. I'm sure they've improved the code. |
some test cases will need to check the ssh output