Transport Inconsistency
See original GitHub issueDescribe the bug When using different transport layers (telnet vs ssh) the read / write commands don’t quite seem to behave the same way. Meaning the Driver has to understand what Transport is being used to function consistently across all transports. Based on my interpretation of the docs it would seem they should be transparent to the docs.
It is definitely possible the device I am connecting to is behaving poorly but that is harder to tell. I can sit in wireshark and read all of telnet, but not so much when its ssh.
I am working on a python API wrapper for more recent WattBoxs, where they no longer have the nice REST API and only have a telnet / ssh API. Its identical in its behavior between the two protocols, just how you connect is different.
Once you are logged in you are met with Successfully Logged In!\n
so you are in a terminal on a new line with nothing else on it. You can type in various input commands starting with either ?
(to get info) or !
(to set things) and it will respond back with your ?
and additional info or an Ok\n
or #Error\n
Docs Here if they matter.
To Reproduce
from scrapli import Driver
MY_DEVICE = {
"host": "...",
"auth_username": "...",
"auth_password": "...",
"auth_strict_key": False,
}
tconn = Driver(
**MY_DEVICE,
port=23,
transport="telnet",
# This was the best way I found to get it through all the login prompts
comms_prompt_pattern=r"^Successfully Logged In!\n$"
)
tconn.open()
# It doesn't really have "prompts", just sends a line, this seems to work
tconn._base_channel_args.comms_prompt_pattern = r"^.*$"
# Send a command
tconn.channel.write("?Firmware\n")
print(tconn.channel.read())
# b'?Firmware=2.2.1.0\n'
# Exactly the same settings and commands other then port / transport.
sconn = Driver(
**MY_DEVICE,
port=22,
transport="ssh2",
comms_prompt_pattern=r"^Successfully Logged In!\n$"
)
sconn.open()
sconn._base_channel_args.comms_prompt_pattern = r"^.*$"
# Two extra `.read` here necessary to get through the logged in message
print(sconn.channel.read())
# b'Connecting...\n'
print(sconn.channel.read())
# b'Successfully Logged In!\n'
# Send the same command
conn.channel.write("?Firmware\n")
print(sconn.channel.read())
# b'?Firmware\n?Firmware=2.2.1.0\n'
# Where the `.read` includes what I sent with `.write` and the response from telnet read.
Expected behavior
Consistent behavior between transport layers so I can write one Driver which can use telnet
, asynctelnet
, ssh2
, or asyncssh
to control the system depending on the user’s needs.
OS (please complete the following information):
- OS: Ubuntu 22.04
- scrapli version: 2022.7.30
Additional context
I also cannot use the channel.send_input
command because it will .write
then _read_until_input
which reads the actual response but tosses it, then sends an extra \n
which gets an #Error
response. And if I don’t include the \n
in my message it won’t ever get anything for _read_until_input
since the server is still waiting on the \n
.
If this is expected behavior, any tips for working around this without having to write a bunch of extra logic around the transport in a Driver?
Issue Analytics
- State:
- Created a year ago
- Comments:6 (4 by maintainers)
thats right, you already mentioned that, sorry!
telnet things behaving the same and ssh things behaving the same makes me feel like things are reasonably well behaved so thats good to hear!
I guess at this point I’ll go ahead and close this out – feel free to reach out or move this to a discussion (so I can be at zero issues to appease my ocd!) if ya wanna chat more. Hoping you can get things working nicely!
Carl
I just got thrown off because effectively the telnet ones do a
_read_until_prompt
for you during theopen
, where the ssh ones do not, and you have to do it yourself. I initially expected all of them to get to the same spot when callingopen
, but not a big deal.I was thinking about doing that same thing by overriding
open
, but anon_open
does seem to be nicer.Eager sadly doesn’t work for what I am seeing.
Telnet / AsyncTelnet have behaved the same so far. And SSH2 / AsyncSSH have behaved the same so far. If I remember correctly I didn’t manage to get System to connect at all, and haven’t checked Paramiko. I’ll try to check both of those next time I take a crack at it.
I am way out of my element here. Quite different than the REST APIs I am used to. So, really not sure what is sensible and what isn’t. Asking Telnet and SSH to behave the same probably is a bit of a stretch. And since this device seems to be quite unique, I can’t imagine it makes any sense to add potentially breaking changes to the library when I can just work around them.