#!/usr/bin/perl

use strict;
use File::Basename;
use Getopt::Long;
use Data::Dumper;

my $version				= '20201119';
my $cmd					= '/usr/bin/doveadm -f tab replicator status';
my $debug				= 0;
my $warn_q_failed_req	= 0;
my $crit_q_failed_req	= 0;
my $warn_w_failed_req	= 0;
my $crit_w_failed_req	= 0;

my %array;

my %ERRORS =
			(
				'OK'		=> 0,
				'WARNING'	=> 1,
				'CRITICAL'	=> 2,
				'UNKNOWN'	=> 3,
				'DEPENDENT'	=> 4
			);

#
# Functions
#
sub usage() {
	my $basename = basename($0);
	print <<DATA;

	Version: $version
	$basename [-h] [-d]

	-h|--help	This help screen
	-d|--debug	Activate debug mode
	--wqfq		Warning  'Queued failed requests'  threshold
	--cqfr		Critical 'Queued failed requests'  threshold
	--wwfq		Warning  'Waiting failed requests' threshold
	--cwfr		Critical 'Waiting failed requests' threshold

DATA

	exit $ERRORS{'UNKNOWN'};
}

sub check_options() {
	my $o_help;
	my $o_debug;

	Getopt::Long::Configure ("bundling");
	GetOptions(
		'h|help'	=> \$o_help,
		'd|debug'	=> \$o_debug,
		'wqfq:i'	=> \$warn_q_failed_req,
		'cqfr:i'	=> \$crit_q_failed_req,
		'wwfq:i'	=> \$warn_w_failed_req,
		'cwfr:i'	=> \$crit_w_failed_req,
	);

	usage() if (defined($o_help));
	$debug = 1 if (defined($o_debug));

	if ( $warn_q_failed_req < 0 or $crit_q_failed_req < 0 or $warn_w_failed_req < 0 or $crit_w_failed_req < 0 ) {
		usage();
	}
}

##
## Main
##

#
# Verify passed arguments
#
check_options();

#
# Get actual values
#
if (!open(CMD, "$cmd|")) {
	print "Cannot run $cmd\n";
	exit $ERRORS{'CRITICAL'};
}

while (<CMD>) {
	chomp;
	next if ($_ =~ /^field/);
	my ($key,$value) = split(/\t/);

	#
	# Sample output
	#
	#Queued 'sync' requests        0
	#Queued 'high' requests        0
	#Queued 'low' requests         0
	#Queued 'failed' requests      0
	#Queued 'full resync' requests 0
	#Waiting 'failed' requests     0
	#Total number of known users   3917

	print "key=$key, value=$value\n" if $debug;

	$array{'q_sync_req'} = $value			if ($key =~ /Queued \'sync\' requests/);
	$array{'q_high_req'} = $value			if ($key =~ /Queued \'high\' requests/);
	$array{'q_low_req'} = $value			if ($key =~ /Queued \'low\' requests/);
	$array{'q_failed_req'} = $value			if ($key =~ /Queued \'failed\' requests/);
	$array{'q_full_resync_req'} = $value	if ($key =~ /Queued \'full resync\' requests/);
	$array{'w_failed_req'} = $value			if ($key =~ /Waiting \'failed\' requests/);
	$array{'n_users'} = $value				if ($key =~ /Total number of known users/);
}

close (CMD);

#
# Status check
#
my $status	= $ERRORS{'OK'};
my $s_q_failed_req;
my $s_w_failed_req;

# for test only
#$array{'q_failed_req'} = 2;
#$array{'w_failed_req'} = 2;

if ( $warn_q_failed_req > 0 and $array{'q_failed_req'} >= $warn_q_failed_req ) {
	$status	= $ERRORS{'WARNING'};
	$s_q_failed_req = '(!)';
}
if ( $warn_w_failed_req > 0 and $array{'w_failed_req'} >= $warn_w_failed_req ) {
	$status	= $ERRORS{'WARNING'};
	$s_w_failed_req = '(!)';
}
if ( $crit_q_failed_req > 0 and $array{'q_failed_req'} >= $crit_q_failed_req ) {
	$status	= $ERRORS{'CRITICAL'};
	$s_q_failed_req = '(!!)';
}
if ( $crit_w_failed_req > 0 and $array{'w_failed_req'} >= $crit_w_failed_req ) {
	$status	= $ERRORS{'CRITICAL'};
	$s_w_failed_req = '(!!)';
}
	
#
# Output write
#
print "Dovecot replication: users=$array{'n_users'}, full_resync=$array{'q_full_resync_req'}, ";
print "queued_failed=$array{'q_failed_req'}$s_q_failed_req, waiting_failed=$array{'w_failed_req'}$s_w_failed_req";
print " |";
print " 'users'=$array{'n_users'};;;0";
print " 'q_sync_req'=$array{'q_sync_req'};;;0";
print " 'q_high_req'=$array{'q_high_req'};;;0";
print " 'q_low_req'=$array{'q_low_req'};;;0";
print " 'q_failed_req'=$array{'q_failed_req'};;;0";
print " 'q_full_resync_req'=$array{'q_full_resync_req'};;;0";
print " 'w_failed_req'=$array{'w_failed_req'};;;0";
print "\n";

exit $status;

