From e764eccf6e1fc78cc6a8124afb3b14bd91a03107 Mon Sep 17 00:00:00 2001 From: Digimer Date: Sun, 5 Jan 2020 15:07:35 -0700 Subject: [PATCH] * Started work on Email->check_alert_recipients(). * Created Database->get_recipients() (from what used to be get_alert_recipients), as well as ->get_mail_servers() and ->insert_or_update_notifications(). * Renamed 'recipients -> notification_anvil_uuid' to 'notification_host_uuid'. * Started work on scancore -> check_email. Signed-off-by: Digimer --- Anvil/Tools/Database.pm | 458 ++++++++++++++++++++++++++++++++-- Anvil/Tools/Email.pm | 65 +++++ html/skins/alteeve/email.html | 2 +- share/anvil.sql | 10 +- share/words.xml | 3 + tools/scancore | 30 +++ 6 files changed, 546 insertions(+), 22 deletions(-) diff --git a/Anvil/Tools/Database.pm b/Anvil/Tools/Database.pm index 60b6d01b..8af881a5 100644 --- a/Anvil/Tools/Database.pm +++ b/Anvil/Tools/Database.pm @@ -20,13 +20,15 @@ my $THIS_FILE = "Database.pm"; # configure_pgsql # connect # disconnect -# get_alert_recipients +# get_recipients # get_host_from_uuid # get_hosts # get_hosts_info # get_job_details # get_jobs # get_local_uuid +# get_mail_servers +# get_notifications # initialize # insert_or_update_anvils # insert_or_update_bridges @@ -39,6 +41,7 @@ my $THIS_FILE = "Database.pm"; # insert_or_update_jobs # insert_or_update_mail_servers # insert_or_update_network_interfaces +# insert_or_update_notifications # insert_or_update_mac_to_ip # insert_or_update_oui # insert_or_update_recipients @@ -1379,42 +1382,82 @@ sub disconnect } -=head2 get_alert_recipients +=head2 get_recipients This returns a list of users listening to alerts for a given host, along with their alert level. -Parameters; - -=head3 host_uuid (optional, default Get->host_uuid) - -This is the host we're querying. - =cut -sub get_alert_recipients +sub get_recipients { my $self = shift; my $parameter = shift; my $anvil = $self->parent; my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3; - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Database->get_alert_recipients()" }}); + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Database->get_recipients()" }}); my $host_uuid = defined $parameter->{host_uuid} ? $parameter->{host_uuid} : $anvil->Get->host_uuid; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { host_uuid => $host_uuid, }}); - my $lowest_level = 0; + ### TODO: Read in 'notifications' my $query = " SELECT - notification_recipient_uuid, - notification_alert_level + recipient_uuid, + recipient_name, + recipient_email, + recipient_language, + recipient_units, + recipient_new_level FROM - notifications -WHERE - notification_host_uuid = ".$anvil->Database->quote($anvil->Get->host_uuid)." + recipients ;"; $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }}); + my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__}); + my $count = @{$results}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + results => $results, + count => $count, + }}); + foreach my $row (@{$results}) + { + my $recipient_uuid = $row->[0]; + my $recipient_name = $row->[1]; + my $recipient_email = $row->[2]; + my $recipient_language = $row->[3]; + my $recipient_units = $row->[4]; + my $recipient_new_level = $row->[5]; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + recipient_uuid => $recipient_uuid, + recipient_name => $recipient_name, + recipient_email => $recipient_email, + recipient_language => $recipient_language, + recipient_units => $recipient_units, + recipient_new_level => $recipient_new_level, + }}); + + # Store the data + $anvil->data->{recipients}{recipient_uuid}{$recipient_uuid}{recipient_name} = $recipient_name; + $anvil->data->{recipients}{recipient_uuid}{$recipient_uuid}{recipient_email} = $recipient_email; + $anvil->data->{recipients}{recipient_uuid}{$recipient_uuid}{recipient_language} = $recipient_language; + $anvil->data->{recipients}{recipient_uuid}{$recipient_uuid}{recipient_units} = $recipient_units; + $anvil->data->{recipients}{recipient_uuid}{$recipient_uuid}{recipient_new_level} = $recipient_new_level; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + "recipients::recipient_uuid::${recipient_uuid}}::recipient_name" => $anvil->data->{recipients}{recipient_uuid}{$recipient_uuid}{recipient_name}, + "recipients::recipient_uuid::${recipient_uuid}}::recipient_email" => $anvil->data->{recipients}{recipient_uuid}{$recipient_uuid}{recipient_email}, + "recipients::recipient_uuid::${recipient_uuid}}::recipient_language" => $anvil->data->{recipients}{recipient_uuid}{$recipient_uuid}{recipient_language}, + "recipients::recipient_uuid::${recipient_uuid}}::recipient_units" => $anvil->data->{recipients}{recipient_uuid}{$recipient_uuid}{recipient_units}, + "recipients::recipient_uuid::${recipient_uuid}}::recipient_new_level" => $anvil->data->{recipients}{recipient_uuid}{$recipient_uuid}{recipient_new_level}, + }}); + + # Make it easy to look up the mail server's UUID from the server address. + $anvil->data->{recipients}{email_to_uuid}{$recipient_email} = $recipient_uuid; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + "recipients::email_to_uuid::${recipient_email}" => $anvil->data->{recipients}{email_to_uuid}{$recipient_email}, + }}); + } + return(); } @@ -1541,9 +1584,21 @@ FROM modified_date => $modified_date, }; + # Record the data in the hash, too. + $anvil->data->{hosts}{host_uuid}{$host_uuid}{host_name} = $host_name; + $anvil->data->{hosts}{host_uuid}{$host_uuid}{host_type} = $host_type; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + "hosts::host_uuid::${host_uuid}::host_name" => $anvil->data->{hosts}{host_uuid}{$host_uuid}{host_name}, + "hosts::host_uuid::${host_uuid}::host_type" => $anvil->data->{hosts}{host_uuid}{$host_uuid}{host_type}, + }}); + # Record the host_uuid in a hash so that the name can be easily retrieved. $anvil->data->{sys}{hosts}{by_uuid}{$host_uuid} = $host_name; $anvil->data->{sys}{hosts}{by_name}{$host_name} = $host_uuid; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + "sys::hosts::by_uuid::${host_uuid}" => $anvil->data->{sys}{hosts}{by_uuid}{$host_uuid}, + "sys::hosts::by_name::${host_name}" => $anvil->data->{sys}{hosts}{by_name}{$host_name}, + }}); } my $return_count = @{$return}; @@ -1977,6 +2032,181 @@ sub get_local_uuid } +=head2 get_mail_servers + +This gets the list of configured mail servers. + +=cut +sub get_mail_servers +{ + my $self = shift; + my $parameter = shift; + my $anvil = $self->parent; + my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3; + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Database->initialize()" }}); + + my $query = " +SELECT + mail_server_uuid, + mail_server_address, + mail_server_port, + mail_server_username, + mail_server_password, + mail_server_security, + mail_server_authentication, + mail_server_helo_domain +FROM + mail_servers +;"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }}); + + my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__}); + my $count = @{$results}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + results => $results, + count => $count, + }}); + foreach my $row (@{$results}) + { + my $mail_server_uuid = $row->[0]; + my $mail_server_address = $row->[1]; + my $mail_server_port = $row->[2]; + my $mail_server_username = $row->[3]; + my $mail_server_password = $row->[4]; + my $mail_server_security = $row->[5]; + my $mail_server_authentication = $row->[6]; + my $mail_server_helo_domain = $row->[7]; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + mail_server_uuid => $mail_server_uuid, + mail_server_address => $mail_server_address, + mail_server_port => $mail_server_port, + mail_server_username => $mail_server_username, + mail_server_password => $mail_server_password, + mail_server_security => $mail_server_security, + mail_server_authentication => $mail_server_authentication, + mail_server_helo_domain => $mail_server_helo_domain, + }}); + + # Store the data + $anvil->data->{mail_servers}{mail_server}{$mail_server_uuid}{mail_server_address} = $mail_server_address; + $anvil->data->{mail_servers}{mail_server}{$mail_server_uuid}{mail_server_port} = $mail_server_port; + $anvil->data->{mail_servers}{mail_server}{$mail_server_uuid}{mail_server_username} = $mail_server_username; + $anvil->data->{mail_servers}{mail_server}{$mail_server_uuid}{mail_server_password} = $mail_server_password; + $anvil->data->{mail_servers}{mail_server}{$mail_server_uuid}{mail_server_security} = $mail_server_security; + $anvil->data->{mail_servers}{mail_server}{$mail_server_uuid}{mail_server_authentication} = $mail_server_authentication; + $anvil->data->{mail_servers}{mail_server}{$mail_server_uuid}{mail_server_helo_domain} = $mail_server_helo_domain; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + "mail_servers::mail_server::${mail_server_uuid}}::mail_server_address" => $anvil->data->{mail_servers}{mail_server}{$mail_server_uuid}{mail_server_address}, + "mail_servers::mail_server::${mail_server_uuid}}::mail_server_port" => $anvil->data->{mail_servers}{mail_server}{$mail_server_uuid}{mail_server_port}, + "mail_servers::mail_server::${mail_server_uuid}}::mail_server_username" => $anvil->data->{mail_servers}{mail_server}{$mail_server_uuid}{mail_server_username}, + "mail_servers::mail_server::${mail_server_uuid}}::mail_server_password" => $anvil->data->{mail_servers}{mail_server}{$mail_server_uuid}{mail_server_password}, + "mail_servers::mail_server::${mail_server_uuid}}::mail_server_security" => $anvil->data->{mail_servers}{mail_server}{$mail_server_uuid}{mail_server_security}, + "mail_servers::mail_server::${mail_server_uuid}}::mail_server_authentication" => $anvil->data->{mail_servers}{mail_server}{$mail_server_uuid}{mail_server_authentication}, + "mail_servers::mail_server::${mail_server_uuid}}::mail_server_helo_domain" => $anvil->data->{mail_servers}{mail_server}{$mail_server_uuid}{mail_server_helo_domain}, + }}); + + # Make it easy to look up the mail server's UUID from the server address. + $anvil->data->{mail_servers}{address_to_uuid}{$mail_server_address} = $mail_server_uuid; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + "mail_servers::address_to_uuid::${mail_server_address}" => $anvil->data->{mail_servers}{address_to_uuid}{$mail_server_address}, + }}); + + ### TODO; + # Look up variables for this server. +=cut + my $query = " +SELECT + variable_name, + variable_value +FROM + variables +WHERE + variable_source_uuid = ".$anvil->Database->quote($host_uuid)." +AND + variable_source_table = 'hosts' +;"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }}); + + my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__}); + my $count = @{$results}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + results => $results, + count => $count, + }}); + foreach my $row (@{$results}) + { + my $variable_name = $row->[0]; + my $variable_value = $row->[1]; + $anvil->data->{machine}{host_uuid}{$host_uuid}{variables}{$variable_name} = $variable_value; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + "machine::host_uuid::${host_uuid}::hosts::variables::${variable_name}" => $anvil->data->{machine}{host_uuid}{$host_uuid}{variables}{$variable_name}, + }}); + } +=cut + } + + return(0); +} + + +=head2 get_notifications + +This gets the list of configured mail servers. + +=cut +sub get_notifications +{ + my $self = shift; + my $parameter = shift; + my $anvil = $self->parent; + my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3; + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Database->initialize()" }}); + + my $query = " +SELECT + notification_uuid, + notification_recipient_uuid, + notification_host_uuid, + notification_alert_level +FROM + notifications +;"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }}); + + my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__}); + my $count = @{$results}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + results => $results, + count => $count, + }}); + foreach my $row (@{$results}) + { + my $notification_uuid = $row->[0]; + my $notification_recipient_uuid = $row->[1]; + my $notification_host_uuid = $row->[2]; + my $notification_alert_level = $row->[3]; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + notification_uuid => $notification_uuid, + notification_recipient_uuid => $notification_recipient_uuid, + notification_host_uuid => $notification_host_uuid, + notification_alert_level => $notification_alert_level, + }}); + + # Store the data + $anvil->data->{notifications}{notification_uuid}{$notification_uuid}{notification_recipient_uuid} = $notification_recipient_uuid; + $anvil->data->{notifications}{notification_uuid}{$notification_uuid}{notification_host_uuid} = $notification_host_uuid; + $anvil->data->{notifications}{notification_uuid}{$notification_uuid}{notification_alert_level} = $notification_alert_level; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + "notifications::notification_uuid::${notification_uuid}}::notification_recipient_uuid" => $anvil->data->{notifications}{mail_server}{$mail_server_uuid}{notification_recipient_uuid}, + "notifications::notification_uuid::${notification_uuid}}::notification_host_uuid" => $anvil->data->{notifications}{mail_server}{$mail_server_uuid}{notification_host_uuid}, + "notifications::notification_uuid::${notification_uuid}}::notification_alert_level" => $anvil->data->{notifications}{mail_server}{$mail_server_uuid}{notification_alert_level}, + }}); + } + + return(0); +} + + =head2 initialize This will initialize a database using a given file. @@ -5250,6 +5480,202 @@ INSERT INTO } +=head2 insert_or_update_notifications + +This updates (or inserts) a record in the C<< notifications >> table used for configuring what recipients get what alerts for a given host. + +If there is an error, an empty string is returned. + +B<< NOTE >>: The information is this table IS NOT AUTHORITATIVE! It's generally updated daily, so the information here could be stale. + +Parameters; + +=head3 notification_uuid (optional) + +If set, this is the specific entry that will be updated. + +=head3 notification_recipient_uuid (required) + +This is the C<< recipients >> -> C<< recipient_uuid >> of the alert recipient. + +=head3 notification_host_uuid (required) + +This is the C<< hosts >> -> C<< host_uuid >> of the machine generating alerts. + +=head3 notification_alert_level (required) + +This is the alert level that the recipient is interested in. Any alert of equal or higher level will be sent to the associated recipient. + +Valid values; + +=head4 0 (ignore) + +No alerts from the associated system will be sent to this recipient. + +=head4 1 (critical) + +Critical alerts. These are alerts that almost certainly indicate an issue with the system that has are likely will cause a service interruption. (ie: node was fenced, emergency shut down, etc) + +=head4 2 (warning) + +Warning alerts. These are alerts that likely require the attention of an administrator, but have not caused a service interruption. (ie: power loss/load shed, over/under voltage, fan failure, network link failure, etc) + +=head4 3 (notice) + +Notice alerts. These are generally low priority alerts that do not need attention, but might be indicators of developing problems. (ie: UPSes transfering to batteries, server migration/shut down/boot up, etc) + +=cut +sub insert_or_update_notifications +{ + my $self = shift; + my $parameter = shift; + my $anvil = $self->parent; + my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3; + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Database->insert_or_update_notifications()" }}); + + my $uuid = defined $parameter->{uuid} ? $parameter->{uuid} : ""; + my $file = defined $parameter->{file} ? $parameter->{file} : ""; + my $line = defined $parameter->{line} ? $parameter->{line} : ""; + my $notification_uuid = defined $parameter->{notification_uuid} ? $parameter->{notification_uuid} : ""; + my $notification_recipient_uuid = defined $parameter->{notification_recipient_uuid} ? $parameter->{notification_recipient_uuid} : ""; + my $notification_host_uuid = defined $parameter->{notification_host_uuid} ? $parameter->{notification_host_uuid} : ""; + my $notification_alert_level = defined $parameter->{notification_alert_level} ? $parameter->{notification_alert_level} : ""; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + notification_uuid => $notification_uuid, + notification_recipient_uuid => $notification_recipient_uuid, + notification_host_uuid => $notification_host_uuid, + notification_alert_level => $notification_alert_level, + }}); + + if (not $notification_recipient_uuid) + { + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Database->insert_or_update_notifications()", parameter => "notification_recipient_uuid" }}); + return(""); + } + if (not $notification_host_uuid) + { + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Database->insert_or_update_notifications()", parameter => "notification_host_uuid" }}); + return(""); + } + if ($notification_alert_level eq "") + { + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Database->insert_or_update_notifications()", parameter => "notification_alert_level" }}); + return(""); + } + elsif (($notification_alert_level =~ /\D/) or ($notification_alert_level < 0) or ($notification_alert_level > 3)) + { + # Not an integer + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "error_0109", variables => { notification_alert_level => $notification_alert_level }}); + return(""); + } + + # If we don't have the notification_uuid, see if we can look it up. + if (not $notification_uuid) + { + my $query = " +SELECT + notification_uuid +FROM + notifications +WHERE + notification_recipient_uuid = ".$anvil->Database->quote($notification_recipient_uuid)." +AND + notification_host_uuid = ".$anvil->Database->quote($notification_host_uuid)." +;"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }}); + + my $results = $anvil->Database->query({uuid => $uuid, query => $query, source => $file ? $file." -> ".$THIS_FILE : $THIS_FILE, line => $line ? $line." -> ".__LINE__ : __LINE__}); + my $count = @{$results}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + results => $results, + count => $count, + }}); + if ($count) + { + $notification_uuid = $results->[0]->[0]; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { notification_uuid => $notification_uuid }}); + } + } + + # Do we have an existing entry? + if ($notification_uuid) + { + # Yes, look up the previous notification_alert_level. + my $query = " +SELECT + notification_alert_level +FROM + notifications +WHERE + notification_uuid = ".$anvil->Database->quote($notification_uuid)." +;"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }}); + + # If this doesn't return anything, the passed in UUID was invalid. + + my $results = $anvil->Database->query({uuid => $uuid, query => $query, source => $file ? $file." -> ".$THIS_FILE : $THIS_FILE, line => $line ? $line." -> ".__LINE__ : __LINE__}); + my $count = @{$results}; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + results => $results, + count => $count, + }}); + if (not $count) + { + # Error out. + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "error_0110", variables => { notification_uuid => $notification_uuid }}); + return(""); + } + my $old_notification_alert_level = $results->[0]->[0]; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { old_notification_alert_level => $old_notification_alert_level }}); + + # Did the level change? + if ($notification_alert_level ne $old_notification_alert_level) + { + # UPDATE + my $query = " +UPDATE + notifications +SET + notification_alert_level = ".$anvil->Database->quote($notification_alert_level).", + modified_date = ".$anvil->Database->quote($anvil->data->{sys}{database}{timestamp})." +WHERE + notification_uuid = ".$anvil->Database->quote($notification_uuid)." +"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); + $anvil->Database->write({uuid => $uuid, query => $query, source => $file ? $file." -> ".$THIS_FILE : $THIS_FILE, line => $line ? $line." -> ".__LINE__ : __LINE__}); + } + } + else + { + # Nope, INSERT + $notification_uuid = $anvil->Get->uuid; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { notification_uuid => $notification_uuid }}); + + my $query = " +INSERT INTO + notifications +( + notification_uuid, + notification_recipient_uuid, + notification_host_uuid, + notification_alert_level, + modified_date +) VALUES ( + ".$anvil->Database->quote($notification_uuid).", + ".$anvil->Database->quote($notification_recipient_uuid).", + ".$anvil->Database->quote($notification_host_uuid).", + ".$anvil->Database->quote($notification_alert_level).", + ".$anvil->Database->quote($anvil->data->{sys}{database}{timestamp})." +); +"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }}); + $anvil->Database->write({uuid => $uuid, query => $query, uuid => $uuid, source => $file ? $file." -> ".$THIS_FILE : $THIS_FILE, line => $line ? $line." -> ".__LINE__ : __LINE__}); + } + + return($notification_uuid) +} + + =head2 insert_or_update_mac_to_ip This updates (or inserts) a record in the C<< mac_to_ip >> table used for tracking what MAC addresses have what IP addresses. diff --git a/Anvil/Tools/Email.pm b/Anvil/Tools/Email.pm index 88d30dec..9e082616 100755 --- a/Anvil/Tools/Email.pm +++ b/Anvil/Tools/Email.pm @@ -13,6 +13,8 @@ our $VERSION = "3.0.0"; my $THIS_FILE = "Email.pm"; ### Methods; +# check_alert_recipients +# check_postfix =pod @@ -73,6 +75,69 @@ sub parent # Public methods # ############################################################################################################# + +=head2 check_alert_recipients + +This loops through all known hosts and all known C<< recipients >> and any C<< hosts >> that don't have a corresponding entry in C<< notifications >>. When found, an entry is created using the recipient's new level. + +=cut +sub check_alert_recipients +{ + my $self = shift; + my $parameter = shift; + my $anvil = $self->parent; + my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3; + + # Get a list of all recipients. + $anvil->Database->get_recipients({debug => 2}); + + # Get a list of hosts. + $anvil->Database->get_hosts({debug => 2}); + + # Get the notification list + $anvil->Database->get_notifications({debug => 2}); + + # Now loop! + foreach my $host_uuid (keys %{$anvil->data->{hosts}{host_uuid}}) + { + my $host_name = $anvil->data->{hosts}{host_uuid}{$host_uuid}{host_name}; + + # Loop through recipients. + foreach my $recipient_uuid (keys %{$anvil->data->{recipients}{recipient_uuid}}) + { + my $recipient_new_level = $anvil->data->{recipients}{recipient_uuid}{$recipient_uuid}{recipient_new_level}; + + # Now see if there's already an entry in notifications. + my $exists = 0; + foreach my $notification_uuid (keys %{$anvil->data->{notifications}{notification_uuid}}) + { + my $notification_recipient_uuid = $anvil->data->{notifications}{notification_uuid}{$notification_uuid}{notification_recipient_uuid}; + my $notification_host_uuid = $anvil->data->{notifications}{notification_uuid}{$notification_uuid}{notification_host_uuid}; + if (($host_uuid eq $notification_host_uuid) && ($recipient_uuid eq $notification_recipient_uuid)) + { + $exists = 1; + last; + } + } + + # Did we find an entry? + if (not $exists) + { + # Nope, save it. + my ($notification_uuid) = $anvil->Database->insert_or_update_notifications({ + debug => 2, + notification_recipient_uuid => $recipient_uuid, + notification_host_uuid => $host_uuid, + notification_alert_level => $recipient_new_level, + }); + } + } + } + + return(0); +} + + =head2 check_postfix This method checks the current postfix server configuration to see if it needs to be updated, then checks to see if the local C<< postfix >> daemin is enabled and started. diff --git a/html/skins/alteeve/email.html b/html/skins/alteeve/email.html index 98eaa824..7c5cdfe1 100644 --- a/html/skins/alteeve/email.html +++ b/html/skins/alteeve/email.html @@ -466,7 +466,7 @@ - #!string!striker_0187!# + #!string!striker_0201!# diff --git a/share/anvil.sql b/share/anvil.sql index b1fd0c60..0c1faa83 100644 --- a/share/anvil.sql +++ b/share/anvil.sql @@ -503,11 +503,11 @@ CREATE TRIGGER trigger_recipients CREATE TABLE notifications ( notification_uuid uuid not null primary key, notification_recipient_uuid uuid not null, -- The recipient we're linking. - notification_anvil_uuid uuid not null, -- The Anvil! system we're linking. + notification_host_uuid uuid not null, -- This host_uuid of the referenced machine notification_alert_level integer not null, -- This is the alert level (at or above) that this user wants alerts from. modified_date timestamp with time zone not null, - FOREIGN KEY(notification_anvil_uuid) REFERENCES anvils(anvil_uuid), + FOREIGN KEY(notification_host_uuid) REFERENCES anvils(anvil_uuid), FOREIGN KEY(notification_recipient_uuid) REFERENCES recipients(recipient_uuid) ); ALTER TABLE notifications OWNER TO admin; @@ -516,7 +516,7 @@ CREATE TABLE history.notifications ( history_id bigserial, notification_uuid uuid, notification_recipient_uuid uuid, - notification_anvil_uuid uuid, + notification_host_uuid uuid, notification_alert_level integer, modified_date timestamp with time zone not null ); @@ -531,13 +531,13 @@ BEGIN INSERT INTO history.notifications (notification_uuid, notification_recipient_uuid, - notification_anvil_uuid, + notification_host_uuid, notification_alert_level, modified_date) VALUES (history_notifications.notification_uuid, history_notifications.notification_recipient_uuid, - history_notifications.notification_anvil_uuid, + history_notifications.notification_host_uuid, history_notifications.notification_alert_level, history_notifications.modified_date); RETURN NULL; diff --git a/share/words.xml b/share/words.xml index 53053eac..56d5f175 100644 --- a/share/words.xml +++ b/share/words.xml @@ -1061,6 +1061,7 @@ If you are comfortable that the target has changed for a known reason, you can s The language the user will receive alerts in. Does the user want imperial or metric units? The alert level used for new (and existing) Anvil! systems. + Existing alert recipients: #!variable!number!#/sec @@ -1363,6 +1364,8 @@ Failed to generate an RSA public key for the user: [#!variable!user!#]. The outp find_matches() was given the hash key: [#!variable!key!#], but it does not reference a hash. Are any IPs associated with this target?]]> Failed to reconnect after reconfiguring the network, exiting. The 'recipient_new_level': [#!variable!recipient_new_level!#] is invalid. It should be '0', '1', '2', or '3'. + The 'notification_alert_level': [#!variable!notification_alert_level!#] is invalid. It should be '0', '1', '2', or '3'. + The 'notification_uuid': [#!variable!notification_uuid!#] was not found in the database. Yes diff --git a/tools/scancore b/tools/scancore index b8e83e25..16a66ae7 100755 --- a/tools/scancore +++ b/tools/scancore @@ -234,6 +234,36 @@ sub prepare_for_run $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0132"}); # TODO: Check/configure the mail server. + check_email($anvil); + + return(0); +} + +sub check_email +{ + my ($anvil) = @_; + + # We check to see if there are any emails in the queue. If we see queued emails for more than five + # minutes, and a second mail server is configured, we'll automatically reconfigure for the next + # known server. + + # Before we do anything, we want to make sure all recipients have been registered against all hosts. + $anvil->Email->check_alert_recipients(); + + ### TODO: + # If not configured look in variables for 'mail_server::last_used::'. The first one + # that doesn't have an existing variable will be used. If all known mail servers have variables, the + # oldest is used. + # + # If configured/running, the number of messages in queue is checked. If '0', + # 'mail_server::queue_empty' is updated with the current time. If 1 or more, the time since the queue + # was last 0 is checked. If > 300, the mail server is reconfigured to use the mail server with the + # oldest 'mail_server::last_used::' time. + # + # In any case where the mail server is configured, the server that is used has their + # 'mail_server::last_used::' variable set to the current time stamp. + + # Is the postfix daemon running? return(0); }