Added keepalived and common
This commit is contained in:
commit
11e1b4f2db
22
deployment/puppet/common/README
Normal file
22
deployment/puppet/common/README
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
|
||||||
|
The common module installs various functions that are required by other
|
||||||
|
modules. This module should be installed before any of the other module.
|
||||||
|
|
||||||
|
To use this module, follow these directions:
|
||||||
|
|
||||||
|
1. Your modules directory will need all the files included in this
|
||||||
|
repository placed under a directory called "common"
|
||||||
|
|
||||||
|
2. Add the following line to manifests/site.pp:
|
||||||
|
|
||||||
|
import "modules.pp"
|
||||||
|
|
||||||
|
3. Add the following line to manifests/modules.pp:
|
||||||
|
|
||||||
|
import "common"
|
||||||
|
|
||||||
|
|
||||||
|
Author:: David Schmitt (mailto:david@dasz.at)
|
||||||
|
Copyright:: Copyright (c) 2007-2009 dasz.at OG
|
||||||
|
License:: 3-clause BSD
|
||||||
|
|
0
deployment/puppet/common/files/empty/.ignore
Normal file
0
deployment/puppet/common/files/empty/.ignore
Normal file
1
deployment/puppet/common/files/modules/README
Normal file
1
deployment/puppet/common/files/modules/README
Normal file
@ -0,0 +1 @@
|
|||||||
|
this directory contains various data collected for system wide configurations
|
@ -0,0 +1,22 @@
|
|||||||
|
# This function has two modes of operation:
|
||||||
|
#
|
||||||
|
# basename(string) : string
|
||||||
|
#
|
||||||
|
# Returns the last component of the filename given as argument, which must be
|
||||||
|
# formed using forward slashes ("/") regardless of the separator used on the
|
||||||
|
# local file system.
|
||||||
|
#
|
||||||
|
# basename(string[]) : string[]
|
||||||
|
#
|
||||||
|
# Returns an array of strings with the basename of each item from the argument.
|
||||||
|
#
|
||||||
|
module Puppet::Parser::Functions
|
||||||
|
newfunction(:basename, :type => :rvalue) do |args|
|
||||||
|
if args[0].is_a?(Array)
|
||||||
|
args.collect do |a| File.basename(a) end
|
||||||
|
else
|
||||||
|
File.basename(args[0])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -0,0 +1,17 @@
|
|||||||
|
# concat.rb
|
||||||
|
|
||||||
|
# concatenate the contents of arrays
|
||||||
|
# Use it like this:
|
||||||
|
# $base_metrics = ['a', 'b']
|
||||||
|
# $extended_metrics = ['c']
|
||||||
|
# $metrics = concat($base_metrics, $extended_metrics)
|
||||||
|
module Puppet::Parser::Functions
|
||||||
|
newfunction(:concat, :type => :rvalue) do |args|
|
||||||
|
result = []
|
||||||
|
args.each do |arg|
|
||||||
|
result = result.concat(arg)
|
||||||
|
end
|
||||||
|
result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -0,0 +1,22 @@
|
|||||||
|
# This function has two modes of operation:
|
||||||
|
#
|
||||||
|
# dirname(string) : string
|
||||||
|
#
|
||||||
|
# Returns all components of the filename given as argument except the last
|
||||||
|
# one. The filename must be formed using forward slashes (``/..) regardless of
|
||||||
|
# the separator used on the local file system.
|
||||||
|
#
|
||||||
|
# dirname(string[]) : string[]
|
||||||
|
#
|
||||||
|
# Returns an array of strings with the basename of each item from the argument.
|
||||||
|
#
|
||||||
|
module Puppet::Parser::Functions
|
||||||
|
newfunction(:dirname, :type => :rvalue) do |args|
|
||||||
|
if args[0].is_a?(Array)
|
||||||
|
args.collect do |a| File.dirname(a) end
|
||||||
|
else
|
||||||
|
File.dirname(args[0])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -0,0 +1,183 @@
|
|||||||
|
# Puppet External Data Sources
|
||||||
|
#
|
||||||
|
# This is a parser function to read data from external files, this version
|
||||||
|
# uses CSV files but the concept can easily be adjust for databases, yaml
|
||||||
|
# or any other queryable data source.
|
||||||
|
#
|
||||||
|
# The object of this is to make it obvious when it's being used, rather than
|
||||||
|
# magically loading data in when an module is loaded I prefer to look at the code
|
||||||
|
# and see statements like:
|
||||||
|
#
|
||||||
|
# $snmp_contact = extlookup("snmp_contact")
|
||||||
|
#
|
||||||
|
# The above snippet will load the snmp_contact value from CSV files, this in its
|
||||||
|
# own is useful but a common construct in puppet manifests is something like this:
|
||||||
|
#
|
||||||
|
# case $domain {
|
||||||
|
# "myclient.com": { $snmp_contact = "John Doe <john@myclient.com>" }
|
||||||
|
# default: { $snmp_contact = "My Support <support@my.com>" }
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# Over time there will be a lot of this kind of thing spread all over your manifests
|
||||||
|
# and adding an additional client involves grepping through manifests to find all the
|
||||||
|
# places where you have constructs like this.
|
||||||
|
#
|
||||||
|
# This is a data problem and shouldn't be handled in code, a using this function you
|
||||||
|
# can do just that.
|
||||||
|
#
|
||||||
|
# First you configure it in site.pp:
|
||||||
|
# $extlookup_datadir = "/etc/puppet/manifests/extdata"
|
||||||
|
# $extlookup_precedence = ["%{fqdn}", "domain_%{domain}", "common"]
|
||||||
|
#
|
||||||
|
# The array tells the code how to resolve values, first it will try to find it in
|
||||||
|
# web1.myclient.com.csv then in domain_myclient.com.csv and finally in common.csv
|
||||||
|
#
|
||||||
|
# Now create the following data files in /etc/puppet/manifests/extdata
|
||||||
|
#
|
||||||
|
# domain_myclient.com.csv:
|
||||||
|
# snmp_contact,John Doe <john@myclient.com>
|
||||||
|
# root_contact,support@%{domain}
|
||||||
|
# client_trusted_ips,192.168.1.130,192.168.10.0/24
|
||||||
|
#
|
||||||
|
# common.csv:
|
||||||
|
# snmp_contact,My Support <support@my.com>
|
||||||
|
# root_contact,support@my.com
|
||||||
|
#
|
||||||
|
# Now you can replace the case statement with the simple single line to achieve
|
||||||
|
# the exact same outcome:
|
||||||
|
#
|
||||||
|
# $snmp_contact = extlookup("snmp_contact")
|
||||||
|
#
|
||||||
|
# The obove code shows some other features, you can use any fact or variable that
|
||||||
|
# is in scope by simply using %{varname} in your data files, you can return arrays
|
||||||
|
# by just having multiple values in the csv after the initial variable name.
|
||||||
|
#
|
||||||
|
# In the event that a variable is nowhere to be found a critical error will be raised
|
||||||
|
# that will prevent your manifest from compiling, this is to avoid accidentally putting
|
||||||
|
# in empty values etc. You can however specify a default value:
|
||||||
|
#
|
||||||
|
# $ntp_servers = extlookup("ntp_servers", "1.${country}.pool.ntp.org")
|
||||||
|
#
|
||||||
|
# In this case it will default to "1.${country}.pool.ntp.org" if nothing is defined in
|
||||||
|
# any data file.
|
||||||
|
#
|
||||||
|
# You can also specify an additional data file to search first before any others at use
|
||||||
|
# time, for example:
|
||||||
|
#
|
||||||
|
# $version = extlookup("rsyslog_version", "present", "packages")
|
||||||
|
#
|
||||||
|
# package{"rsyslog": ensure => $version }
|
||||||
|
#
|
||||||
|
# This will look for a version configured in packages.csv and then in the rest as configured
|
||||||
|
# by $extlookup_precedence if it's not found anywhere it will default to "present", this kind
|
||||||
|
# of use case makes puppet a lot nicer for managing large amounts of packages since you do not
|
||||||
|
# need to edit a load of manifests to do simple things like adjust a desired version number.
|
||||||
|
#
|
||||||
|
# For more information on installing and writing your own custom functions see:
|
||||||
|
# http://reductivelabs.com/trac/puppet/wiki/WritingYourOwnFunctions
|
||||||
|
#
|
||||||
|
# For further help contact Volcane on #puppet
|
||||||
|
require 'csv'
|
||||||
|
|
||||||
|
module Puppet::Parser::Functions
|
||||||
|
newfunction(:extlookup, :type => :rvalue) do |args|
|
||||||
|
key = args[0]
|
||||||
|
default = "_ExtUNSET_"
|
||||||
|
datafile = "_ExtUNSET_"
|
||||||
|
|
||||||
|
default = args[1] if args[1]
|
||||||
|
datafile = args[2] if args[2]
|
||||||
|
|
||||||
|
extlookup_datadir = lookupvar('extlookup_datadir')
|
||||||
|
extlookup_precedence = Array.new
|
||||||
|
|
||||||
|
# precedence values can have variables embedded in them
|
||||||
|
# in the form %{fqdn}, you could for example do
|
||||||
|
#
|
||||||
|
# $extlookup_precedence = ["hosts/%{fqdn}", "common"]
|
||||||
|
#
|
||||||
|
# this will result in /path/to/extdata/hosts/your.box.com.csv
|
||||||
|
# being searched.
|
||||||
|
#
|
||||||
|
# we parse the precedence here because the best place to specify
|
||||||
|
# it would be in site.pp but site.pp is only evaluated at startup
|
||||||
|
# so $fqdn etc would have no meaning there, this way it gets evaluated
|
||||||
|
# each run and has access to the right variables for that run
|
||||||
|
lookupvar('extlookup_precedence').each do |prec|
|
||||||
|
while prec =~ /%\{(.+?)\}/
|
||||||
|
prec.gsub!(/%\{#{$1}\}/, lookupvar($1))
|
||||||
|
end
|
||||||
|
|
||||||
|
extlookup_precedence << prec
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
datafiles = Array.new
|
||||||
|
|
||||||
|
# if we got a custom data file, put it first in the array of search files
|
||||||
|
if datafile != ""
|
||||||
|
if File.exists?(extlookup_datadir + "/#{datafile}.csv")
|
||||||
|
datafiles << extlookup_datadir + "/#{datafile}.csv"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
extlookup_precedence.each do |d|
|
||||||
|
datafiles << extlookup_datadir + "/#{d}.csv"
|
||||||
|
end
|
||||||
|
|
||||||
|
desired = "_ExtUNSET_"
|
||||||
|
|
||||||
|
datafiles.each do |file|
|
||||||
|
parser.watch_file(file) if File.exists?(file)
|
||||||
|
|
||||||
|
if desired == "_ExtUNSET_"
|
||||||
|
if File.exists?(file)
|
||||||
|
result = CSV.read(file).find_all do |r|
|
||||||
|
r[0] == key
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# return just the single result if theres just one,
|
||||||
|
# else take all the fields in the csv and build an array
|
||||||
|
if result.length > 0
|
||||||
|
if result[0].length == 2
|
||||||
|
val = result[0][1].to_s
|
||||||
|
|
||||||
|
# parse %{}'s in the CSV into local variables using lookupvar()
|
||||||
|
while val =~ /%\{(.+?)\}/
|
||||||
|
val.gsub!(/%\{#{$1}\}/, lookupvar($1))
|
||||||
|
end
|
||||||
|
|
||||||
|
desired = val
|
||||||
|
elsif result[0].length > 1
|
||||||
|
length = result[0].length
|
||||||
|
cells = result[0][1,length]
|
||||||
|
|
||||||
|
# Individual cells in a CSV result are a weird data type and throws
|
||||||
|
# puppets yaml parsing, so just map it all to plain old strings
|
||||||
|
desired = cells.map do |c|
|
||||||
|
# parse %{}'s in the CSV into local variables using lookupvar()
|
||||||
|
while c =~ /%\{(.+?)\}/
|
||||||
|
c.gsub!(/%\{#{$1}\}/, lookupvar($1))
|
||||||
|
end
|
||||||
|
|
||||||
|
c.to_s
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# don't accidently return nil's and such rather throw a parse error
|
||||||
|
if desired == "_ExtUNSET_" && default == "_ExtUNSET_"
|
||||||
|
raise Puppet::ParseError, "No match found for '#{key}' in any data file during extlookup()"
|
||||||
|
else
|
||||||
|
desired = default if desired == "_ExtUNSET_"
|
||||||
|
end
|
||||||
|
|
||||||
|
desired
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# vi:tabstop=4:expandtab:ai
|
21
deployment/puppet/common/lib/puppet/parser/functions/gsub.rb
Normal file
21
deployment/puppet/common/lib/puppet/parser/functions/gsub.rb
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#
|
||||||
|
# A thin wrapper around the ruby gsub function.
|
||||||
|
#
|
||||||
|
# gsub($string, $pattern, $replacement)
|
||||||
|
#
|
||||||
|
# will replace all occurrences of $pattern in $string with $replacement.
|
||||||
|
# $string can be either a single value or an array. In the latter case, each
|
||||||
|
# element of the array will be processed in turn.
|
||||||
|
#
|
||||||
|
module Puppet::Parser::Functions
|
||||||
|
newfunction(:gsub, :type => :rvalue) do |args|
|
||||||
|
if args[0].is_a?(Array)
|
||||||
|
args[0].collect do |val|
|
||||||
|
val.gsub(/#{args[1]}/, args[2])
|
||||||
|
end
|
||||||
|
else
|
||||||
|
args[0].gsub(/#{args[1]}/, args[2])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -0,0 +1,19 @@
|
|||||||
|
# Prefixes arguments 2..n with first argument.
|
||||||
|
#
|
||||||
|
# prefix_with(string prefix, string[] arguments) : string[]
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
#
|
||||||
|
# prefix_with("php-", [ "blah", "foo" ])
|
||||||
|
#
|
||||||
|
# will result in this array:
|
||||||
|
#
|
||||||
|
# [ "php-blah", "php-foo" ]
|
||||||
|
#
|
||||||
|
module Puppet::Parser::Functions
|
||||||
|
newfunction(:prefix_with, :type => :rvalue) do |args|
|
||||||
|
prefix = args.shift
|
||||||
|
args.collect {|v| "%s%s" % [prefix, v] }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -0,0 +1,7 @@
|
|||||||
|
# apply ruby regexp escaping to a string
|
||||||
|
module Puppet::Parser::Functions
|
||||||
|
newfunction(:re_escape, :type => :rvalue) do |args|
|
||||||
|
Regexp.escape(args[0])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -0,0 +1,23 @@
|
|||||||
|
# This function has two modes of operation:
|
||||||
|
#
|
||||||
|
# split($string, $delimiter) : $string
|
||||||
|
#
|
||||||
|
# Split the first argument on every $delimiter. $delimiter is interpreted as
|
||||||
|
# Ruby regular expression.
|
||||||
|
#
|
||||||
|
# split($string[], $delimiter) : $string[][]
|
||||||
|
#
|
||||||
|
# Returns an array of split results with the result of applying split to each
|
||||||
|
# item from the first argument.
|
||||||
|
#
|
||||||
|
# For long-term portability it is recommended to refrain from using Ruby's
|
||||||
|
# extended RE features.
|
||||||
|
module Puppet::Parser::Functions
|
||||||
|
newfunction(:split, :type => :rvalue) do |args|
|
||||||
|
if args[0].is_a?(Array)
|
||||||
|
args.collect do |a| a.split(/#{args[1]}/) end
|
||||||
|
else
|
||||||
|
args[0].split(/#{args[1]}/)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
49
deployment/puppet/common/manifests/classes/lsb_release.pp
Normal file
49
deployment/puppet/common/manifests/classes/lsb_release.pp
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
# common/manifests/classes/lsb_release.pp -- request the installation of
|
||||||
|
# lsb_release to get to lsbdistcodename, which is used throughout the manifests
|
||||||
|
#
|
||||||
|
# Copyright (C) 2007 David Schmitt <david@schmitt.edv-bus.at>
|
||||||
|
# See LICENSE for the full license granted to you.
|
||||||
|
|
||||||
|
# Changelog:
|
||||||
|
# 2007-08-26: micah <micah@riseup.net> reported, that lsb_release can report
|
||||||
|
# nonsensical values for lsbdistcodename; assert_lsbdistcodename now
|
||||||
|
# recognises "n/a" and acts accordingly
|
||||||
|
|
||||||
|
# This lightweight class only asserts that $lsbdistcodename is set.
|
||||||
|
# If the assertion fails, an error is printed on the server
|
||||||
|
#
|
||||||
|
# To fail individual resources on a missing lsbdistcodename, require
|
||||||
|
# Exec[assert_lsbdistcodename] on the specific resource
|
||||||
|
#
|
||||||
|
# This is just one example of how you could avoid evaluation of parts of the
|
||||||
|
# manifest, before a bootstrapping class has enabled all the necessary goodies.
|
||||||
|
class assert_lsbdistcodename {
|
||||||
|
|
||||||
|
case $lsbdistcodename {
|
||||||
|
'': {
|
||||||
|
err("Please install lsb_release or set facter_lsbdistcodename in the environment of $fqdn")
|
||||||
|
exec { "false # assert_lsbdistcodename": alias => assert_lsbdistcodename, loglevel => err }
|
||||||
|
}
|
||||||
|
'n/a': {
|
||||||
|
case $operatingsystem {
|
||||||
|
"Debian": {
|
||||||
|
err("lsb_release was unable to report your distcodename; This seems to indicate a broken apt/sources.list on $fqdn")
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
err("lsb_release was unable to report your distcodename; please set facter_lsbdistcodename in the environment of $fqdn")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exec { "false # assert_lsbdistcodename": alias => assert_lsbdistcodename, loglevel => err }
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
exec { "true # assert_lsbdistcodename": alias => assert_lsbdistcodename, loglevel => debug }
|
||||||
|
exec { "true # require_lsbdistcodename": alias => require_lsbdistcodename, loglevel => debug }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
# To fail the complete compilation on a missing $lsbdistcodename, include this class
|
||||||
|
class require_lsbdistcodename inherits assert_lsbdistcodename {
|
||||||
|
exec { "false # require_lsbdistcodename": require => Exec[require_lsbdistcodename], loglevel => err }
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
#
|
||||||
|
# This define is only for "CFEngine compatability". It is only a light
|
||||||
|
# wrapper around the "line" define, which is equally dangerous, but at
|
||||||
|
# least named according to a proper resource model.
|
||||||
|
#
|
||||||
|
define append_if_no_such_line($file, $line) {
|
||||||
|
line {
|
||||||
|
$name:
|
||||||
|
ensure => present,
|
||||||
|
file => $file,
|
||||||
|
line => $line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
117
deployment/puppet/common/manifests/defines/concatenated_file.pp
Normal file
117
deployment/puppet/common/manifests/defines/concatenated_file.pp
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
# common/manifests/defines/concatenated_file.pp -- create a file from snippets
|
||||||
|
# stored in a directory
|
||||||
|
#
|
||||||
|
# Copyright (C) 2007 David Schmitt <david@schmitt.edv-bus.at>
|
||||||
|
# See LICENSE for the full license granted to you.
|
||||||
|
|
||||||
|
module_dir { "common/cf": }
|
||||||
|
|
||||||
|
# TODO:
|
||||||
|
# * create the directory in _part too
|
||||||
|
|
||||||
|
# This resource collects file snippets from a directory ($dir) and concatenates
|
||||||
|
# them in lexical order of their names into a new file ($name). This can be
|
||||||
|
# used to collect information from disparate sources, when the target file
|
||||||
|
# format doesn't allow includes.
|
||||||
|
#
|
||||||
|
# concatenated_file_part can be used to easily configure content for this.
|
||||||
|
#
|
||||||
|
# If no $dir is specified, the target name with '.d' appended will be used.
|
||||||
|
#
|
||||||
|
# The $dir is purged by puppet and will only contain explicitely configured
|
||||||
|
# files. This can be overridden by defining the directory before the
|
||||||
|
# concatenated_file.
|
||||||
|
#
|
||||||
|
# Depend on File[$name] to change if and only if its contents change. Notify
|
||||||
|
# Exec["concat_${name}"] if you want to force an update.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# concatenated_file { "/etc/some.conf":
|
||||||
|
# dir => "/etc/some.conf.d",
|
||||||
|
# }
|
||||||
|
define concatenated_file (
|
||||||
|
# where the snippets are located
|
||||||
|
$dir = '',
|
||||||
|
# a file with content to prepend
|
||||||
|
$header = '',
|
||||||
|
# a file with content to append
|
||||||
|
$footer = '',
|
||||||
|
# default permissions for the target file
|
||||||
|
$mode = 0644, $owner = root, $group = 0
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
$dir_real = $dir ? { '' => "${name}.d", default => $dir }
|
||||||
|
|
||||||
|
$tmp_file_name = regsubst($dir_real, '/', '_', 'G')
|
||||||
|
$tmp_file = "${module_dir_path}/${tmp_file_name}"
|
||||||
|
|
||||||
|
if defined(File[$dir_real]) {
|
||||||
|
debug("${dir_real} already defined")
|
||||||
|
} else {
|
||||||
|
file {
|
||||||
|
$dir_real:
|
||||||
|
source => "puppet:///modules/common/empty",
|
||||||
|
checksum => mtime,
|
||||||
|
ignore => '.ignore',
|
||||||
|
recurse => true, purge => true, force => true,
|
||||||
|
mode => $mode, owner => $owner, group => $group,
|
||||||
|
notify => Exec["concat_${name}"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
file {
|
||||||
|
$tmp_file:
|
||||||
|
ensure => present, checksum => md5,
|
||||||
|
mode => $mode, owner => $owner, group => $group;
|
||||||
|
# decouple the actual file from the generation process by using a
|
||||||
|
# temporary file and puppet's source mechanism. This ensures that events
|
||||||
|
# for notify/subscribe will only be generated when there is an actual
|
||||||
|
# change.
|
||||||
|
$name:
|
||||||
|
ensure => present, checksum => md5,
|
||||||
|
source => $tmp_file,
|
||||||
|
mode => $mode, owner => $owner, group => $group,
|
||||||
|
require => File[$tmp_file];
|
||||||
|
}
|
||||||
|
|
||||||
|
# if there is a header or footer file, add it
|
||||||
|
$additional_cmd = $header ? {
|
||||||
|
'' => $footer ? {
|
||||||
|
'' => '',
|
||||||
|
default => "| cat - '${footer}' "
|
||||||
|
},
|
||||||
|
default => $footer ? {
|
||||||
|
'' => "| cat '${header}' - ",
|
||||||
|
default => "| cat '${header}' - '${footer}' "
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# use >| to force clobbering the target file
|
||||||
|
exec { "concat_${name}":
|
||||||
|
command => "/usr/bin/find ${dir_real} -maxdepth 1 -type f ! -name '*puppettmp' -print0 | sort -z | xargs -0 cat ${additional_cmd} >| ${tmp_file}",
|
||||||
|
subscribe => [ File[$dir_real] ],
|
||||||
|
before => File[$tmp_file],
|
||||||
|
alias => [ "concat_${dir_real}"],
|
||||||
|
loglevel => info
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Add a snippet called $name to the concatenated_file at $dir.
|
||||||
|
# The file can be referenced as File["cf_part_${name}"]
|
||||||
|
define concatenated_file_part (
|
||||||
|
$dir, $content = '', $ensure = present,
|
||||||
|
$mode = 0644, $owner = root, $group = 0
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
file { "${dir}/${name}":
|
||||||
|
ensure => $ensure, content => $content,
|
||||||
|
mode => $mode, owner => $owner, group => $group,
|
||||||
|
alias => "cf_part_${name}",
|
||||||
|
notify => Exec["concat_${dir}"],
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
60
deployment/puppet/common/manifests/defines/config_file.pp
Normal file
60
deployment/puppet/common/manifests/defines/config_file.pp
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
# common/manifests/defines/config_file.pp -- create a config file with default permissions
|
||||||
|
# Copyright (C) 2007 David Schmitt <david@schmitt.edv-bus.at>
|
||||||
|
# See LICENSE for the full license granted to you.
|
||||||
|
|
||||||
|
# A simple wrapper to give all configuration files common defaults.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# config_file { filename:
|
||||||
|
# content => "....\n",
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# Examples:
|
||||||
|
#
|
||||||
|
# To create the file /etc/vservers/${vs_name}/context with specific
|
||||||
|
# content:
|
||||||
|
#
|
||||||
|
# config_file {
|
||||||
|
# "/etc/vservers/${vs_name}/context":
|
||||||
|
# content => "${context}\n",
|
||||||
|
# notify => Exec["vs_restart_${vs_name}"],
|
||||||
|
# require => Exec["vs_create_${vs_name}"];
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# To create the file /etc/apache2/sites-available/munin-stats with the
|
||||||
|
# content pulled from a template:
|
||||||
|
#
|
||||||
|
# config_file {
|
||||||
|
# "/etc/apache2/sites-available/munin-stats":
|
||||||
|
# content => template("apache/munin-stats"),
|
||||||
|
# require => Package["apache2"],
|
||||||
|
# notify => Exec["reload-apache2"];
|
||||||
|
# }
|
||||||
|
define config_file (
|
||||||
|
$content = '',
|
||||||
|
$source = '',
|
||||||
|
$ensure = 'present')
|
||||||
|
{
|
||||||
|
file { $name:
|
||||||
|
ensure => $ensure,
|
||||||
|
# keep old versions on the server
|
||||||
|
backup => server,
|
||||||
|
# default permissions for config files
|
||||||
|
mode => 0644, owner => root, group => 0,
|
||||||
|
# really detect changes to this file
|
||||||
|
checksum => md5,
|
||||||
|
}
|
||||||
|
|
||||||
|
case $source {
|
||||||
|
'': { }
|
||||||
|
default: { File[$name] { source => $source } }
|
||||||
|
}
|
||||||
|
|
||||||
|
case $content {
|
||||||
|
'': { }
|
||||||
|
default: { File[$name] { content => $content } }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
57
deployment/puppet/common/manifests/defines/line.pp
Normal file
57
deployment/puppet/common/manifests/defines/line.pp
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
# common/manifests/defines/line.pp -- a trivial mechanism to ensure a line exists in a file
|
||||||
|
# Copyright (C) 2007 David Schmitt <david@schmitt.edv-bus.at>
|
||||||
|
# See LICENSE for the full license granted to you.
|
||||||
|
|
||||||
|
# Ensures that a specific line is present or absent in a file. This can
|
||||||
|
# be very brittle, since even small changes can throw this off.
|
||||||
|
#
|
||||||
|
# If the line is not present yet, it will be appended to the file.
|
||||||
|
#
|
||||||
|
# The name of the define is not used. Just keep it (globally) unique and
|
||||||
|
# descriptive.
|
||||||
|
#
|
||||||
|
# Use this only for very trivial stuff. Usually replacing the whole file
|
||||||
|
# is a more stable solution with less maintenance headaches afterwards.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# line {
|
||||||
|
# description:
|
||||||
|
# file => "filename",
|
||||||
|
# line => "content",
|
||||||
|
# ensure => {absent,*present*}
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
# The following ensures that the line "allow ^$munin_host$" exists in
|
||||||
|
# /etc/munin/munin-node.conf, and if there are any changes notify the
|
||||||
|
# service for a restart
|
||||||
|
#
|
||||||
|
# line {
|
||||||
|
# allow_munin_host:
|
||||||
|
# file => "/etc/munin/munin-node.conf",
|
||||||
|
# line => "allow ^$munin_host$",
|
||||||
|
# ensure => present,
|
||||||
|
# notify => Service[munin-node],
|
||||||
|
# require => Package[munin-node];
|
||||||
|
# }
|
||||||
|
define line(
|
||||||
|
$file,
|
||||||
|
$line,
|
||||||
|
$ensure = 'present'
|
||||||
|
) {
|
||||||
|
case $ensure {
|
||||||
|
default : { err ( "unknown ensure value '${ensure}'" ) }
|
||||||
|
present: {
|
||||||
|
exec { "echo '${line}' >> '${file}'":
|
||||||
|
unless => "grep -qFx '${line}' '${file}'"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
absent: {
|
||||||
|
exec { "perl -ni -e 'print if \$_ ne \"${line}\n\";' '${file}'":
|
||||||
|
onlyif => "grep -qFx '${line}' '${file}'"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
43
deployment/puppet/common/manifests/defines/module_dir.pp
Normal file
43
deployment/puppet/common/manifests/defines/module_dir.pp
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
# common/manifests/defines/module_dir.pp -- create a default directory
|
||||||
|
# for storing module specific information
|
||||||
|
#
|
||||||
|
# Copyright (C) 2007 David Schmitt <david@schmitt.edv-bus.at>
|
||||||
|
# See LICENSE for the full license granted to you.
|
||||||
|
|
||||||
|
# Use this variable to reference the base path. Thus you are safe from any
|
||||||
|
# changes.
|
||||||
|
$module_dir_path = '/var/lib/puppet/modules'
|
||||||
|
|
||||||
|
# A module_dir is a storage place for all the stuff a module might want to
|
||||||
|
# store. According to the FHS, this should go to /var/lib. Since this is a part
|
||||||
|
# of puppet, the full path is /var/lib/puppet/modules/${name}. Every module
|
||||||
|
# should # prefix its module_dirs with its name.
|
||||||
|
#
|
||||||
|
# By default, the module_dir is loaded from "puppet:///${name}/module_dir". If
|
||||||
|
# that doesn't exist an empty directory is taken as source. The directory is
|
||||||
|
# purged so that modules do not have to worry about removing cruft.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# module_dir { ["common", "common/dir1", "common/dir2" ]: }
|
||||||
|
define module_dir (
|
||||||
|
$mode = 0644,
|
||||||
|
$owner = root,
|
||||||
|
$group = 0
|
||||||
|
)
|
||||||
|
{
|
||||||
|
$dir = "${module_dir_path}/${name}"
|
||||||
|
if defined(File[$dir]) {
|
||||||
|
debug("${dir} already defined")
|
||||||
|
} else {
|
||||||
|
file {
|
||||||
|
$dir:
|
||||||
|
source => [ "puppet:///modules/${name}/module_dir", "puppet:///modules/common/empty"],
|
||||||
|
checksum => md5,
|
||||||
|
# ignore the placeholder
|
||||||
|
ignore => '\.ignore',
|
||||||
|
recurse => true, purge => true, force => true,
|
||||||
|
mode => $mode, owner => $owner, group => $group;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
24
deployment/puppet/common/manifests/defines/module_file.pp
Normal file
24
deployment/puppet/common/manifests/defines/module_file.pp
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# common/manifests/defines/module_file.pp -- use an already defined module_dir
|
||||||
|
# to store module specific files
|
||||||
|
#
|
||||||
|
# Copyright (C) 2007 David Schmitt <david@schmitt.edv-bus.at>
|
||||||
|
# See LICENSE for the full license granted to you.
|
||||||
|
|
||||||
|
# Put a file into module-local storage.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# module_file {
|
||||||
|
# "module/file":
|
||||||
|
# source => "puppet://..",
|
||||||
|
# }
|
||||||
|
define module_file (
|
||||||
|
$source,
|
||||||
|
$mode = 0644, $owner = root, $group = 0
|
||||||
|
)
|
||||||
|
{
|
||||||
|
file {
|
||||||
|
"${module_dir_path}/${name}":
|
||||||
|
source => $source,
|
||||||
|
mode => $mode, owner => $owner, group => $group;
|
||||||
|
}
|
||||||
|
}
|
41
deployment/puppet/common/manifests/defines/replace.pp
Normal file
41
deployment/puppet/common/manifests/defines/replace.pp
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
# common/manifests/defines/replace.pp -- replace a pattern in a file with a string
|
||||||
|
# Copyright (C) 2007 David Schmitt <david@schmitt.edv-bus.at>
|
||||||
|
# See LICENSE for the full license granted to you.
|
||||||
|
|
||||||
|
# A hack to replace all ocurrances of a regular expression in a file with a
|
||||||
|
# specified string. Sometimes it can be less effort to replace only a single
|
||||||
|
# value in a huge config file instead of creating a template out of it. Still,
|
||||||
|
# creating a template is often better than this hack.
|
||||||
|
#
|
||||||
|
# This define uses perl regular expressions.
|
||||||
|
#
|
||||||
|
# Use this only for very trivial stuff. Usually replacing the whole file is a
|
||||||
|
# more stable solution with less maintenance headaches afterwards.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
#
|
||||||
|
# replace { description:
|
||||||
|
# file => "filename",
|
||||||
|
# pattern => "regexp",
|
||||||
|
# replacement => "replacement"
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
# To replace the current port in /etc/munin/munin-node.conf
|
||||||
|
# with a new port, but only disturbing the file when needed:
|
||||||
|
#
|
||||||
|
# replace {
|
||||||
|
# set_munin_node_port:
|
||||||
|
# file => "/etc/munin/munin-node.conf",
|
||||||
|
# pattern => "^port (?!$port)[0-9]*",
|
||||||
|
# replacement => "port $port"
|
||||||
|
# }
|
||||||
|
define replace($file, $pattern, $replacement) {
|
||||||
|
$pattern_no_slashes = regsubst($pattern, '/', '\\/', 'G', 'U')
|
||||||
|
$replacement_no_slashes = regsubst($replacement, '/', '\\/', 'G', 'U')
|
||||||
|
|
||||||
|
exec { "replace_${pattern}_${file}":
|
||||||
|
command => "/usr/bin/perl -pi -e 's/${pattern_no_slashes}/${replacement_no_slashes}/' '${file}'",
|
||||||
|
onlyif => "/usr/bin/perl -ne 'BEGIN { \$ret = 1; } \$ret = 0 if /${pattern_no_slashes}/ && ! /\\Q${replacement_no_slashes}\\E/; END { exit \$ret; }' '${file}'",
|
||||||
|
alias => "exec_$name",
|
||||||
|
}
|
||||||
|
}
|
29
deployment/puppet/common/manifests/init.pp
Normal file
29
deployment/puppet/common/manifests/init.pp
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# common/manifests/init.pp - Define common infrastructure for modules
|
||||||
|
# Copyright (C) 2007 David Schmitt <david@schmitt.edv-bus.at>
|
||||||
|
# See LICENSE for the full license granted to you.
|
||||||
|
|
||||||
|
import "defines/*.pp"
|
||||||
|
import "classes/*.pp"
|
||||||
|
|
||||||
|
class common {
|
||||||
|
module_dir { [ 'common' ]: }
|
||||||
|
|
||||||
|
file {
|
||||||
|
# Module programmers can use /var/lib/puppet/modules/$modulename to save
|
||||||
|
# module-local data, e.g. for constructing config files. See module_dir
|
||||||
|
# for details
|
||||||
|
"/var/lib/puppet/modules":
|
||||||
|
ensure => directory,
|
||||||
|
source => "puppet:///modules/common/modules",
|
||||||
|
ignore => ".ignore",
|
||||||
|
recurse => true, purge => true, force => true,
|
||||||
|
mode => 0755, owner => root, group => 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
include common
|
||||||
|
|
||||||
|
# common packages
|
||||||
|
class pkg::openssl { package { openssl: ensure => installed } }
|
||||||
|
class pkg::rsync { package { rsync: ensure => installed } }
|
||||||
|
|
Loading…
Reference in New Issue
Block a user