py-junos-eznc icon indicating copy to clipboard operation
py-junos-eznc copied to clipboard

Timeout for Device.open()

Open lampwins opened this issue 7 years ago • 7 comments

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 avatar Sep 13 '17 00:09 lampwins

@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)
>>> 

stacywsmith avatar Sep 13 '17 03:09 stacywsmith

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.

derfWayne avatar Sep 13 '17 04:09 derfWayne

@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().

lampwins avatar Sep 13 '17 17:09 lampwins

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.)

stacywsmith avatar Sep 13 '17 17:09 stacywsmith

I agree that a proper timeout on open() would be more appropriate.

Let's use this issue to track that.

stacywsmith avatar Sep 13 '17 17:09 stacywsmith

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.

njayarama avatar May 30 '18 21:05 njayarama

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.

attila123 avatar Sep 04 '19 10:09 attila123

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.

ipmonk avatar Dec 20 '22 05:12 ipmonk

conn_open_timeout argument supported

dineshbaburam91 avatar Feb 27 '24 04:02 dineshbaburam91