Repository: ansible/ansible

Issue:
Ansible 1.8.2 does not create known_hosts file if none exists when pinging
```
[ec2-user@some_host ~]$ ansible all -m ping

paramiko: The authenticity of host 'some_other_host_a' can't be established.
The ssh-rsa key fingerprint is some_fingerprint.
Are you sure you want to continue connecting (yes/no)?
yes

paramiko: The authenticity of host 'some_other_host_b' can't be established.
The ssh-rsa key fingerprint is some_other_fingerprint.
Are you sure you want to continue connecting (yes/no)?
Traceback (most recent call last):
  File "/usr/lib/python2.6/site-packages/ansible/runner/connection_plugins/paramiko_ssh.py", line 393, in close
    key_stat = os.stat(self.keyfile)
OSError: [Errno 2] No such file or directory: '/home/ec2-user/.ssh/known_hosts'

some_other_host_a | success >> {
    "changed": false,
    "ping": "pong"
}

Traceback (most recent call last):
  File "/usr/lib/python2.6/site-packages/ansible/runner/connection_plugins/paramiko_ssh.py", line 393, in close
    key_stat = os.stat(self.keyfile)
OSError: [Errno 2] No such file or directory: '/home/ec2-user/.ssh/known_hosts'
some_other_host_b | success >> {
    "changed": false,
    "ping": "pong"
}
```



Discussion:
Note: this only happens with:
- No known_hosts file: so have to remove ~/.ssh/known_hosts
- paramiko rather than ssh:

```
mv ~/.ssh/known_hosts ~/.ssh/known_hosts.bak
ansible -i '127.0.0.5,127.0.0.6' all -m ping -c paramiko
```

This doesn't seem to be an issue with current devel:

```
[11:41] ebastos@main:~/projects/github/ansible (devel)$ rm ~/.ssh/known_hosts                                                                                                                                                                                                  
[11:41] ebastos@main:~/projects/github/ansible (devel)$ ansible  test -m ping -c paramiko -vvv -k                                                                                                                                                                        
SSH password:                                                                                                                                                                                                                                                                  
<10.0.2.21> ESTABLISH CONNECTION FOR USER: ebastos on PORT 22 TO 10.0.2.21                                                                                                                                                                                                     
<10.0.2.21> REMOTE_MODULE ping                                                                                                                                                                                                                                                 
<10.0.2.21> EXEC /bin/sh -c 'mkdir -p $HOME/.ansible/tmp/ansible-tmp-1427121689.09-195068587207183 && chmod a+rx $HOME/.ansible/tmp/ansible-tmp-1427121689.09-195068587207183 && echo $HOME/.ansible/tmp/ansible-tmp-1427121689.09-195068587207183'                            
<10.0.2.21> PUT /tmp/tmp6iPnEL TO /home/ebastos/.ansible/tmp/ansible-tmp-1427121689.09-195068587207183/ping                                                                                                                                                                    
<10.0.2.21> EXEC /bin/sh -c 'LANG=en_US.UTF-8 LC_CTYPE=en_US.UTF-8 /usr/bin/python /home/ebastos/.ansible/tmp/ansible-tmp-1427121689.09-195068587207183/ping; rm -rf /home/ebastos/.ansible/tmp/ansible-tmp-1427121689.09-195068587207183/ >/dev/null 2>&1'                    
10.0.2.21 | success >> {                                                                                                                                                                                                                                                       
    "changed": false,
    "ping": "pong"
}
```

HI @tmwilder based on @ebastos' comment above, are you still seeing this issue with the current devel?

Still seeing the issue on a Centos 6.5 host running 1.9.2.

@tmwilder 
I have the same issue on Centos 6.5 running ansible 1.9.2(installed from epel).
I had to run 'touch ~/.ssh/known_hosts', before run ansible first.

I am seeing this issue on ansible 1.9.2 on CentOS release 6.5 (Final).

Got same problem

```
# cat /etc/redhat-release
CentOS release 6.5 (Final)
#ansible --version
ansible 1.9.4
```

Running into this on OS-X.  Installed with `brew install ansible`.  

```
$ ansible --version
ansible 2.1.0.0
  config file = 
  configured module search path = Default w/o overrides
```

It happened with the example on pp 15-18 of _Ansible for Devops_.  No special `ssh` configuration.  I did have to put the `hosts` file in `/usr/local/etc/ansible`, rather than the `/etc/local/ansible` location recommended by the book.

Reproduced with 2.1.1RC1

```
###################################
v2.1.1.0-0.1.rc1
###################################
No config file found; using defaults
Loaded callback minimal of type stdout, v2.0
<10.0.0.106> ESTABLISH CONNECTION FOR USER: root on PORT 22 TO 10.0.0.106
<10.0.0.106> CONNECTION: pid 17094 waiting for lock on 5
<10.0.0.106> CONNECTION: pid 17094 acquired lock on 5

paramiko: The authenticity of host '10.0.0.106' can't be established.
The ssh-rsa key fingerprint is 43de187a243a7b707436a4dabbbe5037.
Are you sure you want to continue connecting (yes/no)?
yes
<10.0.0.106> CONNECTION: pid 17094 released lock on 5
<10.0.0.106> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo $HOME/.ansible/tmp/ansible-tmp-1467402171.52-233172936493924 `" && echo ansible-tmp-1467402171.52-233172936493924="` echo $HOME/.ansible/tmp/ansible-tmp-1467402171.52-233172936493924 `" ) && sleep 0'
<10.0.0.106> PUT /tmp/tmpBY6qXM TO /root/.ansible/tmp/ansible-tmp-1467402171.52-233172936493924/ping
<10.0.0.106> EXEC /bin/sh -c 'LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8 /usr/bin/python /root/.ansible/tmp/ansible-tmp-1467402171.52-233172936493924/ping; rm -rf "/root/.ansible/tmp/ansible-tmp-1467402171.52-233172936493924/" > /dev/null 2>&1 && sleep 0'
Traceback (most recent call last):
  File "/tmp/ansible.v2.1.1.0-0.1.rc1/lib/ansible/plugins/connection/paramiko_ssh.py", line 445, in close
    key_stat = os.stat(self.keyfile)
OSError: [Errno 2] No such file or directory: '/home/jtanner/.ssh/known_hosts'
el6host | SUCCESS => {
    "changed": false, 
    "invocation": {
        "module_args": {
            "data": null
        }, 
        "module_name": "ping"
    }, 
    "ping": "pong"
}
## RC: 
```


Resolving patch:
diff --git a/lib/ansible/plugins/connection/paramiko_ssh.py b/lib/ansible/plugins/connection/paramiko_ssh.py
--- a/lib/ansible/plugins/connection/paramiko_ssh.py
+++ b/lib/ansible/plugins/connection/paramiko_ssh.py
@@ -442,15 +442,23 @@ def close(self):
                 # we can ensure the new file has the correct mode/owner
 
                 key_dir  = os.path.dirname(self.keyfile)
-                key_stat = os.stat(self.keyfile)
+                if os.path.exists(self.keyfile):
+                    key_stat = os.stat(self.keyfile)
+                    mode = key_stat.st_mode
+                    uid = key_stat.st_uid
+                    gid = key_stat.st_gid
+                else:
+                    mode = 33188
+                    uid = os.getuid()
+                    gid = os.getgid()
 
                 # Save the new keys to a temporary file and move it into place
                 # rather than rewriting the file. We set delete=False because
                 # the file will be moved into place rather than cleaned up.
 
                 tmp_keyfile = tempfile.NamedTemporaryFile(dir=key_dir, delete=False)
-                os.chmod(tmp_keyfile.name, key_stat.st_mode & 0o7777)
-                os.chown(tmp_keyfile.name, key_stat.st_uid, key_stat.st_gid)
+                os.chmod(tmp_keyfile.name, mode & 0o7777)
+                os.chown(tmp_keyfile.name, uid, gid)
 
                 self._save_ssh_host_keys(tmp_keyfile.name)
                 tmp_keyfile.close()


Test patch: