#!/usr/bin/perl -w
#
# Copyright (C) 2005-2007 Rodolphe Quiedeville <rodolphe@quiedeville.org>
# Copyright (C) 2007 Maximilian Wilhelm <max@rfc2324.org>
#
# 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; version 2 dated June,
# 1991.
#
# 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, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
# If you improve this script please send your version to my email address
# with the copyright notice upgrade with your name.
#
# Munin's plugin to monitor number of clients connected to openvpn server
#
# Usage: copy or link into /etc/munin/plugins
#        Mayb you have to tell munin to run this plugin as root or
#        any other user which can access the openvpn logs.
#        (See /etc/munin/plugin-conf.d/munin-node)
#
# Parameters:
#
#       config   (required)
#       autoconf (optional - used by munin-config)
#
# $Log$
# Revision 1.2  2007/01/17 15:57:19  rodo
# Correct family
#
# Revision 1.1  2005/10/11 14:12:19  Rodolphe Quiedeville
#
# Magic markers (optinal - used by munin-config and some installation
# scripts):
#
#%# family=auto
#%# capabilities=autoconf

use strict;

my $ovpn_logdir = "/var/log/openvpn";
my $client_count = 0;

#
# Helper function to get a list of all instances (two-digit integer) which
# write a status log in $ovpn_logdir.
#
# The status file naming schema is 'ovpn-<instance>.status' where instance
# is a number between '00' and '99'
sub get_status_file_instance_list () {
	my @status_files;
	my @instances;

	return undef if (! -d $ovpn_logdir);

	opendir (OVPN_LOGDIR, "$ovpn_logdir")
		or die "Could not open ovnp logdir \"$ovpn_logdir\"";

	@status_files = grep { -f "$ovpn_logdir/$_" } readdir (OVPN_LOGDIR);

	closedir (OVPN_LOGDIR);

	foreach my $file (@status_files) {
		if ($file =~ m/^ovpn-(\d\d).status$/) {
			push @instances, $1
		}
	}

	return @instances;
}


#
# Check if there is/are status logfile(s)
if ($ARGV[0] and $ARGV[0] eq "autoconf") {
	if (get_status_file_instance_list ()) {
		print "yes\n";
		exit 0;
	} else {
		print "no\n";
		exit 1;
	}
}


#
# Build config from status logfile list
if ($ARGV[0] and $ARGV[0] eq "config" ) {
	print "graph_title Connected OpenVPN clients per server instance\n";
	print "graph_args --base 1000 -l 0\n";
	print "graph_scale yes\n";
	print "graph_vlabel clients\n";
	print "graph_category network\n";
	print "graph_info This graph shows the numbers of clients currently connected to each openvpn server instance found on the system.\n";

	foreach my $instance (get_status_file_instance_list ()) {
		print "ovpn_${instance}.label ovpn-$instance\n";
		print "ovpn_${instance}.info The number of clients currently connected to OpenVPN instance $instance\n";
	}

	exit 0;
}


#
# Print out the number of clients per instance
foreach my $instance (get_status_file_instance_list ()) {
	my $status_file = "$ovpn_logdir/ovpn-$instance.status";

	open (STATUS_FILE, "< $status_file")
		or die "Could not open status file \"$status_file\"";

	my $read_user_list = 0;

	while (<STATUS_FILE>) {
		if (/^Common Name,Real Address,Bytes Received,Bytes Sent,Connected Since$/) {
			$read_user_list = 1;
			next;
		}

		if (/^ROUTING TABLE$/) {
			last;
		}

		if ($read_user_list) {
			$client_count++;
		}
    	}

	close (STATUS_FILE);

	print "ovpn_${instance}.value $client_count\n";
}
