ansible-junos-stdlib icon indicating copy to clipboard operation
ansible-junos-stdlib copied to clipboard

PyEZ connection fails when ~/.ssh/config has a IdentityFile option for target hosts

Open p3rdu opened this issue 1 year ago • 1 comments

Issue Type

  • Bug Report

Module Name

Concerns any module from the juniper.device collection e.g. juniper.device.facts

Juniper.device collection and Python libraries version

$ ansible --version
ansible 2.10.8
  config file = None
  configured module search path = ['/home/user/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3/dist-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.10.12 (main, Jun 11 2023, 05:26:28) [GCC 11.4.0]

$ pip freeze | grep "junos\|paramiko"
junos-eznc==2.6.7
paramiko==2.9.3

# /home/user/.ansible/collections/ansible_collections
Collection     Version
-------------- -------
juniper.device 1.0.2  

OS / Environment

QFX5120-48Y version 22.2R3.15

Summary

If Ansible control node has an IdentityFile option set for managed hosts in ~/.ssh/config then executing a playbook results in PyEZ connection error. If one comments the IdentityFile option out then the playbook executes normally.

Steps to reproduce

ping.yml:

---
- name: Get Device Facts
  hosts: all
  connection: juniper.device.pyez
  gather_facts: no

  tasks:
    - name: Retrieve facts from devices running Junos OS
      juniper.device.facts:  
      
    - name: Print version
      debug:
        var: junos.version

~/.ssh/config:

Host v1-* v2-*
  User perttu
  IdentityFile ~/.ssh/juniper-id_rsa

Command

user@admin-host:~/vxlan-bgp-evpn-fabric/juniper$ ansible-playbook ping.yml -l v1-leaf1

Expected results

PLAY [Get Device Facts] ****************************************************************************************

TASK [Retrieve facts from devices running Junos OS] ************************************************************
ok: [v1-leaf1]

TASK [Print version] *******************************************************************************************
ok: [v1-leaf1] => {
    "junos.version": "22.2R3.15"
}

PLAY RECAP *****************************************************************************************************
v1-leaf1                   : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

If I comment out the IdentityFile in the ssh/config

Host v1-* v2-*
  User perttu
 # IdentityFile ~/.ssh/juniper-id_rsa

or add a variable ssh_config in the playbook with some nonexistent content the playbook works again

vars:
  ssh_config: "asdf"

Actual results

user@admin-host:~/vxlan-bgp-evpn-fabric/juniper$ ansible-playbook -vvv ping.yml -l v1-leaf1

ansible-playbook 2.10.8
  config file = /home/user/vxlan-bgp-evpn-fabric/juniper/ansible.cfg
  configured module search path = ['/home/user/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3/dist-packages/ansible
  executable location = /usr/bin/ansible-playbook
  python version = 3.10.12 (main, Jun 11 2023, 05:26:28) [GCC 11.4.0]
Using /home/user/vxlan-bgp-evpn-fabric/juniper/ansible.cfg as config file
host_list declined parsing /home/user/vxlan-bgp-evpn-fabric/juniper/hosts as it did not pass its verify_file() method
script declined parsing /home/user/vxlan-bgp-evpn-fabric/juniper/hosts as it did not pass its verify_file() method
auto declined parsing /home/user/vxlan-bgp-evpn-fabric/juniper/hosts as it did not pass its verify_file() method
Skipping empty key (hosts) in group (all)
Parsed /home/user/vxlan-bgp-evpn-fabric/juniper/hosts inventory source with yaml plugin
Skipping callback 'default', as we already have a stdout callback.
Skipping callback 'minimal', as we already have a stdout callback.
Skipping callback 'oneline', as we already have a stdout callback.

PLAYBOOK: ping.yml *************************************************************************************************************************
1 plays in ping.yml

PLAY [Get Device Facts] ********************************************************************************************************************
META: ran handlers

TASK [Retrieve facts from devices running Junos OS] ****************************************************************************************
task path: /home/user/vxlan-bgp-evpn-fabric/juniper/ping.yml:8
<v1-leaf1.local> ESTABLISH LOCAL CONNECTION FOR USER: user
<v1-leaf1.local> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/user/.ansible/tmp/ansible-local-34119095do66r `"&& mkdir "` echo /home/user/.ansible/tmp/ansible-local-34119095do66r/ansible-tmp-1692703777.3118594-34122-266155588055694 `" && echo ansible-tmp-1692703777.3118594-34122-266155588055694="` echo /home/user/.ansible/tmp/ansible-local-34119095do66r/ansible-tmp-1692703777.3118594-34122-266155588055694 `" ) && sleep 0'
Using module file /home/user/.ansible/collections/ansible_collections/juniper/device/plugins/modules/facts.py
<v1-leaf1.local> PUT /home/user/.ansible/tmp/ansible-local-34119095do66r/tmpviuubr1o TO /home/user/.ansible/tmp/ansible-local-34119095do66r/ansible-tmp-1692703777.3118594-34122-266155588055694/AnsiballZ_facts.py
<v1-leaf1.local> EXEC /bin/sh -c 'chmod u+x /home/user/.ansible/tmp/ansible-local-34119095do66r/ansible-tmp-1692703777.3118594-34122-266155588055694/ /home/user/.ansible/tmp/ansible-local-34119095do66r/ansible-tmp-1692703777.3118594-34122-266155588055694/AnsiballZ_facts.py && sleep 0'
<v1-leaf1.local> EXEC /bin/sh -c '/usr/bin/python3 /home/user/.ansible/tmp/ansible-local-34119095do66r/ansible-tmp-1692703777.3118594-34122-266155588055694/AnsiballZ_facts.py && sleep 0'
<v1-leaf1.local> EXEC /bin/sh -c 'rm -f -r /home/user/.ansible/tmp/ansible-local-34119095do66r/ansible-tmp-1692703777.3118594-34122-266155588055694/ > /dev/null 2>&1 && sleep 0'
The full traceback is:
Traceback (most recent call last):
  File "/home/user/.ansible/tmp/ansible-local-34119095do66r/ansible-tmp-1692703777.3118594-34122-266155588055694/AnsiballZ_facts.py", line 102, in <module>
    _ansiballz_main()
  File "/home/user/.ansible/tmp/ansible-local-34119095do66r/ansible-tmp-1692703777.3118594-34122-266155588055694/AnsiballZ_facts.py", line 94, in _ansiballz_main
    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
  File "/home/user/.ansible/tmp/ansible-local-34119095do66r/ansible-tmp-1692703777.3118594-34122-266155588055694/AnsiballZ_facts.py", line 40, in invoke_module
    runpy.run_module(mod_name='ansible_collections.juniper.device.plugins.modules.facts', init_globals=None, run_name='__main__', alter_sys=True)
  File "/usr/lib/python3.10/runpy.py", line 224, in run_module
    return _run_module_code(code, init_globals, run_name, mod_spec)
  File "/usr/lib/python3.10/runpy.py", line 96, in _run_module_code
    _run_code(code, mod_globals, init_globals,
  File "/usr/lib/python3.10/runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "/tmp/ansible_juniper.device.facts_payload_iwmmzaf5/ansible_juniper.device.facts_payload.zip/ansible_collections/juniper/device/plugins/modules/facts.py", line 369, in <module>
  File "/tmp/ansible_juniper.device.facts_payload_iwmmzaf5/ansible_juniper.device.facts_payload.zip/ansible_collections/juniper/device/plugins/modules/facts.py", line 311, in main
  File "/tmp/ansible_juniper.device.facts_payload_iwmmzaf5/ansible_juniper.device.facts_payload.zip/ansible_collections/juniper/device/plugins/module_utils/juniper_junos_common.py", line 630, in __init__
  File "/tmp/ansible_juniper.device.facts_payload_iwmmzaf5/ansible_juniper.device.facts_payload.zip/ansible_collections/juniper/device/plugins/module_utils/juniper_junos_common.py", line 691, in get_connection
  File "/tmp/ansible_juniper.device.facts_payload_iwmmzaf5/ansible_juniper.device.facts_payload.zip/ansible_collections/juniper/device/plugins/module_utils/juniper_junos_common.py", line 707, in get_capabilities
  File "/tmp/ansible_juniper.device.facts_payload_iwmmzaf5/ansible_juniper.device.facts_payload.zip/ansible/module_utils/connection.py", line 195, in __rpc__
ansible.module_utils.connection.ConnectionError: Unable to make a PyEZ connection: ConnectAuthError(v1-leaf1.local)
fatal: [v1-leaf1]: FAILED! => {
    "changed": false,
    "module_stderr": "Traceback (most recent call last):\n  File \"/home/user/.ansible/tmp/ansible-local-34119095do66r/ansible-tmp-1692703777.3118594-34122-266155588055694/AnsiballZ_facts.py\", line 102, in <module>\n    _ansiballz_main()\n  File \"/home/user/.ansible/tmp/ansible-local-34119095do66r/ansible-tmp-1692703777.3118594-34122-266155588055694/AnsiballZ_facts.py\", line 94, in _ansiballz_main\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n  File \"/home/user/.ansible/tmp/ansible-local-34119095do66r/ansible-tmp-1692703777.3118594-34122-266155588055694/AnsiballZ_facts.py\", line 40, in invoke_module\n    runpy.run_module(mod_name='ansible_collections.juniper.device.plugins.modules.facts', init_globals=None, run_name='__main__', alter_sys=True)\n  File \"/usr/lib/python3.10/runpy.py\", line 224, in run_module\n    return _run_module_code(code, init_globals, run_name, mod_spec)\n  File \"/usr/lib/python3.10/runpy.py\", line 96, in _run_module_code\n    _run_code(code, mod_globals, init_globals,\n  File \"/usr/lib/python3.10/runpy.py\", line 86, in _run_code\n    exec(code, run_globals)\n  File \"/tmp/ansible_juniper.device.facts_payload_iwmmzaf5/ansible_juniper.device.facts_payload.zip/ansible_collections/juniper/device/plugins/modules/facts.py\", line 369, in <module>\n  File \"/tmp/ansible_juniper.device.facts_payload_iwmmzaf5/ansible_juniper.device.facts_payload.zip/ansible_collections/juniper/device/plugins/modules/facts.py\", line 311, in main\n  File \"/tmp/ansible_juniper.device.facts_payload_iwmmzaf5/ansible_juniper.device.facts_payload.zip/ansible_collections/juniper/device/plugins/module_utils/juniper_junos_common.py\", line 630, in __init__\n  File \"/tmp/ansible_juniper.device.facts_payload_iwmmzaf5/ansible_juniper.device.facts_payload.zip/ansible_collections/juniper/device/plugins/module_utils/juniper_junos_common.py\", line 691, in get_connection\n  File \"/tmp/ansible_juniper.device.facts_payload_iwmmzaf5/ansible_juniper.device.facts_payload.zip/ansible_collections/juniper/device/plugins/module_utils/juniper_junos_common.py\", line 707, in get_capabilities\n  File \"/tmp/ansible_juniper.device.facts_payload_iwmmzaf5/ansible_juniper.device.facts_payload.zip/ansible/module_utils/connection.py\", line 195, in __rpc__\nansible.module_utils.connection.ConnectionError: Unable to make a PyEZ connection: ConnectAuthError(v1-leaf1.local)\n",
    "module_stdout": "",
    "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
    "rc": 1
}

PLAY RECAP *********************************************************************************************************************************
v1-leaf1                   : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   

p3rdu avatar Aug 23 '23 08:08 p3rdu