diff options
author | Jerome Charaoui <jcharaoui@cmaisonneuve.qc.ca> | 2015-03-06 16:47:08 -0500 |
---|---|---|
committer | Jerome Charaoui <jcharaoui@cmaisonneuve.qc.ca> | 2015-03-06 16:47:08 -0500 |
commit | 1ef94f1f2e49e032c6c416830345fc3b4beacb01 (patch) | |
tree | 4c6bc037e48bcfc75412d86f638e2cdbc118d8c7 | |
parent | fa28702f46db802494872272ca50e0b1c37de09e (diff) | |
parent | bab96a631337b87dd6f168f663f5b24537f58a5c (diff) | |
download | puppet-backupninja-1ef94f1f2e49e032c6c416830345fc3b4beacb01.tar.gz puppet-backupninja-1ef94f1f2e49e032c6c416830345fc3b4beacb01.tar.bz2 |
Merge branch 'master' of https://git-nadir.immerda.ch/puppet-backupninja
Conflicts:
manifests/rdiff.pp
-rw-r--r-- | README | 33 | ||||
-rw-r--r-- | files/nagios_plugins/duplicity/README.md | 24 | ||||
-rw-r--r-- | files/nagios_plugins/duplicity/backupninja_duplicity_freshness.sh | 268 | ||||
-rw-r--r-- | files/nagios_plugins/duplicity/check_backupninja_duplicity.py | 123 | ||||
-rw-r--r-- | manifests/client.pp | 30 | ||||
-rw-r--r-- | manifests/dup.pp | 24 | ||||
-rw-r--r-- | manifests/generate_sshkey.pp | 33 | ||||
-rw-r--r-- | manifests/init.pp | 1 | ||||
-rw-r--r-- | manifests/nagios_plugin/duplicity.pp | 45 | ||||
-rw-r--r-- | manifests/pgsql.pp | 29 | ||||
-rw-r--r-- | manifests/rdiff.pp | 18 | ||||
-rw-r--r-- | templates/pgsql.conf.erb | 11 |
12 files changed, 610 insertions, 29 deletions
@@ -1,7 +1,7 @@ Backupninja Module ------------------- -This module helps you configure all of your backups with puppet, using +This module helps you configure all of your backups with puppet, using backupninja! ! Upgrade notice ! @@ -32,12 +32,12 @@ Configure your backup server Now you will need to configure a backup server by adding the following to your node definition for that server: - + include backupninja::server By configuring a backupninja::server, this module will automatically create sandboxed users on the server for each client for their -backups. +backups. You may also want to set some variables on your backup server, such as: @@ -130,6 +130,33 @@ backupninja::config { conf: } +Automatic creation of ssh-keys for duplicity +-------------------------------------------- + +backupninja::duplicity can be used to + +- create an ssh keypair for a client +- place the keypair on the puppetmaster in a given location +- place the keypair in /root/.ssh on the client + +i.e.: + + backupninja::duplicity { "duplicity_${::fqdn}": + sshoptions => "-oIdentityFile=/root/.ssh/backupninja_${::hostname}_id_rsa", + desthost => 'HOST', + destdir => "/var/backup/backupninja/${::fqdn}", + destuser => "backupninja_${::hostname}", + encryptkey => 'KEYID', + password => 'PW', + backupkeystore => 'puppet:///keys', + backupkeystorefspath => '/etc/puppet/modules/keys/files', + backupkeydestname => "backupninja_${::hostname}_id_rsa", + createkey => true, + installkey => true, + ... + } + + Nagios alerts about backup freshness ------------------------------------ diff --git a/files/nagios_plugins/duplicity/README.md b/files/nagios_plugins/duplicity/README.md new file mode 100644 index 0000000..1cd349a --- /dev/null +++ b/files/nagios_plugins/duplicity/README.md @@ -0,0 +1,24 @@ +duplicity-backup-status +======================= + +Backupninja generates duplicity configfiles, this nagios plugin can check their freshness. Currently only the config files generated by backupninja can be parsed and we depend on that. + +## Prerequisites + +Make sure you have python-argparse installed (yes an extra dependency, getopt doubles the amount of code, so I gave up on that). The Python script will look for the duplicity_freshness.sh shell script in /usr/local/lib/nagios/plugins/ or /usr/lib/nagios/plugins/ make sure you copy it there and make executable. + +## Getting started + +Run the python script from your nagios. Don't forget to specify some extras like when warnings or criticalities should be emerged. + +- -w WARNINC Number of hours allowed for incremential backup warning level default 28 +- -W WARNFULL Number of hours allowed for incremential backup critical level default 40 +- -c CRITINC Number of days allowed for full backup warning level default 52 +- -C CRITFULL Number of days allowed for full backup critical level default 60 + + +## TODO: + +- make it cuter, tidy up +- make it more robust +- support other config backends as backupninja - this can be done by writing more scripts like backupninja_duplicity_freshness.sh and parsing an extra parameter diff --git a/files/nagios_plugins/duplicity/backupninja_duplicity_freshness.sh b/files/nagios_plugins/duplicity/backupninja_duplicity_freshness.sh new file mode 100644 index 0000000..7af2bf7 --- /dev/null +++ b/files/nagios_plugins/duplicity/backupninja_duplicity_freshness.sh @@ -0,0 +1,268 @@ +#!/bin/bash +# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*- +# vim: set filetype=sh sw=3 sts=3 expandtab autoindent: + +# Load backupninja library/helpers, because why reinventing the wheel? [Because my wheels weren't round] +# some duplication is to be expected +# this is only supposed to work with duplicity + +## Functions +# simple lowercase function +function tolower() { + echo "$1" | tr '[:upper:]' '[:lower:]' +} + +# we grab the current time once, since processing +# all the configs might take more than an hour. +nowtime=`LC_ALL=C date +%H` +nowday=`LC_ALL=C date +%d` +nowdayofweek=`LC_ALL=C date +%A` +nowdayofweek=`tolower "$nowdayofweek"` + +conffile="/etc/backupninja.conf" + +# find $libdirectory +libdirectory=`grep '^libdirectory' $conffile | /usr/bin/awk '{print $3}'` +if [ -z "$libdirectory" ]; then + if [ -d "/usr/lib/backupninja" ]; then + libdirectory="/usr/lib/backupninja" + else + echo "Could not find entry 'libdirectory' in $conffile." + fatal "Could not find entry 'libdirectory' in $conffile." + fi +else + if [ ! -d "$libdirectory" ]; then + echo "Lib directory $libdirectory not found." + fatal "Lib directory $libdirectory not found." + fi +fi + +. $libdirectory/tools + +setfile $conffile + +# get global config options (second param is the default) +getconf configdirectory /etc/backup.d +getconf scriptdirectory /usr/share/backupninja +getconf reportdirectory +getconf reportemail +getconf reporthost +getconf reportspace +getconf reportsuccess yes +getconf reportinfo no +getconf reportuser +getconf reportwarning yes +getconf loglevel 3 +getconf when "Everyday at 01:00" +defaultwhen=$when +getconf logfile /var/log/backupninja.log +getconf usecolors "yes" +getconf SLAPCAT /usr/sbin/slapcat +getconf LDAPSEARCH /usr/bin/ldapsearch +getconf RDIFFBACKUP /usr/bin/rdiff-backup +getconf CSTREAM /usr/bin/cstream +getconf MYSQLADMIN /usr/bin/mysqladmin +getconf MYSQL /usr/bin/mysql +getconf MYSQLHOTCOPY /usr/bin/mysqlhotcopy +getconf MYSQLDUMP /usr/bin/mysqldump +getconf PGSQLDUMP /usr/bin/pg_dump +getconf PGSQLDUMPALL /usr/bin/pg_dumpall +getconf PGSQLUSER postgres +getconf GZIP /bin/gzip +getconf GZIP_OPTS --rsyncable +getconf RSYNC /usr/bin/rsync +getconf admingroup root + +if [ ! -d "$configdirectory" ]; then + echo "Configuration directory '$configdirectory' not found." + fatal "Configuration directory '$configdirectory' not found." +fi + +# get the duplicity configuration +function get_dupconf(){ + setfile $1 + getconf options + getconf testconnect yes + getconf nicelevel 0 + getconf tmpdir + + setsection gpg + getconf password + getconf sign no + getconf encryptkey + getconf signkey + + setsection source + getconf include + getconf vsnames all + getconf vsinclude + getconf exclude + + setsection dest + getconf incremental yes + getconf increments 30 + getconf keep 60 + getconf keepincroffulls all + getconf desturl + getconf awsaccesskeyid + getconf awssecretaccesskey + getconf cfusername + getconf cfapikey + getconf cfauthurl + getconf ftp_password + getconf sshoptions + getconf bandwidthlimit 0 + getconf desthost + getconf destdir + getconf destuser + destdir=${destdir%/} +} + +### some voodoo to mangle the correct commands + +function mangle_cli(){ + + execstr_options="$options " + execstr_source= + if [ -n "$desturl" ]; then + [ -z "$destuser" ] || warning 'the configured destuser is ignored since desturl is set' + [ -z "$desthost" ] || warning 'the configured desthost is ignored since desturl is set' + [ -z "$destdir" ] || warning 'the configured destdir is ignored since desturl is set' + execstr_serverpart="$desturl" + else + execstr_serverpart="scp://$destuser@$desthost/$destdir" + fi + + + ### Symmetric or asymmetric (public/private key pair) encryption + if [ -n "$encryptkey" ]; then + execstr_options="${execstr_options} --encrypt-key $encryptkey" + fi + + ### Data signing (or not) + if [ "$sign" == yes ]; then + # duplicity is not able to sign data when using symmetric encryption + [ -n "$encryptkey" ] || fatal "The encryptkey option must be set when signing." + # if needed, initialize signkey to a value that is not empty (checked above) + [ -n "$signkey" ] || signkey="$encryptkey" + execstr_options="${execstr_options} --sign-key $signkey" + fi + + ### Temporary directory + precmd= + if [ -n "$tmpdir" ]; then + if [ ! -d "$tmpdir" ]; then + #info "Temporary directory ($tmpdir) does not exist, creating it." + mkdir -p "$tmpdir" + [ $? -eq 0 ] || fatal "Could not create temporary directory ($tmpdir)." + chmod 0700 "$tmpdir" + fi + #info "Using $tmpdir as TMPDIR" + precmd="${precmd}TMPDIR=$tmpdir " + fi + + ### Source + + set -o noglob + + # excludes + SAVEIFS=$IFS + IFS=$(echo -en "\n\b") + for i in $exclude; do + str="${i//__star__/*}" + execstr_source="${execstr_source} --exclude '$str'" + done + IFS=$SAVEIFS + + # includes + SAVEIFS=$IFS + IFS=$(echo -en "\n\b") + for i in $include; do + [ "$i" != "/" ] || fatal "Sorry, you cannot use 'include = /'" + str="${i//__star__/*}" + execstr_source="${execstr_source} --include '$str'" + done + IFS=$SAVEIFS + + set +o noglob + + execstr_options="${execstr_options} --ssh-options '$sshoptions'" + if [ "$bandwidthlimit" != 0 ]; then + [ -z "$desturl" ] || warning 'The bandwidthlimit option is not used when desturl is set.' + execstr_precmd="trickle -s -d $bandwidthlimit -u $bandwidthlimit" + fi +} + +#function findlastdates(){ +# outputfile=$1 +# lastfull=0 +# lastinc=0 +# backuptime=0 +# +# while read line; do +# atime=0 +# arr=() +# sort='' +# test=$(echo $line|awk '{if (NF == 7); if ($1 == "Full" || $1 == "Incremental") {print $4, $3, $6, $5}}' ) +# +# if [ -n "$test" ]; then +# backuptime=$(date -u -d "$test" +%s) +# +# arr=($(echo $line|awk '{print $1, $2, $3, $4, $5, $6}')) +# if [ ${arr[0]} == "Incremental" ] && [ "$lastinc" -lt "$backuptime" ] ; then +# lastinc=$backuptime +# elif [ ${arr[0]} == "Full" ] && [ "$lastfull" -lt "$backuptime" ] ; then +# lastfull=$backuptime +# fi +# +# fi +# +# done < $outputfile +# # a full backup can be seen as incremental too +# lastinc=$(echo $lastinc | awk 'max=="" || $1 > max {max=$1} END{ print max}') +#} + +function check_status() { + grep -q 'No orphaned or incomplete backup sets found.' $1 + if [ $? -ne 0 ] ; then + exit 2 + fi +} + +## +## this function handles the freshness check of a backup action +## + +function process_action() { + local file="$1" + local suffix="$2" + setfile $file + get_dupconf $1 + mangle_cli + + outputfile=`maketemp backupout` + export PASSPHRASE=$password + export FTP_PASSWORD=$ftp_password + output=` su -c \ + "$execstr_precmd duplicity $execstr_options collection-status $execstr_serverpart >$outputfile 2>&1"` + exit_code=$? + echo -n $outputfile + + #check_status + #findlastdates +} + +files=`find $configdirectory -follow -mindepth 1 -maxdepth 1 -type f ! -name '.*.swp' | sort -n` + +for file in $files; do + [ -f "$file" ] || continue + suffix="${file##*.}" + base=`basename $file` + if [ "${base:0:1}" == "0" -o "$suffix" == "disabled" ]; then + continue + fi + if [ -e "$scriptdirectory/$suffix" -a "$suffix" == "dup" ]; then + process_action $file $suffix + fi +done + diff --git a/files/nagios_plugins/duplicity/check_backupninja_duplicity.py b/files/nagios_plugins/duplicity/check_backupninja_duplicity.py new file mode 100644 index 0000000..8ed9ce6 --- /dev/null +++ b/files/nagios_plugins/duplicity/check_backupninja_duplicity.py @@ -0,0 +1,123 @@ +#!/usr/bin/env python + +# Inspired by Arne Schwabe <arne-nagios@rfc2549.org> [with BSD license] +# Inspired by backupninja [that's gpl some version] +# minor changes by someon who doesn't understand all the license quirks + +from subprocess import Popen,PIPE +import sys +import time +import os +import argparse +import getopt + +def main(): + # getopt = much more writing + parser = argparse.ArgumentParser(description='Nagios Duplicity status checker') + + parser.add_argument("-w", dest="warninc", default=28, type=int, + help="Number of hours allowed for incremential backup warning level, default 28") + parser.add_argument("-W", dest="warnfull", default=31, type=int, + help="Number of days allowed for full backup warning level, default 31") + parser.add_argument("-c", dest="critinc", default=52, type=int, + help="Number of hours allowed for incremential backup critical level, default 52") + parser.add_argument("-C", dest="critfull", default=33, type=int, + help="Number of days allowed for full backup critical level, default 33") + args = parser.parse_args() + + okay = 0 + + # *sigh* check_output is from python 2.7 and onwards. Debian, upgrade yourself. + #output , err = check_output(['/root/freshness.sh']) + + if os.path.isfile("/usr/lib/nagios/plugins/backupninja_duplicity_freshness.sh") and os.access("/usr/lib/nagios/plugins/backupninja_duplicity_freshness.sh", os.X_OK): + checkstatus, err = Popen(['/bin/bash', '/usr/lib/nagios/plugins/backupninja_duplicity_freshness.sh'], stdout=PIPE, stderr=PIPE, env={'HOME': '/root', 'PATH': os.environ['PATH']}).communicate() + elif os.path.isfile("/usr/local/lib/nagios/plugins/backupninja_duplicity_freshness.sh") and os.access("/usr/local/lib/nagios/plugins/backupninja_duplicity_freshness.sh", os.X_OK): + checkstatus, err = Popen(['/bin/bash', '/usr/local/lib/nagios/plugins/backupninja_duplicity_freshness.sh'], stdout=PIPE, stderr=PIPE, env={'HOME': '/root', 'PATH': os.environ['PATH']}).communicate() + + # Don't use exec(), popen(), etc. to execute external commands without explicity using the full path of the external program. Hijacked search path could be problematic. + #checkstatus, err = Popen(['/bin/bash', './freshness.sh'], stdout=PIPE, stderr=PIPE, env={'HOME': '/root', 'PATH': os.environ['PATH']}).communicate() + + #another sigh: Debian testing, upgrade yourself, this is only needed because Debian testing uses duplicity 0.6.18-3 + # open file read/write + f = open (checkstatus,"r") + checklines = f.readlines() + f.close() + + # remove the line that says Import of duplicity.backends.giobackend Failed: No module named gio + f = open(checkstatus,"w") + for line in checklines: + if not 'Import of duplicity.backends.giobackend Failed: No module named gio' in line: + f.write(line) + f.close() + + output = open(checkstatus).read() + + lastfull, lastinc = findlastdates(output) + + sincelastfull = time.time() - lastfull + sincelastinc = time.time() - lastinc + + msg = "OK: " + + if sincelastfull > (args.warnfull * 24 * 3600) or sincelastinc > (args.warninc * 3600): + okay = 1 + msg = "WARNING: " + if sincelastfull > (args.critfull * 24 * 3600) or sincelastinc > (args.critinc * 3600): + okay = 2 + msg = "CRITICAL: " + if not checkoutput(output): + okay = max(okay,1) + msg = "WARNING: duplicity output: %s " % repr(output) + if err: + okay=2 + msg = "Unexpected output: %s, " % repr(err) + + print msg, "last full %s ago, last incremential %s ago|lastfull=%d, lastinc=%d" % ( formattime(sincelastfull), formattime(sincelastinc), sincelastfull, sincelastinc) + + #clean up cruft + os.remove(checkstatus) + sys.exit(okay) + +def checkoutput(output): + if not 'No orphaned or incomplete backup sets found.' in output: + return False + + return True + +def formattime(seconds): + days = seconds / (3600 * 24) + hours = seconds / 3600 % 24 + + if days: + return "%d days %d hours" % (days,hours) + else: + return "%d hours" % hours + + +def findlastdates(output): + lastfull = 0 + lastinc = 0 + + for line in output.split("\n"): + parts = line.split() + + # ['Incremental', 'Sun', 'Oct', '31', '03:00:04', '2010', '1'] + if len (parts) == 7 and parts[0] in ["Full","Incremental"]: + foo = time.strptime(" ".join(parts[1:6]),"%a %b %d %H:%M:%S %Y") + + backuptime = time.mktime(foo) + + if parts[0] == "Incremental" and lastinc < backuptime: + lastinc = backuptime + elif parts[0] == "Full" and lastfull < backuptime: + lastfull = backuptime + + + # Count a full backup as incremental backup + lastinc = max(lastfull,lastinc) + return (lastfull, lastinc) + + +if __name__=='__main__': + main() diff --git a/manifests/client.pp b/manifests/client.pp index 287b02f..7e689bf 100644 --- a/manifests/client.pp +++ b/manifests/client.pp @@ -46,8 +46,10 @@ class backupninja::client::defaults { class backupninja::client inherits backupninja::client::defaults { define key( - $user = false, $host = false, $installkey=false, $keyowner=false, - $keygroup=false, $keystore=false, $keytype=false) + $user = false, $host = false, $createkey=false, $installkey=false, + $keyowner=false, $keygroup=false, $keystore=false, $keystorefspath='', + $keytype=false, + $keydest=false, $keydestname=false ) { $real_user = $user ? { false => $name, @@ -78,9 +80,23 @@ class backupninja::client inherits backupninja::client::defaults { false => "${backupninja::client::defaults::real_keytype}", default => $keytype, } + $key_dest = $keydest ? { + false => "${backupninja::client::defaults::real_keydestination}", + default => $keydest, + } + $key_dest_name = $keydestname ? { + false => "id_$key_type", + default => $keydestname, + } + $key_dest_file = "${key_dest}/${key_dest_name}" - $key_dest = "${backupninja::client::defaults::real_keydestination}" - $key_dest_file = "$key_dest/id_$key_type" + if $createkey == true { + if $keystorefspath == false { + err("need to define a destination directory for sshkey creation!") + } + $ssh_keys = ssh_keygen("${keystorefspath}/${key_dest_name}") + } + case $install_key { true: { @@ -92,7 +108,7 @@ class backupninja::client inherits backupninja::client::defaults { } if !defined(File["$key_dest_file"]) { file { "$key_dest_file": - source => "${key_store}/${real_user}_id_${key_type}", + source => "${key_store}/${key_dest_name}", mode => 0400, owner => $key_owner, group => $key_group, require => File["$key_dest"], } @@ -109,7 +125,7 @@ class backupninja::client::maildir inherits backupninja::client::defaults { package { 'rsync': ensure => $rsync_ensure_version, } - } + } } class backupninja::client::rdiff_backup inherits backupninja::client::defaults { @@ -150,4 +166,4 @@ class backupninja::client::sys inherits backupninja::client::defaults { } default: {} } -} +} diff --git a/manifests/dup.pp b/manifests/dup.pp index 23da8cd..5ffce29 100644 --- a/manifests/dup.pp +++ b/manifests/dup.pp @@ -79,7 +79,10 @@ define backupninja::duplicity( $order = 90, $destuser = false, # configs to backupninja client $backupkeystore = false, + $backupkeystorefspath = '', $backupkeytype = "rsa", + $backupkeydest = false, + $backupkeydestname = false, # options to backupninja server sandbox $ssh_dir_manage = true, $ssh_dir = false, @@ -87,6 +90,7 @@ define backupninja::duplicity( $order = 90, $installuser = true, $backuptag = false, # key options + $createkey = false, $installkey = true ) { # the client with configs for this machine @@ -95,7 +99,7 @@ define backupninja::duplicity( $order = 90, case $desthost { false: { err("need to define a destination host for remote backups!") } } case $destdir { false: { err("need to define a destination directory for remote backups!") } } case $password { false: { err("a password is necessary either to unlock the GPG key, or for symmetric encryption!") } } - + # guarantees there's a configured backup space for this backup backupninja::server::sandbox { "${user}-${name}": user => $destuser, @@ -109,14 +113,18 @@ define backupninja::duplicity( $order = 90, backupkeys => $backupkeystore, keytype => $backupkeytype, } - + # the client's ssh key backupninja::client::key { "${destuser}-${name}": - user => $destuser, - host => $desthost, - installkey => $installkey, - keytype => $backupkeytype, - keystore => $backupkeystore, + user => $destuser, + host => $desthost, + createkey => $createkey, + installkey => $installkey, + keytype => $backupkeytype, + keystore => $backupkeystore, + keystorefspath => $backupkeystorefspath, + keydest => $backupkeydest, + keydestname => $backupkeydestname } # the backupninja rule for this duplicity backup @@ -129,4 +137,4 @@ define backupninja::duplicity( $order = 90, require => File["${backupninja::client::defaults::configdir}"] } } - + diff --git a/manifests/generate_sshkey.pp b/manifests/generate_sshkey.pp new file mode 100644 index 0000000..a3008e5 --- /dev/null +++ b/manifests/generate_sshkey.pp @@ -0,0 +1,33 @@ +define backupninja::generate_sshkey( + $ssh_key_basepath = '/etc/puppet/modules/keys/files/backupkeys', +){ + + # generate backupninja ssh keypair + $ssh_key_name = "backup_${::hostname}_id_rsa" + $ssh_keys = ssh_keygen("${ssh_key_basepath}/${ssh_key_name}") + $public = split($ssh_keys[1],' ') + $public_type = $public[0] + $public_key = $public[1] + + file { '/root/.ssh': + ensure => directory, + owner => 'root', + group => 'root', + mode => '0600'; + } + + # install ssh keypair on client + file { "/root/.ssh/$ssh_key_name": + content => $ssh_keys[0], + owner => root, + group => 0, + mode => '0600'; + } + + file { "/root/.ssh/$ssh_key_name.pub": + content => $public_key, + owner => root, + group => 0, + mode => '0666'; + } +} diff --git a/manifests/init.pp b/manifests/init.pp index 23b4268..fba8cc4 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -4,6 +4,7 @@ import "dup.pp" import "labelmount.pp" import "maildir.pp" import "mysql.pp" +import "pgsql.pp" import "rdiff.pp" import "server.pp" import "sh.pp" diff --git a/manifests/nagios_plugin/duplicity.pp b/manifests/nagios_plugin/duplicity.pp new file mode 100644 index 0000000..7dbd263 --- /dev/null +++ b/manifests/nagios_plugin/duplicity.pp @@ -0,0 +1,45 @@ +class backupninja::nagios_plugin::duplicity { + case $::operatingsystem { + 'Debian': { package { 'python-argparse': ensure => installed, } } + 'Ubuntu': { package { 'python-argh': ensure => installed, } } + default: { + notify {'Backupninja-Duplicity Nagios check needs python-argparse to be installed !':} } + } + + file { '/usr/lib/nagios/plugins/check_backupninja_duplicity.py': + source => 'puppet:///modules/backupninja/nagios_plugins/duplicity/check_backupninja_duplicity.py', + mode => '0755', + owner => 'nagios', + group => 'nagios', + } + + # deploy helper script + file { '/usr/lib/nagios/plugins/backupninja_duplicity_freshness.sh': + source => 'puppet:///modules/backupninja/nagios_plugins/duplicity/backupninja_duplicity_freshness.sh', + mode => '0755', + owner => 'nagios', + group => 'nagios', + } + + nagios::nrpe::command { 'check_backupninja_duplicity': + command_line => "sudo ${::nagios::nrpe::nagios_plugin_dir}/check_backupninja_duplicity.py" + } + sudo::spec {'nrpe_check_backupninja_duplicity': + ensure => present, + users => 'nagios', + hosts => 'ALL', + commands => "NOPASSWD: ${::nagios::nrpe::nagios_plugin_dir}/check_backupninja_duplicity.py"; + } + + nagios::service { "Backupninja Duplicity $::fqdn": + use_nrpe => true, + check_command => 'check_backupninja_duplicity', + nrpe_timeout => '60', + # check only twice a day + normal_check_interval => '720', + # recheck every hour + retry_check_interval => '60', + } + + +} diff --git a/manifests/pgsql.pp b/manifests/pgsql.pp new file mode 100644 index 0000000..07fab32 --- /dev/null +++ b/manifests/pgsql.pp @@ -0,0 +1,29 @@ +# Safe PGSQL dumps, as part of a backupninja run. +# +# Valid attributes for this type are: +# +# order: The prefix to give to the handler config filename, to set +# order in which the actions are executed during the backup run. +# +# ensure: Allows you to delete an entry if you don't want it any more +# (but be sure to keep the configdir, name, and order the same, so +# that we can find the correct file to remove). +# +# backupdir, compress, configfile: As defined in the +# backupninja documentation, with the caveat that hotcopy, sqldump, +# and compress take true/false rather than yes/no. +# +define backupninja::pgsql( + $order = 10, $ensure = present, $databases = 'all', $backupdir = "/var/backups/postgres", $compress = true, $vsname = false) +{ + + include backupninja::client::defaults + file { "${backupninja::client::defaults::configdir}/${order}_${name}.pgsql": + ensure => $ensure, + content => template('backupninja/pgsql.conf.erb'), + owner => root, + group => root, + mode => 0600, + require => File["${backupninja::client::defaults::configdir}"] + } +} diff --git a/manifests/rdiff.pp b/manifests/rdiff.pp index 5ff7cb5..1fc9abb 100644 --- a/manifests/rdiff.pp +++ b/manifests/rdiff.pp @@ -16,7 +16,8 @@ # directories. # define backupninja::rdiff( - $order = 90, $ensure = present, $user = false, $home = false, $host = false, + $order = 90, $ensure = present, $user = false, + $home = "/home/${user}-${name}", $host = false, $type = 'local', $exclude = [ "/home/*/.gnupg", "/home/*/.local/share/Trash", "/home/*/.Trash", "/home/*/.thumbnails", "/home/*/.beagle", "/home/*/.aMule", @@ -29,6 +30,8 @@ define backupninja::rdiff( { include backupninja::client::rdiff_backup + $directory = "$home/rdiff-backup/" + case $type { 'remote': { case $host { false: { err("need to define a host for remote backups!") } } @@ -37,18 +40,9 @@ define backupninja::rdiff( default => $backuptag } - $real_home = $home ? { - false => $backupdir ? { - '' => "/backup/${fqdn}", - default => "${backupdir}/${fqdn}", - }, - default => $home, - } - $directory = "${real_home}/rdiff-backup/" - backupninja::server::sandbox { - "${user}-${name}": user => $user, host => $fqdn, dir => $real_home, + "${user}-${name}": user => $user, host => $fqdn, dir => $home, manage_ssh_dir => $ssh_dir_manage, ssh_dir => $ssh_dir, key => $key, authorized_keys_file => $authorized_keys_file, installuser => $installuser, backuptag => $real_backuptag, keytype => $backupkeytype, backupkeys => $backupkeystore, @@ -64,6 +58,8 @@ define backupninja::rdiff( } } } + + file { "${backupninja::client::defaults::configdir}/${order}_${name}.rdiff": ensure => $ensure, content => template('backupninja/rdiff.conf.erb'), diff --git a/templates/pgsql.conf.erb b/templates/pgsql.conf.erb new file mode 100644 index 0000000..7781ef4 --- /dev/null +++ b/templates/pgsql.conf.erb @@ -0,0 +1,11 @@ +<% if vsname %> +vsname = <%= vsname %> +<% end %> +<% if backupdir %> +backupdir = <%= backupdir %> +<% end %> +<% if databases %> +databases = <%= databases %> +<% end %> +compress = <%= compress ? 'yes' : 'no' %> + |