Repository: ansible/ansible

Issue:
ssh_pub_keys.py loses ECDSA hash type
##### ISSUE TYPE

 - Bug Report
 - Feature Idea

##### COMPONENT NAME
lib/ansible/module_utils/facts/system/ssh_pub_keys.py

##### ANSIBLE VERSION
```
ansible-playbook 2.4.0 (devel b1d297d144) last updated 2017/08/17 04:53:45 (GMT -700)
  config file = None
  configured module search path = [u'/home/clint/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /home/clint/src/ansible/lib/ansible
  executable location = /home/clint/src/ansible/bin/ansible-playbook
  python version = 2.7.12 (default, Nov 19 2016, 06:48:10) [GCC 5.4.0 20160609]
```

##### CONFIGURATION
N/A

##### OS / ENVIRONMENT
LSB Version:	core-9.20160110ubuntu0.2-amd64:core-9.20160110ubuntu0.2-noarch:security-9.20160110ubuntu0.2-amd64:security-9.20160110ubuntu0.2-noarch
Distributor ID:	Ubuntu
Description:	Ubuntu 16.04.3 LTS
Release:	16.04
Codename:	xenial
##### SUMMARY
If one wants to generate a known_hosts entry from the facts created by the ssh_pub_keys fact collector, theyll have to guess at the ECDSA hash type.

Currently one only gets the key as clue to the key type: "ssh_host_key_ecdsa_public", but ecdsa's have a hash component and can bee one of these:

“ecdsa-sha2-nistp256”, “ecdsa-sha2-nistp384”, “ecdsa-sha2-nistp521”

##### STEPS TO REPRODUCE
Look at facts of any host with SSH keys.

##### EXPECTED RESULTS
Need key type

##### ACTUAL RESULTS
No key type provided.

I recommend another fact key is added with the same name, and _type appended. So one gets

`ssh_host_key_ecdsa_public_type`


Discussion:

Resolving patch:
diff --git a/lib/ansible/module_utils/facts/system/ssh_pub_keys.py b/lib/ansible/module_utils/facts/system/ssh_pub_keys.py
--- a/lib/ansible/module_utils/facts/system/ssh_pub_keys.py
+++ b/lib/ansible/module_utils/facts/system/ssh_pub_keys.py
@@ -31,22 +31,24 @@ class SshPubKeyFactCollector(BaseFactCollector):
 
     def collect(self, module=None, collected_facts=None):
         ssh_pub_key_facts = {}
-        keytypes = ('dsa', 'rsa', 'ecdsa', 'ed25519')
+        algos = ('dsa', 'rsa', 'ecdsa', 'ed25519')
 
         # list of directories to check for ssh keys
         # used in the order listed here, the first one with keys is used
         keydirs = ['/etc/ssh', '/etc/openssh', '/etc']
 
         for keydir in keydirs:
-            for type_ in keytypes:
-                factname = 'ssh_host_key_%s_public' % type_
+            for algo in algos:
+                factname = 'ssh_host_key_%s_public' % algo
                 if factname in ssh_pub_key_facts:
                     # a previous keydir was already successful, stop looking
                     # for keys
                     return ssh_pub_key_facts
-                key_filename = '%s/ssh_host_%s_key.pub' % (keydir, type_)
+                key_filename = '%s/ssh_host_%s_key.pub' % (keydir, algo)
                 keydata = get_file_content(key_filename)
                 if keydata is not None:
-                    ssh_pub_key_facts[factname] = keydata.split()[1]
+                    (keytype, key) = keydata.split()[0:2]
+                    ssh_pub_key_facts[factname] = key
+                    ssh_pub_key_facts[factname + '_keytype'] = keytype
 
         return ssh_pub_key_facts


Test patch: