Puppet Function: ssh::global_known_hosts
- Defined in:
- lib/puppet/functions/ssh/global_known_hosts.rb
- Function type:
- Ruby 4.x API
Summary
Update the ssh_known_hosts files for all hosts, purging old files,Overview
removing duplicates, and creating catalog resources that are found
Note: This function if marked as an InternalFunction because it
changes the state of the system by adding/removing files and
adding catalog resources.
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/puppet/functions/ssh/global_known_hosts.rb', line 8 Puppet::Functions.create_function(:'ssh::global_known_hosts', Puppet::Functions::InternalFunction) do # @param expire_days expire time in days; defaults to 7; value of 0 # means never purge # # @return [None] dispatch :global_known_hosts do optional_param 'Integer', :expire_days end def global_known_hosts(expire_days = 7) require 'yaml' require 'find' require 'fileutils' env = closure_scope.lookupvar('::environment') basedir = "#{Puppet[:vardir]}/simp/environments/#{env}/simp_autofiles/ssh_global_known_hosts" # First, write out my key. write_this_host_key_file(basedir) # Now read all keys, resolve duplicates, and update the catalogue. update_catalog(basedir, expire_days) # Finally, purge any keys past the expire date. If the date is set to 0, # then don't purge. if expire_days != 0 then Dir.glob("#{basedir}/*").each do |file| if (Time.now - File.stat(file).mtime)/86400 > expire_days then FileUtils.rm(file) end end end end def write_this_host_key_file(basedir) #FIXME accessing facts per the documentation doesn't work in unit tests # fqdn = closure_scope['facts']['networking']['fqdn'] # rsakey = closure_scope['facts']['sshrsakey'] fqdn = closure_scope.lookupvar('::fqdn') rsakey = closure_scope.lookupvar('::sshrsakey') begin if not FileTest.directory?(basedir) then FileUtils.mkdir_p(basedir, mode: 0750) end if not File.stat(basedir).writable? then fail("ssh::global_known_hosts: Error, can't write #{basedir}") end rescue fail("ssh::global_known_hosts: Error, #{basedir} must be writable by #{Process.uid}") end hostkey = File.open("#{basedir}/#{fqdn}",'w+',0640) hostkey.puts(rsakey) hostkey.close end def collect_hostnames(basedir) hnames = { :longnames => [], :shortnames => [] } # Collect current list of hostnames Find.find(basedir) do |file| if ( not FileTest.directory?(file) ) and FileTest.readable?(file) hname = File.basename(file).strip if hname.include?('.') then hnames[:longnames] << hname else hnames[:shortnames] << hname end end end # Remove any old files that exist that have newer conflicts. hnames[:shortnames].dup.each do |short_name| long_dup = hnames[:longnames].find{|x| x =~ /^#{short_name}\..*$/ } if long_dup then to_del = nil if File.stat("#{basedir}/#{short_name}").mtime < File.stat("#{basedir}/#{long_dup}").mtime then hnames[:shortnames].delete(short_name) to_del = "#{basedir}/#{short_name}" else hnames[:longnames].delete(long_dup) to_del = "#{basedir}/#{long_dup}" end #FIXME Shouldn't we remove/modify to ensure-absent any existing catalog entry for # the file we will be deleting? Puppet.notice("ssh::global_known_hosts is removing '#{to_del}' due to a conflict.") FileUtils.rm_f(to_del) end end (hnames[:longnames] + hnames[:shortnames]) end def update_catalog(basedir, expire_days) hnames = collect_hostnames(basedir) hnames.each do |hname| file = "#{basedir}/#{hname}" ssh_ensure = 'present' if expire_days != 0 then if (Time.now - File.stat(file).mtime)/86400 > expire_days then ssh_ensure = 'absent' end end sshkey_resource_hash = { hname=> { :type => 'ssh-rsa', :host_aliases => hname.split('.').first, :key => File.open(file,'r').read.strip, :ensure => ssh_ensure } } begin call_function('create_resources', 'sshkey', sshkey_resource_hash) rescue Puppet::Resource::Catalog::DuplicateResourceError => e # FIXME This will fail if the resource exists. We should either # remove any existing resource before creating it, or modify it in # case any of the existing parameters are wrong (notably ensure). end end end end |