py-junos-eznc
py-junos-eznc copied to clipboard
Timeout for Device.open()
I have been going through the code and scratching my head as to how to get Device
to timeout in a reasonable amount of time when I first call open()
. The specific scenario is to have netconf enabled on the device via ssh but the protect RE firewall filter does not allow netconf access. On such a device it takes upwards or 2 minutes to timeout the connection on open()
which gets extremely annoying when I am trying to connect to many devices.
I would like to have the ability to pass a timeout value to open()
to quickly throw an error on a connection that will never open in the first place.
@lampwins We don't yet support passing an initial connection timeout argument, although I agree it would be beneficial.
As an alternative, you can set the auto_probe
argument to the Device()
instantiation or the open()
method. The auto_probe
argument attempts to make a TCP connection to the the port
(default 830) TCP port. If the TCP connection can't be competed within the auto_probe
value number of seconds, then a jnpr.junos.exception.ProbeError
exception is raised.
Here's an example showing a ProbeError
after 5 seconds because r0
isn't really listening for NETCONF over SSH connections on port 666
.
>>> from jnpr.junos.device import Device
>>> dev = Device(host='r0', user='user', passwd='user123', port=666)
>>> dev.open(auto_probe=5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/media/sf_Automation/Projects/PyEZ/Repos/stacywsmith/py-junos-eznc/lib/jnpr/junos/device.py", line 1227, in open
raise EzErrors.ProbeError(self)
jnpr.junos.exception.ProbeError: ProbeError(r0)
>>>
John, You can call dev.timeout and set it to the value you want to timeout at.
from jnpr.junos.device import Device dev = Device(host='r0', user='user', passwd='user123', port=666) dev.open(auto_probe=5) dev.timeout = timeout
On Sep 12, 2017, at 5:08 PM, John Anderson [email protected] wrote:
I have been going through the code and scratching my head as to how to get Device to timeout in a reasonable amount of time when I first call open(). The specific scenario is to have netconf enabled on the device via ssh but the protect RE firewall filter does not allow netconf access. On such a device it takes upwards or 2 minutes to timeout the connection on open() which gets extremely annoying when I am trying to connect to many devices.
I would like to have the ability to pass a timeout value to open() to quickly throw an error on a connection that will never open in the first place.
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/Juniper/py-junos-eznc/issues/780, or mute the thread https://github.com/notifications/unsubscribe-auth/AKorM-KEl82Z4k3q9N03WvJhVBar8NZnks5shxz2gaJpZM4PVab3.
@stacywsmith thank you. I have been playing with auto_probe
and it does cover some of the use cases but I agree that a proper timeout on open()
would be more appropriate.
@derfWayne My understanding is that is the timeout for successive rpc's. My issue is the timeout of the initial device connection via open()
.
My understanding is that is the timeout for successive rpc's. My issue is the timeout of the initial device connection via
open()
.
That's correct. The dev.timeout
attribute sets the default timeout for RPC responses and doesn't effect the connection timeout (in spite of some incorrect documentation that says otherwise.)
I agree that a proper timeout on
open()
would be more appropriate.
Let's use this issue to track that.
what is current timeout value of the open()? is there any plan to fix this issue, am hitting this one on my network. I need to increase the timeout value.
TL;DR: it should be possible to set ssh connect timeout via the "connecttimeout" parameter in ~/.ssh/config (or some other ssh config file with custom path). I did some debugging and looks like:
- PyEZ uses the ncclient library for ssh connections. In ncclient SSHSession.connect() can make use of the "connecttimeout" parameter from an ssh config file, see https://github.com/ncclient/ncclient/blob/v0.6.6/ncclient/transport/ssh.py#L382 (for the current ncclient 0.6.6)
- According to PyEZ documentation https://junos-pyez.readthedocs.io/en/2.2.1/jnpr.junos.html#module-jnpr.junos.device the Device constructor takes an optional parameter: "ssh_config (str) – OPTIONAL The path to the SSH configuration file. This can be used to load SSH information from a configuration file. By default ~/.ssh/config is queried." I tested it by creating ~/.ssh/config with the following content:
connecttimeout=42
and re-run my debugging. The value 42 was read and applied in https://github.com/ncclient/ncclient/blob/v0.6.6/ncclient/transport/ssh.py#L403 BTW the ssh_config man page (see on your computer or e.g. at https://linux.die.net/man/5/ssh_config) says that the keywords are case-insensitive and indeed it is parsed like that (ncclient uses the config parsing of paramiko (ssh client library) which converts the keywords to lowercase).
Update: to test this I created a "black hole" IP address such that all packets sent to it from my computer will be dropped:
sudo iptables -A OUTPUT -d 10.22.215.174 -j DROP
I verified that the command line ssh client now times out in 42s using this IP:
$ time ssh 10.22.215.174
ssh: connect to host 10.22.215.174 port 22: Connection timed out
ssh 10.22.215.174 0,01s user 0,00s system 0% cpu 42,056 total
So far so good. I also verified that socket connect at https://github.com/ncclient/ncclient/blob/v0.6.6/ncclient/transport/ssh.py#L409 timed out in 42s and there was some timeout exception raised. When not using the "connecttimeout" in ~/.ssh/config then I got the jnpr.junos.exception.ConnectTimeoutError in about 96-99 sec (but in your system it might be different).
Update2: at one occasion I saw the timeout happening in about 11 sec (if I am not mistaken). (then again 42 without any code change) Could be a python (3.7.4) or Linux kernel (5.1.21) issue??? But usually it works correctly, so maybe it was an exceptional case.
This should be closed. we can pass conn_open_timeout variable to Device.open()
:param int conn_open_timeout:
*OPTIONAL* To specify the timeout in seconds, which will
be used while opening SSH connection to the device
if it times out, ncclient will raise SSHError("Could not open socket to %s:%s" % (host, port)), and pyez will raise jnpr.junos.exception.ConnectRefusedError as a result.
conn_open_timeout argument supported