eaiovnaovbqoebvqoeavibavo ext/puppetlisten/puppetlisten.rb000075500000003717147633135120013201 0ustar00#! /usr/bin/env ruby # this is a daemon which accepts non standard (within puppet normal intervals) puppet configruation run request # uses SSL for communication based on the puppet infrastructure # ohadlevy@gmail.com port = 8139 cmd = "puppetd -o -v --no-daemonize" require 'puppet/sslcertificates/support' require 'socket' require 'facter' # load puppet configuration, needed to find SSL certificates Puppet.initialize_settings # set the SSL environment ctx = OpenSSL::SSL::SSLContext.new ctx.key = OpenSSL::PKey::RSA.new(File::read(Puppet[:hostprivkey])) ctx.cert = OpenSSL::X509::Certificate.new(File::read(Puppet[:hostcert])) ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER|OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT ctx.ca_file = Puppet[:localcacert] # find which hosts are allowed to trigger us allowed_servers = Array.new runner = false; File.open(Puppet[:authconfig]).each do |line| case line when /^\s*#/: next # skip comments when /^\s*$/: next # skip blank lines when /\[puppetrunner\]/: # puppetrunner section runner=true when /^\s*(\w+)\s+(.+)$/: var = $1 value = $2 case var when "allow": value.split(/\s*,\s*/).each { |val| allowed_servers << val puts "allowing #{val} access" } if runner==true end else runner=false end end # be a daemon sock = TCPServer.new(port) ssls = OpenSSL::SSL::SSLServer.new(sock, ctx) loop do begin ns = ssls.accept # start SSL session af, port, host, ip = ns.peeraddr print "connection from #{host+"("+ip+")"} " if allowed_servers.include?(host) #TODO add support for tags and other command line arguments puts "accepted" ns.puts "Executing #{cmd} on #{Facter.fqdn}.\n*******OUTPUT********\n\n" IO.popen(cmd) do |f| while line = f.gets ns.puts line end end ns.puts "\n*********DONE**********" else ns.puts "denied\n" puts "denied" end ns.close rescue ns.close next end end ext/puppetlisten/puppetrun.rb000075500000002065147633135120012502 0ustar00#! /usr/bin/env ruby # this scripts calls a client and ask him to trigger a puppetd run # uses SSL for communication based on the puppet infrastructure # the client allows access based on the namespaceauth # ohadlevy@gmail.com port = 8139 if ARGV[0].nil? warn "Usage: hostname to run against" exit 1 else host = ARGV[0] end require 'puppet/sslcertificates/support' require 'socket' # load puppet configuration, needed to find ssl certificates Puppet.initialize_settings # establish the certificate ctx = OpenSSL::SSL::SSLContext.new ctx.key = OpenSSL::PKey::RSA.new(File::read(Puppet[:hostprivkey])) ctx.cert = OpenSSL::X509::Certificate.new(File::read(Puppet[:hostcert])) ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER ctx.ca_file = Puppet[:localcacert] # establish the connection s = TCPSocket.new(host, port) ssl = OpenSSL::SSL::SSLSocket.new(s, ctx) ssl.connect # start SSL session ssl.sync_close = true # if true the underlying socket will be # closed in SSLSocket#close. (default: false) while (line = ssl.gets) puts line end ssl.close ext/upload_facts.rb000075500000006044147633135120010351 0ustar00#!/usr/bin/env ruby require 'net/https' require 'openssl' require 'openssl/x509' require 'optparse' require 'pathname' require 'yaml' require 'puppet' require 'puppet/network/http_pool' class Puppet::Application::UploadFacts < Puppet::Application run_mode :master option('--debug', '-d') option('--verbose', '-v') option('--logdest DEST', '-l DEST') do |arg| Puppet::Util::Log.newdestination(arg) options[:setdest] = true end option('--minutes MINUTES', '-m MINUTES') do |minutes| options[:time_limit] = 60 * minutes.to_i end def help print <] [-l|--logdest syslog||console] = Description This command will read YAML facts from the puppet master's YAML directory, and save them to the configured facts_terminus. It is intended to be used with the facts_terminus set to inventory_service, in order to ensure facts which have been cached locally due to a temporary failure are still uploaded to the inventory service. = Usage Notes upload_facts is intended to be run from cron, with the facts_terminus set to inventory_service. The +--minutes+ argument should be set to the length of time between upload_facts runs. This will ensure that only new YAML files are uploaded. = Options Note that any setting that's valid in the configuration file is also a valid long argument. For example, 'server' is a valid configuration parameter, so you can specify '--server ' as an argument. See the configuration file documentation at http://docs.puppetlabs.com/references/stable/configuration.html for the full list of acceptable parameters. A commented list of all configuration options can also be generated by running puppet agent with '--genconfig'. minutes:: Limit the upload only to YAML files which have been added within the last n minutes. HELP exit end def setup # Handle the logging settings. if options[:debug] or options[:verbose] if options[:debug] Puppet::Util::Log.level = :debug else Puppet::Util::Log.level = :info end Puppet::Util::Log.newdestination(:console) unless options[:setdest] end exit(Puppet.settings.print_configs ? 0 : 1) if Puppet.settings.print_configs? end def main dir = Pathname.new(Puppet[:yamldir]) + 'facts' cutoff = options[:time_limit] ? Time.now - options[:time_limit] : Time.at(0) files = dir.children.select do |file| file.extname == '.yaml' && file.mtime > cutoff end failed = false terminus = Puppet::Node::Facts.indirection.terminus files.each do |file| facts = YAML.load_file(file) request = Puppet::Indirector::Request.new(:facts, :save, facts) # The terminus warns for us if we fail. if terminus.save(request) Puppet.info "Uploaded facts for #{facts.name} to inventory service" else failed = true end end exit !failed end end Puppet::Application::UploadFacts.new.run ext/regexp_nodes/classes/webservers000064400000000023147633135120013575 0ustar00^(web|www) leterel ext/regexp_nodes/classes/databases000064400000000016147633135120013337 0ustar00db\d{2} mysql ext/regexp_nodes/environment/development000064400000000022147633135120014636 0ustar00^dev- prod-canary ext/regexp_nodes/regexp_nodes.rb000075500000023041147633135120013045 0ustar00#!/usr/bin/env ruby # = Synopsis # This is an external node classifier script, after # http://docs.puppetlabs.com/guides/external_nodes.html # # = Usage # regexp_nodes.rb # # = Description # This classifier implements filesystem autoloading: It looks through classes, # parameters, and environment subdirectories, looping through each file it # finds. Each file's contents are a regexp-per-line which, if they match the # hostname passed to the program as ARGV[0], sets a class, parameter value # or environment named the same thing as the file itself. At the end, the # resultant data structure is returned back to the puppet master process as # yaml. # # = Caveats # Since the files are read in directory order, multiple matches for a given # hostname in the parameters/ and environment/ subdirectories will return the # last-read value. (Multiple classes/ matches don't cause a problem; the # class is either incuded or it isn't) # # Unmatched hostnames in any of the environment/ files will cause 'production' # to be emitted; be aware of the complexity surrounding the interaction between # ENC and environments as discussed in https://projects.puppetlabs.com/issues/3910 # # = Examples # Based on the example files in the classes/ and parameters/ subdirectories # in the distribution, classes/database will set the 'database' class for # hosts matching %r{db\d{2}} (that is, 'db' followed by two digits) or with # 'mysql' anywhere in the hostname. Similarly, hosts beginning with 'www' or # 'web' or the hostname 'leterel' (my workstation) will be assigned the # 'webserver' class. # # Under parameters/ there is one subdirectory 'service' which # sets the a parameter called 'service' to the value 'prod' for production # hosts (whose hostnames always end with a three-digit code), 'qa' for # anything that starts with 'qa-' 'qa2-' or 'qa3-', and 'sandbox' for any # development machines whose hostnames start with 'dev-'. # # In the environment/ subdirectory, any hosts matching '^dev-' and a single # production host which serves as 'canary in the coal mine' will be put into # the development environment # # = Author # Eric Sorenson # we need yaml or there's not much point in going on require 'yaml' # Sets are like arrays but automatically de-duplicate elements require 'set' # set up some syslog logging require 'syslog' Syslog.open('extnodes', Syslog::LOG_PID | Syslog::LOG_NDELAY, Syslog::LOG_DAEMON) # change this to LOG_UPTO(Sysslog::LOG_DEBUG) if you want to see everything # but remember your syslog.conf needs to match this or messages will be filtered Syslog.mask = Syslog::LOG_UPTO(Syslog::LOG_INFO) # Helper method to log to syslog; we log at level debug if no level is specified # since those are the most frequent calls to this method def log(message,level=:debug) Syslog.send(level,message) end # set our workingdir to be the directory we're executed from, regardless # of parent's cwd, symlinks, etc. via handy Pathname.realpath method require 'pathname' p = Pathname.new(File.dirname(__FILE__)) WORKINGDIR = "#{p.realpath}" # This class holds all the methods for creating and accessing the properties # of an external node. There are really only two public methods: initialize # and a special version of to_yaml class ExternalNode # Make these instance variables get/set-able with eponymous methods attr_accessor :classes, :parameters, :environment, :hostname # initialize takes three arguments: # hostname:: usually passed in via ARGV[0] but it could be anything # classdir:: directory under WORKINGDIR to look for files named after # classes # parameterdir:: directory under WORKINGDIR to look for directories to set # parameters def initialize(hostname, classdir = 'classes/', parameterdir = 'parameters/', environmentdir = 'environment/') # instance variables that contain the lists of classes and parameters @hostname @classes = Set.new @parameters = Hash.new("unknown") # sets a default value of "unknown" @environment = "production" self.parse_argv(hostname) self.match_classes("#{WORKINGDIR}/#{classdir}") self.match_parameters("#{WORKINGDIR}/#{parameterdir}") self.match_environment("#{WORKINGDIR}/#{environmentdir}") end # private method called by initialize which sanity-checks our hostname. # good candidate for overriding in a subclass if you need different checks def parse_argv(hostname) if hostname =~ /^([-\w]+?)\.([-\w\.]+)/ # non-greedy up to the first . is hostname @hostname = $1 elsif hostname =~ /^([-\w]+)$/ # sometimes puppet's @name is just a name @hostname = hostname log("got shortname for [#{hostname}]") else log("didn't receive parsable hostname, got: [#{hostname}]",:err) exit(1) end end # to_yaml massages a copy of the object and outputs clean yaml so we don't # feed weird things back to puppet []< def to_yaml classes = self.classes.to_a if self.parameters.empty? # otherwise to_yaml prints "parameters: {}" parameters = nil else parameters = self.parameters end ({ 'classes' => classes, 'parameters' => parameters, 'environment' => environment}).to_yaml end # Private method that expects an absolute path to a file and a string to # match - it returns true if the string was matched by any of the lines in # the file def matched_in_patternfile?(filepath, matchthis) patternlist = [] begin open(filepath).each { |l| l.chomp! next if l =~ /^$/ next if l =~ /^#/ if l =~ /^\s*(\S+)/ m = Regexp.last_match log("found a non-comment line, transforming [#{l}] into [#{m[1]}]") l.gsub!(l,m[1]) else next l end pattern = %r{#{l}} patternlist << pattern log("appending [#{pattern}] to patternlist for [#{filepath}]") } rescue Exception log("Problem reading #{filepath}: #{$!}",:err) exit(1) end log("list of patterns for #{filepath}: #{patternlist}") if matchthis =~ Regexp.union(patternlist) log("matched #{$~.to_s} in #{matchthis}, returning true") return true else # hostname didn't match anything in patternlist log("#{matchthis} unmatched, returning false") return nil end end # def # private method - takes a path to look for files, iterates through all # readable, regular files it finds, and matches this instance's @hostname # against each line; if any match, the class will be set for this node. def match_classes(fullpath) Dir.foreach(fullpath) do |patternfile| filepath = "#{fullpath}/#{patternfile}" next unless File.file?(filepath) and File.readable?(filepath) next if patternfile =~ /^\./ log("Attempting to match [#{@hostname}] in [#{filepath}]") if matched_in_patternfile?(filepath,@hostname) @classes << patternfile.to_s log("Appended #{patternfile.to_s} to classes instance variable") end end end # match_environment is similar to match_classes but it overwrites # any previously set value (usually just the default, 'production') # with a match def match_environment(fullpath) Dir.foreach(fullpath) do |patternfile| filepath = "#{fullpath}/#{patternfile}" next unless File.file?(filepath) and File.readable?(filepath) next if patternfile =~ /^\./ log("Attempting to match [#{@hostname}] in [#{filepath}]") if matched_in_patternfile?(filepath,@hostname) @environment = patternfile.to_s log("Wrote #{patternfile.to_s} to environment instance variable") end end end # Parameters are handled slightly differently; we make another level of # directories to get the parameter name, then use the names of the files # contained in there for the values of those parameters. # # ex: cat ./parameters/service/production # ^prodweb # would set parameters["service"] = "production" for prodweb001 def match_parameters(fullpath) Dir.foreach(fullpath) do |parametername| filepath = "#{fullpath}/#{parametername}" next if File.basename(filepath) =~ /^\./ # skip over dotfiles next unless File.directory?(filepath) and File.readable?(filepath) # skip over non-directories log("Considering contents of #{filepath}") Dir.foreach("#{filepath}") do |patternfile| secondlevel = "#{filepath}/#{patternfile}" log("Found parameters patternfile at #{secondlevel}") next unless File.file?(secondlevel) and File.readable?(secondlevel) log("Attempting to match [#{@hostname}] in [#{secondlevel}]") if matched_in_patternfile?(secondlevel, @hostname) @parameters[ parametername.to_s ] = patternfile.to_s log("Set @parameters[#{parametername.to_s}] = #{patternfile.to_s}") end end end end end # Logic for local hacks that don't fit neatly into the autoloading model can # happen as we initialize a subclass class MyExternalNode < ExternalNode def initialize(hostname, classdir = 'classes/', parameterdir = 'parameters/') super # Set "hostclass" parameter based on hostname, # stripped of leading environment prefix and numeric suffix if @hostname =~ /^(\w*?)-?(\D+)(\d{2,3})$/ match = Regexp.last_match hostclass = match[2] log("matched hostclass #{hostclass}") @parameters[ "hostclass" ] = hostclass else log("couldn't figure out class from #{@hostname}",:warning) end end end # Here we begin actual execution by calling methods defined above mynode = MyExternalNode.new(ARGV[0]) puts mynode.to_yaml ext/regexp_nodes/parameters/service/prod000064400000000007147633135120014522 0ustar00\d{3}$ ext/regexp_nodes/parameters/service/qa000064400000000021147633135120014153 0ustar00^qa- ^qa2- ^qa3- ext/regexp_nodes/parameters/service/sandbox000064400000000006147633135120015213 0ustar00^dev- ext/systemd/puppet.service000064400000000544147633135120011743 0ustar00[Unit] Description=Puppet agent Wants=basic.target After=basic.target network.target puppetmaster.service [Service] EnvironmentFile=-/etc/sysconfig/puppetagent EnvironmentFile=-/etc/sysconfig/puppet ExecStart=/usr/bin/puppet agent $PUPPET_EXTRA_OPTS --no-daemonize ExecReload=/bin/kill -HUP $MAINPID KillMode=process [Install] WantedBy=multi-user.target ext/systemd/puppetmaster.service000064400000000375147633135120013161 0ustar00[Unit] Description=Puppet master Wants=basic.target After=basic.target network.target [Service] EnvironmentFile=-/etc/sysconfig/puppetmaster ExecStart=/usr/bin/puppet master $PUPPETMASTER_EXTRA_OPTS --no-daemonize [Install] WantedBy=multi-user.target ext/envpuppet000075500000010243147633135120007325 0ustar00#! /bin/sh # # Jeff McCune # 2010-10-20 # # Copyright (c) 2010, Puppet Labs # License: BSD 3-clause license # # This script provides a simple way to execute puppet and related tools # directly from a git clone of the upstream repositories. This allows you to # quickly switch branches and test different versions of code without much # friction. # # NOTE: There may be issues if puppet, facter, etc... are already installed # into RUBY's site_ruby directory. If you run into strange problems, make sure # the correct ruby libraries are being loaded... # # Sample Usage: # ============= # cd ~/src # git clone git://github.com/puppetlabs/puppet.git # git clone git://github.com/puppetlabs/facter.git # pushd puppet # git checkout tags/2.6.1 # popd # pushd facter # git checkout tags/1.5.8 # export ENVPUPPET_BASEDIR=/home/jeff/src # envpuppet puppet --version # 2.6.1 # envpuppet facter --version # 1.5.8 set -e set -u if [ "${1:-}" = "--help" ]; then cat < 2011-02-09 Puppet should not be installed in site_ruby because all of \$LOAD_PATH is searched by puppet when loading libraries and the installed version will taint the development version The following enviornment variables configure the behavior of envpuppet ENVPUPPET_BASEDIR=${HOME}/src the base directory where puppet, facter, etc... live. ENVPUPPET_BLEEDING=true Enables bleeding edge prototypes like puppet-interfaces The PATH and RUBYLIB are the primary environment variables modified by the envpuppet script. If no arguments are given, the environment variables are printed to STDOUT allowing the output to be sourced. For example: eval \$(envpuppet) EO_HELP exit 0 fi if test -d puppet -o -d facter; then ( echo " WARNING!" echo " Strange things happen if puppet or facter are in the" echo " current working directory" echo " (import errors from ruby are a prime example)" echo " WARNING!" echo "" echo "I suggest changing to ~ or /tmp or something..." echo "" echo "Sleeping 2 seconds." echo "" ) 1>&2 sleep 2 fi # Set this to where you check out puppet and facter : ${ENVPUPPET_BASEDIR:="${HOME}/src"} # Are we bleeding edge? : ${ENVPUPPET_BLEEDING:='false'} # git://github.com/puppetlabs/puppet.git mypath="${ENVPUPPET_BASEDIR}/puppet/sbin:${ENVPUPPET_BASEDIR}/puppet/bin" myrubylib="${ENVPUPPET_BASEDIR}/puppet/lib" # git://github.com/puppetlabs/facter.git mypath="${mypath}:${ENVPUPPET_BASEDIR}/facter/bin" myrubylib="${myrubylib}:${ENVPUPPET_BASEDIR}/facter/lib" # git://github.com/puppetlabs/hiera.git mypath="${mypath}:${ENVPUPPET_BASEDIR}/hiera/bin" myrubylib="${myrubylib}:${ENVPUPPET_BASEDIR}/hiera/lib" if [ "${ENVPUPPET_BLEEDING:-}" = "true" ]; then # git://github.com/puppetlabs/facter.git mypath="${mypath}:${ENVPUPPET_BASEDIR}/puppet-interfaces/bin" myrubylib="${myrubylib}:${ENVPUPPET_BASEDIR}/puppet-interfaces/lib" fi # http://github.com/jamtur01/puppet-scaffold.git mypath="${mypath}:${ENVPUPPET_BASEDIR}/puppet-scaffold/bin" myrubylib="${myrubylib}:${ENVPUPPET_BASEDIR}/puppet-scaffold/lib" # http://github.com/puppetlabs/puppet-module-tool.git # Also known as "pmt" Will become "puppet module" mypath="${mypath}:${ENVPUPPET_BASEDIR}/puppet-module-tool/bin" myrubylib="${myrubylib}:${ENVPUPPET_BASEDIR}/puppet-module-tool/lib" # Use the existing environment, if present. # Default to no value to prevent unbound variable issues mypath="${mypath}:${PATH:-}" myrubylib="${myrubylib}:${RUBYLIB:-}" export ENVPUPPET_OLD_PATH="${PATH:-}" export ENVPUPPET_OLD_RUBYLIB="${RUBYLIB:-}" # Trim any trailing colons from the path list. export PATH="${mypath%%:}" export RUBYLIB="${myrubylib%%:}" if [ $# -eq 0 ]; then echo "export ENVPUPPET_OLD_PATH='${ENVPUPPET_OLD_PATH}'" echo "export ENVPUPPET_OLD_RUBYLIB='${ENVPUPPET_OLD_RUBYLIB}'" echo "export ENVPUPPET_BASEDIR='${ENVPUPPET_BASEDIR}'" echo "export ENVPUPPET_BLEEDING='${ENVPUPPET_BLEEDING}'" echo "export PATH='${PATH}'" echo "export RUBYLIB='${RUBYLIB}'" else exec "$@" fi ext/dbfix.sql000064400000007565147633135120007203 0ustar00-- MySQL DB consistency check/fix -- -- Usage: -- cat dbfix.sql | mysql -u user -p puppet -- -- WARNING: perform a database backup before running this script -- Remove duplicate resources, and keep the latest one DELETE bad_rows.* FROM resources AS bad_rows INNER JOIN ( SELECT title,restype,host_id, MAX(id) as max_id FROM resources GROUP BY title,restype,host_id HAVING count(*) > 1 ) AS good_rows ON good_rows.title = bad_rows.title AND good_rows.restype = bad_rows.restype AND good_rows.host_id = bad_rows.host_id AND good_rows.max_id <> bad_rows.id; -- Remove duplicate param_values, and keep the latest one DELETE bad_rows.* FROM param_values AS bad_rows INNER JOIN ( SELECT value,param_name_id,resource_id, MAX(id) as max_id FROM param_values GROUP BY value,param_name_id,resource_id HAVING count(*) > 1 ) AS good_rows ON good_rows.value = bad_rows.value AND good_rows.param_name_id = bad_rows.param_name_id AND good_rows.resource_id = bad_rows.resource_id AND good_rows.max_id <> bad_rows.id; -- rewrite param_values that points to duplicated param_names -- to point to the highest param_name id. UPDATE param_values v INNER JOIN param_names n ON n.id = v.param_name_id INNER JOIN ( SELECT name, MAX(id) as max_id FROM param_names GROUP BY name HAVING count(*) > 1 ) nmax ON n.name = nmax.name SET v.param_name_id = nmax.max_id; -- Remove duplicate param_names, and keep the latest one DELETE bad_rows.* FROM param_names AS bad_rows INNER JOIN ( SELECT name, MAX(id) as max_id FROM param_names GROUP BY name HAVING count(*) > 1 ) AS good_rows ON good_rows.name = bad_rows.name AND good_rows.max_id <> bad_rows.id; -- Remove duplicate resource_tags, and keep the highest one DELETE bad_rows.* FROM resource_tags AS bad_rows INNER JOIN ( SELECT resource_id,puppet_tag_id, MAX(id) as max_id FROM resource_tags GROUP BY resource_id,puppet_tag_id HAVING count(*) > 1 ) AS good_rows ON good_rows.resource_id = bad_rows.resource_id AND good_rows.puppet_tag_id = bad_rows.puppet_tag_id AND good_rows.max_id <> bad_rows.id; -- rewrite resource_tags that points to duplicated puppet_tags -- to point to the highest puppet_tags id. UPDATE resource_tags v INNER JOIN puppet_tags n ON n.id = v.puppet_tag_id INNER JOIN ( SELECT name, MAX(id) as max_id FROM puppet_tags GROUP BY name HAVING count(*) > 1 ) nmax ON n.name = nmax.name SET v.puppet_tag_id = nmax.max_id; -- Remove duplicate puppet_tags, and keep the highest one DELETE bad_rows.* FROM puppet_tags AS bad_rows INNER JOIN ( SELECT name, MAX(id) as max_id FROM puppet_tags GROUP BY name HAVING count(*) > 1 ) AS good_rows ON good_rows.name = bad_rows.name AND good_rows.max_id <> bad_rows.id; -- Fix dangling resources -- note: we use a table to not exceed the number of InnoDB locks if there are two much -- rows to delete. -- this is an alternative to: DELETE resources FROM resources r LEFT JOIN hosts h ON h.id=r.host_id WHERE h.id IS NULL; -- CREATE TABLE resources_c LIKE resources; INSERT INTO resources_c SELECT r.* FROM resources r INNER JOIN hosts h ON h.id=r.host_id; RENAME TABLE resources TO resources_old, resources_c TO resources; DROP TABLE resources_old; -- Fix dangling param_values CREATE TABLE param_values_c LIKE param_values; INSERT INTO param_values_c SELECT v.* FROM param_values v INNER JOIN resources r ON r.id=v.resource_id; RENAME TABLE param_values TO param_values_old, param_values_c TO param_values; DROP TABLE param_values_old; -- Fix dangling resource_tags CREATE TABLE resource_tags_c LIKE resource_tags; INSERT INTO resource_tags_c SELECT t.* FROM resource_tags t INNER JOIN resources r ON r.id=t.resource_id; RENAME TABLE resource_tags TO resource_tags_old, resource_tags_c TO resource_tags; DROP TABLE resource_tags_old; ext/logcheck/puppet000064400000004145147633135120010374 0ustar00^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-master\[[0-9]+\]: (Handled resources in|Resource comparison took|Searched for (host|resources|resource params and tags) in) [0-9.]+ seconds ^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-master\[[0-9]+\]: Starting Puppet server version [.0-9]+$ ^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-master\[[0-9]+\]: Compiled catalog for [._[:alnum:]-]+ in [.0-9]+ seconds$ ^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-master\[[0-9]+\]: Caught TERM; shutting down$ ^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-master\[[0-9]+\]: Shutting down$ ^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-agent\[[0-9]+\]: Starting Puppet client version [.0-9]+$ ^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-agent\[[0-9]+\]: getting config$ ^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-agent\[[0-9]+\]: Caching configuration at [\/._[:alnum:]-]+$ ^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-agent\[[0-9]+\]: Loaded state in [.0-9]+ seconds$ ^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-agent\[[0-9]+\]: Calling puppetmaster.getconfig$ ^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-agent\[[0-9]+\]: Retrieved configuration in [.0-9]+ seconds$ ^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-agent\[[0-9]+\]: Starting configuration run$ ^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-agent\[[0-9]+\]: Finished configuration run in [.0-9]+ seconds$ ^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-agent\[[0-9]+\]: Caught (TERM|INT); shutting down$ ^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-agent\[[0-9]+\]: Shutting down$ ^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-agent\[[0-9]+\]: Restarting with .*$ ^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-agent\[[0-9]+\]: Starting catalog run$ ^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-agent\[[0-9]+\]: Finished catalog run in [.0-9]+ seconds$ ^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-agent\[[0-9]+\]: Loading fact .*$ ^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-agent\[[0-9]+\]: Ignoring cache$ ^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-agent\[[0-9]+\]: Ignoring --listen on onetime run$ ^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-agent\[[0-9]+\]: Retrieving plugins$ ^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppet-master\[[0-9]+\]: Reopening log files$ ext/rack/example-passenger-vhost.conf000064400000004722147633135120013726 0ustar00# This Apache 2 virtual host config shows how to use Puppet as a Rack # application via Passenger. See # http://docs.puppetlabs.com/guides/passenger.html for more information. # You can also use the included config.ru file to run Puppet with other Rack # servers instead of Passenger. # you probably want to tune these settings PassengerHighPerformance on PassengerMaxPoolSize 12 PassengerPoolIdleTime 1500 # PassengerMaxRequests 1000 PassengerStatThrottleRate 120 RackAutoDetect Off RailsAutoDetect Off Listen 8140 SSLEngine on SSLProtocol ALL -SSLv2 -SSLv3 SSLCipherSuite EDH+CAMELLIA:EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH:+CAMELLIA256:+AES256:+CAMELLIA128:+AES128:+SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!IDEA:!ECDSA:kEDH:CAMELLIA256-SHA:AES256-SHA:CAMELLIA128-SHA:AES128-SHA SSLHonorCipherOrder on SSLCertificateFile /etc/puppet/ssl/certs/squigley.namespace.at.pem SSLCertificateKeyFile /etc/puppet/ssl/private_keys/squigley.namespace.at.pem SSLCertificateChainFile /etc/puppet/ssl/ca/ca_crt.pem SSLCACertificateFile /etc/puppet/ssl/ca/ca_crt.pem # If Apache complains about invalid signatures on the CRL, you can try disabling # CRL checking by commenting the next line, but this is not recommended. SSLCARevocationFile /etc/puppet/ssl/ca/ca_crl.pem # Apache 2.4 introduces the SSLCARevocationCheck directive and sets it to none # which effectively disables CRL checking; if you are using Apache 2.4+ you must # specify 'SSLCARevocationCheck chain' to actually use the CRL. # SSLCARevocationCheck chain SSLVerifyClient optional SSLVerifyDepth 1 # The `ExportCertData` option is needed for agent certificate expiration warnings SSLOptions +StdEnvVars +ExportCertData # This header needs to be set if using a loadbalancer or proxy RequestHeader unset X-Forwarded-For RequestHeader set X-SSL-Subject %{SSL_CLIENT_S_DN}e RequestHeader set X-Client-DN %{SSL_CLIENT_S_DN}e RequestHeader set X-Client-Verify %{SSL_CLIENT_VERIFY}e DocumentRoot /etc/puppet/rack/public/ RackBaseURI / Options None AllowOverride None Order allow,deny allow from all ext/rack/config.ru000064400000002315147633135120010107 0ustar00# a config.ru, for use with every rack-compatible webserver. # SSL needs to be handled outside this, though. # if puppet is not in your RUBYLIB: # $LOAD_PATH.unshift('/opt/puppet/lib') $0 = "master" # if you want debugging: # ARGV << "--debug" ARGV << "--rack" # Rack applications typically don't start as root. Set --confdir and --vardir # to prevent reading configuration from ~puppet/.puppet/puppet.conf and writing # to ~puppet/.puppet ARGV << "--confdir" << "/etc/puppet" ARGV << "--vardir" << "/var/lib/puppet" # NOTE: it's unfortunate that we have to use the "CommandLine" class # here to launch the app, but it contains some initialization logic # (such as triggering the parsing of the config file) that is very # important. We should do something less nasty here when we've # gotten our API and settings initialization logic cleaned up. # # Also note that the "$0 = master" line up near the top here is # the magic that allows the CommandLine class to know that it's # supposed to be running master. # # --cprice 2012-05-22 require 'puppet/util/command_line' # we're usually running inside a Rack::Builder.new {} block, # therefore we need to call run *here*. run Puppet::Util::CommandLine.new.execute ext/envpuppet.bat000064400000000545147633135120010073 0ustar00@echo off SETLOCAL REM net use Z: "\\vmware-host\Shared Folders" /persistent:yes SET PUPPET_DIR=%~dp0.. SET FACTER_DIR=%PUPPET_DIR%\..\facter SET HIERA_DIR=%PUPPET_DIR%\..\hiera SET PATH=%PUPPET_DIR%\bin;%FACTER_DIR%\bin;%HIERA_DIR%\bin;%PATH% SET RUBYLIB=%PUPPET_DIR%\lib;%FACTER_DIR%\lib;%HIERA_DIR%\lib;%RUBYLIB% SET RUBYLIB=%RUBYLIB:\=/% ruby -S %* ext/puppet-test000075500000041175147633135120007601 0ustar00#!/usr/bin/env ruby # == Synopsis # # Test individual client performance. Can compile configurations, describe # files, or retrieve files. # # = Usage # # puppet-test [-c|--compile] [-D|--describe ] [-d|--debug] # [--fork ] [-h|--help] [-H|--hostname ] [-l|--list] [-r|--repeat ] # [-R|--retrieve ] [-t|--test ] [-V|--version] [-v|--verbose] # # = Description # # This is a simple script meant for doing performance tests with Puppet. By # default it pulls down a compiled configuration, but it supports multiple # other tests. # # = Options # # Note that any setting that's valid in the configuration file # is also a valid long argument. For example, 'server' is a valid configuration # parameter, so you can specify '--server ' as an argument. # # See the configuration file documentation at # http://reductivelabs.com/projects/puppet/reference/configref.html for # the full list of acceptable parameters. A commented list of all # configuration $options can also be generated by running puppetd with # '--genconfig'. # # compile:: # Compile the client's configuration. The default. # # debug:: # Enable full debugging. # # describe:: # Describe the file being tested. This is a query to get information about # the file from the server, to determine if it should be copied, and is the # first half of every file transfer. # # fork:: # Fork the specified number of times, thus acting as multiple clients. # # fqdn:: # Set the fully-qualified domain name of the client. This is only used for # certificate purposes, but can be used to override the discovered hostname. # If you need to use this flag, it is generally an indication of a setup problem. # # help:: # Print this help message # # list:: # List all available tests. # # node:: # Specify the node to use. This is useful for looking up cached yaml data # in your :clientyaml directory, and forcing a specific host's configuration to # get compiled. # # pause:: # Pause before starting test (useful for testing with dtrace). # # repeat:: # How many times to perform the test. # # retrieve:: # Test file retrieval performance. Retrieves the specified file from the # remote system. Note that the server should be specified via --server, # so the argument to this option is just the remote module name and path, # e.g., "/dist/apps/myapp/myfile", where "dist" is the module and # "apps/myapp/myfile" is the path to the file relative to the module. # # test:: # Specify the test to run. You can see the list of tests by running this command with --list. # # verbose:: # Turn on verbose reporting. # # version:: # Print the puppet version number and exit. # # = Example # # puppet-test --retrieve /module/path/to/file # # = License # Copyright 2011 Luke Kanies # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Do an initial trap, so that cancels don't get a stack trace. trap(:INT) do $stderr.puts "Cancelling startup" exit(1) end require 'puppet' require 'puppet/network/client' require 'getoptlong' class Suite attr_reader :name, :doc @@suites = {} @@tests = {} def self.[](name) @@suites[name] end # Run a test by first finding the suite then running the appropriate test. def self.run(test) unless suite_name = @@tests[test] raise "Unknown test %s" % test end unless suite = @@suites[suite_name] raise "Unknown test suite %s from test %s" % [suite_name, test] end suite.run(test) end # What suites are available? def self.suites @@suites.keys end def forked? defined? @forking end # Create a new test suite. def initialize(name, doc, &block) @name = name @doc = doc @tests = {} @@suites[name] = self raise "You must pass a block to the Test" unless block_given? instance_eval(&block) end # Define a new type of test on this suite. def newtest(name, doc, &block) @tests[name] = doc if @@tests[name] raise "Test names must be unique; cannot redefine %s" % name end @@tests[name] = @name meta_def(name, &block) end # Run the actual test. def run(test) unless doc = @tests[test] raise "Suite %s only supports tests %s; not %s" % [@name, @tests.keys.collect { |k| k.to_s }.join(","), test] end puts "Running %s %s test" % [@name, test] prepare() if respond_to?(:prepare) if $options[:pause] puts "Hit any key to continue" $stdin.readline puts "Continuing with test" end if $options[:fork] > 0 @forking = true $options[:fork].times { if pid = fork $pids << pid else break end } end $options[:repeat].times do |i| @count = i if forked? msg = doc + " in PID %s" % Process.pid else msg = doc end Puppet::Util.benchmark(:notice, msg) do begin send(test) rescue => detail puts detail.backtrace if Puppet[:trace] Puppet.err "%s failed: %s" % [@name, detail.to_s] end end end end # What tests are available on this suite? def tests @tests.keys end end Suite.new :parser, "Manifest parsing" do newtest :parse, "Parsed files" do @parser = Puppet::Parser::Parser.new(:environment => Puppet[:environment]) @parser.file = Puppet[:manifest] @parser.parse end end Suite.new :local_catalog, "Local catalog handling" do def prepare @node = Puppet::Node.find($options[:nodes][0]) end newtest :compile, "Compiled catalog" do Puppet::Resource::Catalog.find(@node) end end Suite.new :resource_type, "Managing resource types" do newtest :find, "Find a type" do Puppet::Resource::Type.terminus_class = :parser ARGV.each do |name| json = Puppet::Resource::Type.find(name).to_pson data = PSON.parse(json) p Puppet::Resource::Type.from_data_hash(data) end end newtest :search_types, "Find all types" do Puppet::Resource::Type.terminus_class = :rest result = Puppet::Resource::Type.search("*") result.each { |r| p r } end newtest :restful_type, "Find a type and return it via REST" do Puppet::Resource::Type.terminus_class = :rest ARGV.each do |name| p Puppet::Resource::Type.find(name) end end end Suite.new :remote_catalog, "Remote catalog handling" do def prepare $args[:cache] = false # Create a config client and pull the config down @client = Puppet::Network::Client.master.new($args) unless @client.read_cert fail "Could not read client certificate" end if tmp = Puppet::Node::Facts.find($options[:nodes][0]) @facts = tmp.values else raise "Could not find facts for %s" % $optins[:nodes][0] end if host = $options[:fqdn] @facts["fqdn"] = host @facts["hostname"] = host.sub(/\..+/, '') @facts["domain"] = host.sub(/^[^.]+\./, '') end @facts = YAML.dump(@facts) end newtest :getconfig, "Compiled catalog" do @client.driver.getconfig(@facts, "yaml") end # This test will always force a false answer. newtest :fresh, "Checked freshness" do @client.driver.freshness end end Suite.new :file, "File interactions" do def prepare unless $options[:file] fail "You must specify a file (using --file ) to interact with on the server" end @client = Puppet::Network::Client.file.new($args) unless @client.read_cert fail "Could not read client certificate" end end newtest :describe, "Described file" do @client.describe($options[:file], :ignore) end newtest :retrieve, "Retrieved file" do @client.retrieve($options[:file], :ignore) end end Suite.new :filebucket, "Filebucket interactions" do def prepare require 'tempfile' @client = Puppet::FileBucket::Dipper.new($args) end newtest :backup, "Backed up file" do Tempfile.open("bucket_testing") do |f| f.print rand(1024) f.close @client.backup(f.path) end end end # Note that this uses an env variable to determine how many resources per # host to create (with a default of 10). 'repeat' determines how # many hosts to create. You probably will get mad failures if you # use forking and sqlite. # Here's an example run of this test, using sqlite: # RESOURCE_COUNT=50 ext/puppet-test --suite rails --test storage --confdir /tmp/storagetesting --vardir /tmp/storagetesting --repeat 10 Suite.new :rails, "Rails Interactions" do def prepare Puppet::Rails.init @facts = Facter.to_hash if num = ENV["RESOURCECOUNT"] @resources = Integer(num) else @resources = 10 end end Resource = Puppet::Parser::Resource def execute(test, msg) begin send(test) rescue => detail puts detail.backtrace if Puppet[:trace] Puppet.err "%s failed: %s" % [@name, detail.to_s] end end def mkresource(type, title, parameters) source = "fakesource" res = Resource.new(:type => type, :title => title, :source => source, :scope => "fakescope") parameters.each do |param, value| res.set(param, value, source) end res end def ref(type, title) Resource::Reference.new(:type => type, :title => title) end newtest :storage, "Stored resources" do hostname = "host%s" % @count @facts["hostname"] = hostname args = {:facts => @facts, :name => hostname} # Make all of the resources we want. Make them at least slightly complex, # so we model real resources as close as we can. resources = [] args[:resources] = resources @resources.times do |resnum| exec = mkresource("exec", "exec%s" % resnum, :command => "/bin/echo do something %s" % resnum) exec.tags = %w{exec one} << "exec%s" % resnum user = mkresource("user", "user%s" % resnum, :uid => resnum.to_s, :require => ref("exec", "exec%s" % resnum)) user.tags = %w{user one two} << "user%s" % resnum file = mkresource("file", "/tmp/file%s" % resnum, :owner => resnum.to_s, :require => [ref("exec", "exec%s" % resnum), ref("user", "user%s" % resnum)]) file.tags = %w{file one three} << "file%s" % resnum file.exported = true resources << exec << user << file end Puppet::Rails::Host.store(args) end end Suite.new :report, "Reports interactions" do def prepare Puppet::Transaction::Report.terminus_class = :rest end newtest :empty, "send empty report" do report = Puppet::Transaction::Report.new report.time = Time.now report.save end newtest :fake, "send fake report" do report = Puppet::Transaction::Report.new resourcemetrics = { :total => 12, :out_of_sync => 20, :applied => 45, :skipped => 1, :restarted => 23, :failed_restarts => 1, :scheduled => 10 } report.newmetric(:resources, resourcemetrics) timemetrics = { :resource1 => 10, :resource2 => 50, :resource3 => 40, :resource4 => 20, } report.newmetric(:times, timemetrics) report.newmetric(:changes, :total => 20 ) report.time = Time.now report.save end end $cmdargs = [ [ "--compile", "-c", GetoptLong::NO_ARGUMENT ], [ "--describe", GetoptLong::REQUIRED_ARGUMENT ], [ "--retrieve", "-R", GetoptLong::REQUIRED_ARGUMENT ], [ "--fork", GetoptLong::REQUIRED_ARGUMENT ], [ "--fqdn", "-F", GetoptLong::REQUIRED_ARGUMENT ], [ "--suite", "-s", GetoptLong::REQUIRED_ARGUMENT ], [ "--test", "-t", GetoptLong::REQUIRED_ARGUMENT ], [ "--pause", "-p", GetoptLong::NO_ARGUMENT ], [ "--repeat", "-r", GetoptLong::REQUIRED_ARGUMENT ], [ "--node", "-n", GetoptLong::REQUIRED_ARGUMENT ], [ "--debug", "-d", GetoptLong::NO_ARGUMENT ], [ "--help", "-h", GetoptLong::NO_ARGUMENT ], [ "--list", "-l", GetoptLong::NO_ARGUMENT ], [ "--verbose", "-v", GetoptLong::NO_ARGUMENT ], [ "--version", "-V", GetoptLong::NO_ARGUMENT ], ] # Add all of the config parameters as valid $options. Puppet.settings.addargs($cmdargs) Puppet::Util::Log.newdestination(:console) Puppet::Node.terminus_class = :plain Puppet::Node.cache_class = :yaml Puppet::Node::Facts.terminus_class = :facter Puppet::Node::Facts.cache_class = :yaml result = GetoptLong.new(*$cmdargs) $args = {} $options = {:repeat => 1, :fork => 0, :pause => false, :nodes => []} begin explicit_waitforcert = false result.each { |opt,arg| case opt # First check to see if the argument is a valid setting; # if so, set it. when "--compile" $options[:suite] = :configuration $options[:test] = :compile when "--retrieve" $options[:suite] = :file $options[:test] = :retrieve $options[:file] = arg when "--fork" begin $options[:fork] = Integer(arg) rescue => detail $stderr.puts "The argument to 'fork' must be an integer" exit(14) end when "--describe" $options[:suite] = :file $options[:test] = :describe $options[:file] = arg when "--fqdn" $options[:fqdn] = arg when "--repeat" $options[:repeat] = Integer(arg) when "--help" if Puppet.features.usage? RDoc::usage && exit else puts "No help available unless you have RDoc::usage installed" exit end when "--version" puts "%s" % Puppet.version exit when "--verbose" Puppet::Util::Log.level = :info Puppet::Util::Log.newdestination(:console) when "--debug" Puppet::Util::Log.level = :debug Puppet::Util::Log.newdestination(:console) when "--suite" $options[:suite] = arg.intern when "--test" $options[:test] = arg.intern when "--file" $options[:file] = arg when "--pause" $options[:pause] = true when "--node" $options[:nodes] << arg when "--list" Suite.suites.sort { |a,b| a.to_s <=> b.to_s }.each do |suite_name| suite = Suite[suite_name] tests = suite.tests.sort { |a,b| a.to_s <=> b.to_s }.join(", ") puts "%20s: %s" % [suite_name, tests] end exit(0) else Puppet.settings.handlearg(opt, arg) end } rescue GetoptLong::InvalidOption => detail $stderr.puts detail $stderr.puts "Try '#{$0} --help'" exit(1) end # Now parse the config Puppet.initialize_settings $options[:nodes] << Puppet.settings[:certname] if $options[:nodes].empty? $args[:Server] = Puppet[:server] unless $options[:test] $options[:suite] = :remote_catalog $options[:test] = :getconfig end unless $options[:test] raise "A suite was specified without a test" end $pids = [] Suite.run($options[:test]) if $options[:fork] > 0 Process.waitall end ext/nagios/naggen000075500000020563147633135120010024 0ustar00#!/usr/bin/env ruby # # = Synopsis # # Generate Nagios configurations from Puppet Resources in an ActiveRecord database # # = Usage # # naggen [-h|--help] [-d|--debug] [-v|--verbose] [--compare] # # = Description # # This executable is a means of short-circuiting the process of generating nagios # configurations on your server using Puppet Exported Resources. It skips any possible # naming conflicts resulting from Puppet's resource uniqueness requirements, and it # also skips the inefficiencies involved in converting and transporting large numbers # of Puppet resources. # # At the least, the machine that runs this will need ActiveRecord (2.0.2) installed, # along with any database libraries you use. # # = Options # # Note that any setting that's valid in the configuration file # is also a valid long argument. For example, 'ssldir' is a valid configuration # parameter, so you can specify '--ssldir ' as an argument. # # You can add naggen-specific settings to your puppet.conf in a '[naggen]' section, # just like any other executable. # # See the configuration file documentation at # http://reductivelabs.com/projects/puppet/reference/configref.html for # the full list of acceptable parameters. A commented list of all # configuration options can also be generated by running puppet with # '--genconfig'. # # compare:: # Compare new and old files and only backup and write if the files are different. # Potentially expensive computationally, but idempotent. Will exit with 0 if # no changes were made and 1 if there were. # # debug:: # Enable full debugging. # # detailed-exitcodes:: # Provide transaction information via exit codes. If this is enabled, an exit # code of '2' means there were changes, and an exit code of '4' means that there # were failures during the transaction. # # help:: # Print this help message # # verbose:: # Print extra information. # # = Example # # naggen --storeconfigs --confdir /foo --compare # # # = License # Copyright 2011 Luke Kanies # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require 'puppet' require 'puppet/rails' require 'puppet/rails/resource' require 'puppet/rails/param_value' require 'puppet/network/client' require 'puppet/parser/collector' require 'puppet/provider/naginator' require 'getoptlong' # Monkey-patch the rails resources so we can # easily convert them to nagios instances. class Puppet::Rails::Resource def to_param_hash values = @params_hash || Puppet::Rails::ParamValue.find_all_params_from_resource(self) if values.size == 0 return {} end values.inject({}) do |hash, value| hash[value['name']] ||= [] hash[value['name']] << value["value"] hash end end def to_nagios unless nagios_type = Nagios::Base.type(restype.sub("Nagios_", '').to_sym) raise Puppet::DevError, "Could not find nagios type '%s'" % restype end result = nagios_type.new to_param_hash.each do |param, value| next unless nagios_type.parameter?(param) result[param] = value end result[:name] = self.title result end end class NagiosWriter class FakeScope def debug(string) Puppet.debug string end def host "this host doesn't exist" end end attr_accessor :nagios_type, :bucket def backup(target) return unless FileTest.exist?(target) and File.stat(target).size > 0 Puppet.info "Backing up %s" % target bucket.backup(target) end def collector collector = Puppet::Parser::Collector.new(FakeScope.new, "nagios_" + @nagios_type.to_s, nil, nil, :exported) # We don't have a scope, so we're stubbing everything out that would interact # with the scope. class << collector def collect_virtual(*args) [] end def exported_resource(res) res end end collector end def default_target "/etc/nagios/nagios_#{nagios_type.to_s}.cfg" end def evaluate return unless resources = rails_resources() resources_by_target = resources.inject({}) do |hash, resource| target = resource["target"] || default_target hash[target] ||= [] hash[target] << resource hash end changed = false resources_by_target.each do |target, resources| begin result = write(target, resources) rescue => detail $stderr.puts detail.backtrace Puppet.err "Could not write to %s: %s" % [target, detail] end changed = true if result end changed end def initialize(nagios_type) @nagios_type = nagios_type @bucket = Puppet::FileBucket::Dipper.new(:Path => Puppet[:clientbucketdir]) end def rails_resources collector.send(:collect_exported) end def write(target, resources) # Skip the nagios type when we have no resources and no existing # file. return if resources.empty? and ! FileTest.exist?(target) dir = File.dirname(target) unless FileTest.exist?(dir) FileUtils.mkdir_p(dir) end count = 0 tempfile = target + ".tmp" File.open(tempfile, "w") do |file| resources.each do |resource| count += 1 file.puts resource.to_nagios.to_s.gsub("_naginator_name", Puppet::Provider::Naginator::NAME_STRING) end end if $options[:compare] if FileTest.exist?(target) and File.read(tempfile) == File.read(target) return false end end backup(target) # Atomic rename File.rename(tempfile, target) Puppet.notice "Wrote %s resources to %s" % [count, target] return true ensure File.unlink(tempfile) if tempfile and FileTest.exist?(tempfile) end end arguments = [ [ "--compare", "-c", GetoptLong::NO_ARGUMENT ], [ "--debug", "-d", GetoptLong::NO_ARGUMENT ], [ "--verbose", "-v", GetoptLong::NO_ARGUMENT ], [ "--help", "-h", GetoptLong::NO_ARGUMENT ] ] Puppet.settings.addargs(arguments) result = GetoptLong.new(*arguments) $options = {} result.each { |opt,arg| case opt when "--help" begin require 'rdoc/usage' RDoc::usage && exit rescue LoadError docs = [] File.readlines(__FILE__).each do |line| next if line =~ /^#\!/ unless line =~ /^#/ next if docs.length == 0 # skip the first line or so break # else, we've passed the docs, so just break end docs << line.sub(/^# ?/, '') end print docs exit end when "--compare" $options[:compare] = true when "--verbose" $options[:verbose] = true when "--debug" $options[:debug] = true when "--debug" $options[:debug] = true else Puppet.settings.handlearg(opt, arg) end } # Read in Puppet settings, so we know how Puppet's configured. Puppet.initialize_settings Puppet::Util::Log.newdestination(:console) if $options[:debug] Puppet::Util::Log.level = :debug elsif $options[:verbose] Puppet::Util::Log.level = :info end # See if Naginator is installed directly, else load Puppet's version. begin require 'nagios' rescue LoadError require 'puppet/external/nagios' end changed = false Nagios::Base.eachtype do |name, type| writer = NagiosWriter.new(name) changed = true if writer.evaluate end if $options[:compare] and changed exit(1) else exit(0) end ext/nagios/check_puppet.rb000075500000005022147633135120011632 0ustar00#!/usr/bin/env ruby require 'optparse' require 'sys/proctable' include Sys class CheckPuppet VERSION = '0.1' script_name = File.basename($0) # default options OPTIONS = { :statefile => "/var/lib/puppet/state/state.yaml", :process => "puppetd", :interval => 30, } o = OptionParser.new do |o| o.set_summary_indent(' ') o.banner = "Usage: #{script_name} [OPTIONS]" o.define_head "The check_puppet Nagios plug-in checks that specified Puppet process is running and the state file is no older than specified interval." o.separator "" o.separator "Mandatory arguments to long options are mandatory for short options too." o.on( "-s", "--statefile=statefile", String, "The state file", "Default: #{OPTIONS[:statefile]}") { |op| OPTIONS[:statefile] = op } o.on( "-p", "--process=processname", String, "The process to check", "Default: #{OPTIONS[:process]}") { |op| OPTIONS[:process] = op } o.on( "-i", "--interval=value", Integer, "Default: #{OPTIONS[:interval]} minutes") { |op| OPTIONS[:interval] = op } o.separator "" o.on_tail("-h", "--help", "Show this help message.") do puts o exit end o.parse!(ARGV) end def check_proc unless ProcTable.ps.find { |p| p.name == OPTIONS[:process]} @proc = 2 else @proc = 0 end end def check_state # Set variables curt = Time.now intv = OPTIONS[:interval] * 60 # Check file time begin @modt = File.mtime("#{OPTIONS[:statefile]}") rescue @file = 3 end diff = (curt - @modt).to_i if diff > intv @file = 2 else @file = 0 end end def output_status case @file when 0 state = "state file status okay updated on " + @modt.strftime("%m/%d/%Y at %H:%M:%S") when 2 state = "state fille is not up to date and is older than #{OPTIONS[:interval]} minutes" when 3 state = "state file status unknown" end case @proc when 0 process = "process #{OPTIONS[:process]} is running" when 2 process = "process #{OPTIONS[:process]} is not running" end case when (@proc == 2 or @file == 2) status = "CRITICAL" exitcode = 2 when (@proc == 0 and @file == 0) status = "OK" exitcode = 0 else status = "UNKNOWN" exitcode = 3 end puts "PUPPET #{status}: #{process}, #{state}" exit(exitcode) end end cp = CheckPuppet.new cp.check_proc cp.check_state cp.output_status ext/puppet-load.rb000075500000026626147633135120010147 0ustar00#!/usr/bin/env ruby # == Synopsis # # This tool can exercize a puppetmaster by simulating an arbitraty number of concurrent clients # in a lightweight way. # # = Prerequisites # # This tool requires Event Machine and em-http-request, and an installation of Puppet. # Event Machine can be installed from gem. # em-http-request can be installed from gem. # # = Usage # # puppet-load [-d|--debug] [--concurrency ] [--repeat ] [-V|--version] [-v|--verbose] # [--node ] [--facts ] [--cert ] [--key ] # [--factsdir ] [--server ] # # = Description # # This is a simple script meant for doing performance tests of puppet masters. It does this # by simulating concurrent connections to a puppet master and asking for catalog compilation. # # = Options # # Unlike other puppet executables, puppet-load doesn't parse puppet.conf nor use puppet options # # debug:: # Enable full debugging. # # concurreny:: # Number of simulated concurrent clients. # # server:: # Set the puppet master hostname or IP address.. # # node:: # Set the fully-qualified domain name of the client. This option can be given multiple # times. In this case puppet-load will ask for catalog compilation of all the given nodes # on a round robin way. # # help:: # Print this help message # # facts:: # This can be used to provide facts for the compilation, directly from a YAML # file as found in the clientyaml directory. If none are provided, puppet-load # will look by itself using Puppet facts indirector. # # factsdir:: # Specify a directory where the yaml facts files can be found. If provided puppet-load # will look up facts in this directory. If not found it will resort to using Puppet Facts # indirector. # # cert:: # This option is mandatory. It should be set to the cert PEM file that will be used # to quthenticate the client connections. # # key:: # This option is mandatory. It should be set to the private key PEM file that will be used # to quthenticate the client connections. # # timeout:: # The number of seconds after which a simulated client is declared in error if it didn't get # a catalog. The default is 180s. # # repeat:: # How many times to perform the test. This means puppet-load will ask for # concurrency * repeat catalogs. # # verbose:: # Turn on verbose reporting. # # version:: # Print the puppet version number and exit. # # = Example usage # # SINGLE NODE: # 1) On the master host, generate a new certificate and private key for our test host: # puppet ca --generate puppet-load.domain.com # # 2) Copy the cert and key to the puppet-load host (which can be the same as the master one) # # 3) On the master host edit or create the auth.conf so that the catalog ACL match: # path ~ ^/catalog/([^/]+)$ # method find # allow $1 # allow puppet-load.domain.com # # 4) launch the master(s) # # 5) Prepare or get a fact file. One way to get one is to look on the master in $vardir/yaml/ for the host # you want to simulate. # # 5) launch puppet-load # puppet-load -debug --node server.domain.com --server master.domain.com --facts server.domain.com.yaml --concurrency 2 --repeat 20 # # MULTIPLE NODES: # 1) On the master host, generate a new certificate and private key for our test host: # puppet ca --generate puppet-load.domain.com # # 2) Copy the cert and key to the puppet-load host (which can be the same as the master one) # # 3) On the master host edit or create the auth.conf so that the catalog ACL match: # path ~ ^/catalog/([^/]+)$ # method find # allow $1 # allow puppet-load.domain.com # # 4) launch the master(s) # # 5) Prepare or get a fact file. One way to get one is to look on the master in $vardir/yaml/ for the host # you want to simulate. # # 5) launch puppet-load # puppet-load -debug --node server1.domain.com --node server2.domain.com --node server3.domain.com \ # --server master.domain.com --factsdir /var/lib/puppet/yaml/facts --concurrency 2 --repeat 20 # # puppet-load will load facts file in the --factsdir directory based on the node name. # # = TODO # * More output stats for error connections (ie report errors, HTTP code...) # # # Do an initial trap, so that cancels don't get a stack trace. trap(:INT) do $stderr.puts "Cancelling startup" exit(1) end require 'rubygems' require 'eventmachine' require 'em-http' require 'getoptlong' require 'puppet' $cmdargs = [ [ "--concurrency", "-c", GetoptLong::REQUIRED_ARGUMENT ], [ "--node", "-n", GetoptLong::REQUIRED_ARGUMENT ], [ "--facts", GetoptLong::REQUIRED_ARGUMENT ], [ "--factsdir", GetoptLong::REQUIRED_ARGUMENT ], [ "--repeat", "-r", GetoptLong::REQUIRED_ARGUMENT ], [ "--cert", "-C", GetoptLong::REQUIRED_ARGUMENT ], [ "--key", "-k", GetoptLong::REQUIRED_ARGUMENT ], [ "--timeout", "-t", GetoptLong::REQUIRED_ARGUMENT ], [ "--server", "-s", GetoptLong::REQUIRED_ARGUMENT ], [ "--debug", "-d", GetoptLong::NO_ARGUMENT ], [ "--help", "-h", GetoptLong::NO_ARGUMENT ], [ "--verbose", "-v", GetoptLong::NO_ARGUMENT ], [ "--version", "-V", GetoptLong::NO_ARGUMENT ], ] Puppet::Util::Log.newdestination(:console) times = {} def read_facts(file) Puppet.debug("reading facts from: #{file}") fact = YAML.load(File.read(file)) end result = GetoptLong.new(*$cmdargs) $args = {} $options = {:repeat => 1, :concurrency => 1, :pause => false, :cert => nil, :key => nil, :timeout => 180, :masterport => 8140, :node => [], :factsdir => nil} begin result.each { |opt,arg| case opt when "--concurrency" begin $options[:concurrency] = Integer(arg) rescue => detail $stderr.puts "The argument to 'fork' must be an integer" exit(14) end when "--node" $options[:node] << arg when "--factsdir" $options[:factsdir] = arg when "--server" $options[:server] = arg when "--masterport" $options[:masterport] = arg when "--facts" $options[:facts] = arg when "--repeat" $options[:repeat] = Integer(arg) when "--help" if Puppet.features.usage? RDoc::usage && exit else puts "No help available unless you have RDoc::usage installed" exit end when "--version" puts "%s" % Puppet.version exit when "--verbose" Puppet::Util::Log.level = :info Puppet::Util::Log.newdestination(:console) when "--debug" Puppet::Util::Log.level = :debug Puppet::Util::Log.newdestination(:console) when "--cert" $options[:cert] = arg when "--key" $options[:key] = arg end } rescue GetoptLong::InvalidOption => detail $stderr.puts detail $stderr.puts "Try '#{$0} --help'" exit(1) end unless $options[:cert] and $options[:key] raise "--cert and --key are mandatory to authenticate the client" end parameters = [] unless $options[:node].size > 0 raise "--node is a mandatory argument. It tells to the master what node to compile" end $options[:node].each do |node| factfile = $options[:factsdir] ? File.join($options[:factsdir], node + ".yaml") : $options[:facts] unless fact = read_facts(factfile) or fact = Puppet::Node::Facts.find(node) raise "Could not find facts for %s" % node end fact.values["fqdn"] = node fact.values["hostname"] = node.sub(/\..+/, '') fact.values["domain"] = node.sub(/^[^.]+\./, '') parameters << {:facts_format => "b64_zlib_yaml", :facts => CGI.escape(fact.render(:b64_zlib_yaml))} end class RequestPool include EventMachine::Deferrable attr_reader :requests, :responses, :times, :sizes attr_reader :repeat, :concurrency, :max_request def initialize(concurrency, repeat, parameters) @parameters = parameters @current_request = 0 @max_request = repeat * concurrency @repeat = repeat @concurrency = concurrency @requests = [] @responses = {:succeeded => [], :failed => []} @times = {} @sizes = {} # initial spawn (1..concurrency).each do |i| spawn end end def spawn_request(index) @times[index] = Time.now @sizes[index] = 0 nodeidx = index % $options[:node].size node = $options[:node][nodeidx] EventMachine::HttpRequest.new("https://#{$options[:server]}:#{$options[:masterport]}/production/catalog/#{node}").get( :port => $options[:masterport], :query => @parameters[nodeidx], :timeout => $options[:timeout], :head => { "Accept" => "pson, yaml, b64_zlib_yaml, marshal, dot, raw", "Accept-Encoding" => "gzip, deflate" }, :ssl => { :private_key_file => $options[:key], :cert_chain_file => $options[:cert], :verify_peer => false } ) do @times[index] = Time.now @sizes[index] = 0 Puppet.debug("starting client #{index} for #{node}") end end def add(index, conn) @requests.push(conn) conn.stream { |data| @sizes[index] += data.length } conn.callback { @times[index] = Time.now - @times[index] code = conn.response_header.status if code >= 200 && code < 300 Puppet.debug("Client #{index} finished successfully") @responses[:succeeded].push(conn) else Puppet.debug("Client #{index} finished with HTTP code #{code}") @responses[:failed].push(conn) end check_progress } conn.errback { Puppet.debug("Client #{index} finished with an error: #{conn.error}") @times[index] = Time.now - @times[index] @responses[:failed].push(conn) check_progress } end def all_responses @responses[:succeeded] + @responses[:failed] end protected def check_progress spawn unless all_spawned? succeed if all_finished? end def all_spawned? @requests.size >= max_request end def all_finished? @responses[:failed].size + @responses[:succeeded].size >= max_request end def spawn add(@current_request, spawn_request(@current_request)) @current_request += 1 end end def mean(array) array.inject(0) { |sum, x| sum += x } / array.size.to_f end def median(array) array = array.sort m_pos = array.size / 2 return array.size % 2 == 1 ? array[m_pos] : mean(array[m_pos-1..m_pos]) end def format_bytes(bytes) if bytes < 1024 "%.2f B" % bytes elsif bytes < 1024 * 1024 "%.2f KiB" % (bytes/1024.0) else "%.2f MiB" % (bytes/(1024.0*1024.0)) end end EM::run { start = Time.now multi = RequestPool.new($options[:concurrency], $options[:repeat], parameters) multi.callback do duration = Time.now - start puts "#{multi.max_request} requests finished in #{duration} s" puts "#{multi.responses[:failed].size} requests failed" puts "Availability: %3.2f %%" % (100.0*multi.responses[:succeeded].size/(multi.responses[:succeeded].size+multi.responses[:failed].size)) minmax = multi.times.values.minmax all_time = multi.times.values.reduce(:+) puts "\nTime (s):" puts "\tmin: #{minmax[0]} s" puts "\tmax: #{minmax[1]} s" puts "\taverage: #{mean(multi.times.values)} s" puts "\tmedian: #{median(multi.times.values)} s" puts "\nConcurrency: %.2f" % (all_time/duration) puts "Transaction Rate (tps): %.2f t/s" % (multi.max_request / duration) transferred = multi.sizes.values.reduce(:+) puts "\nReceived bytes: #{format_bytes(transferred)}" puts "Throughput: %.5f MiB/s" % (transferred/duration/(1024.0*1024.0)) # this is the end EventMachine.stop end } ext/autotest/readme.rst000064400000001367147633135120011217 0ustar00Autotest is a simple tool that automatically links tests with the files being tested, and runs tests automatically when either the test or code has changed. If you are running on a Mac and have growlnotify_ installed, install the ZenTest_ gem, then copy the ``config`` file to ``~/.autotest`` (or just run ``rake`` in this directory). Once you have ``autotest`` installed, change to the root of your Puppet git repository and run ``autotest`` with no arguments. To refresh the list of files to scan, hit ``^c`` (that is, control-c). It's recommended you leave this running in another terminal during all development, preferably on another monitor. .. _zentest: http://www.zenspider.com/ZSS/Products/ZenTest/ .. _growlnotify: http://growl.info/extras.php ext/autotest/Rakefile000064400000000237147633135120010670 0ustar00dest = File.expand_path("~/.autotest") file dest => ["config", "Rakefile"] do sh "cp config #{dest}" end task :install => dest task :default => :install ext/autotest/config000064400000002450147633135120010412 0ustar00# vim: syntax=ruby # From http://pastie.caboo.se/115692, linked from rickbradley require 'autotest/redgreen' require 'autotest/timestamp' Autotest.send(:alias_method, :real_find_files, :find_files) Autotest.send(:define_method, :find_files) do |*args| real_find_files.reject do |k, v| if (ENV['AUTOTEST'] and !ENV['AUTOTEST'].empty?) !Regexp.new(ENV['AUTOTEST']).match(k) end end end module Autotest::Growl def self.growl title, msg, img, pri=0, sticky="" system "growlnotify -n autotest --image #{img} -p #{pri} -m #{msg.inspect} #{title} #{sticky}" end Autotest.add_hook :ran_command do |at| image_root = "~/.autotest_images" results = [at.results].flatten.join("\n") output = results.slice(/(\d+)\stests,\s(\d+)\sassertions,\s(\d+)\sfailures,\s(\d+)\serrors/) if output if $~[3].to_i > 0 || $~[4].to_i > 0 growl "FAIL", "#{output}", "#{image_root}/fail.png", 2 else growl "Pass", "#{output}", "#{image_root}/pass.png" end end output = results.slice(/(\d+)\sexamples,\s(\d+)\sfailures?(,\s+\d+\s+pending)?/) if output if $~[2].to_i > 0 || $~[4].to_i > 0 growl "FAIL", "#{output}", "#{image_root}/fail.png", 2 else growl "Pass", "#{output}", "#{image_root}/pass.png" end end end end ext/redhat/client.sysconfig000064400000000523147633135120012024 0ustar00# The puppetmaster server #PUPPET_SERVER=puppet # If you wish to specify the port to connect to do so here #PUPPET_PORT=8140 # Where to log to. Specify syslog to send log messages to the system log. #PUPPET_LOG=/var/log/puppet/puppet.log # You may specify other parameters to the puppet client here #PUPPET_EXTRA_OPTS=--waitforcert=500 ext/redhat/fileserver.conf000064400000002666147633135120011647 0ustar00# fileserver.conf # Puppet automatically serves PLUGINS and FILES FROM MODULES: anything in # /files/ is available to authenticated nodes at # puppet:///modules//. You do not need to edit this # file to enable this. # MOUNT POINTS # If you need to serve files from a directory that is NOT in a module, # you must create a static mount point in this file: # # [extra_files] # path /etc/puppet/files # allow * # # In the example above, anything in /etc/puppet/files/ would be # available to authenticated nodes at puppet:///extra_files/. # # Mount points may also use three placeholders as part of their path: # # %H - The node's certname. # %h - The portion of the node's certname before the first dot. (Usually the # node's short hostname.) # %d - The portion of the node's certname after the first dot. (Usually the # node's domain name.) # PERMISSIONS # Every static mount point should have an `allow *` line; setting more # granular permissions in this file is deprecated. Instead, you can # control file access in auth.conf by controlling the # /file_metadata/ and /file_content/ paths: # # path ~ ^/file_(metadata|content)/extra_files/ # auth yes # allow /^(.+)\.example\.com$/ # allow_ip 192.168.100.0/24 # # If added to auth.conf BEFORE the "path /file" rule, the rule above # will add stricter restrictions to the extra_files mount point. ext/redhat/puppet.spec000064400000073442147633135120011023 0ustar00# Augeas and SELinux requirements may be disabled at build time by passing # --without augeas and/or --without selinux to rpmbuild or mock # Fedora 17 ships with ruby 1.9, RHEL 7 with ruby 2.0, which use vendorlibdir instead # of sitelibdir. Adjust our target if installing on f17 or rhel7. %if 0%{?fedora} >= 17 || 0%{?rhel} >= 7 || 0%{?amzn} >= 1 %global puppet_libdir %(ruby -rrbconfig -e 'puts RbConfig::CONFIG["vendorlibdir"]') %else %global puppet_libdir %(ruby -rrbconfig -e 'puts RbConfig::CONFIG["sitelibdir"]') %endif %if 0%{?fedora} >= 17 || 0%{?rhel} >= 7 %global _with_systemd 1 %else %global _with_systemd 0 %endif # VERSION is subbed out during rake srpm process %global realversion 3.8.7 %global rpmversion 3.8.7 %global confdir ext/redhat %global pending_upgrade_path %{_localstatedir}/lib/rpm-state/puppet %global pending_upgrade_file %{pending_upgrade_path}/upgrade_pending Name: puppet Version: %{rpmversion} Release: 1%{?dist} Vendor: %{?_host_vendor} Summary: A network tool for managing many disparate systems License: ASL 2.0 URL: http://puppetlabs.com Source0: http://puppetlabs.com/downloads/%{name}/%{name}-%{realversion}.tar.gz Group: System Environment/Base BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: facter >= 1:1.7.0 # Puppet 3.x drops ruby 1.8.5 support and adds ruby 1.9 support BuildRequires: ruby >= 1.8.7 BuildRequires: hiera >= 1.0.0 BuildArch: noarch Requires: ruby >= 1.8 Requires: ruby-shadow Requires: rubygem-json # Pull in ruby selinux bindings where available %if 0%{?fedora} || 0%{?rhel} >= 6 %{!?_without_selinux:Requires: ruby(selinux), libselinux-utils} %else %if ( 0%{?rhel} && 0%{?rhel} == 5 ) || 0%{?amzn} >= 1 %{!?_without_selinux:Requires: libselinux-ruby, libselinux-utils} %endif %endif Requires: facter >= 1:1.7.0 # Puppet 3.x drops ruby 1.8.5 support and adds ruby 1.9 support # Ruby 1.8.7 available for el5 at: yum.puppetlabs.com/el/5/devel/$ARCH Requires: ruby >= 1.8.7 Requires: hiera >= 1.0.0 Obsoletes: hiera-puppet < 1.0.0 Provides: hiera-puppet >= 1.0.0 %{!?_without_augeas:Requires: ruby-augeas} # Required for %%pre Requires: shadow-utils %if 0%{?_with_systemd} # Required for %%post, %%preun, %%postun Requires: systemd %if 0%{?fedora} >= 18 || 0%{?rhel} >= 7 BuildRequires: systemd %else BuildRequires: systemd-units %endif %else # Required for %%post and %%preun Requires: chkconfig # Required for %%preun and %%postun Requires: initscripts %endif %description Puppet lets you centrally manage every important aspect of your system using a cross-platform specification language that manages all the separate elements normally aggregated in different files, like users, cron jobs, and hosts, along with obviously discrete elements like packages, services, and files. %package server Group: System Environment/Base Summary: Server for the puppet system management tool Requires: puppet = %{version}-%{release} # chkconfig (%%post, %%preun) and initscripts (%%preun %%postun) are required for non systemd # and systemd (%%post, %%preun, and %%postun) are required for systems with systemd as default # They come along transitively with puppet-%{version}-%{release}. %description server Provides the central puppet server daemon which provides manifests to clients. The server can also function as a certificate authority and file server. %prep %setup -q -n %{name}-%{realversion} %build for f in external/nagios.rb relationship.rb; do sed -i -e '1d' lib/puppet/$f done find examples/ -type f | xargs --no-run-if-empty chmod a-x %install rm -rf %{buildroot} ruby install.rb --destdir=%{buildroot} --quick --no-rdoc --sitelibdir=%{puppet_libdir} install -d -m0755 %{buildroot}%{_sysconfdir}/puppet/environments/example_env/manifests install -d -m0755 %{buildroot}%{_sysconfdir}/puppet/environments/example_env/modules install -d -m0755 %{buildroot}%{_sysconfdir}/puppet/manifests install -d -m0755 %{buildroot}%{_datadir}/%{name}/modules install -d -m0755 %{buildroot}%{_localstatedir}/lib/puppet install -d -m0755 %{buildroot}%{_localstatedir}/lib/puppet/state install -d -m0755 %{buildroot}%{_localstatedir}/lib/puppet/reports install -d -m0755 %{buildroot}%{_localstatedir}/run/puppet # As per redhat bz #495096 install -d -m0750 %{buildroot}%{_localstatedir}/log/puppet %if 0%{?_with_systemd} # Systemd for fedora >= 17 or el 7 %{__install} -d -m0755 %{buildroot}%{_unitdir} install -Dp -m0644 ext/systemd/puppet.service %{buildroot}%{_unitdir}/puppet.service ln -s %{_unitdir}/puppet.service %{buildroot}%{_unitdir}/puppetagent.service install -Dp -m0644 ext/systemd/puppetmaster.service %{buildroot}%{_unitdir}/puppetmaster.service %else # Otherwise init.d for fedora < 17 or el 5, 6 install -Dp -m0644 %{confdir}/client.sysconfig %{buildroot}%{_sysconfdir}/sysconfig/puppet install -Dp -m0755 %{confdir}/client.init %{buildroot}%{_initrddir}/puppet install -Dp -m0644 %{confdir}/server.sysconfig %{buildroot}%{_sysconfdir}/sysconfig/puppetmaster install -Dp -m0755 %{confdir}/server.init %{buildroot}%{_initrddir}/puppetmaster install -Dp -m0755 %{confdir}/queue.init %{buildroot}%{_initrddir}/puppetqueue %endif install -Dp -m0644 %{confdir}/fileserver.conf %{buildroot}%{_sysconfdir}/puppet/fileserver.conf install -Dp -m0644 %{confdir}/puppet.conf %{buildroot}%{_sysconfdir}/puppet/puppet.conf install -Dp -m0644 %{confdir}/logrotate %{buildroot}%{_sysconfdir}/logrotate.d/puppet install -Dp -m0644 ext/README.environment %{buildroot}%{_sysconfdir}/puppet/environments/example_env/README.environment # Install the ext/ directory to %%{_datadir}/%%{name} install -d %{buildroot}%{_datadir}/%{name} cp -a ext/ %{buildroot}%{_datadir}/%{name} # emacs and vim bits are installed elsewhere rm -rf %{buildroot}%{_datadir}/%{name}/ext/{emacs,vim} # remove misc packaging artifacts not applicable to rpms rm -rf %{buildroot}%{_datadir}/%{name}/ext/{gentoo,freebsd,solaris,suse,windows,osx,ips,debian} rm -f %{buildroot}%{_datadir}/%{name}/ext/redhat/*.init rm -f %{buildroot}%{_datadir}/%{name}/ext/{build_defaults.yaml,project_data.yaml} # Rpmlint fixup chmod 755 %{buildroot}%{_datadir}/%{name}/ext/regexp_nodes/regexp_nodes.rb chmod 755 %{buildroot}%{_datadir}/%{name}/ext/puppet-load.rb # Install emacs mode files emacsdir=%{buildroot}%{_datadir}/emacs/site-lisp install -Dp -m0644 ext/emacs/puppet-mode.el $emacsdir/puppet-mode.el install -Dp -m0644 ext/emacs/puppet-mode-init.el \ $emacsdir/site-start.d/puppet-mode-init.el # Install vim syntax files vimdir=%{buildroot}%{_datadir}/vim/vimfiles install -Dp -m0644 ext/vim/ftdetect/puppet.vim $vimdir/ftdetect/puppet.vim install -Dp -m0644 ext/vim/syntax/puppet.vim $vimdir/syntax/puppet.vim %if 0%{?fedora} >= 15 || 0%{?rhel} >= 7 # Setup tmpfiles.d config mkdir -p %{buildroot}%{_sysconfdir}/tmpfiles.d echo "D /var/run/%{name} 0755 %{name} %{name} -" > \ %{buildroot}%{_sysconfdir}/tmpfiles.d/%{name}.conf %endif # Create puppet modules directory for puppet module tool mkdir -p %{buildroot}%{_sysconfdir}/%{name}/modules %files %defattr(-, root, root, 0755) %doc LICENSE README.md examples %{_bindir}/puppet %{_bindir}/extlookup2hiera %{puppet_libdir}/* %if 0%{?_with_systemd} %{_unitdir}/puppet.service %{_unitdir}/puppetagent.service %else %{_initrddir}/puppet %config(noreplace) %{_sysconfdir}/sysconfig/puppet %endif %dir %{_sysconfdir}/puppet %dir %{_sysconfdir}/%{name}/modules %if 0%{?fedora} >= 15 || 0%{?rhel} >= 7 %config(noreplace) %{_sysconfdir}/tmpfiles.d/%{name}.conf %endif %config(noreplace) %{_sysconfdir}/puppet/puppet.conf %config(noreplace) %{_sysconfdir}/puppet/auth.conf %config(noreplace) %{_sysconfdir}/logrotate.d/puppet # We don't want to require emacs or vim, so we need to own these dirs %{_datadir}/emacs %{_datadir}/vim %{_datadir}/%{name} # man pages %{_mandir}/man5/puppet.conf.5.gz %{_mandir}/man8/puppet.8.gz %{_mandir}/man8/puppet-agent.8.gz %{_mandir}/man8/puppet-apply.8.gz %{_mandir}/man8/puppet-catalog.8.gz %{_mandir}/man8/puppet-describe.8.gz %{_mandir}/man8/puppet-ca.8.gz %{_mandir}/man8/puppet-cert.8.gz %{_mandir}/man8/puppet-certificate.8.gz %{_mandir}/man8/puppet-certificate_request.8.gz %{_mandir}/man8/puppet-certificate_revocation_list.8.gz %{_mandir}/man8/puppet-config.8.gz %{_mandir}/man8/puppet-device.8.gz %{_mandir}/man8/puppet-doc.8.gz %{_mandir}/man8/puppet-facts.8.gz %{_mandir}/man8/puppet-file.8.gz %{_mandir}/man8/puppet-filebucket.8.gz %{_mandir}/man8/puppet-help.8.gz %{_mandir}/man8/puppet-inspect.8.gz %{_mandir}/man8/puppet-instrumentation_data.8.gz %{_mandir}/man8/puppet-instrumentation_listener.8.gz %{_mandir}/man8/puppet-instrumentation_probe.8.gz %{_mandir}/man8/puppet-key.8.gz %{_mandir}/man8/puppet-kick.8.gz %{_mandir}/man8/puppet-man.8.gz %{_mandir}/man8/puppet-module.8.gz %{_mandir}/man8/puppet-node.8.gz %{_mandir}/man8/puppet-parser.8.gz %{_mandir}/man8/puppet-plugin.8.gz %{_mandir}/man8/puppet-queue.8.gz %{_mandir}/man8/puppet-report.8.gz %{_mandir}/man8/puppet-resource.8.gz %{_mandir}/man8/puppet-resource_type.8.gz %{_mandir}/man8/puppet-secret_agent.8.gz %{_mandir}/man8/puppet-status.8.gz %{_mandir}/man8/extlookup2hiera.8.gz # These need to be owned by puppet so the server can # write to them. The separate %defattr's are required # to work around RH Bugzilla 681540 %defattr(-, puppet, puppet, 0755) %{_localstatedir}/run/puppet %defattr(-, puppet, puppet, 0750) %{_localstatedir}/log/puppet %{_localstatedir}/lib/puppet %{_localstatedir}/lib/puppet/state %{_localstatedir}/lib/puppet/reports # Return the default attributes to 0755 to # prevent incorrect permission assignment on EL6 %defattr(-, root, root, 0755) %files server %defattr(-, root, root, 0755) %if 0%{?_with_systemd} %{_unitdir}/puppetmaster.service %else %{_initrddir}/puppetmaster %{_initrddir}/puppetqueue %config(noreplace) %{_sysconfdir}/sysconfig/puppetmaster %endif %config(noreplace) %{_sysconfdir}/puppet/fileserver.conf %dir %{_sysconfdir}/puppet/manifests %dir %{_sysconfdir}/puppet/environments %dir %{_sysconfdir}/puppet/environments/example_env %dir %{_sysconfdir}/puppet/environments/example_env/manifests %dir %{_sysconfdir}/puppet/environments/example_env/modules %{_sysconfdir}/puppet/environments/example_env/README.environment %{_mandir}/man8/puppet-ca.8.gz %{_mandir}/man8/puppet-master.8.gz # Fixed uid/gid were assigned in bz 472073 (Fedora), 471918 (RHEL-5), # and 471919 (RHEL-4) %pre getent group puppet &>/dev/null || groupadd -r puppet -g 52 &>/dev/null getent passwd puppet &>/dev/null || \ useradd -r -u 52 -g puppet -d %{_localstatedir}/lib/puppet -s /sbin/nologin \ -c "Puppet" puppet &>/dev/null # ensure that old setups have the right puppet home dir if [ $1 -gt 1 ] ; then usermod -d %{_localstatedir}/lib/puppet puppet &>/dev/null fi exit 0 %post %if 0%{?_with_systemd} /bin/systemctl daemon-reload >/dev/null 2>&1 || : if [ "$1" -ge 1 ]; then # The pidfile changed from 0.25.x to 2.6.x, handle upgrades without leaving # the old process running. oldpid="%{_localstatedir}/run/puppet/puppetd.pid" newpid="%{_localstatedir}/run/puppet/agent.pid" if [ -s "$oldpid" -a ! -s "$newpid" ]; then (kill $(< "$oldpid") && rm -f "$oldpid" && \ /bin/systemctl start puppet.service) >/dev/null 2>&1 || : fi fi %else /sbin/chkconfig --add puppet || : if [ "$1" -ge 1 ]; then # The pidfile changed from 0.25.x to 2.6.x, handle upgrades without leaving # the old process running. oldpid="%{_localstatedir}/run/puppet/puppetd.pid" newpid="%{_localstatedir}/run/puppet/agent.pid" if [ -s "$oldpid" -a ! -s "$newpid" ]; then (kill $(< "$oldpid") && rm -f "$oldpid" && \ /sbin/service puppet start) >/dev/null 2>&1 || : fi # If an old puppet process (one whose binary is located in /sbin) is running, # kill it and then start up a fresh with the new binary. if [ -e "$newpid" ]; then if ps aux | grep `cat "$newpid"` | grep -v grep | awk '{ print $12 }' | grep -q sbin; then (kill $(< "$newpid") && rm -f "$newpid" && \ /sbin/service puppet start) >/dev/null 2>&1 || : fi fi fi %endif %post server %if 0%{?_with_systemd} /bin/systemctl daemon-reload >/dev/null 2>&1 || : if [ "$1" -ge 1 ]; then # The pidfile changed from 0.25.x to 2.6.x, handle upgrades without leaving # the old process running. oldpid="%{_localstatedir}/run/puppet/puppetmasterd.pid" newpid="%{_localstatedir}/run/puppet/master.pid" if [ -s "$oldpid" -a ! -s "$newpid" ]; then (kill $(< "$oldpid") && rm -f "$oldpid" && \ /bin/systemctl start puppetmaster.service) > /dev/null 2>&1 || : fi fi %else /sbin/chkconfig --add puppetmaster || : if [ "$1" -ge 1 ]; then # The pidfile changed from 0.25.x to 2.6.x, handle upgrades without leaving # the old process running. oldpid="%{_localstatedir}/run/puppet/puppetmasterd.pid" newpid="%{_localstatedir}/run/puppet/master.pid" if [ -s "$oldpid" -a ! -s "$newpid" ]; then (kill $(< "$oldpid") && rm -f "$oldpid" && \ /sbin/service puppetmaster start) >/dev/null 2>&1 || : fi fi %endif %preun %if 0%{?_with_systemd} if [ "$1" -eq 0 ] ; then # Package removal, not upgrade /bin/systemctl --no-reload disable puppetagent.service > /dev/null 2>&1 || : /bin/systemctl --no-reload disable puppet.service > /dev/null 2>&1 || : /bin/systemctl stop puppetagent.service > /dev/null 2>&1 || : /bin/systemctl stop puppet.service > /dev/null 2>&1 || : /bin/systemctl daemon-reload >/dev/null 2>&1 || : fi if [ "$1" == "1" ]; then /bin/systemctl is-enabled puppetagent.service > /dev/null 2>&1 if [ "$?" == "0" ]; then /bin/systemctl --no-reload disable puppetagent.service > /dev/null 2>&1 ||: /bin/systemctl stop puppetagent.service > /dev/null 2>&1 ||: /bin/systemctl daemon-reload >/dev/null 2>&1 ||: if [ ! -d %{pending_upgrade_path} ]; then mkdir -p %{pending_upgrade_path} fi if [ ! -e %{pending_upgrade_file} ]; then touch %{pending_upgrade_file} fi fi fi %else if [ "$1" = 0 ] ; then /sbin/service puppet stop > /dev/null 2>&1 /sbin/chkconfig --del puppet || : fi %endif %preun server %if 0%{?_with_systemd} if [ $1 -eq 0 ] ; then # Package removal, not upgrade /bin/systemctl --no-reload disable puppetmaster.service > /dev/null 2>&1 || : /bin/systemctl stop puppetmaster.service > /dev/null 2>&1 || : /bin/systemctl daemon-reload >/dev/null 2>&1 || : fi %else if [ "$1" = 0 ] ; then /sbin/service puppetmaster stop > /dev/null 2>&1 /sbin/chkconfig --del puppetmaster || : fi %endif %postun %if 0%{?_with_systemd} if [ $1 -ge 1 ] ; then if [ -e %{pending_upgrade_file} ]; then /bin/systemctl --no-reload enable puppet.service > /dev/null 2>&1 ||: /bin/systemctl start puppet.service > /dev/null 2>&1 ||: /bin/systemctl daemon-reload >/dev/null 2>&1 ||: rm %{pending_upgrade_file} fi # Package upgrade, not uninstall /bin/systemctl try-restart puppetagent.service >/dev/null 2>&1 || : fi %else if [ "$1" -ge 1 ]; then /sbin/service puppet condrestart >/dev/null 2>&1 || : fi %endif %postun server %if 0%{?_with_systemd} if [ $1 -ge 1 ] ; then # Package upgrade, not uninstall /bin/systemctl try-restart puppetmaster.service >/dev/null 2>&1 || : fi %else if [ "$1" -ge 1 ]; then /sbin/service puppetmaster condrestart >/dev/null 2>&1 || : fi %endif %clean rm -rf %{buildroot} %changelog * Mon Apr 25 2016 Puppet Labs Release - 3.8.7-1 - Build for 3.8.7 * Wed Oct 2 2013 Jason Antman - Move systemd service and unit file names back to "puppet" from erroneous "puppetagent" - Add symlink to puppetagent unit file for compatibility with current bug - Alter package removal actions to deactivate and stop both service names * Thu Jun 27 2013 Matthaus Owens - 3.2.3-0.1rc0 - Bump requires on ruby-rgen to 0.6.5 * Fri Apr 12 2013 Matthaus Owens - 3.2.0-0.1rc0 - Add requires on ruby-rgen for new parser in Puppet 3.2 * Fri Jan 25 2013 Matthaus Owens - 3.1.0-0.1rc1 - Add extlookup2hiera.8.gz to the files list * Wed Jan 9 2013 Ryan Uber - 3.1.0-0.1rc1 - Work-around for RH Bugzilla 681540 * Fri Dec 28 2012 Michael Stahnke - 3.0.2-2 - Added a script for Network Manager for bug https://bugzilla.redhat.com/532085 * Tue Dec 18 2012 Matthaus Owens - Remove for loop on examples/ code which no longer exists. Add --no-run-if-empty to xargs invocations. * Sat Dec 1 2012 Ryan Uber - Fix for logdir perms regression (#17866) * Wed Aug 29 2012 Moses Mendoza - 3.0.0-0.1rc5 - Update for 3.0.0 rc5 * Fri Aug 24 2012 Eric Sorenson - 3.0.0-0.1rc4 - Facter requirement is 1.6.11, not 2.0 - Update for 3.0.0 rc4 * Tue Aug 21 2012 Moses Mendoza - 2.7.19-1 - Update for 2.7.19 * Tue Aug 14 2012 Moses Mendoza - 2.7.19-0.1rc3 - Update for 2.7.19rc3 * Tue Aug 7 2012 Moses Mendoza - 2.7.19-0.1rc2 - Update for 2.7.19rc2 * Wed Aug 1 2012 Moses Mendoza - 2.7.19-0.1rc1 - Update for 2.7.19rc1 * Wed Jul 11 2012 William Hopper - 2.7.18-2 - (#15221) Create /etc/puppet/modules for puppet module tool * Mon Jul 9 2012 Moses Mendoza - 2.7.18-1 - Update for 2.7.18 * Tue Jun 19 2012 Matthaus Litteken - 2.7.17-1 - Update for 2.7.17 * Wed Jun 13 2012 Matthaus Litteken - 2.7.16-1 - Update for 2.7.16 * Fri Jun 08 2012 Moses Mendoza - 2.7.16-0.1rc1.2 - Updated facter 2.0 dep to include epoch 1 * Wed Jun 06 2012 Matthaus Litteken - 2.7.16-0.1rc1 - Update for 2.7.16rc1, added generated manpages * Fri Jun 01 2012 Matthaus Litteken - 3.0.0-0.1rc3 - Puppet 3.0.0rc3 Release * Fri Jun 01 2012 Matthaus Litteken - 2.7.15-0.1rc4 - Update for 2.7.15rc4 * Tue May 29 2012 Moses Mendoza - 2.7.15-0.1rc3 - Update for 2.7.15rc3 * Tue May 22 2012 Matthaus Litteken - 3.0.0-0.1rc2 - Puppet 3.0.0rc2 Release * Thu May 17 2012 Matthaus Litteken - 3.0.0-0.1rc1 - Puppet 3.0.0rc1 Release * Wed May 16 2012 Moses Mendoza - 2.7.15-0.1rc2 - Update for 2.7.15rc2 * Tue May 15 2012 Moses Mendoza - 2.7.15-0.1rc1 - Update for 2.7.15rc1 * Wed May 02 2012 Moses Mendoza - 2.7.14-1 - Update for 2.7.14 * Tue Apr 10 2012 Matthaus Litteken - 2.7.13-1 - Update for 2.7.13 * Mon Mar 12 2012 Michael Stahnke - 2.7.12-1 - Update for 2.7.12 * Fri Feb 24 2012 Matthaus Litteken - 2.7.11-2 - Update 2.7.11 from proper tag, including #12572 * Wed Feb 22 2012 Michael Stahnke - 2.7.11-1 - Update for 2.7.11 * Wed Jan 25 2012 Michael Stahnke - 2.7.10-1 - Update for 2.7.10 * Fri Dec 9 2011 Matthaus Litteken - 2.7.9-1 - Update for 2.7.9 * Thu Dec 8 2011 Matthaus Litteken - 2.7.8-1 - Update for 2.7.8 * Wed Nov 30 2011 Michael Stahnke - 2.7.8-0.1rc1 - Update for 2.7.8rc1 * Mon Nov 21 2011 Michael Stahnke - 2.7.7-1 - Relaese 2.7.7 * Tue Nov 01 2011 Michael Stahnke - 2.7.7-0.1rc1 - Update for 2.7.7rc1 * Fri Oct 21 2011 Michael Stahnke - 2.7.6-1 - 2.7.6 final * Thu Oct 13 2011 Michael Stahnke - 2.7.6-.1rc3 - New RC * Fri Oct 07 2011 Michael Stahnke - 2.7.6-0.1rc2 - New RC * Mon Oct 03 2011 Michael Stahnke - 2.7.6-0.1rc1 - New RC * Fri Sep 30 2011 Michael Stahnke - 2.7.5-1 - Fixes for CVE-2011-3869, 3870, 3871 * Wed Sep 28 2011 Michael Stahnke - 2.7.4-1 - Fix for CVE-2011-3484 * Wed Jul 06 2011 Michael Stahnke - 2.7.2-0.2.rc1 - Clean up rpmlint errors - Put man pages in correct package * Wed Jul 06 2011 Michael Stahnke - 2.7.2-0.1.rc1 - Update to 2.7.2rc1 * Wed Jun 15 2011 Todd Zullinger - 2.6.9-0.1.rc1 - Update rc versioning to ensure 2.6.9 final is newer to rpm - sync changes with Fedora/EPEL * Tue Jun 14 2011 Michael Stahnke - 2.6.9rc1-1 - Update to 2.6.9rc1 * Thu Apr 14 2011 Todd Zullinger - 2.6.8-1 - Update to 2.6.8 * Thu Mar 24 2011 Todd Zullinger - 2.6.7-1 - Update to 2.6.7 * Wed Mar 16 2011 Todd Zullinger - 2.6.6-1 - Update to 2.6.6 - Ensure %%pre exits cleanly - Fix License tag, puppet is now GPLv2 only - Create and own /usr/share/puppet/modules (#615432) - Properly restart puppet agent/master daemons on upgrades from 0.25.x - Require libselinux-utils when selinux support is enabled - Support tmpfiles.d for Fedora >= 15 (#656677) * Wed Feb 09 2011 Fedora Release Engineering - 0.25.5-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild * Mon May 17 2010 Todd Zullinger - 0.25.5-1 - Update to 0.25.5 - Adjust selinux conditional for EL-6 - Apply rundir-perms patch from tarball rather than including it separately - Update URL's to reflect the new puppetlabs.com domain * Fri Jan 29 2010 Todd Zullinger - 0.25.4-1 - Update to 0.25.4 * Tue Jan 19 2010 Todd Zullinger - 0.25.3-2 - Apply upstream patch to fix cron resources (upstream #2845) * Mon Jan 11 2010 Todd Zullinger - 0.25.3-1 - Update to 0.25.3 * Tue Jan 05 2010 Todd Zullinger - 0.25.2-1.1 - Replace %%define with %%global for macros * Tue Jan 05 2010 Todd Zullinger - 0.25.2-1 - Update to 0.25.2 - Fixes CVE-2010-0156, tmpfile security issue (#502881) - Install auth.conf, puppetqd manpage, and queuing examples/docs * Wed Nov 25 2009 Jeroen van Meeuwen - 0.25.1-1 - New upstream version * Tue Oct 27 2009 Todd Zullinger - 0.25.1-0.3 - Update to 0.25.1 - Include the pi program and man page (R.I.Pienaar) * Sat Oct 17 2009 Todd Zullinger - 0.25.1-0.2.rc2 - Update to 0.25.1rc2 * Tue Sep 22 2009 Todd Zullinger - 0.25.1-0.1.rc1 - Update to 0.25.1rc1 - Move puppetca to puppet package, it has uses on client systems - Drop redundant %%doc from manpage %%file listings * Fri Sep 04 2009 Todd Zullinger - 0.25.0-1 - Update to 0.25.0 - Fix permissions on /var/log/puppet (#495096) - Install emacs mode and vim syntax files (#491437) - Install ext/ directory in %%{_datadir}/%%{name} (/usr/share/puppet) * Mon May 04 2009 Todd Zullinger - 0.25.0-0.1.beta1 - Update to 0.25.0beta1 - Make Augeas and SELinux requirements build time options * Mon Mar 23 2009 Todd Zullinger - 0.24.8-1 - Update to 0.24.8 - Quiet output from %%pre - Use upstream install script - Increase required facter version to >= 1.5 * Tue Dec 16 2008 Todd Zullinger - 0.24.7-4 - Remove redundant useradd from %%pre * Tue Dec 16 2008 Jeroen van Meeuwen - 0.24.7-3 - New upstream version - Set a static uid and gid (#472073, #471918, #471919) - Add a conditional requirement on libselinux-ruby for Fedora >= 9 - Add a dependency on ruby-augeas * Wed Oct 22 2008 Todd Zullinger - 0.24.6-1 - Update to 0.24.6 - Require ruby-shadow on Fedora and RHEL >= 5 - Simplify Fedora/RHEL version checks for ruby(abi) and BuildArch - Require chkconfig and initstripts for preun, post, and postun scripts - Conditionally restart puppet in %%postun - Ensure %%preun, %%post, and %%postun scripts exit cleanly - Create puppet user/group according to Fedora packaging guidelines - Quiet a few rpmlint complaints - Remove useless %%pbuild macro - Make specfile more like the Fedora/EPEL template * Mon Jul 28 2008 David Lutterkort - 0.24.5-1 - Add /usr/bin/puppetdoc * Thu Jul 24 2008 Brenton Leanhardt - New version - man pages now ship with tarball - examples/code moved to root examples dir in upstream tarball * Tue Mar 25 2008 David Lutterkort - 0.24.4-1 - Add man pages (from separate tarball, upstream will fix to include in main tarball) * Mon Mar 24 2008 David Lutterkort - 0.24.3-1 - New version * Wed Mar 5 2008 David Lutterkort - 0.24.2-1 - New version * Sat Dec 22 2007 David Lutterkort - 0.24.1-1 - New version * Mon Dec 17 2007 David Lutterkort - 0.24.0-2 - Use updated upstream tarball that contains yumhelper.py * Fri Dec 14 2007 David Lutterkort - 0.24.0-1 - Fixed license - Munge examples/ to make rpmlint happier * Wed Aug 22 2007 David Lutterkort - 0.23.2-1 - New version * Thu Jul 26 2007 David Lutterkort - 0.23.1-1 - Remove old config files * Wed Jun 20 2007 David Lutterkort - 0.23.0-1 - Install one puppet.conf instead of old config files, keep old configs around to ease update - Use plain shell commands in install instead of macros * Wed May 2 2007 David Lutterkort - 0.22.4-1 - New version * Thu Mar 29 2007 David Lutterkort - 0.22.3-1 - Claim ownership of _sysconfdir/puppet (bz 233908) * Mon Mar 19 2007 David Lutterkort - 0.22.2-1 - Set puppet's homedir to /var/lib/puppet, not /var/puppet - Remove no-lockdir patch, not needed anymore * Mon Feb 12 2007 David Lutterkort - 0.22.1-2 - Fix bogus config parameter in puppetd.conf * Sat Feb 3 2007 David Lutterkort - 0.22.1-1 - New version * Fri Jan 5 2007 David Lutterkort - 0.22.0-1 - New version * Mon Nov 20 2006 David Lutterkort - 0.20.1-2 - Make require ruby(abi) and buildarch: noarch conditional for fedora 5 or later to allow building on older fedora releases * Mon Nov 13 2006 David Lutterkort - 0.20.1-1 - New version * Mon Oct 23 2006 David Lutterkort - 0.20.0-1 - New version * Tue Sep 26 2006 David Lutterkort - 0.19.3-1 - New version * Mon Sep 18 2006 David Lutterkort - 0.19.1-1 - New version * Thu Sep 7 2006 David Lutterkort - 0.19.0-1 - New version * Tue Aug 1 2006 David Lutterkort - 0.18.4-2 - Use /usr/bin/ruby directly instead of /usr/bin/env ruby in executables. Otherwise, initscripts break since pidof can't find the right process * Tue Aug 1 2006 David Lutterkort - 0.18.4-1 - New version * Fri Jul 14 2006 David Lutterkort - 0.18.3-1 - New version * Wed Jul 5 2006 David Lutterkort - 0.18.2-1 - New version * Wed Jun 28 2006 David Lutterkort - 0.18.1-1 - Removed lsb-config.patch and yumrepo.patch since they are upstream now * Mon Jun 19 2006 David Lutterkort - 0.18.0-1 - Patch config for LSB compliance (lsb-config.patch) - Changed config moves /var/puppet to /var/lib/puppet, /etc/puppet/ssl to /var/lib/puppet, /etc/puppet/clases.txt to /var/lib/puppet/classes.txt, /etc/puppet/localconfig.yaml to /var/lib/puppet/localconfig.yaml * Fri May 19 2006 David Lutterkort - 0.17.2-1 - Added /usr/bin/puppetrun to server subpackage - Backported patch for yumrepo type (yumrepo.patch) * Wed May 3 2006 David Lutterkort - 0.16.4-1 - Rebuilt * Fri Apr 21 2006 David Lutterkort - 0.16.0-1 - Fix default file permissions in server subpackage - Run puppetmaster as user puppet - rebuilt for 0.16.0 * Mon Apr 17 2006 David Lutterkort - 0.15.3-2 - Don't create empty log files in post-install scriptlet * Fri Apr 7 2006 David Lutterkort - 0.15.3-1 - Rebuilt for new version * Wed Mar 22 2006 David Lutterkort - 0.15.1-1 - Patch0: Run puppetmaster as root; running as puppet is not ready for primetime * Mon Mar 13 2006 David Lutterkort - 0.15.0-1 - Commented out noarch; requires fix for bz184199 * Mon Mar 6 2006 David Lutterkort - 0.14.0-1 - Added BuildRequires for ruby * Wed Mar 1 2006 David Lutterkort - 0.13.5-1 - Removed use of fedora-usermgmt. It is not required for Fedora Extras and makes it unnecessarily hard to use this rpm outside of Fedora. Just allocate the puppet uid/gid dynamically * Sun Feb 19 2006 David Lutterkort - 0.13.0-4 - Use fedora-usermgmt to create puppet user/group. Use uid/gid 24. Fixed problem with listing fileserver.conf and puppetmaster.conf twice * Wed Feb 8 2006 David Lutterkort - 0.13.0-3 - Fix puppetd.conf * Wed Feb 8 2006 David Lutterkort - 0.13.0-2 - Changes to run puppetmaster as user puppet * Mon Feb 6 2006 David Lutterkort - 0.13.0-1 - Don't mark initscripts as config files * Mon Feb 6 2006 David Lutterkort - 0.12.0-2 - Fix BuildRoot. Add dist to release * Tue Jan 17 2006 David Lutterkort - 0.11.0-1 - Rebuild * Thu Jan 12 2006 David Lutterkort - 0.10.2-1 - Updated for 0.10.2 Fixed minor kink in how Source is given * Wed Jan 11 2006 David Lutterkort - 0.10.1-3 - Added basic fileserver.conf * Wed Jan 11 2006 David Lutterkort - 0.10.1-1 - Updated. Moved installation of library files to sitelibdir. Pulled initscripts into separate files. Folded tools rpm into server * Thu Nov 24 2005 Duane Griffin - Added init scripts for the client * Wed Nov 23 2005 Duane Griffin - First packaging ext/redhat/server.sysconfig000064400000000776147633135120012066 0ustar00# Location of the main manifest #PUPPETMASTER_MANIFEST=/etc/puppet/manifests/site.pp # Where to log general messages to. # Specify syslog to send log messages to the system log. #PUPPETMASTER_LOG=syslog # You may specify an alternate port on which your puppetmaster should listen. Default is: 8140 # An example with puppetmaster on a different port, run with standard webrick servertype #PUPPETMASTER_PORTS="8141" # You may specify other parameters to the puppetmaster here #PUPPETMASTER_EXTRA_OPTS=--no-ca ext/redhat/puppet.conf000064400000001525147633135120011007 0ustar00[main] # The Puppet log directory. # The default value is '$vardir/log'. logdir = /var/log/puppet # Where Puppet PID files are kept. # The default value is '$vardir/run'. rundir = /var/run/puppet # Where SSL certificates are kept. # The default value is '$confdir/ssl'. ssldir = $vardir/ssl [agent] # The file in which puppetd stores a list of the classes # associated with the retrieved configuratiion. Can be loaded in # the separate ``puppet`` executable using the ``--loadclasses`` # option. # The default value is '$confdir/classes.txt'. classfile = $vardir/classes.txt # Where puppetd caches the local configuration. An # extension indicating the cache format is added automatically. # The default value is '$confdir/localconfig'. localconfig = $vardir/localconfig ext/redhat/logrotate000064400000000400147633135120010535 0ustar00/var/log/puppet/*log { missingok notifempty create 0644 puppet puppet sharedscripts postrotate pkill -USR2 -u puppet -f 'puppet master' || true [ -e /etc/init.d/puppet ] && /etc/init.d/puppet reload > /dev/null 2>&1 || true endscript } ext/yaml_nodes.rb000075500000005621147633135120010037 0ustar00#!/usr/bin/ruby # # = Synopsis # # Use YAML files to provide external node support. # # = Usage # # yaml-nodes # # = Description # # This is a simple example external node script. It allows you to maintain your # node information in yaml files, and it will find a given node's file and produce # it on stdout. It has simple inheritance, in that a node can specify a parent # node, and the node will inherit that parent's classes and parameters. # # = Options # # help:: # Print this help message # # yamldir:: # Specify where the yaml is found. Defaults to 'yaml' in the current directory. # # = License # Copyright 2011 Luke Kanies # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require 'yaml' require 'optparse' BASEDIR = Dir.chdir(File.dirname(__FILE__) + "/..") { Dir.getwd } options = {:yamldir => File.join(BASEDIR, "yaml")} OptionParser.new do |opts| opts.banner = "Usage: yaml-nodes [options] " opts.on("-y dir", "--yamldir dir", "Specify the directory with the YAML files") do |arg| raise "YAML directory #{arg} does not exist or is not a directory" unless FileTest.directory?(arg) options[:yamldir] = arg end opts.on("-h", "--help", "Print this help") do puts opts.help exit(0) end end.parse! # Read in a pure yaml representation of our node. def read_node(node) nodefile = File.join(YAMLDIR, "#{node}.yaml") if FileTest.exist?(nodefile) return YAML.load_file(nodefile) else raise "Could not find information for #{node}" end end node = ARGV[0] info = read_node(node) # Iterate over any provided parents, merging in there information. parents_seen = [] while parent = info["parent"] raise "Found inheritance loop with parent #{parent}" if parents_seen.include?(parent) parents_seen << parent info.delete("parent") parent_info = read_node(parent) # Include any parent classes in our list. if pclasses = parent_info["classes"] info["classes"] += pclasses info["classes"].uniq! end # And inherit parameters from our parent, while preferring our own values. if pparams = parent_info["parameters"] # When using Hash#merge, the hash being merged in wins, and we # want the subnode parameters to be the parent node parameters. info["parameters"] = pparams.merge(info["parameters"]) end # Copy over any parent node name. if pparent = parent_info["parent"] info["parent"] = pparent end end puts YAML.dump(info) ext/ldap/puppet.schema000064400000001521147633135120010767 0ustar00attributetype ( 1.3.6.1.4.1.34380.1.1.3.10 NAME 'puppetClass' DESC 'Puppet Node Class' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) attributetype ( 1.3.6.1.4.1.34380.1.1.3.9 NAME 'parentNode' DESC 'Puppet Parent Node' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) attributetype ( 1.3.6.1.4.1.34380.1.1.3.11 NAME 'environment' DESC 'Puppet Node Environment' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) attributetype ( 1.3.6.1.4.1.34380.1.1.3.12 NAME 'puppetVar' DESC 'A variable setting for puppet' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) objectclass ( 1.3.6.1.4.1.34380.1.1.1.2 NAME 'puppetClient' SUP top AUXILIARY DESC 'Puppet Client objectclass' MAY ( puppetclass $ parentnode $ environment $ puppetvar )) ext/pure_ruby_dsl/dsl_test.rb000064400000000167147633135120012401 0ustar00hostclass "foobar" do notify "this is a test", "loglevel" => "warning" end node "default" do acquire "foobar" end ext/cert_inspector000075500000010606147633135120010325 0ustar00#!/usr/bin/env ruby require 'openssl' class X509Collector include Enumerable def initialize @collected_data = {} end def interpret_contents(contents) cls = case contents.split("\n")[0] when /BEGIN X509 CRL/ then OpenSSL::X509::CRL when /BEGIN CERTIFICATE REQUEST/ then OpenSSL::X509::Request when /BEGIN CERTIFICATE/ then OpenSSL::X509::Certificate when /BEGIN RSA (PRIVATE|PUBLIC) KEY/ then OpenSSL::PKey::RSA else return nil end cls.new(contents) rescue nil end def expected_non_x509_files ['inventory.txt', 'ca.pass', 'serial'] end def investigate_path(path) if File.directory?(path) Dir.foreach(path) do |x| next if ['.', '..'].include? x investigate_path File.join(path, x) end else contents = File.read path meaning = interpret_contents contents unless meaning || expected_non_x509_files.include?(File.basename(path)) puts "WARNING: file #{path.inspect} could not be interpreted" end @collected_data[path] = meaning if meaning end end def each(&block) @collected_data.each(&block) end def extract_public_key_info(path, meaning) case meaning when OpenSSL::PKey::RSA if meaning.private? [meaning.public_key, 2, path] else [meaning, 3, path] end when OpenSSL::X509::Certificate [meaning.public_key, 0, meaning.subject.to_s] when OpenSSL::X509::Request [meaning.public_key, 1, meaning.subject.to_s] end end def who_signed(meaning, key_names, keys) signing_key = keys.find { |key| meaning.verify(key) } if signing_key then "#{key_names[signing_key.to_s]}" else "???" end end def explain(meaning, key_names, keys) case meaning when OpenSSL::PKey::RSA if meaning.private? "Private key for #{key_names[meaning.public_key.to_s]}" else "Public key for #{key_names[meaning.public_key.to_s]}" end when OpenSSL::X509::Certificate signature_desc = who_signed(meaning, key_names, keys) "Certificate assigning name #{meaning.subject.to_s} to #{key_names[meaning.public_key.to_s]}\n serial number #{meaning.serial}\n issued by #{meaning.issuer.to_s}\n signed by #{signature_desc}" when OpenSSL::X509::Request signature_desc = who_signed(meaning, key_names, keys) "Certificate request for #{meaning.subject.to_s} having key #{key_names[meaning.public_key.to_s]}\n signed by #{signature_desc}" when OpenSSL::X509::CRL signature_desc = who_signed(meaning, key_names, keys) revoked_serial_numbers = meaning.revoked.map { |r| r.serial } revoked_desc = if revoked_serial_numbers.count > 0 then "serial numbers #{revoked_serial_numbers.inspect}" else "nothing" end "Certificate revocation list revoking #{revoked_desc}\n issued by #{meaning.issuer.to_s}\n signed by #{signature_desc}" else "Unknown" end end # Yield unique public keys, with a canonical name for each. def collect_public_keys key_data = {} # pem => (priority, name, public_key) @collected_data.collect do |path, meaning| begin next unless public_key_info = extract_public_key_info(path, meaning) public_key, priority, name = public_key_info pem = public_key.to_s existing_priority, existing_name, existing_public_key = key_data[pem] next if existing_priority and existing_priority < priority key_data[pem] = priority, name, public_key rescue puts "exception!" end end name_to_key_hash = {} key_data.each do |pem, data| priority, name, public_key = data if name_to_key_hash[name] suffix_num = 2 while name_to_key_hash[name + " (#{suffix_num})"] suffix_num += 1 end name = name + " (#{suffix_num})" end name_to_key_hash[name] = public_key end key_names = {} keys = [] name_to_key_hash.each do |name, public_key| key_names[public_key.to_s] = "key<#{name}>" keys << public_key end [key_names, keys] end end collector = X509Collector.new ARGV.each do |path| collector.investigate_path(path) end key_names, keys = collector.collect_public_keys collector.map do |path, meaning| [collector.explain(meaning, key_names, keys), path] end.sort.each do |description, path| puts "#{path}:" puts " #{description}" puts end ext/README.environment000064400000000640147633135120010574 0ustar00This is an example environment directory. The environment's modules can be placed in a "modules" subdirectory. The environments initial manifests are placed in a "manifests" subdirectory. By default the environment also has any modules that are installed globally (normally in /etc/puppet/modules) for the puppet master. For more information see http://docs.puppetlabs.com/puppet/latest/reference/environments.html