require 'net/http'
# Query db to fetch latest ssh known hosts, and store locally for 24 hours.
module Puppet::Parser::Functions
newfunction(:sshkeyfromdb, :type => :rvalue) do |args|
#local cache file on each puppetmaster
ssh_keys_file = "/tmp/sshkeys"
#URL to query
host = "puppet"
url = "/setting/ssh_keys"
#Time to keep cache - e.g. 24 hours.
ttl = (60 * 60 * 24)
# create a cache file
if not File.exist?(ssh_keys_file) or File.mtime(ssh_keys_file) < (Time.now - ttl) # file is older than 24hours.
keys = Net::HTTP.get host,url
File.new(ssh_keys_file,"w", 0600).write(keys)
# convert Marshal to hash
keys = Marshal.load keys
else
keys = Marshal.load File.open(ssh_keys_file).read
end
case args[0].downcase
when nil
warn "Must supply key type - RSA or DSA"
exit 1
when "hosts" # return an array of all hosts has a ssh public key
hosts = Array.new
keys.each_key do |fqdn| # return an array of all hosts
ipaddress = keys[fqdn]["ipaddress"]
hosts << [fqdn, ipaddress, 'ssh-rsa', keys[fqdn]["rsa"]] if keys[fqdn].has_key?('rsa')
hosts << [fqdn, ipaddress, 'ssh-dss', keys[fqdn]["dsa"]] if keys[fqdn].has_key?('dsa')
end
return hosts
end
end
end
USAGE:
class ssh::knownhosts {
$ssh_hosts = sshkeyfromdb(hosts)
# Generate known_hosts out of a template
file{"/etc/ssh/ssh_known_hosts":
owner => root,
group => root,
mode => 644,
content => template("ssh/known_hosts.erb"),
schedule => "maint",
require => Schedule["maint"]
}
}
template:
<%# generate ssh keys from sshkeyfromdb function, not using native sshkey type do to performance difference %>
<% ssh_hosts.each do |host|
fqdn, ipaddress, key_type, key = host[0], host[1], host[2], host[3]
hostname = fqdn.split('.')[0] -%>
<%="#{hostname},#{fqdn},#{ipaddress} #{key_type} #{key}"%>
<%end -%>