From c0de5a612aed73cbbf2ce07b092c8595ff8b2a3c Mon Sep 17 00:00:00 2001 From: mischa Date: Sun, 17 May 2020 17:40:46 +0200 Subject: [PATCH] added notify.pl, informing users about deployed and stopped VM, renewal, maintenance --- email-deployed.txt | 12 ++ email-notify.txt | 13 ++ email-renewal.txt | 12 ++ email-stopped.txt | 12 ++ notify.pl | 305 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 354 insertions(+) create mode 100644 email-deployed.txt create mode 100644 email-notify.txt create mode 100644 email-renewal.txt create mode 100644 email-stopped.txt create mode 100755 notify.pl diff --git a/email-deployed.txt b/email-deployed.txt new file mode 100644 index 0000000..4ffe590 --- /dev/null +++ b/email-deployed.txt @@ -0,0 +1,12 @@ +From: admin +Subject: OpenBSD Amsterdam + +Hi NAME, + +Welcome to OpenBSD Amsterdam! Your VM has been deployed. + +Your IPv4: IP +Your VM name: VMID +Your host: SERVER.openbsd.amsterdam + +Mischa diff --git a/email-notify.txt b/email-notify.txt new file mode 100644 index 0000000..d7fbaa2 --- /dev/null +++ b/email-notify.txt @@ -0,0 +1,13 @@ +From: admin +Subject: OpenBSD Amsterdam - maintenance + +Hi NAME, + +You have a VM (VMID) running on SERVER. +We will sysupgrade SERVER from OpenBSD 6.6 to OpenBSD 6.7. + +Mischa + +-- +OpenBSD Amsterdam +https://obsda.ms diff --git a/email-renewal.txt b/email-renewal.txt new file mode 100644 index 0000000..3d926c9 --- /dev/null +++ b/email-renewal.txt @@ -0,0 +1,12 @@ +From: admin +Subject: OpenBSD Amsterdam Renewal YEAR + +Hi NAME, + +Your renewal fee for VMID on SERVER this year is €PAYMENT. + +Mischa + +-- +OpenBSD Amsterdam +https://obsda.ms diff --git a/email-stopped.txt b/email-stopped.txt new file mode 100644 index 0000000..230dfdb --- /dev/null +++ b/email-stopped.txt @@ -0,0 +1,12 @@ +From: admin +Subject: OpenBSD Amsterdam VM not running + +Hi NAME, + +Your VM, VMID on SERVER, is currently not running. + +Mischa + +-- +OpenBSD Amsterdam +https://obsda.ms diff --git a/notify.pl b/notify.pl new file mode 100755 index 0000000..0e0f859 --- /dev/null +++ b/notify.pl @@ -0,0 +1,305 @@ +#!/usr/bin/env perl +# +# Copyright (c) 2020 Mischa Peters +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# +# vmm(4)/vmd(8) VM notify script for OpenBSD Amsterdam +# 2020/05/17 initial release +# +# This is WIP, currently there is a lot of overlap in the functions. +# +use 5.024; +use strict; +use warnings; +use autodie; +use POSIX qw(strftime); + +# Get function and function_variable (vmid) from arguments +my $function = $ARGV[0] || "empty"; +my $function_variable = $ARGV[1] || "empty"; + +# fuction to parse _deploy.conf and vm*.txt files +# all variables are stripped and added to either %vms or %conf +sub get_variables { + my ($hash_name, @files) = @_; + my %hash; + my $filename; + my $vm_name; + my $vm_number; + + for my $file (@files) { + # When hash is 'vms' use the vm_name as key + # Otherwise use 'conf' as key + if ($hash_name eq "vms") { + ($filename = $file) =~ s/.*\///; + ($vm_name = $filename) =~ s/\.txt//; + ($vm_number = $vm_name) =~ s/^vm//; + $hash{$vm_name}{'vm_number'} = $vm_number; + } + + open my $fh, "<", "$file"; + while (my $row = <$fh>) { + next if ($row =~ /^\s*($|#)/); + chomp ($row); + (my $key, my $val) = split(/=/, $row, 2); + if ($hash_name eq "vms") { + ($hash{$vm_name}{$key} .= $val) =~ s/^"+|"+$//g; + } else { + ($hash{$hash_name}{$key} .= $val) =~ s/^"+|"+$//g; + } + } + close $fh; + } + return %hash; +} + +sub deployed { + my %conf = %{$_[0]}; + my %vms = %{$_[1]}; + my $_etc = $conf{'conf'}{'ETC'}; + my $_vms = $conf{'conf'}{'VMS'}; + my $_tmpl = $conf{'conf'}{'TEMPLATES'}; + my $_server = $conf{'conf'}{'SERVER'}; + my $template = "$_tmpl/email-deployed.txt"; + + for my $vm_name (sort keys %vms) { + my $_date = $vms{$vm_name}{'date'}; + my $_payment = $vms{$vm_name}{'payment'}; + my $_donated = $vms{$vm_name}{'donated'}; + my $_name = $vms{$vm_name}{'name'}; + my $_email = $vms{$vm_name}{'email'}; + my $_hostname = $vms{$vm_name}{'hostname'}; + my $_boot = $vms{$vm_name}{'boot'} || "yes"; + + if ($function_variable =~ /empty/) { print "No VMID provided\n"; last; } + if ($function_variable =~ /$vm_name/) { + (my $_firstname, my $_lastname) = split(/ /, $_name, 2); + my $ipaddress = qx(grep -A2 $vm_name $_etc/dhcpd.conf | awk '/fixed-address/{print \$2}' | tr -d ';\n'); + + open(my $fh, '<', $template); + open my $fh_email, "|-", "/usr/sbin/sendmail -t"; + printf $fh_email "To: %s\n", $_email; + while (my $row = <$fh>) { + chomp $row; + $row =~ s/NAME/$_firstname/g; + $row =~ s/IP$/$ipaddress/g; + $row =~ s/VMID/$vm_name/g; + $row =~ s/SERVER/$_server/g; + print $fh_email "$row\n"; + } + close $fh_email; + print "NOTIFIED: $_date, $_payment, $_name, $_email, $_hostname, $_server ($vm_name), $ipaddress\n"; + } + } +} + +# function to collect stopped vms +sub stopped { + my %conf = %{$_[0]}; + my %vms = %{$_[1]}; + my $_etc = $conf{'conf'}{'ETC'}; + my $_vms = $conf{'conf'}{'VMS'}; + my $_tmpl = $conf{'conf'}{'TEMPLATES'}; + my $_server = $conf{'conf'}{'SERVER'}; + my $template = "$_tmpl/email-stopped.txt"; + + my @stopped_vms = qx(vmctl show | grep stopped | awk '{print \$9}'); + + for my $vm_name (sort keys %vms) { + my $_date = $vms{$vm_name}{'date'}; + my $_payment = $vms{$vm_name}{'payment'}; + my $_donated = $vms{$vm_name}{'donated'}; + my $_name = $vms{$vm_name}{'name'}; + my $_email = $vms{$vm_name}{'email'}; + my $_hostname = $vms{$vm_name}{'hostname'}; + my $_boot = $vms{$vm_name}{'boot'} || "yes"; + + if ($_boot =~ /no/) { + print "NOT NOTIFIED: $_name, $_email, $_hostname, $_server ($vm_name)\n"; + next; + } + if (grep(/$vm_name/, @stopped_vms)) { + (my $_firstname, my $_lastname) = split(/ /, $_name, 2); + my $ipaddress = qx(grep -A2 $vm_name $_etc/dhcpd.conf | awk '/fixed-address/{print \$2}' | tr -d ';\n'); + + open(my $fh, '<', $template); + open my $fh_email, "|-", "/usr/sbin/sendmail -t"; + printf $fh_email "To: %s\n", $_email; + while (my $row = <$fh>) { + chomp $row; + $row =~ s/NAME/$_firstname/g; + $row =~ s/IP$/$ipaddress/g; + $row =~ s/VMID/$vm_name/g; + $row =~ s/SERVER/$_server/g; + print $fh_email "$row\n"; + } + close $fh_email; + print "NOTIFIED: $_date, $_payment, $_name, $_email, $_hostname, $_server ($vm_name), $ipaddress\n"; + } + } +} + +sub renewal { + my %conf = %{$_[0]}; + my %vms = %{$_[1]}; + my $_etc = $conf{'conf'}{'ETC'}; + my $_vms = $conf{'conf'}{'VMS'}; + my $_tmpl = $conf{'conf'}{'TEMPLATES'}; + my $_server = $conf{'conf'}{'SERVER'}; + my $template = "$_tmpl/email-renewal.txt"; + + my $year = strftime("%Y", localtime); + my $month = strftime("%m", localtime); + + my $total_donated = qx(ftp -Vo- https://obsda.ms/index.html | grep "donated to OpenBSD" | awk -F';' '{print \$4}' | awk '{printf \$1}'); + my $total_vms = qx(ftp -Vo- https://obsda.ms/index.html | grep "deployed" | awk -F '>' '{print \$3}' | awk '{printf \$1}'); + my $total_hosts = qx(ftp -Vo- https://obsda.ms/servers.html | grep -c ">Server " | tr -d '\n'); + + for my $vm_name (sort keys %vms) { + my $_date = $vms{$vm_name}{'date'}; + my $_payment = $vms{$vm_name}{'payment'}; + my $_donated = $vms{$vm_name}{'donated'}; + my $_name = $vms{$vm_name}{'name'}; + my $_email = $vms{$vm_name}{'email'}; + my $_hostname = $vms{$vm_name}{'hostname'}; + my $_boot = $vms{$vm_name}{'boot'} || "yes"; + + if ($_donated =~ /done/) { next; } + if ($_donated =~ /expire/) { next; } + if ($_donated =~ /sponsor/) { next; } + if ($_donated =~ /renewal/) { next; } + if ($_date =~ /$year\//) { next; } + if ($_date =~ /\/$month\//) { + (my $_firstname, my $_lastname) = split(/ /, $_name, 2); + (my $_year, my $_month, my $_day) = split(/\//, $_date, 3); + my $ipaddress = qx(grep -A2 $vm_name $_etc/dhcpd.conf | awk '/fixed-address/{print \$2}' | tr -d ';\n'); + + open(my $fh, '<', $template); + open my $fh_email, "|-", "/usr/sbin/sendmail -t"; + printf $fh_email "To: %s\n", $_email; + while (my $row = <$fh>) { + chomp $row; + $row =~ s/NAME/$_firstname/g; + $row =~ s/IP$/$ipaddress/g; + $row =~ s/VMID/$vm_name/g; + $row =~ s/SERVER/$_server/g; + + $row =~ s/YEAR/$year/g; + $row =~ s/TOTAL_DONATED/$total_donated/g; + $row =~ s/TOTAL_VMS/$total_vms/g; + $row =~ s/TOTAL_HOSTS/$total_hosts/g; + $row =~ s/PAYMENT/$_payment/g; + + print $fh_email "$row\n"; + } + close $fh_email; + print "NOTIFIED: $_date, $_payment, $_name, $_email, $_hostname, $_server ($vm_name), $ipaddress\n"; + } + } +} + +# function to notify people +sub notify { + my %conf = %{$_[0]}; + my %vms = %{$_[1]}; + my $_etc = $conf{'conf'}{'ETC'}; + my $_vms = $conf{'conf'}{'VMS'}; + my $_tmpl = $conf{'conf'}{'TEMPLATES'}; + my $_server = $conf{'conf'}{'SERVER'}; + my $template = "$_tmpl/email-notify.txt"; + + for my $vm_name (sort keys %vms) { + my $_date = $vms{$vm_name}{'date'}; + my $_payment = $vms{$vm_name}{'payment'}; + my $_donated = $vms{$vm_name}{'donated'}; + my $_name = $vms{$vm_name}{'name'}; + my $_email = $vms{$vm_name}{'email'}; + my $_hostname = $vms{$vm_name}{'hostname'}; + my $_boot = $vms{$vm_name}{'boot'} || "yes"; + + if (-e "$template") { + #if ($_boot =~ /yes/) { + (my $_firstname, my $_lastname) = split(/ /, $_name, 2); + my $ipaddress = qx(grep -A2 $vm_name $_etc/dhcpd.conf | awk '/fixed-address/{print \$2}' | tr -d ';\n'); + + open(my $fh, '<', $template); + open my $fh_email, "|-", "/usr/sbin/sendmail -t"; + printf $fh_email "To: %s\n", $_email; + while (my $row = <$fh>) { + chomp $row; + $row =~ s/NAME/$_firstname/g; + $row =~ s/IP$/$ipaddress/g; + $row =~ s/VMID/$vm_name/g; + $row =~ s/SERVER/$_server/g; + print $fh_email "$row\n"; + } + close $fh_email; + print "NOTIFIED: $_date, $_payment, $_name, $_email, $_hostname, $_server ($vm_name), $ipaddress\n"; + } + } +} + +# function to print all keys & values for debug purposes +sub debug_parse { + my %conf = %{$_[0]}; + my %vms = %{$_[1]}; + my $_etc = $conf{'conf'}{'ETC'}; + my $_vms = $conf{'conf'}{'VMS'}; + my $_tmpl = $conf{'conf'}{'TEMPLATES'}; + my $_server = $conf{'conf'}{'SERVER'}; + my $template = "$_tmpl/email-debug.txt"; + print "All VMs\n##\n"; + for my $vm_name (sort keys %vms) { + my $_date = $vms{$vm_name}{'date'}; + my $_payment = $vms{$vm_name}{'payment'}; + my $_donated = $vms{$vm_name}{'donated'}; + my $_name = $vms{$vm_name}{'name'}; + my $_email = $vms{$vm_name}{'email'}; + my $_hostname = $vms{$vm_name}{'hostname'}; + my $_boot = $vms{$vm_name}{'boot'} || "yes"; + print "$_date, $_payment, $_name, $_email, $_hostname, $_server ($vm_name)\n"; + } + print "##\n"; +} + +# check if _deploy.conf exists +my $dev = $ENV{'HOME'} . "/openbsd.amsterdam/deploy.pl"; +my $prod = $ENV{'HOME'}; +my $dir; +my $debug; +my %conf; +my %vms; +if (-d "$dev") { + $dir = $dev; + $debug = 1; + %conf = get_variables('conf', "$dir/_deploy.conf"); +} elsif (-d "$prod") { + $dir = $prod; + %conf = get_variables('conf', "$dir/_deploy.conf"); +} else { + printf "Unable to find config file\n"; + exit 1; +} + +# parse all vm*.txt files in the VMS directory +my @files = glob "$conf{'conf'}{'VMS'}/*.txt"; +%vms = get_variables('vms', @files); + +# run functions +if ($debug) { debug_parse(\%conf, \%vms); } +if ($function =~ /deployed/) { deployed(\%conf, \%vms); } +elsif ($function =~ /stopped/) { stopped(\%conf, \%vms); } +elsif ($function =~ /renewal/) { renewal(\%conf, \%vms); } +elsif ($function =~ /notify/) { notify(\%conf, \%vms); } +else { print "Specify function: deployed, stopped, renewal, notify\n"; }