import to mercurial
authorarnold
Thu, 29 Nov 2012 12:12:29 +0100
changeset 0 a04ea5e7c15b
child 1 36f66a013838
import to mercurial
.hgignore
Makefile
check_ldap_repl.pl
debian/changelog
debian/compat
debian/control
debian/copyright
debian/docs
debian/rules
debian/source/format
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgignore	Thu Nov 29 12:12:29 2012 +0100
@@ -0,0 +1,8 @@
+syntax: glob
+*.swp
+debian/files
+check_ldap_repl
+
+syntax: regexp
+(build|configure)-stamp$
+debian/nagios-plugin-ldap-repl[./]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Makefile	Thu Nov 29 12:12:29 2012 +0100
@@ -0,0 +1,22 @@
+SCRIPTS = check_ldap_repl
+CLEANFILES = ${SCRIPTS}
+DESTDIR =
+prefix = /usr
+
+plugindir = ${prefix}/lib/nagios/plugins/ius
+
+.PHONY:	all clean install
+
+all:	${SCRIPTS}
+
+clean:
+	-rm -f ${CLEANFILES}
+
+install:	all
+	install -d -m 0755 ${DESTDIR}/${plugindir}
+	install -m 0755 $(SCRIPTS) ${DESTDIR}/${plugindir}/
+
+%:	%.pl
+	@perl -c $<
+	@cp -f $< $@
+	@chmod +x $@
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/check_ldap_repl.pl	Thu Nov 29 12:12:29 2012 +0100
@@ -0,0 +1,402 @@
+#! /usr/bin/perl -w
+
+#    Copyright (C) 2012  Christian Arnold
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#    Christian Arnold <arnold@schlittermann.de>
+
+# packages: libnet-ldap-perl
+# packages: libio-prompt-perl
+# packages: libio-socket-ssl-perl
+# packages: libconfig-inifiles-perl
+# packages: perl-doc (optional - for man page)
+
+use strict;
+use File::Basename;
+use Getopt::Long;
+use Config::IniFiles;
+use Net::LDAP;
+use IO::Prompt;
+use File::stat;
+use Pod::Usage;
+use if $ENV{DEBUG} => "Smart::Comments";
+
+sub version($$);
+sub read_config();
+sub ldap_object($);
+sub get_stamp($$);
+sub compare_results(%);
+
+my %ERRORS = (
+	OK        => 0,
+	WARNING   => 1,
+	CRITICAL  => 2,
+	UNKNOWN   => 3,
+	DEPENDENT => 4
+);
+
+my $ME      = basename $0;
+my $NAME    = "LDAPREPL";
+my $VERSION = "0.1";
+
+my %opt = (
+	init	=> 0,
+	delete  => 0,
+	refresh => 0,
+	cn      => "replcheck",
+	wait    => 1,
+	file    => "/etc/nagios/ius/plugins/config/check_ldap_repl.cfg",
+	master	=> "ldap://ldap-master:389/",
+	slave	=> "ldap://ldap-slave:389/"
+);
+
+MAIN: {
+	Getopt::Long::Configure('bundling');
+	GetOptions(
+		"i|init"       => \$opt{init},
+		"d|delete"     => \$opt{delete},
+		"r|refresh"    => \$opt{refresh},
+		"b|binddn=s"   => \$opt{binddn},
+		"p|password=s" => \$opt{password},
+		"c|cn=s"       => \$opt{cn},
+		"w|wait=i"     => \$opt{wait},
+		"M|master=s"   => \$opt{master},
+		"S|slave=s"    => \$opt{slave},
+		"f|file=s"     => \$opt{file},
+		"h|help"       => sub { pod2usage( -verbose => 1, -exitval => $ERRORS{OK} ) },
+		"m|man"        => sub { pod2usage( -verbose => 2, -exitval => $ERRORS{OK} ) },
+		"V|version"    => sub { version( $ME, $VERSION ); exit $ERRORS{OK}; }
+	) or pod2usage( -verbose => 1, -exitval => $ERRORS{CRITICAL} );
+
+	if ($opt{init}) {
+		ldap_object("init");
+		print "new object successfully initialized\n";
+		exit $ERRORS{OK};
+	} elsif ($opt{delete}) {
+		ldap_object("delete");
+		print "object successfully deleted\n";
+		exit $ERRORS{OK};
+	}
+
+	ldap_object("refresh") if ($opt{refresh});
+
+	my ($master, $slave, $cn) = undef;
+	my @slaves = ();
+	my %results = ();
+
+	if (-r $opt{file}) {
+		(undef, undef, $master, $slave, $cn) = read_config();
+		@slaves = split(/,/, $slave);
+	} else {
+		$master = $opt{master};
+		@slaves = split(/,/, $opt{slave});
+		$cn = $opt{cn};
+	}
+
+	$results{$master}{'master'} = get_stamp($master, $cn);
+	sleep $opt{wait};
+	foreach (@slaves) {
+		$results{$_}{'slave'} = get_stamp($_, $cn);
+	}
+
+	compare_results(\%results);
+}
+
+sub compare_results(%) {
+	my @output = ();
+	my %stamps = ();
+	my (%results) = %{$_[0]};
+	for my $server ( keys %results ) {
+		for my $type ( keys %{ $results{$server} } ) {
+			$stamps{$results{$server}{$type}} = "";
+			push @output, "$type: $server = $results{$server}{$type}";
+		}
+	}
+
+	@output = sort(@output);
+	if (scalar(keys(%stamps)) != 1 ) {
+		print "$NAME CRITICAL: server are not in sync @output\n";
+		exit $ERRORS{CRITICAL};
+	} else {
+		print "$NAME OK: servers are in sync @output\n";
+		exit $ERRORS{OK};
+	}
+}
+
+sub read_config() {
+	my ($binddn, $password, $cn, $master, $slave);
+	my $cfg = new Config::IniFiles( -file => "$opt{file}");
+	$binddn = $cfg->val('bind', 'dn')?$cfg->val('bind', 'dn'):$opt{binddn};
+	$password = $cfg->val('bind', 'password')?$cfg->val('bind', 'password'):$opt{password};
+	$master = $cfg->val('master', 'server')?$cfg->val('master', 'server'):$opt{master};
+	$slave = $cfg->val('slave', 'server')?$cfg->val('slave', 'server'):$opt{slave};
+	$cn = $cfg->val('object', 'cn')? $cfg->val('object', 'cn'):$opt{cn};
+
+	return ($binddn, $password, $master, $slave, $cn);
+}
+
+sub ldap_object($) {
+	my $type = shift;
+	my ($binddn, $password) = undef;
+
+	my $master = $opt{master};
+	my $cn = $opt{cn};
+
+	if ( ($type eq "init") || ($type eq "delete") ) {
+		$binddn = prompt('BindDN: ');
+		$password = prompt('Password: ', -e => '*');
+	} else {
+		if ($opt{binddn} && $opt{password}) {
+			$binddn = $opt{binddn};
+			$password = $opt{password};
+		} elsif (-r $opt{file}) {
+			($binddn, $password, $master, undef, $cn) = read_config();
+		} else {
+			$binddn = prompt('BindDN: ');
+			$password = prompt('Password: ', -e => '*');
+		}
+	}
+	
+	my $ldap = Net::LDAP->new( $master ) or die "$@";
+
+	my $mesg = $ldap->bind("$binddn", password => $password);
+	if ($mesg->code) {
+		$ldap->unbind() if ($ldap);
+		print "$NAME CRITICAL: " . $mesg->error . "\n";
+		exit $ERRORS{CRITICAL};
+	}
+
+	# get ldap naming context
+	my $dse = $ldap->root_dse();
+	my $context = $dse->get_value('namingContexts');
+
+	if (! defined $context) {
+		print "$NAME CRITICAL: can't determine ldap 'naming context'\n";
+		exit $ERRORS{CRITICAL};
+	}
+
+	if ($mesg->code) {
+		print "$NAME CRITICAL: " . $mesg->error . "\n";
+		exit $ERRORS{CRITICAL};
+	}
+
+	# initialize check object
+	$mesg = $ldap->add(
+		"cn=$cn,$context",
+		attr => [
+			'objectclass' => [ 'top', 'person' ],
+			'cn' => "$cn",
+			'sn' => "$cn",
+			'description' => time()
+			],
+	) if ($type eq "init");
+
+	# delete check object
+	$mesg = $ldap->delete("cn=$cn,$context") if ($type eq "delete");
+
+	if ($mesg->code && ($type eq "delete" || $type eq "init")) {
+		print "$NAME CRITICAL: " . $mesg->error . "\n";
+		exit $ERRORS{CRITICAL};
+	}
+
+	# refresh check object
+	$mesg = $ldap->modify(
+		"cn=$cn,$context",
+		replace => {
+			description => time()
+		}
+	) if ($opt{refresh});
+
+	$ldap->unbind() if ($ldap);
+	return 0;
+}
+
+sub get_stamp($$) {
+	my ($server, $cn) = @_;
+	my $ldap = Net::LDAP->new( $server ) or die "$@";
+	my $mesg = $ldap->bind();
+
+	if ($mesg->code) {
+		$ldap->unbind() if ($ldap);
+		print "$NAME CRITICAL: " . $mesg->error . "\n";
+		exit $ERRORS{CRITICAL};
+	}
+
+	# get ldap naming context
+	my $dse = $ldap->root_dse();
+	my $context = $dse->get_value('namingContexts');
+
+	if (! defined $context) {
+		print "$NAME CRITICAL: can't determine ldap 'naming context'\n";
+		exit $ERRORS{CRITICAL};
+	}
+
+	$mesg = $ldap->search(
+		base => "cn=replcheck,$context",
+		scope => "base",
+		filter => "(cn=$cn)",
+		attr => [ 'description' ]
+
+	);
+
+	if ($mesg->code) {
+		$ldap->unbind() if ($ldap);
+		print "$NAME CRITICAL: " . $mesg->error . "\n";
+		exit $ERRORS{CRITICAL};
+	}
+
+	if ($mesg->count != 1) {
+		print "$NAME CRITICAL: \n";
+		exit $ERRORS{CRITICAL};
+	}
+
+	my $entry = $mesg->entry(0);
+	return $entry->get_value("description");
+
+	$ldap->unbind() if ($ldap);
+}
+
+sub version($$) {
+	my ( $progname, $version ) = @_;
+	
+	print <<_VERSION;
+$progname version $version
+Copyright (C) 2012 by Christian Arnold and Schlittermann internet & unix support.
+
+$ME comes with ABSOLUTELY NO WARRANTY. This is free software,
+and you are welcome to redistribute it under certain conditions.
+See the GNU General Public Licence for details.
+_VERSION
+}
+
+__END__
+
+=head1 NAME
+
+check_ldap_repl - nagios/icinga plugin to check correctly working of ldap replication.
+
+=head1 SYNOPSIS
+
+check_ldap_repl [-i|--init]
+                [-d|--delete]
+                [-r|--refresh]
+                [-c|--cn string]
+                [-b|--binddn string]
+                [-p|--password string]
+                [-f|--file string]
+                [-M|--master string]
+                [-S|--slave string]
+                [-w|--wait integer]
+                [-h|--help]
+                [-m|--man]
+                [-V|--version]
+
+=head1 OPTIONS
+
+=over
+
+=item B<-i>|B<--init>
+
+Add the check object cn=replcheck,I<namingContext> to the master server if not existis. See also the B<--cn> option.
+You will ask for an B<binddn> and B<password>, if not given B<--binddn> and B<--password> options.
+Your B<binddn> must have write permission to the ldap master server.
+
+=item B<-d>|B<--delete>
+
+Delete the check object from the ldap master server if existis. See also the B<--cn> option.
+You will ask for an B<binddn> and B<password>, if not given B<--binddn> and B<--password> options.
+Your B<binddn> must have write permission to the ldap master server.
+
+=item B<-r>|B<--refresh>
+
+Refresh the stamp attribute of the check attribute with current unix time.
+You will ask for an B<binddn> and B<password>, if not given B<--binddn> and B<--password> options. See also B<--file> option.
+Your B<binddn> must have write permission to the ldap master server.
+
+=item B<-c>|B<--cn> I<string>
+
+cn for the initialized object. See also the B<--init> option. (default: replcheck)
+
+=item B<-b>|B<--binddn> I<string>
+
+DN to bind to ldap master server.
+
+=item B<-p>|B<--password> I<string>
+
+Password for binddn to ldap master server. B<PASSWORD IS SHOWN IN PROCESSES, USE CONFIG FILE!>
+
+=item B<-M>|B<--master> I<string>
+
+LDAP master server (provider) (default: ldap://ldap-master:389/)
+
+=item B<-S>|B<--slave> I<string>
+
+LDAP slave server (consumer), multiple slaves can be specified as a comma-separate list (default: ldap://ldap-slave:389/)
+
+=item B<-f>|B<--file> I<string>
+
+Config file with B<binddn> and B<password>. Verify the file B<owner>/B<group> and B<permissions>, B<(0400)> is a good choice!
+You can also set B<master,slave> and B<cn> options. (default: /etc/nagios/ius/plugins/config/check_ldap_repl.cfg)
+
+ [bind]
+ dn = cn=admin,dc=local,dc=site
+ password = secret
+
+ [master]
+ server = ldap://ldap-master:389/
+
+ [slave]
+ server = ldap://ldap-slave01:389/,ldap://ldap-slave02:389/,...
+
+ [object]
+ cn = replcheck
+
+=item B<-w>|B<--wait> I<integer>
+
+Wait I<n> seconds before check the slave servers. (default: 1)
+
+=item B<-h>|B<--help>
+
+Print detailed help screen.
+
+=item B<-m>|B<--man>
+
+Print manual page.
+
+=item B<-V>|B<--version>
+
+Print version information.
+
+=back
+
+=head1 DESCRIPTION
+
+This plugin checks if the ldap replication works correctly.
+
+=head1 VERSION
+
+This man page is current for version 0.1 of B<check_ldap_repl>.
+
+=head1 AUTHOR
+
+Written by Christian Arnold L<arnold@schlittermann.de>
+
+=head1 COPYRIGHT
+
+Copyright (C) 2012 by Christian Arnold and Schlittermann internet & unix support.
+This is free software, and you are welcome to redistribute it under certain conditions.
+See the GNU General Public Licence for details.
+
+=cut
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/debian/changelog	Thu Nov 29 12:12:29 2012 +0100
@@ -0,0 +1,5 @@
+nagios-plugin-ldap-repl (0.1) stable; urgency=low
+
+  * Initial Release.
+
+ -- Christian Arnold <arnold@schlittermann.de>  Thu, 29 Nov 2012 11:51:52 +0100
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/debian/compat	Thu Nov 29 12:12:29 2012 +0100
@@ -0,0 +1,1 @@
+7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/debian/control	Thu Nov 29 12:12:29 2012 +0100
@@ -0,0 +1,14 @@
+Source: nagios-plugin-ldap-repl
+Section: net
+Priority: extra
+Maintainer: Christian Arnold <arnold@schlittermann.de>
+Build-Depends: debhelper (>= 7.0.50~)
+Standards-Version: 3.8.4
+Homepage: https://ssl.schlittermann.de/hg/ius/nagios/nagios-plugin-ldap-repl/
+
+Package: nagios-plugin-ldap-repl
+Architecture: all
+Depends: ${misc:Depends}, ${perl:Depends}, libnet-ldap-perl, libio-prompt-perl, libio-socket-ssl-perl, libconfig-inifiles-perl
+Suggests: perl-doc
+Description: nagios/icinga plugin to check ldap replication
+ This plugin checks if the ldap replication works correctly.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/debian/copyright	Thu Nov 29 12:12:29 2012 +0100
@@ -0,0 +1,39 @@
+This work was packaged for Debian by:
+
+    Christian Arnold <arnold@schlittermann.de> on Thu, 29 Nov 2012 11:51:52 +0100
+
+It was downloaded from:
+
+    https://ssl.schlittermann.de/hg/ius/nagios/nagios-plugin-ldap-repl/
+
+Upstream Author(s):
+
+    Christian Arnold <arnold@schlittermann.de>
+
+Copyright:
+
+    Copyright (C) 2011 Schlittermann internet & unix support
+
+License:
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This package is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+On Debian systems, the complete text of the GNU General
+Public License version 3 can be found in "/usr/share/common-licenses/GPL-3".
+
+The Debian packaging is:
+
+    Copyright (C) 2012 Christian Arnold <arnold@schlittermann.de>
+
+and is licensed under the GPL version 3, see above.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/debian/rules	Thu Nov 29 12:12:29 2012 +0100
@@ -0,0 +1,13 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+# Sample debian/rules that uses debhelper.
+# This file was originally written by Joey Hess and Craig Small.
+# As a special exception, when this file is copied by dh-make into a
+# dh-make output file, you may use that output file without restriction.
+# This special exception was added by Craig Small in version 0.37 of dh-make.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+%:
+	dh $@ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/debian/source/format	Thu Nov 29 12:12:29 2012 +0100
@@ -0,0 +1,1 @@
+3.0 (native)