Repository: ansible/ansible

Issue:
"junos_config" executes commands fine, but looses connection to the device and PB fails
##### ISSUE TYPE
 - Bug Report

##### COMPONENT NAME
junos_config

##### ANSIBLE VERSION
```
$ ansible --version
ansible 2.4.0 (devel 09ba70f7c4) last updated 2017/05/30 19:37:29 (GMT -600)
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/usr/share/my_modules/']
  ansible python module location = /home/bl839s/ansible/lib/ansible
  executable location = /usr/local/bin/ansible
  python version = 2.7.12 (default, Nov 19 2016, 06:48:10) [GCC 5.4.0 20160609]
```

##### CONFIGURATION
Using `virtualenv` to test `devel` branch of Ansible

##### OS / ENVIRONMENT
```
$ cat /etc/*-release | grep PRETTY
PRETTY_NAME="Ubuntu 16.04.2 LTS"
```
##### SUMMARY
A continuation of a previous bug that was resolved (Issue #25081) When using the module `junos_config`, the change in configuration DOES take place, but the module fails and reports the following:
```
"msg": "unable to connect to socket"
```
##### STEPS TO REPRODUCE
A fairly straight-forward PB:
```$ cat junos_core_config.yml
---

- name: Testing
  hosts: hpr-vba-b
  connection: local
  gather_facts: false

  tasks:

  - name: Testing Junos Core Config Module
    junos_config:
      provider: "{{ creds }}"
      src: EX2200-24T.conf
      update: replace
      confirm: 1
    register: junos_log

  - debug:
      var: junos_log
```
With very simple `src` file:
```
$ cat EX2200-24T.conf
system {
    host-name foo;
}
```
##### EXPECTED RESULTS
Similar to the following galaxy module:
```

PLAY [Testing] ***************************************************************************************************************************************************************************************

TASK [Testing Junos Galaxy Module] *******************************************************************************************************************************************************************
changed: [hpr-vba-b]

TASK [debug] *****************************************************************************************************************************************************************************************
ok: [hpr-vba-b] => {
    "junos_log": {
        "changed": true,
        "file": "/home/bl839s/qos-management/EX2200-24T.conf"
    }
}

PLAY RECAP *******************************************************************************************************************************************************************************************
hpr-vba-b                  : ok=2    changed=1    unreachable=0    failed=0
```
Which contains a very similar PB:
```
$ cat junos_gal_config.yml
---

- name: Testing
  hosts: hpr-vba-b
  connection: local
  gather_facts: false
  roles:
    - Juniper.junos

  tasks:

  - name: Testing Junos Galaxy Module
    junos_install_config:
      host: "{{ creds['host'] }}"
      user: "{{ creds['username'] }}"
      passwd: "{{ creds['password'] }}"
      port: "{{ creds['port'] }}"
      file: EX2200-24T.conf
      replace: yes
      confirm: 1
    register: junos_log

  - debug:
      var: junos_log
```
$ ansible-playbook -i hosts junos_gal_config.yml
##### ACTUAL RESULTS
```
$ ansible-playbook -i hosts junos_core_config.yml -vvvv
ansible-playbook 2.4.0 (devel 09ba70f7c4) last updated 2017/05/30 19:37:29 (GMT -600)
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/usr/share/my_modules/']
  ansible python module location = /home/bl839s/ansible/lib/ansible
  executable location = /usr/local/bin/ansible-playbook
  python version = 2.7.12 (default, Nov 19 2016, 06:48:10) [GCC 5.4.0 20160609]
Using /etc/ansible/ansible.cfg as config file
setting up inventory plugins
Parsed /home/bl839s/qos-management/hosts inventory source with ini plugin
Loading callback plugin default of type stdout, v2.0 from /home/bl839s/ansible/lib/ansible/plugins/callback/__init__.pyc

PLAYBOOK: junos_core_config.yml **********************************************************************************************************************************************************************
1 plays in junos_core_config.yml

PLAY [Testing] ***************************************************************************************************************************************************************************************
META: ran handlers

TASK [Testing Junos Core Config Module] **************************************************************************************************************************************************************
task path: /home/bl839s/qos-management/junos_core_config.yml:10
<hpr-vba-b> using connection plugin netconf
<hpr-vba-b> socket_path: /home/bl839s/.ansible/pc/7dae898068
open_session() returned 0 ok
Using module_utils file /home/bl839s/ansible/lib/ansible/module_utils/_text.py
Using module_utils file /home/bl839s/ansible/lib/ansible/module_utils/basic.py
Using module_utils file /home/bl839s/ansible/lib/ansible/module_utils/junos.py
Using module_utils file /home/bl839s/ansible/lib/ansible/module_utils/netconf.py
Using module_utils file /home/bl839s/ansible/lib/ansible/module_utils/six/__init__.py
Using module_utils file /home/bl839s/ansible/lib/ansible/module_utils/pycompat24.py
Using module_utils file /home/bl839s/ansible/lib/ansible/module_utils/connection.py
Using module_utils file /home/bl839s/ansible/lib/ansible/module_utils/six/_six.py
Using module file /home/bl839s/ansible/lib/ansible/modules/network/junos/junos_config.py
<hpr-vba-b> ESTABLISH LOCAL CONNECTION FOR USER: bl839s
<hpr-vba-b> EXEC /bin/sh -c 'echo ~ && sleep 0'
<hpr-vba-b> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/bl839s/.ansible/tmp/ansible-tmp-1496195290.65-165568177200079 `" && echo ansible-tmp-1496195290.65-165568177200079="` echo /home/bl8
39s/.ansible/tmp/ansible-tmp-1496195290.65-165568177200079 `" ) && sleep 0'
<hpr-vba-b> PUT /tmp/tmphKqm4J TO /home/bl839s/.ansible/tmp/ansible-tmp-1496195290.65-165568177200079/junos_config.py
<hpr-vba-b> EXEC /bin/sh -c 'chmod u+x /home/bl839s/.ansible/tmp/ansible-tmp-1496195290.65-165568177200079/ /home/bl839s/.ansible/tmp/ansible-tmp-1496195290.65-165568177200079/junos_config.py && sle
ep 0'
<hpr-vba-b> EXEC /bin/sh -c '/usr/bin/python /home/bl839s/.ansible/tmp/ansible-tmp-1496195290.65-165568177200079/junos_config.py; rm -rf "/home/bl839s/.ansible/tmp/ansible-tmp-1496195290.65-16556817
7200079/" > /dev/null 2>&1 && sleep 0'
fatal: [hpr-vba-b]: FAILED! => {
    "changed": false,
    "err": "[Errno 111] Connection refused",
    "failed": true,
    "invocation": {
        "module_args": {
            "backup": false,
            "comment": "configured by junos_config",
            "confirm": 1,
            "host": null,
            "lines": null,
            "password": null,
            "port": null,
            "provider": {
                "auth_pass": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
                "host": "hpr-vba-b",
                "password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
                "port": 22,
                "ssh_keyfile": null,
                "timeout": null,
                "transport": null,
                "username": "[REMOVED]"
            },
            "replace": null,
            "rollback": null,
            "src": "system {\n    host-name foo;\n}\n",
            "src_format": null,
            "ssh_keyfile": null,
            "timeout": 10,
            "transport": null,
            "update": "replace",
            "username": null,
            "zeroize": false
        }
    },
    "msg": "unable to connect to socket"
}

PLAY RECAP *******************************************************************************************************************************************************************************************
hpr-vba-b                  : ok=0    changed=0    unreachable=0    failed=1
```
But the change on the device DOES occur:
```
{master:0}
bl839s@hpr-vba-b>

# commit confirmed will be rolled back in less than 1 minute
{master:0}
bl839s@foo>

Broadcast Message from root@hpr-vba-b
        (no tty) at 17:49 UTC...

Commit was not confirmed; automatic rollback complete.


{master:0}
bl839s@hpr-vba-b>
```


Discussion:
cc @Qalthos @ganeshrn
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->
Hi, Can you please follow the steps in https://docs.ansible.com/ansible/network_debug_troubleshooting.html#enabling-networking-logging-and-how-to-read-the-logfile and include those log details. 

I wonder if we are hitting a timeout and the shell (socket) is being closed.
needs_info
As requested.

[ansible hpr-vba-b.txt](https://github.com/ansible/ansible/files/1042104/ansible.hpr-vba-b.txt)

It seems odd that it can initially connect fine, perform the change, and then fail the PB.
Also, after the change takes place and before the "rollback" automatically occurs (due to the commit not being "confirmed") I can run the PB and it connects as well.

I appreciate your help getting to the bottom of this.
We're seeing this as well. My theory is that the config contains a directive to enable netconf over ssh, and this bounces the port ansible is using to configure the device.
Has there been any update on this?  I need to know if this is a legitimate bug or not.
Please let me know if you need additional information.

Thanks,
Brady Lamprecht
I can replicate this issue by just changing the hostname on a device, netconf availability should not be affected in this case.

playbooks/test.yaml:

```---
- name: Apply configuration
  hosts: all
  gather_facts: False
  tasks:
    - name: Juniper Commit
      junos_config:
        lines:
          - set system host-name AMS4-LAB-MX80-01
        src_format: set
        comment: "Push from Ansible"
        provider:
          timeout: 60
```

ansible.cfg:

```[defaults]
transport = ssh
gathering = implicit
host_key_checking = False
inventory = ./scripts/test.sh

[paramiko_connection]
record_host_keys = False
pty = False
look_for_keys = False
host_key_auto_add = True
```

scripts/test.sh:

```
$ ./scripts/test.sh --list
{'all': ['ams4-lab-mx80-03']}

$ ./scripts/test.sh --host=ams4-lab-mx80-03
{'ansible_connection': 'local', 'device_name': 'ams4-lab-mx80-03', 'ansible_ssh_port': 22, 'ansible_ssh_pass': 'password', 'ansible_ssh_user': 'root'}
```

Playbook run command: `ANSIBLE_DEBUG=1 ANSIBLE_LOG_PATH=$(pwd)/ansible.log ansible-playbook playbooks/test.yaml -vvvv`

Ansible log: [ansible.log.txt](https://github.com/ansible/ansible/files/1066411/ansible.log.txt)

Interestingly, I have previously had this working against similar devices. It seems the error is rather intermittent though currently, I can replicate it on every change against this box.

Running with `check_mode: yes` allows this to run successfully every time, with a valid diff being returned. It would appear the issue is during the commit phase.

Resolving patch:
diff --git a/lib/ansible/plugins/action/junos.py b/lib/ansible/plugins/action/junos.py
--- a/lib/ansible/plugins/action/junos.py
+++ b/lib/ansible/plugins/action/junos.py
@@ -60,10 +60,10 @@ def run(self, tmp=None, task_vars=None):
 
         if self._task.action == 'junos_netconf':
             pc.connection = 'network_cli'
-            pc.port = provider['port'] or self._play_context.port or 22
+            pc.port = int(provider['port'] or self._play_context.port or 22)
         else:
             pc.connection = 'netconf'
-            pc.port = provider['port'] or self._play_context.port or 830
+            pc.port = int(provider['port'] or self._play_context.port or 830)
 
         pc.remote_user = provider['username'] or self._play_context.connection_user
         pc.password = provider['password'] or self._play_context.password


Test patch: