#!/usr/bin/perl
# Includes --------------------------------------------------------------------
# Common stuff:
# Yell at me.
use strict;
use warnings;
# Database
use DBI;
# Email
use Email::MIME;
use Email::Sender::Simple qw(sendmail);
use POSIX qw(floor);
# Not so common stuff.
use IPC::System::Simple qw(capture); # We use IPC::System::Simple's capture
# function instead of backticks. It
# properly sanitizes arguments and does
# proper error checking.
# Stuff you should configure --------------------------------------------------
my $mailfrom = '
[email protected]';
my $mailto = '
[email protected]';
my $servername = 'supercoolserver';
# Debug -----------------------------------------------------------------------
use Data::Dumper;
# Enable backtraces via Carp. Comment out this section if not needed.
# When enabled, the standard perl die() outputs a backtrace, which is much more
# useful than the standard die-message-only behavior.
use Carp 'verbose';
$SIG{ __DIE__ } = sub { Carp::confess( @_ ) };
# Globals ---------------------------------------------------------------------
my $dbh;
my $interactive;
my $self=$0;
# Subroutines -----------------------------------------------------------------
# Connects to the plesk database.
sub connect_to_db()
{
my $db_password = capture('/bin/cat',qw(/etc/psa/.psa.shadow));
chomp($db_password);
$dbh = DBI->connect(
'DBI:mysql:database=psa;host=localhost', #connection string
'admin', # username
$db_password, # password
{'RaiseError' => 1} # options
);
}
# Show usage
sub show_help()
{
print "Usage: $self [options]\n\n";
print "-i\tInteractive - Output in shell instead of email.\n";
print "-h\tHelp - Display program help (this text).\n";
}
# Entry point -----------------------------------------------------------------
# Defaults
$interactive = 0;
# Parse commandline args
my $argc = $#ARGV;
for (my $argn = 0 ; $argn <= $argc ; $argn++)
{
my $opt = $ARGV[$argn];
if ($opt eq '-i')
{
$argn++;
$interactive = 1;
}
else
{
show_help();
exit 1;
}
}
connect_to_db();
# Get results from db.
my $rs = $dbh->prepare('
SELECT
domains.name AS `domain`,
domains.real_size AS `total`,
Limits.value AS `allowed`,
0 + disk_usage.httpdocs + disk_usage.httpsdocs + disk_usage.subdomains + disk_usage.web_users + disk_usage.webapps AS `web`,
0 + disk_usage.mailboxes + disk_usage.maillists AS `mail`,
0 + disk_usage.dbases AS `databases`,
0 + disk_usage.logs AS `logs`,
0 + disk_usage.anonftp + disk_usage.domaindumps + disk_usage.configs + disk_usage.chroot AS `other`
FROM
disk_usage
INNER JOIN domains ON domains.id=disk_usage.dom_id
INNER JOIN Limits ON Limits.id=domains.limits_id
WHERE
domains.overuse=true AND
Limits.limit_name="disk_space"
ORDER BY
domains.real_size DESC
');
$rs->execute();
# Prepare table headers and stuff
my $num_processed = 0;
my $result_text = "Overuse data, all values in megabytes.\n\n";
my $colformat = "%49s | %-10s | %-11s | %-8s| %-8s | %-9s | %-8s | %-8s\n";
$result_text .= sprintf($colformat,'Domain','Total use','Allowed use','Website','Mail','Databases','Logs','Other');
$result_text .= "--------------------------------------------------+------------+-------------+---------+----------+-----------+----------+----------\n";
# Get results.
my $have_results = 0;
while (my $row = $rs->fetchrow_hashref())
{
$have_results = 1;
my $domain = $row->{'domain'};
my $total_usage = floor($row->{'total'} / (1024**2));
my $allowed_usage = floor($row->{'allowed'} / (1024**2));
my $web_usage = floor($row->{'web'} / (1024**2));
my $mail_usage = floor($row->{'mail'} / (1024**2));
my $db_usage = floor($row->{'databases'} / (1024**2));
my $log_usage = floor($row->{'logs'} / (1024**2));
my $other_usage = floor($row->{'other'} / (1024**2));
if ($allowed_usage == -1)
{
$allowed_usage = 'unlimited';
}
$result_text .= sprintf($colformat,$domain,$total_usage,$allowed_usage,$web_usage,$mail_usage,$db_usage,$log_usage,$other_usage);
}
$rs->finish;
$dbh->disconnect;
# If no results, exit now.
if ($have_results == 0)
{
exit 0;
}
# In interactive mode, show results in shell,
# otherwise email results.
if ($interactive == 1)
{
print "$result_text\n";
}
else
{
my $message = Email::MIME->create(
header_str => [
From => $mailfrom,
To => $mailto,
Subject => 'Overuse report ' . $servername
],
attributes => {
encoding => 'quoted-printable',
charset => 'ISO-8859-1'
},
body_str => $result_text
);
sendmail($message);
}
exit 0;