#!/usr/bin/ruby # Reads the puppet YAML cache and prints out all the resources in it # for each resource it will show the file it was defined in on the # master # # Simply pass in the path to the yaml file # # History: # 2009/07/30 - Initial Release # 2010/02/26 - Add 0.25 Support # 2010/03/01 - Add options to load a new config file, limit resources # and some 0.24 and 0.25 improvements for guessing where # to find the yaml # 2010/03/30 - Improves Puppet 0.25 support thanks to Andy Asquelt # 2010/09/14 - Add Puppet 2.6.x support # # Contact: # R.I.Pienaar - www.devco.net - @ripienaar # fool it into giving me the right config later on so I can guess # about the location of localconfig.yaml as the puppetd would see things $0 = "puppetd" require 'puppet' require 'yaml' require 'optparse' require 'facter' require 'pp' @limit = nil @notags = false OptionParser.new do |opt| opt.banner = "Usage: #{__FILE__} [options] [yaml file]" opt.on("--config [FILE]", "-c", "Config file") do |v| Puppet[:config] = v end opt.on("--limit [TYPE]", "-l", "Limit to resources of type") do |v| @limit = v end opt.on("--no-classes", "--nc", "Don't show classes list") do |v| @noclasses = true end opt.on("--no-tags", "--nt", "Don't show tags list") do |v| @notags = true end opt.on("--help", "-h", "Help") do |v| puts opt exit end end.parse! Puppet.parse_config if Puppet.version =~ /^([0-9]+[.][0-9]+)[.][0-9]+$/ version = $1 unless ["0.25", "0.24", "2.6"].include?(version) puts("Don't know how to print catalogs for verion #{Puppet.version} only 0.24, 0.25 and 2.6 is supported") exit 1 end else puts("Could not figure out version from #{Puppet.version}") exit 1 end # Navigate the hellish mess of changing behaviour 24 v 25 case version when "0.24" ARGV[0] ? localconfig = ARGV[0] : localconfig = "#{Puppet[:localconfig]}.yaml" else facts = Facter.to_hash fqdn = facts['fqdn'] ARGV[0] ? localconfig = ARGV[0] : localconfig = "#{Puppet[:clientyamldir]}/catalog/#{fqdn}.yaml" end unless File.exist?(localconfig) puts("Can't figure out where the localconfig yaml file is, please specify a path") exit 1 end lc = File.open(localconfig) begin pup = Marshal.load(lc) rescue TypeError lc.rewind pup = YAML.load(lc) rescue Exception => e raise end def printbucket(bucket) if bucket.class == Puppet::TransBucket bucket.each do |b| printbucket b end elsif bucket.class == Puppet::TransObject manifestfile = bucket.file.gsub("/etc/puppet/manifests/", "") if @limit if bucket.type == @limit puts "\t#{bucket.type} { #{bucket.name}: }\n\t\tdefined in #{manifestfile}:#{bucket.line}\n\n" end else puts "\t#{bucket.type} { #{bucket.name}: }\n\t\tdefined in #{manifestfile}:#{bucket.line}\n\n" end end end def printresource(resource) if resource.class == Puppet::Resource::Catalog resource.edges.each do |b| printresource b end elsif resource.class == Puppet::Relationship and resource.target.class == Puppet::Resource and resource.target.title != nil and resource.target.file != nil target = resource.target manifestfile = target.file.gsub("/etc/puppet/manifests/", "") if @limit if target.type == @limit puts "\t#{target.type} { #{target.title}: }\n\t\tdefined in #{manifestfile}:#{target.line}\n\n" end else puts "\t#{target.type} { #{target.title}: }\n\t\tdefined in #{manifestfile}:#{target.line}\n\n" end end end unless @noclasses puts("Classes included on this node:") pup.classes.each do |klass| puts("\t#{klass}") end puts("\n\n") end unless version == "0.24" unless @notags == false # 0.24 doesn't have tags in it if pup.respond_to?("tags") puts("Tags for this node:") pup.tags.each do |tag| puts("\t#{tag}") end end puts("\n\n") end end puts("Resources managed by puppet on this node:") if version == "0.24" printbucket pup else printresource pup end