summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README34
-rw-r--r--files/client/puppet.conf.FreeBSD26
-rw-r--r--files/cron.d/puppetd2
-rw-r--r--files/cron.d/puppetd.Gentoo2
-rw-r--r--files/master/lastruncheck323
-rw-r--r--manifests/cron/freebsd.pp23
-rw-r--r--manifests/freebsd.pp27
7 files changed, 210 insertions, 227 deletions
diff --git a/README b/README
index d30a8e9..20015e1 100644
--- a/README
+++ b/README
@@ -9,8 +9,20 @@ files, under:
Usage
=====
-The module currently looks for values on different variables to adjust
-configuration of the master.
+The module currently looks for different variable values to adjust configuration
+of the master.
+
+Installing a specific versions
+------------------------------
+
+If you need to install a different version of puppet, other than the most recent,
+you can set the following variable:
+
+$puppet_ensure_version = '2.7.18-1~bpo60+1'
+
+You can also specify a different facter version by setting the following variable:
+
+$facter_ensure_version = '1.6.9-2~bpo60+2'
Run puppet by cron:
-------------------
@@ -49,6 +61,24 @@ mode, you can set $puppetmaster_mode either to:
In both cases you have to setup the appropriate frontends (apache vhost
configuration/nginx vhost configuration) on your own.
+If you need to install a specific version of puppetmaster, you can specify the
+version to be installed by doing the following:
+
+$puppetmaster_ensure_version = '2.7.18-1~bpo60+1'
+
+NOTE: You will need the apt module in order to specify the puppetmaster version.
+Also, this functionality is only implemented for Debian and derived distributions.
+
+This is the apparent minimum manifest for installing puppetmaster:
+
+ import 'common'
+
+ include apt
+ include concat::setup
+ $puppetmaster_mode = 'passenger'
+ include puppet::puppetmaster
+
+
Munin
-----
diff --git a/files/client/puppet.conf.FreeBSD b/files/client/puppet.conf.FreeBSD
new file mode 100644
index 0000000..71bcf77
--- /dev/null
+++ b/files/client/puppet.conf.FreeBSD
@@ -0,0 +1,26 @@
+[main]
+ logdir=/var/log/puppet
+ vardir=/var/puppet
+ rundir=/var/run/puppet
+
+ ssldir=/var/puppet/ssl
+
+ # Where 3rd party plugins and modules are installed
+ libdir = $vardir/lib
+
+ templatedir=$vardir/templates
+
+ # Turn plug-in synchronization on.
+ pluginsync = true
+ pluginsource = puppet://$server/plugins
+ factpath = $vardir/lib/facter
+
+[puppetd]
+ report=true
+ server=server.example.com
+
+ # different run-interval, default= 30min
+ # e.g. run puppetd every 4 hours = 14400
+ # runinterval = 14400
+
+ logdest=$logdir/puppet.log
diff --git a/files/cron.d/puppetd b/files/cron.d/puppetd
index 4db734a..1f2c6b5 100644
--- a/files/cron.d/puppetd
+++ b/files/cron.d/puppetd
@@ -1,5 +1,5 @@
# check if puppet is running
-0 * * * * root /bin/ps ax | /bin/grep -v grep | /bin/grep -q puppetd || (sleep $(( $(</dev/urandom od -N2 -t u2 -A n) >> 6 )) && /etc/init.d/puppet restart > /dev/null)
+0 * * * * root /bin/ps ax | /bin/grep -v grep | /bin/grep -q puppet || (sleep $(( $(</dev/urandom od -N2 -t u2 -A n) >> 6 )) && /etc/init.d/puppet restart > /dev/null)
# restart puppet once in a while and randomly delay the restart between 0 and 32 minutes -> splay puppetmaster hammering
0 22 * * */2 root sleep $(( $( </dev/urandom od -N2 -t u2 -A none ) >> 5 )) && /etc/init.d/puppet restart > /dev/null
diff --git a/files/cron.d/puppetd.Gentoo b/files/cron.d/puppetd.Gentoo
index 2404d68..0d7e6e1 100644
--- a/files/cron.d/puppetd.Gentoo
+++ b/files/cron.d/puppetd.Gentoo
@@ -1,5 +1,5 @@
# check if puppet is running
-# 0 * * * * root /bin/ps ax | /bin/grep -v grep | /bin/grep -q puppetd || ( sleep $(( $(</dev/urandom od -N2 -t u2 -A n) >> 6 )) && /etc/init.d/puppet restart > /dev/null)
+# 0 * * * * root /bin/ps ax | /bin/grep -v grep | /bin/grep -q puppet || ( sleep $(( $(</dev/urandom od -N2 -t u2 -A n) >> 6 )) && /etc/init.d/puppet restart > /dev/null)
# restart puppet once in a while and randomly delay the restart between 0 and 32 minutes -> splay puppetmaster hammering
# 0 22 * * */2 root sleep $(( $(</dev/urandom od -N2 -t u2 -A n) >> 5 )) && /etc/init.d/puppet restart > /dev/null
diff --git a/files/master/lastruncheck b/files/master/lastruncheck
index 149c655..72c0eb5 100644
--- a/files/master/lastruncheck
+++ b/files/master/lastruncheck
@@ -1,224 +1,101 @@
-#!/usr/bin/env ruby
-require 'puppet/application'
-
-module Puppet::Lastcheck
- module Puppet::Lastcheck::Tests
- def self.included(klass)
- klass.extend ClassMethods
- end
- def self.tests
- @tests ||= {}
- end
- module ClassMethods
- def add_test(name, options={})
- include Puppet::Lastcheck::Tests.const_get(name.to_s.split('_').collect{|s| s.capitalize }.join(''))
- Puppet::Lastcheck::Tests.tests[name] = options
- attr_accessor "ignore_#{name}".to_sym
- option("--ignore-#{name.to_s.gsub(/_/,'-')}") do
- self.send("ignore_#{name}=", true)
- end
- end
- end
- module Util
- def facts_hosts
- return @facts_hosts if @facts_hosts
- require 'puppet/indirector/facts/yaml'
- @facts_hosts = Puppet::Node::Facts.search("*").collect do |fqdn|
- if node = Puppet::Node::Facts.find(fqdn)
- { :hostname => node.name, :expired => node.expired?, :timestamp => node.values[:_timestamp], :expiration => node.expiration }
- end
- end.compact
- end
- end
- end
- module Puppet::Lastcheck::Reports
- def self.included(klass)
- klass.extend ClassMethods
- end
- def ordered_reports
- @ordered_reports ||= Puppet::Lastcheck::Reports.reports.keys.sort{|a,b| Puppet::Lastcheck::Reports.reports[a][:priority] <=> Puppet::Lastcheck::Reports.reports[b][:priority] }
- end
-
- def self.reports
- @reports ||= {}
- end
- module ClassMethods
- def add_report(name, options={})
- include Puppet::Lastcheck::Reports.const_get(name.to_s.split('_').collect{|s| s.capitalize }.join(''))
- Puppet::Lastcheck::Reports.reports[name] = options
- Puppet::Lastcheck::Reports.reports[name][:priority] ||= 100
- attr_accessor "report_to_#{name}".to_sym
- option("--report-to-#{name.to_s.gsub(/_/,'-')}") do
- self.send("report_to_#{name}=", true)
- end
- end
- end
- end
-end
-
-module Puppet::Lastcheck::Tests::NoFacts
- def analyze_no_facts
- signed_hosts.each{|host| add_failed_host(host,"No facts available") unless facts_hosts.any?{|fhost| fhost[:hostname] == host } }
- end
- def setup_no_facts
- Puppet::SSL::Host.ca_location = :only
- end
-
- private
- def signed_hosts
- ca.list
- end
-
- def ca
- @ca ||= Puppet::SSL::CertificateAuthority.new
- end
-end
-
-module Puppet::Lastcheck::Tests::ExpiredFacts
- include Puppet::Lastcheck::Tests::Util
- def analyze_expired_facts
- facts_hosts.each{|host| add_failed_host(host[:hostname],"Expired at #{host[:expiration]}") if host[:expired] }
- end
-end
-module Puppet::Lastcheck::Tests::TimedOutFacts
- include Puppet::Lastcheck::Tests::Util
- def analyze_timed_out_facts
- require 'time'
- facts_hosts.each{|host| add_failed_host(host[:hostname], "Last facts save at #{host[:timestamp]}") if Time.parse(host[:timestamp].to_s) < (Time.now - @timeout) }
- end
-
- def setup_timed_out_facts
- if @timeout
- ignore_expired_facts ||= true
- end
- end
-end
-module Puppet::Lastcheck::Tests::Storedconfigs
- def analyze_storedconfigs
- storedconfigs_hosts.each do |host|
- if !facts_hosts.any?{|fact_host| fact_host[:hostname] == host.name }
- add_failed_host(host.name, "In storedconfigs but no facts available!")
- elsif host.last_compile.nil?
- add_failed_host(host.name, "No entry in storedconfigs")
- elsif host.last_compile < (Time.now - @timeout)
- add_failed_host(host.name, "Last compile time in storedconfigs at #{host.last_compile}")
- end
- end
- end
-
- private
- def storedconfigs_hosts
- return @storedconfigs_hosts if @storedconfigs_hosts
- Puppet::Rails.connect
- @storedconfigs_hosts = Puppet::Rails::Host.all
- end
-end
-module Puppet::Lastcheck::Reports::Console
- def deliver_report_to_console(failing_hosts)
- unless failing_hosts.empty?
- puts 'The following hosts are out of date:'
- puts '------------------------------------'
- host_length = 0
- failing_hosts.keys.each{|host| host_length = host.length if host.length > host_length }
- failing_hosts.keys.each{ |host| puts "#{pretty_puts(host,host_length)} - Reason: #{failing_hosts[host][:reason]}" }
- 1
- else
- 0
- end
- end
-end
-module Puppet::Lastcheck::Reports::Nagios
- def deliver_report_to_nagios(failing_hosts)
- unless failing_hosts.empty?
- puts "PUPPETLAST CRITICAL: #{failing_hosts.size} outdated hosts: #{failing_hosts.keys.join(',')}"
- 2
- else
- puts "PUPPETLAST OK: No outdated hosts"
- 0
- end
- end
-end
-#
-# = Synopsis
-#
-# Verifiying your puppet runs. Check different places to verify
-# whether your clients actually still runs successfully.
-# Also checks for left overs of legacy hosts.
+#!/bin/bash
#
-# = Usage
-#
-# puppet lastcheck [-h|--help]
-class Puppet::Application::Lastcheck < Puppet::Application
-
- should_parse_config
- run_mode :master
-
- include Puppet::Lastcheck::Tests
- add_test :no_facts
- add_test :expired_facts, :ignore_by_default => true
- add_test :timed_out_facts
- add_test :storedconfigs
-
- include Puppet::Lastcheck::Reports
- add_report :console, :priority => 50
- add_report :nagios
-
- option("--timeout TIMEOUT") do |v|
- @timeout = v.to_i
- end
-
- option("--ignore-hosts HOSTS") do |v|
- @ignore_hosts = v.split(',')
- end
-
- def main
-
- Puppet::Lastcheck::Tests.tests.keys.each do |test|
- self.send("analyze_#{test}") unless self.send("ignore_#{test}")
- end
- exitcode = 0
- ordered_reports.each do |report|
- if self.send("report_to_#{report}")
- tmpexitcode = self.send("deliver_report_to_#{report}",@failing_hosts)
- exitcode = tmpexitcode unless exitcode > 0
- end
- end
- exit(exitcode)
- end
-
- def setup
- exit(Puppet.settings.print_configs ? 0 : 1) if Puppet.settings.print_configs?
-
- #Puppet::Util::Log.newdestination :console
- Puppet::Node::Facts.terminus_class = :yaml
-
- Puppet::Lastcheck::Tests.tests.keys.each do |test|
- self.send("ignore_#{test}=", Puppet::Lastcheck::Tests.tests[test][:ignore_by_default]||false) unless self.send("ignore_#{test}")
- self.send("setup_#{test}") if self.respond_to?("setup_#{test}") and !self.send("ignore_#{test}")
- end
- report = nil
- report_activated = false
- ordered_reports.each do |report|
- report_activated ||= self.send("report_to_#{report}")
- end
- self.report_to_console = true unless report_activated
-
- @ignore_hosts = [] unless @ignore_hosts
- @failing_hosts = {}
- unless @timeout
- @timeout = Puppet[:runinterval]
- end
- end
-
- private
-
- def add_failed_host(hostname,reason)
- @failing_hosts[hostname] = { :reason => reason } unless (@failing_hosts[hostname] || @ignore_hosts.include?(hostname))
- end
-
- def pretty_puts(str,length)
- sprintf("%0-#{length}s",str)
- end
-end
-
-Puppet::Application.find('lastcheck').new.run
+# Nagios checking script that whines if a node hasn't checked in with the
+# master for a day or more and sets a critical status if the node hasn't
+# checked in for a week or longer. You can of course tweak those thresholds
+# if you want.
+
+# Spot of configuration. Basically just specify where the yaml files live.
+YAMLPATH=/var/lib/puppet/yaml/node
+STATUS_OK=0
+STATUS_WARNING=1
+STATUS_CRITICAL=2
+STATUS_UNKNOWN=3
+INTERVAL_WARNING=$((60 * 60 * 2))
+INTERVAL_CRITICAL=$((60 * 60 * 24))
+PARAMS="-la"
+
+# A space separated list of hostnames to ignore. These might for instance be
+# laptops that just don't get used every day and thus don't sync.
+IGNORE_HOSTS=""
+
+# Override settings from a config file if one exists.
+if [ -f /etc/default/check_puppetmaster ]; then
+ . /etc/default/check_puppetmaster
+fi
+
+# Early exit if no read access to the yaml files.
+if [ ! -r ${YAMLPATH} ]; then
+ echo "UNKNOWN: Cannot access ${YAMLPATH}"
+ exit ${STATUS_UNKNOWN}
+fi
+
+# Bunch of internal vars used for status info output.
+status="OK"
+ret=${STATUS_OK}
+i_count=0
+o_count=0
+w_count=0
+w_string=""
+e_count=0
+e_string=""
+
+# Current time.
+NOW=$(date +"%s")
+
+# The meat.
+
+# Get all hostnames associated with active certificates, and check the time
+# each of these last checked in with the server. Do this by converting the
+# yaml file expiration datestamp to epoch format and subtracting it from now.
+for node in $(/usr/sbin/puppetca ${PARAMS} | awk '/^\+/ {print $2}' | tr -d '"'); do
+
+ EXPIRATION=$(grep expiration ${YAMLPATH}/$node.yaml | awk '{printf("%s %s", $2, $3);}')
+ typeset -i CHECKIN=$(date +"%s" -d "${EXPIRATION}")
+ DIFFERENCE=$((${NOW} - ${CHECKIN}))
+
+ # Count hosts and generate some output strings based on the status.
+ if [ ${DIFFERENCE} -lt ${INTERVAL_WARNING} ]; then
+ o_count=$((${o_count} + 1));
+ else
+ # If there is an issue, first check if we can ignore this host.
+ if [ -n "${IGNORE_HOSTS}" ]; then
+ if [[ ${IGNORE_HOSTS} =~ ${node} ]]; then
+ i_count=$((${i_count} + 1))
+ continue
+ fi
+ fi
+ if [ ${DIFFERENCE} -gt ${INTERVAL_CRITICAL} ]; then
+ e_count=$((${e_count} + 1))
+ e_string="${e_string} ${node}"
+ else
+ w_count=$((${w_count} + 1))
+ w_string="${w_string} ${node}"
+ fi
+ fi
+done
+
+# Generate a status string for user display.
+if [ -n "${e_string}" ]; then
+ s_string="${s_string} ${e_count} critical (${e_string## });"
+fi
+if [ -n "${w_string}" ]; then
+ s_string="${s_string} ${w_count} warning (${w_string## });"
+fi
+if [ ${i_count} -gt 0 ]; then
+ s_string="${s_string} ${i_count} ignored;"
+fi
+s_string="${s_string} ${o_count} ok."
+
+# Create a return value and status string.
+if [ ${e_count} -gt 0 ]; then
+ status="CRITICAL"
+ ret=${STATUS_CRITICAL}
+elif [ ${w_count} -gt 0 ]; then
+ status="WARNING"
+ ret=${STATUS_WARNING}
+fi
+
+# Output the status and inform the user about which hosts are lagging.
+echo -n "${status}:${s_string}"
+exit $ret
diff --git a/manifests/cron/freebsd.pp b/manifests/cron/freebsd.pp
new file mode 100644
index 0000000..5ff3419
--- /dev/null
+++ b/manifests/cron/freebsd.pp
@@ -0,0 +1,23 @@
+class puppet::cron::freebsd inherits puppet::freebsd {
+
+ include puppet::cron::base
+ if $puppet_http_compression { $puppet_http_compression_str = '--http_compression' }
+
+ if !$puppet_crontime {
+ $puppet_crontime_interval_minute = fqdn_rand(29)
+ $puppet_crontime_interval_minute2 = inline_template('<%= 30+puppet_crontime_interval_minute.to_i %>')
+ $puppet_crontime = "${puppet_crontime_interval_minute},${puppet_crontime_interval_minute2} * * * *"
+ }
+
+ #TODO ensure that the service is disabled in /etc/rc.conf[.local]
+
+ cron { 'puppetd_run':
+ command => "/usr/local/bin/puppet agent --onetime --no-daemonize --config=${puppet::puppet_config} --color false $puppet_http_compression_str | grep -E '(^err:|^alert:|^emerg:|^crit:)'",
+ user => 'root',
+ minute => split(regsubst($puppet_crontime,'^([\d,\-,*,/,\,]+) ([\d,\-,*,/,\,]+) ([\d,\-,*,/,\,]+) ([\d,\-,*,/,\,]+) ([\d,\-,*,/,\,]+)$','\1'),','),
+ hour => split(regsubst($puppet_crontime,'^([\d,\-,*,/,\,]+) ([\d,\-,*,/,\,]+) ([\d,\-,*,/,\,]+) ([\d,\-,*,/,\,]+) ([\d,\-,*,/,\,]+)$','\2'),','),
+ weekday => split(regsubst($puppet_crontime,'^([\d,\-,*,/,\,]+) ([\d,\-,*,/,\,]+) ([\d,\-,*,/,\,]+) ([\d,\-,*,/,\,]+) ([\d,\-,*,/,\,]+)$','\3'),','),
+ month => split(regsubst($puppet_crontime,'^([\d,\-,*,/,\,]+) ([\d,\-,*,/,\,]+) ([\d,\-,*,/,\,]+) ([\d,\-,*,/,\,]+) ([\d,\-,*,/,\,]+)$','\4'),','),
+ monthday => split(regsubst($puppet_crontime,'^([\d,\-,*,/,\,]+) ([\d,\-,*,/,\,]+) ([\d,\-,*,/,\,]+) ([\d,\-,*,/,\,]+) ([\d,\-,*,/,\,]+)$','\5'),',')
+ }
+}
diff --git a/manifests/freebsd.pp b/manifests/freebsd.pp
new file mode 100644
index 0000000..cdce989
--- /dev/null
+++ b/manifests/freebsd.pp
@@ -0,0 +1,27 @@
+class puppet::freebsd inherits puppet::base {
+
+ case $puppet_ensure_version {
+ '': { $puppet_ensure_version = 'installed' }
+ 'removed','absent','installed', 'present': {} # those values are OK
+ default: { fail('Package providers for FreeBSD cannot ensure that a specific version is installed.') }
+ }
+ case $facter_ensure_version {
+ '': { $facter_ensure_version = 'installed' }
+ 'removed','absent','installed', 'present': {} # those values are OK
+ default: { fail('Package providers for FreeBSD cannot ensure that a specific version is installed.') }
+ }
+
+ package { 'puppet':
+ ensure => $puppet_ensure_version,
+ }
+
+ package { 'facter':
+ ensure => $facter_ensure_version,
+ }
+
+ Service['puppet'] {
+ path => '/usr/local/etc/rc.d',
+ require => Package[puppet],
+ }
+
+}