From 3dfe317ae1895cf6e411d98a09b2e62ba44df2ed Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Mon, 21 Aug 2017 13:09:55 +0200 Subject: [PATCH] pmgreport: new tool to send daily system reports --- Makefile | 3 +- PMG/CLI/pmgqm.pm | 36 +-------------- PMG/CLI/pmgreport.pm | 102 +++++++++++++++++++++++++++++++++++++++++ PMG/Utils.pm | 34 ++++++++++++++ bin/pmgreport | 8 ++++ templates/pmgreport.tt | 49 ++++++++++++++++++++ 6 files changed, 196 insertions(+), 36 deletions(-) create mode 100644 PMG/CLI/pmgreport.pm create mode 100644 bin/pmgreport create mode 100644 templates/pmgreport.tt diff --git a/Makefile b/Makefile index 2b3de67..687dee5 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ BASHCOMPLDIR=${DESTDIR}/usr/share/bash-completion/completions/ REPOID=`./repoid.pl .git` SERVICES = pmgdaemon pmgproxy pmgtunnel pmgmirror -CLITOOLS = pmgdb pmgconfig pmgperf pmgcm pmgqm +CLITOOLS = pmgdb pmgconfig pmgperf pmgcm pmgqm pmgreport CLISCRIPTS = pmg-smtp-filter pmgsh pmgpolicy CRONSCRIPTS = pmg-hourly pmg-daily @@ -35,6 +35,7 @@ SERVICE_MANS = $(addsuffix .8, ${SERVICES}) pmg-smtp-filter.8 pmgpolicy.8 CONF_MANS= pmg.conf.5 cluster.conf.5 TEMPLATES = \ + pmgreport.tt \ spamreport-verbose.tt \ spamreport-short.tt \ main.cf.in \ diff --git a/PMG/CLI/pmgqm.pm b/PMG/CLI/pmgqm.pm index 7f231b2..ca19ef2 100755 --- a/PMG/CLI/pmgqm.pm +++ b/PMG/CLI/pmgqm.pm @@ -112,40 +112,6 @@ sub get_item_data { return $item; } -sub finalize_report { - my ($tt, $template, $data, $mailfrom, $receiver, $debug) = @_; - - my $html = ''; - - $tt->process($template, $data, \$html) || - die $tt->error() . "\n"; - - my $title; - if ($html =~ m|^\s*(.*)|m) { - $title = $1; - } else { - die "unable to extract template title\n"; - } - - my $top = MIME::Entity->build( - Type => "multipart/related", - To => $data->{pmail}, - From => $mailfrom, - Subject => PMG::Utils::bencode_header(decode_entities($title))); - - $top->attach( - Data => $html, - Type => "text/html", - Encoding => $debug ? 'binary' : 'quoted-printable'); - - if ($debug) { - $top->print(); - return; - } - # we use an empty envelope sender (we dont want to receive NDRs) - PMG::Utils::reinject_mail ($top, '', [$receiver], undef, $data->{fqdn}); -} - __PACKAGE__->register_method ({ name => 'send', path => 'send', @@ -297,7 +263,7 @@ __PACKAGE__->register_method ({ if (!$extern) { $data->{mailcount} = $mailcount; my $sendto = $redirect ? $redirect : $creceiver; - finalize_report($tt, $template, $data, $mailfrom, $sendto, $param->{debug}); + PMG::Utils::finalize_report($tt, $template, $data, $mailfrom, $sendto, $param->{debug}); } } else { my $hint = $extern ? " (external address)" : ""; diff --git a/PMG/CLI/pmgreport.pm b/PMG/CLI/pmgreport.pm new file mode 100644 index 0000000..9b69788 --- /dev/null +++ b/PMG/CLI/pmgreport.pm @@ -0,0 +1,102 @@ +package PMG::CLI::pmgreport; + +use strict; +use Data::Dumper; +use Template; +use POSIX qw(strftime); + +use PVE::INotify; +use PVE::CLIHandler; + +use PMG::Utils; +use PMG::Config; +use PMG::RESTEnvironment; +use PMG::API2::Nodes; + +use base qw(PVE::CLIHandler); + +my $nodename = PVE::INotify::nodename(); + +sub setup_environment { + PMG::RESTEnvironment->setup_default_cli_env(); +} + +my $get_system_table_data = sub { + + my $ni = PMG::API2::NodeInfo->status({ node => $nodename }); + + my $data = []; + + push @$data, { text => 'Hostname', value => $nodename }; + + my $uptime = $ni->{uptime} ? PMG::Utils::format_uptime($ni->{uptime}) : '-'; + + push @$data, { text => 'Uptime', value => $uptime }; + + push @$data, { text => 'Version', value => $ni->{pmgversion} }; + + my $loadavg15 = '-'; + if (my $d = $ni->{loadavg}) { + $loadavg15 = $d->[2]; + } + push @$data, { text => 'Load', value => $loadavg15 }; + + my $mem = '-'; + if (my $d = $ni->{memory}) { + $mem = sprintf("%.2f%%", $d->{used}*100/$d->{total}); + } + push @$data, { text => 'Memory', value => $mem }; + + my $disk = '-'; + if (my $d = $ni->{rootfs}) { + $disk = sprintf("%.2f%%", $d->{used}*100/$d->{total}); + } + push @$data, { text => 'Disk', value => $disk }; + + return $data +}; + + +__PACKAGE__->register_method ({ + name => 'pmgreport', + path => 'pmgreport', + method => 'POST', + description => "Generate and send daily system report email.", + parameters => { + additionalProperties => 0, + properties => {}, + }, + returns => { type => 'null'}, + code => sub { + my ($param) = @_; + + my $fqdn = PVE::Tools::get_fqdn($nodename); + + my $end = time(); # fixme + + my $vars = { + hostname => $nodename, + fqdn => $fqdn, + date => strftime("%F", localtime($end - 1)), + }; + + $vars->{system} = $get_system_table_data->(); + + my $tt = PMG::Config::get_template_toolkit(); + + my $cfg = PMG::Config->new(); + my $email = $cfg->get ('admin', 'email'); + + if (!defined($email)) { + die "STOPHERE"; + } + + my $mailfrom = "Proxmox Mail Gateway "; + PMG::Utils::finalize_report($tt, 'pmgreport.tt', $vars, $mailfrom, $email, $param->{debug}); + + return undef; + }}); + +our $cmddef = [ __PACKAGE__, 'pmgreport', [], undef ]; + +1; diff --git a/PMG/Utils.pm b/PMG/Utils.pm index 5f6974f..81d2dca 100644 --- a/PMG/Utils.pm +++ b/PMG/Utils.pm @@ -995,4 +995,38 @@ sub format_uptime { } } +sub finalize_report { + my ($tt, $template, $data, $mailfrom, $receiver, $debug) = @_; + + my $html = ''; + + $tt->process($template, $data, \$html) || + die $tt->error() . "\n"; + + my $title; + if ($html =~ m|^\s*(.*)|m) { + $title = $1; + } else { + die "unable to extract template title\n"; + } + + my $top = MIME::Entity->build( + Type => "multipart/related", + To => $data->{pmail}, + From => $mailfrom, + Subject => bencode_header(decode_entities($title))); + + $top->attach( + Data => $html, + Type => "text/html", + Encoding => $debug ? 'binary' : 'quoted-printable'); + + if ($debug) { + $top->print(); + return; + } + # we use an empty envelope sender (we dont want to receive NDRs) + PMG::Utils::reinject_mail ($top, '', [$receiver], undef, $data->{fqdn}); +} + 1; diff --git a/bin/pmgreport b/bin/pmgreport new file mode 100644 index 0000000..abf6cc7 --- /dev/null +++ b/bin/pmgreport @@ -0,0 +1,8 @@ +#!/usr/bin/perl -T + +use strict; +use warnings; + +use PMG::CLI::pmgreport; + +PMG::CLI::pmgreport->run_cli_handler(); diff --git a/templates/pmgreport.tt b/templates/pmgreport.tt new file mode 100644 index 0000000..eb15edc --- /dev/null +++ b/templates/pmgreport.tt @@ -0,0 +1,49 @@ + + + +Proxmox Status Report - [% date %] ([% fqdn %]) + + + + + [% IF cluster %] + [% END %] + + [% IF system %] +

System Status

+ + + + + + [% FOREACH item IN system %] + + + + + [% END %] +
PropertyValue
[% item.text %][% item.value %]
+ [% END %] + + + + -- 2.39.2