* Created Database->insert_or_update_recipients() (and did general cleanup of the database module).

* Started work on Striker's notification recipient management page. Cleaned up the variable names in the mail_server management function.
* Added recipients -> recipient_units column to the sql schema.

Signed-off-by: Digimer <digimer@alteeve.ca>
main
Digimer 5 years ago
parent 98211e1228
commit eb0481bcb0
  1. 381
      Anvil/Tools/Database.pm
  2. 359
      cgi-bin/striker
  3. 55
      html/skins/alteeve/email.html
  4. 10
      share/anvil.sql
  5. 3
      share/words.xml
  6. 18
      tools/scancore.README

@ -28,15 +28,20 @@ my $THIS_FILE = "Database.pm";
# get_jobs # get_jobs
# get_local_uuid # get_local_uuid
# initialize # initialize
# insert_or_update_anvils
# insert_or_update_bridges # insert_or_update_bridges
# insert_or_update_bonds # insert_or_update_bonds
# insert_or_update_file_locations # insert_or_update_file_locations
# insert_or_update_files # insert_or_update_files
# insert_or_update_host_keys
# insert_or_update_hosts # insert_or_update_hosts
# insert_or_update_ip_addresses # insert_or_update_ip_addresses
# insert_or_update_jobs # insert_or_update_jobs
# insert_or_update_mail_servers
# insert_or_update_network_interfaces # insert_or_update_network_interfaces
# insert_or_update_mac_to_ip
# insert_or_update_oui # insert_or_update_oui
# insert_or_update_recipients
# insert_or_update_sessions # insert_or_update_sessions
# insert_or_update_states # insert_or_update_states
# insert_or_update_users # insert_or_update_users
@ -273,6 +278,7 @@ sub archive_database
return(0); return(0);
} }
=head2 check_lock_age =head2 check_lock_age
This checks to see if 'sys::database::local_lock_active' is set. If it is, its age is checked and if the age is >50% of sys::database::locking_reap_age, it will renew the lock. This checks to see if 'sys::database::local_lock_active' is set. If it is, its age is checked and if the age is >50% of sys::database::locking_reap_age, it will renew the lock.
@ -332,6 +338,7 @@ sub check_lock_age
return($renewed); return($renewed);
} }
=head2 configure_pgsql =head2 configure_pgsql
This configures the local database server. Specifically, it checks to make sure the daemon is running and starts it if not. It also checks the C<< pg_hba.conf >> configuration to make sure it is set properly to listen on this machine's IP addresses and interfaces. This configures the local database server. Specifically, it checks to make sure the daemon is running and starts it if not. It also checks the C<< pg_hba.conf >> configuration to make sure it is set properly to listen on this machine's IP addresses and interfaces.
@ -689,6 +696,7 @@ sub configure_pgsql
return(0); return(0);
} }
=head2 connect_to_databases =head2 connect_to_databases
This method tries to connect to all databases it knows of. To define databases for a machine to connect to, load a configuration file with the following parameters; This method tries to connect to all databases it knows of. To define databases for a machine to connect to, load a configuration file with the following parameters;
@ -1323,6 +1331,7 @@ sub connect
return($anvil->data->{sys}{database}{connections}); return($anvil->data->{sys}{database}{connections});
} }
=head2 =head2
This cleanly closes any open file handles to all connected databases and clears some internal database related variables. This cleanly closes any open file handles to all connected databases and clears some internal database related variables.
@ -1369,6 +1378,7 @@ sub disconnect
return(0); return(0);
} }
=head2 get_alert_recipients =head2 get_alert_recipients
This returns a list of users listening to alerts for a given host, along with their alert level. This returns a list of users listening to alerts for a given host, along with their alert level.
@ -1408,6 +1418,7 @@ WHERE
return(); return();
} }
=head2 get_host_from_uuid =head2 get_host_from_uuid
This takes a host UUID and returns the host's name. If there is a problem, or if the host UUID isn't found, an empty string is returned. This takes a host UUID and returns the host's name. If there is a problem, or if the host UUID isn't found, an empty string is returned.
@ -1470,6 +1481,7 @@ sub get_host_from_uuid
return($host_name); return($host_name);
} }
=head2 get_hosts =head2 get_hosts
Get a list of hosts from the c<< hosts >> table, returned as an array of hash references. Get a list of hosts from the c<< hosts >> table, returned as an array of hash references.
@ -1539,6 +1551,7 @@ FROM
return($return); return($return);
} }
=head2 get_hosts_info =head2 get_hosts_info
This gathers up all the known information about all known hosts. This gathers up all the known information about all known hosts.
@ -1627,6 +1640,7 @@ AND
return(0); return(0);
} }
=head2 get_job_details =head2 get_job_details
This gets the details for a given job. If the job is found, a hash reference is returned containing the tables that were read in. This gets the details for a given job. If the job is found, a hash reference is returned containing the tables that were read in.
@ -1744,6 +1758,7 @@ WHERE
return($return); return($return);
} }
=head2 get_jobs =head2 get_jobs
This gets the list of running jobs. This gets the list of running jobs.
@ -1886,6 +1901,7 @@ WHERE
return($return); return($return);
} }
=head2 get_local_uuid =head2 get_local_uuid
This returns the database UUID (usually the host's UUID) from C<< anvil.conf >> based on matching the C<< database::<uuid>::host >> to the local machine's host name or one of the active IP addresses on the host. This returns the database UUID (usually the host's UUID) from C<< anvil.conf >> based on matching the C<< database::<uuid>::host >> to the local machine's host name or one of the active IP addresses on the host.
@ -1960,6 +1976,7 @@ sub get_local_uuid
return($local_uuid); return($local_uuid);
} }
=head2 initialize =head2 initialize
This will initialize a database using a given file. This will initialize a database using a given file.
@ -2078,6 +2095,14 @@ sub initialize
return($success); return($success);
}; };
=head2 insert_or_update_anvils
=cut
sub insert_or_update_anvils
{
}
=head2 insert_or_update_bridges =head2 insert_or_update_bridges
This updates (or inserts) a record in the 'bridges' table. The C<< bridge_uuid >> referencing the database row will be returned. This updates (or inserts) a record in the 'bridges' table. The C<< bridge_uuid >> referencing the database row will be returned.
@ -2098,35 +2123,35 @@ If set, this is the file name logged as the source of any INSERTs or UPDATEs.
If set, this is the file line number logged as the source of any INSERTs or UPDATEs. If set, this is the file line number logged as the source of any INSERTs or UPDATEs.
=head2 bridge_uuid (optional) =head3 bridge_uuid (optional)
If not passed, a check will be made to see if an existing entry is found for C<< bridge_name >>. If found, that entry will be updated. If not found, a new record will be inserted. If not passed, a check will be made to see if an existing entry is found for C<< bridge_name >>. If found, that entry will be updated. If not found, a new record will be inserted.
=head2 bridge_host_uuid (optional) =head3 bridge_host_uuid (optional)
This is the host that the IP address is on. If not passed, the local C<< sys::host_uuid >> will be used (indicating it is a local IP address). This is the host that the IP address is on. If not passed, the local C<< sys::host_uuid >> will be used (indicating it is a local IP address).
=head2 bridge_name (required) =head3 bridge_name (required)
This is the bridge's device name. This is the bridge's device name.
=head2 bridge_id (optional) =head3 bridge_id (optional)
This is the unique identifier for the bridge. This is the unique identifier for the bridge.
=head2 bridge_mac_address (optional) =head3 bridge_mac_address (optional)
This is the MAC address of the bridge. This is the MAC address of the bridge.
=head2 bridge_mto (optional) =head3 bridge_mto (optional)
This is the MTU (maximum transfer unit, size in bytes) of the bridge. This is the MTU (maximum transfer unit, size in bytes) of the bridge.
=head2 bridge_stp_enabled (optional) =head3 bridge_stp_enabled (optional)
This is set to C<< yes >> or C<< no >> to indicate if spanning tree protocol is enabled on the switch. This is set to C<< yes >> or C<< no >> to indicate if spanning tree protocol is enabled on the switch.
=head2 delete (optional, default '0') =head3 delete (optional, default '0')
If set to C<< 1 >>, C<< bridge_id >> will be set to C<< DELETED >>, indicating that the bridge has been deleted from the system. If set, only C<< bridge_uuid >> or C<< bridge_name >> is needed. If set to C<< 1 >>, C<< bridge_id >> will be set to C<< DELETED >>, indicating that the bridge has been deleted from the system. If set, only C<< bridge_uuid >> or C<< bridge_name >> is needed.
@ -2376,6 +2401,7 @@ WHERE
return($bridge_uuid); return($bridge_uuid);
} }
=head2 insert_or_update_bonds =head2 insert_or_update_bonds
This updates (or inserts) a record in the 'bonds' table. The C<< bond_uuid >> referencing the database row will be returned. This updates (or inserts) a record in the 'bonds' table. The C<< bond_uuid >> referencing the database row will be returned.
@ -2778,6 +2804,7 @@ WHERE
return($bond_uuid); return($bond_uuid);
} }
=head2 insert_or_update_file_locations =head2 insert_or_update_file_locations
This updates (or inserts) a record in the 'file_locations' table. The C<< file_location_uuid >> referencing the database row will be returned. This updates (or inserts) a record in the 'file_locations' table. The C<< file_location_uuid >> referencing the database row will be returned.
@ -2979,6 +3006,7 @@ WHERE
return($file_location_uuid); return($file_location_uuid);
} }
=head2 insert_or_update_files =head2 insert_or_update_files
This updates (or inserts) a record in the 'files' table. The C<< file_uuid >> referencing the database row will be returned. This updates (or inserts) a record in the 'files' table. The C<< file_uuid >> referencing the database row will be returned.
@ -3249,6 +3277,7 @@ WHERE
return($file_uuid); return($file_uuid);
} }
=head2 insert_or_update_host_keys =head2 insert_or_update_host_keys
This updates (or inserts) a record in the 'host_keys' table. The C<< host_key_uuid >> UUID will be returned. This updates (or inserts) a record in the 'host_keys' table. The C<< host_key_uuid >> UUID will be returned.
@ -3445,6 +3474,7 @@ WHERE
return($host_key_uuid); return($host_key_uuid);
} }
=head2 insert_or_update_hosts =head2 insert_or_update_hosts
This updates (or inserts) a record in the 'hosts' table. The C<< host_uuid >> UUID will be returned. This updates (or inserts) a record in the 'hosts' table. The C<< host_uuid >> UUID will be returned.
@ -3608,6 +3638,7 @@ WHERE
return($host_uuid); return($host_uuid);
} }
=head2 insert_or_update_ip_addresses =head2 insert_or_update_ip_addresses
This updates (or inserts) a record in the 'ip_addresses' table. The C<< ip_address_uuid >> referencing the database row will be returned. This updates (or inserts) a record in the 'ip_addresses' table. The C<< ip_address_uuid >> referencing the database row will be returned.
@ -3632,43 +3663,43 @@ If set, this is the file line number logged as the source of any INSERTs or UPDA
When set to C<< 1 >>, the C<< ip_address_note >> is set to C<< DELETED >>, and nothing else is changed. If set, only C<< ip_address_uuid >> or C<< ip_address_address >> are required. When set to C<< 1 >>, the C<< ip_address_note >> is set to C<< DELETED >>, and nothing else is changed. If set, only C<< ip_address_uuid >> or C<< ip_address_address >> are required.
=head2 ip_address_address (required) =head3 ip_address_address (required)
This is the acual IP address. It's tested with IPv4 addresses in dotted-decimal format, though it can also store IPv6 addresses. If this is set to C<< 0 >>, it will be treated as deleted and will be ignored (unless a new IP is assigned to the same interface in the future). This is the acual IP address. It's tested with IPv4 addresses in dotted-decimal format, though it can also store IPv6 addresses. If this is set to C<< 0 >>, it will be treated as deleted and will be ignored (unless a new IP is assigned to the same interface in the future).
=head2 ip_address_uuid (optional) =head3 ip_address_uuid (optional)
If not passed, a check will be made to see if an existing entry is found for C<< ip_address_address >>. If found, that entry will be updated. If not found, a new record will be inserted. If not passed, a check will be made to see if an existing entry is found for C<< ip_address_address >>. If found, that entry will be updated. If not found, a new record will be inserted.
=head2 ip_address_host_uuid (optional) =head3 ip_address_host_uuid (optional)
This is the host that the IP address is on. If not passed, the local C<< sys::host_uuid >> will be used (indicating it is a local IP address). This is the host that the IP address is on. If not passed, the local C<< sys::host_uuid >> will be used (indicating it is a local IP address).
=head2 ip_address_on_type (required) =head3 ip_address_on_type (required)
This indicates what type of interface the IP address is on. This must be either C<< interface >>, C<< bond >> or C<< bridge >>. This indicates what type of interface the IP address is on. This must be either C<< interface >>, C<< bond >> or C<< bridge >>.
=head2 ip_address_on_uuid (required) =head3 ip_address_on_uuid (required)
This is the UUID of the bridge, bond or interface that this IP address is on. This is the UUID of the bridge, bond or interface that this IP address is on.
=head2 ip_address_subnet_mask (required) =head3 ip_address_subnet_mask (required)
This is the subnet mask for the IP address. It is tested with IPv4 in dotted decimal format, though it can also store IPv6 format subnet masks. This is the subnet mask for the IP address. It is tested with IPv4 in dotted decimal format, though it can also store IPv6 format subnet masks.
=head2 ip_address_default_gateway (optional, default '0') =head3 ip_address_default_gateway (optional, default '0')
If a gateway address is set, and this is set to C<< 1 >>, the associated interface will be the default gateway for the host. If a gateway address is set, and this is set to C<< 1 >>, the associated interface will be the default gateway for the host.
=head2 ip_address_gateway (optional) =head3 ip_address_gateway (optional)
This is an option gateway IP address for this interface. This is an option gateway IP address for this interface.
=head2 ip_address_dns (optional) =head3 ip_address_dns (optional)
This is a comma-separated list of DNS servers used to resolve host names. This is recorded, but ignored unless C<< ip_address_gateway >> is set. Example format is C<< 8.8.8.8 >> or C<< 8.8.8.8,4.4.4.4 >>. This is a comma-separated list of DNS servers used to resolve host names. This is recorded, but ignored unless C<< ip_address_gateway >> is set. Example format is C<< 8.8.8.8 >> or C<< 8.8.8.8,4.4.4.4 >>.
=head2 ip_address_note (optional) =head3 ip_address_note (optional)
This can be set to C<< DELETED >> when the IP address is no longer in use. This can be set to C<< DELETED >> when the IP address is no longer in use.
@ -4765,6 +4796,7 @@ WHERE
return($mail_server_uuid); return($mail_server_uuid);
} }
=head2 insert_or_update_network_interfaces =head2 insert_or_update_network_interfaces
This updates (or inserts) a record in the 'interfaces' table. This table is used to store physical network interface information. This updates (or inserts) a record in the 'interfaces' table. This table is used to store physical network interface information.
@ -5177,6 +5209,7 @@ INSERT INTO
return($network_interface_uuid); return($network_interface_uuid);
} }
=head2 insert_or_update_mac_to_ip =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. This updates (or inserts) a record in the C<< mac_to_ip >> table used for tracking what MAC addresses have what IP addresses.
@ -5393,6 +5426,7 @@ INSERT INTO
return($mac_to_ip_uuid); return($mac_to_ip_uuid);
} }
=head2 insert_or_update_oui =head2 insert_or_update_oui
This updates (or inserts) a record in the C<< oui >> (Organizationally Unique Identifier) table used for converting network MAC addresses to the company that owns it. The C<< oui_uuid >> referencing the database row will be returned. This updates (or inserts) a record in the C<< oui >> (Organizationally Unique Identifier) table used for converting network MAC addresses to the company that owns it. The C<< oui_uuid >> referencing the database row will be returned.
@ -5583,6 +5617,300 @@ INSERT INTO
return($oui_uuid); return($oui_uuid);
} }
=head2 insert_or_update_recipients
This updates (or inserts) a record in the 'recipients' table. The C<< recipient_uuid >> referencing the database row will be returned.
If there is an error, an empty string is returned.
Parameters;
=head3 delete (optional, default '0')
If set to C<< 1 >>, the associated mail server will be deleted. Specifically, the C<< recipient_name >> is set to C<< DELETED >>.
When this is set, either C<< recipient_uuid >> or C<< recipient_email >> is required.
=head3 uuid (optional)
If set, only the corresponding database will be written to.
=head3 file (optional)
If set, this is the file name logged as the source of any INSERTs or UPDATEs.
=head3 line (optional)
If set, this is the file line number logged as the source of any INSERTs or UPDATEs.
=head3 recipient_email (required)
This is the email address of the recipient. This is where alerts are sent to and as such, must be a valid email address.
=head3 recipient_language (optional, default 'en_CA')
This is the language that alert emails are crafted using for this recipient. This is the ISO language code, as set in the C<< <language name="en_CA" ... > >> element of the C<< words.xml >> file. If the preferred language is not available, the system language will be used in stead.
=head3 recipient_name (required)
This is the name of the recipient, and is used when crafting the email body and reply-to lists.
=head3 recipient_new_level (optional, default '2')
When adding a new Anvil! to the system, the recipient will automatically start monitoring the new Anvil! using this alert level. This can be set to C<< 0 >> to prevent auto-monitoring of new systems.
Valid values;
=head4 0 (ignore)
None, ignore new systems
=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)
=head3 recipient_units (optional, default 'metric')
This can be set to 'imperial' if the user wants to receive values in imperial units. Currently, this causes temperatures to be returned in C<< °F >> instead of C<< °C >>.
=head3 recipient_uuid (optional)
If set, this is the UUID that will be used to update a record in the database. If not set, it will be searched for by looking for a matching C<< recipient_email >>.
=cut
sub insert_or_update_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->insert_or_update_recipients()" }});
my $delete = defined $parameter->{'delete'} ? $parameter->{'delete'} : 0;
my $uuid = defined $parameter->{uuid} ? $parameter->{uuid} : "";
my $file = defined $parameter->{file} ? $parameter->{file} : "";
my $line = defined $parameter->{line} ? $parameter->{line} : "";
my $recipient_email = defined $parameter->{recipient_email} ? $parameter->{recipient_email} : "";
my $recipient_language = defined $parameter->{recipient_language} ? $parameter->{recipient_language} : "en_CA";
my $recipient_name = defined $parameter->{recipient_name} ? $parameter->{recipient_name} : "";
my $recipient_new_level = defined $parameter->{recipient_new_level} ? $parameter->{recipient_new_level} : "2";
my $recipient_units = defined $parameter->{recipient_units} ? $parameter->{recipient_units} : "metric";
my $recipient_uuid = defined $parameter->{recipient_uuid} ? $parameter->{recipient_uuid} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
'delete' => $delete,
uuid => $uuid,
file => $file,
line => $line,
recipient_email => $recipient_email,
recipient_language => $recipient_language,
recipient_name => $recipient_name,
recipient_new_level => $recipient_new_level,
recipient_units => $recipient_units,
recipient_uuid => $recipient_uuid,
}});
# Did we get a mail server name?
if ((not $recipient_email) && (not $recipient_uuid))
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Database->insert_or_update_recipients()", parameter => "recipient_email" }});
return("");
}
# Make sure the recipient_new_level is 0, 1, 2 or 3
if (($recipient_new_level ne "0") && ($recipient_new_level ne "1") && ($recipient_new_level ne "3") && ($recipient_new_level ne "3"))
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "error_0108", variables => { recipient_new_level => $recipient_new_level }});
return("");
}
if (not $recipient_uuid)
{
# Can we find it using the mail server address?
my $query = "
SELECT
recipient_uuid
FROM
recipients
WHERE
recipient_email = ".$anvil->Database->quote($recipient_email)."
;";
$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)
{
$recipient_uuid = $results->[0]->[0];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { recipient_uuid => $recipient_uuid }});
}
}
if ($delete)
{
if (not $recipient_uuid)
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Database->insert_or_update_recipients()", parameter => "recipient_uuid" }});
return("");
}
else
{
# Delete it
my $query = "SELECT recipient_name FROM recipients WHERE recipient_uuid = ".$anvil->Database->quote($recipient_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)
{
my $old_recipient_name = $results->[0]->[0];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { old_recipient_name => $old_recipient_name }});
if ($old_recipient_name ne "DELETED")
{
my $query = "UPDATE recipients SET recipient_name = 'DELETED' WHERE recipient_uuid = ".$anvil->Database->quote($recipient_uuid).";";
$anvil->Database->write({uuid => $uuid, query => $query, source => $file ? $file." -> ".$THIS_FILE : $THIS_FILE, line => $line ? $line." -> ".__LINE__ : __LINE__});
}
return($recipient_uuid);
}
else
{
# Not found.
return("");
}
}
}
# If we're here and we still don't have a recipient name, there's a problem.
if (not $recipient_name)
{
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0020", variables => { method => "Database->insert_or_update_recipients()", parameter => "recipient_name" }});
return("");
}
# If I still don't have an recipient_uuid, we're INSERT'ing .
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { recipient_uuid => $recipient_uuid }});
if (not $recipient_uuid)
{
# INSERT
$recipient_uuid = $anvil->Get->uuid();
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { recipient_uuid => $recipient_uuid }});
my $query = "
INSERT INTO
recipients
(
recipient_uuid,
recipient_email,
recipient_language,
recipient_name,
recipient_new_level,
recipient_units,
modified_date
) VALUES (
".$anvil->Database->quote($recipient_uuid).",
".$anvil->Database->quote($recipient_email).",
".$anvil->Database->quote($recipient_language).",
".$anvil->Database->quote($recipient_name).",
".$anvil->Database->quote($recipient_new_level).",
".$anvil->Database->quote($recipient_units).",
".$anvil->Database->quote($anvil->data->{sys}{database}{timestamp})."
);
";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }});
$anvil->Database->write({uuid => $uuid, query => $query, source => $file ? $file." -> ".$THIS_FILE : $THIS_FILE, line => $line ? $line." -> ".__LINE__ : __LINE__});
}
else
{
# Query the rest of the values and see if anything changed.
my $query = "
SELECT
recipient_email,
recipient_language,
recipient_name,
recipient_new_level,
recipient_units
FROM
recipients
WHERE
recipient_uuid = ".$anvil->Database->quote($recipient_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 (not $count)
{
# I have a recipient_uuid but no matching record. Probably an error.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "log_0216", variables => { uuid_name => "recipient_uuid", uuid => $recipient_uuid }});
return("");
}
foreach my $row (@{$results})
{
my $old_recipient_email = $row->[0];
my $old_recipient_language = $row->[1];
my $old_recipient_name = $row->[2];
my $old_recipient_new_level = $row->[3];
my $old_recipient_units = $row->[4];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
old_recipient_email => $old_recipient_email,
old_recipient_language => $old_recipient_language,
old_recipient_name => $old_recipient_name,
old_recipient_new_level => $old_recipient_new_level,
old_recipient_units => $old_recipient_units,
}});
# Anything change?
if (($old_recipient_email ne $recipient_email) or
($old_recipient_language ne $recipient_language) or
($old_recipient_name ne $recipient_name) or
($old_recipient_new_level ne $recipient_new_level) or
($old_recipient_units ne $recipient_units))
{
# Something changed, save.
my $query = "
UPDATE
recipients
SET
recipient_email = ".$anvil->Database->quote($recipient_email).",
recipient_language = ".$anvil->Database->quote($recipient_language).",
recipient_name = ".$anvil->Database->quote($recipient_name).",
recipient_new_level = ".$anvil->Database->quote($recipient_new_level).",
recipient_units = ".$anvil->Database->quote($recipient_units).",
modified_date = ".$anvil->Database->quote($anvil->data->{sys}{database}{timestamp})."
WHERE
recipient_uuid = ".$anvil->Database->quote($recipient_uuid)."
";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }});
$anvil->Database->write({uuid => $uuid, query => $query, source => $file ? $file." -> ".$THIS_FILE : $THIS_FILE, line => $line ? $line." -> ".__LINE__ : __LINE__});
}
}
}
return($recipient_uuid);
}
=head2 insert_or_update_sessions =head2 insert_or_update_sessions
This updates (or inserts) a record in the 'sessions' table. The C<< session_uuid >> referencing the database row will be returned. This updates (or inserts) a record in the 'sessions' table. The C<< session_uuid >> referencing the database row will be returned.
@ -5773,6 +6101,7 @@ INSERT INTO
return($session_uuid); return($session_uuid);
} }
=head2 insert_or_update_states =head2 insert_or_update_states
This updates (or inserts) a record in the 'states' table. The C<< state_uuid >> referencing the database row will be returned. This updates (or inserts) a record in the 'states' table. The C<< state_uuid >> referencing the database row will be returned.
@ -5999,6 +6328,7 @@ WHERE
return($state_uuid); return($state_uuid);
} }
=head2 insert_or_update_users =head2 insert_or_update_users
This updates (or inserts) a record in the 'users' table. The C<< user_uuid >> referencing the database row will be returned. This updates (or inserts) a record in the 'users' table. The C<< user_uuid >> referencing the database row will be returned.
@ -6330,6 +6660,7 @@ WHERE
return($user_uuid); return($user_uuid);
} }
=head2 insert_or_update_variables =head2 insert_or_update_variables
This updates (or inserts) a record in the 'variables' table. The C<< state_uuid >> referencing the database row will be returned. This updates (or inserts) a record in the 'variables' table. The C<< state_uuid >> referencing the database row will be returned.
@ -6672,6 +7003,7 @@ WHERE
return($variable_uuid); return($variable_uuid);
} }
=head2 lock_file =head2 lock_file
This reads, sets or updates the database lock file timestamp. This reads, sets or updates the database lock file timestamp.
@ -6721,6 +7053,7 @@ sub lock_file
return($lock_time); return($lock_time);
} }
=head2 locking =head2 locking
This handles requesting, releasing and waiting on locks. This handles requesting, releasing and waiting on locks.
@ -6958,6 +7291,7 @@ sub locking
return($set); return($set);
} }
=head2 manage_anvil_conf =head2 manage_anvil_conf
This adds, removes or updates a database entry in a machine's anvil.conf file. This returns C<< 0 >> on success, C<< 1 >> if there was a problem. This adds, removes or updates a database entry in a machine's anvil.conf file. This returns C<< 0 >> on success, C<< 1 >> if there was a problem.
@ -7405,6 +7739,7 @@ sub manage_anvil_conf
return(0); return(0);
} }
=head2 mark_active =head2 mark_active
This sets or clears that the caller is about to work on the database This sets or clears that the caller is about to work on the database
@ -7449,6 +7784,7 @@ sub mark_active
return($state_uuid); return($state_uuid);
} }
=head2 query =head2 query
This performs a query and returns an array reference of array references (from C<< DBO->fetchall_arrayref >>). The first array contains all the returned rows and each row is an array reference of columns in that row. This performs a query and returns an array reference of array references (from C<< DBO->fetchall_arrayref >>). The first array contains all the returned rows and each row is an array reference of columns in that row.
@ -7597,6 +7933,7 @@ sub query
return($DBreq->fetchall_arrayref()); return($DBreq->fetchall_arrayref());
} }
=head2 quote =head2 quote
This quotes a string for safe use in database queries/writes. It operates exactly as C<< DBI >>'s C<< quote >> method. This method is simply a wrapper that uses the C<< DBI >> handle set as the currently active read database. This quotes a string for safe use in database queries/writes. It operates exactly as C<< DBI >>'s C<< quote >> method. This method is simply a wrapper that uses the C<< DBI >> handle set as the currently active read database.
@ -7623,6 +7960,7 @@ sub quote
return($quoted); return($quoted);
} }
=head2 read =head2 read
This method returns the active database handle used for reading. When C<< Database->connect() >> is called, it tries to find the local database (if available) and use that for reads. If there is no local database, then the first database successfully connected to is used instead. This method returns the active database handle used for reading. When C<< Database->connect() >> is called, it tries to find the local database (if available) and use that for reads. If there is no local database, then the first database successfully connected to is used instead.
@ -7668,6 +8006,7 @@ sub read
return($anvil->data->{sys}{database}{use_handle}); return($anvil->data->{sys}{database}{use_handle});
} }
=head2 read_variable =head2 read_variable
This reads a variable from the C<< variables >> table. Be sure to only use the reply from here to override what might have been set in a config file. This method always returns the data from the database itself. This reads a variable from the C<< variables >> table. Be sure to only use the reply from here to override what might have been set in a config file. This method always returns the data from the database itself.
@ -7772,6 +8111,7 @@ AND
return($variable_value, $variable_uuid, $modified_date); return($variable_value, $variable_uuid, $modified_date);
} }
=head2 refresh_timestamp =head2 refresh_timestamp
This refreshes C<< sys::database::timestamp >>. It returns C<< sys::database::timestamp >> as well. This refreshes C<< sys::database::timestamp >>. It returns C<< sys::database::timestamp >> as well.
@ -7796,6 +8136,7 @@ sub refresh_timestamp
return($anvil->data->{sys}{database}{timestamp}); return($anvil->data->{sys}{database}{timestamp});
} }
=head2 resync_databases =head2 resync_databases
This will resync the database data on this and peer database(s) if needed. It takes no arguments and will immediately return unless C<< sys::database::resync_needed >> was set. This will resync the database data on this and peer database(s) if needed. It takes no arguments and will immediately return unless C<< sys::database::resync_needed >> was set.
@ -8203,6 +8544,7 @@ sub resync_databases
return(0); return(0);
} }
=head2 write =head2 write
This records data to one or all of the databases. If an ID is passed, the query is written to one database only. Otherwise, it will be written to all DBs. This records data to one or all of the databases. If an ID is passed, the query is written to one database only. Otherwise, it will be written to all DBs.
@ -8701,6 +9043,7 @@ COPY history.".$table." (";
return(0); return(0);
} }
=head2 _find_behind_databases =head2 _find_behind_databases
This returns the most up to date database ID, the time it was last updated and an array or DB IDs that are behind. This returns the most up to date database ID, the time it was last updated and an array or DB IDs that are behind.
@ -8946,6 +9289,7 @@ ORDER BY
return(0); return(0);
} }
=head2 _mark_database_as_behind =head2 _mark_database_as_behind
This method marks that a resync is needed and, if needed, switches the database this machine will read from. This method marks that a resync is needed and, if needed, switches the database this machine will read from.
@ -8998,6 +9342,7 @@ sub _mark_database_as_behind
return(0); return(0);
} }
=head2 _test_access =head2 _test_access
This method takes a database UUID and tests the connection to it using the DBD 'ping' method. If it fails, open references to the database are removed or replaced, then an attempt to reconnect is made. This method takes a database UUID and tests the connection to it using the DBD 'ping' method. If it fails, open references to the database are removed or replaced, then an attempt to reconnect is made.

@ -376,7 +376,7 @@ sub process_email_menu
} }
elsif ($anvil->data->{cgi}{task}{value} eq "email_recipient") elsif ($anvil->data->{cgi}{task}{value} eq "email_recipient")
{ {
#process_email_recipient_page($anvil); process_email_recipient_page($anvil);
} }
else else
{ {
@ -400,50 +400,187 @@ sub process_email_menu
return(0); return(0);
} }
# # This processes mail recipients.
sub process_email_recipient_page
{
my ($anvil) = @_;
my $recipient_uuid = defined $anvil->data->{cgi}{recipient_uuid}{value} ? $anvil->data->{cgi}{recipient_uuid}{value} : "";
my $recipient_name = defined $anvil->data->{cgi}{recipient_name}{value} ? $anvil->data->{cgi}{recipient_name}{value} : "";
my $recipient_email = defined $anvil->data->{cgi}{recipient_email}{value} ? $anvil->data->{cgi}{recipient_email}{value} : "";
my $recipient_language = defined $anvil->data->{cgi}{recipient_language}{value} ? $anvil->data->{cgi}{recipient_language}{value} : "";
my $recipient_units = defined $anvil->data->{cgi}{recipient_units}{value} ? $anvil->data->{cgi}{recipient_units}{value} : "";
my $recipient_new_level = defined $anvil->data->{cgi}{recipient_new_level}{value} ? $anvil->data->{cgi}{recipient_new_level}{value} : "";
my $delete = defined $anvil->data->{cgi}{'delete'}{value} ? $anvil->data->{cgi}{'delete'}{value} : "";
my $back = defined $anvil->data->{cgi}{back}{value} ? $anvil->data->{cgi}{back}{value} : "";
my $save = defined $anvil->data->{cgi}{save}{value} ? $anvil->data->{cgi}{save}{value} : "";
my $confirm = defined $anvil->data->{cgi}{confirm}{value} ? $anvil->data->{cgi}{confirm}{value} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, 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,
back => $back,
save => $save,
'delete' => $delete,
confirm => $confirm,
}});
if ($back)
{
$save = "";
$delete = "";
$confirm = "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
save => $save,
'delete' => $delete,
confirm => $confirm,
}});
}
# If we have a recipient_uuid and we're not saving, load the information.
if (($recipient_uuid) && (not $save))
{
# Load. If we're deleting, we'll check 'mail_server_helo_domain' to see if it already was.
my $query = "
SELECT
recipient_name,
recipient_email,
recipient_language,
recipient_units,
recipient_new_level
FROM
recipients
WHERE
recipient_uuid = ".$anvil->Database->quote($recipient_uuid)."
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, 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 => 2, list => {
results => $results,
count => $count,
}});
foreach my $row (@{$results})
{
$recipient_name = $row->[0];
$recipient_email = $row->[1];
$recipient_language = $row->[2];
$recipient_units = $row->[3];
$recipient_new_level = $row->[4];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
recipient_name => $recipient_name,
recipient_email => $recipient_email,
recipient_language => $recipient_language,
recipient_units => $recipient_units,
recipient_new_level => $recipient_new_level,
}});
if ($delete)
{
# Has the user confirmed?
if ($confirm)
{
# Delete.
$anvil->Database->insert_or_update_recipientss({
debug => 2,
'delete' => 1,
recipient_uuid => $recipient_uuid,
});
# Saved successfully.
my $ok_message = $anvil->Words->string({key => "ok_0003", variables => { recipient_email => $recipient_email }});
$anvil->data->{form}{ok_message} = $anvil->Template->get({file => "main.html", name => "ok_message", variables => { ok_message => $ok_message }});
# Clear the form
$recipient_name = "";
$recipient_email = "";
$recipient_language = "";
$recipient_units = "";
$recipient_new_level = "";
}
else
{
# Ask them to confirm.
$anvil->data->{form}{back_link} = $anvil->data->{sys}{cgi_string};
$anvil->data->{form}{back_link} =~ s/save=.*?&//;
$anvil->data->{form}{back_link} =~ s/save=.*?$//;
$anvil->data->{form}{refresh_link} = "";
$anvil->data->{form}{body} = $anvil->Template->get({file => "email.html", name => "recipient-delete-confirm", variables => {
recipient_name => $recipient_name,
recipient_email => $recipient_email
mail_server_uuid => $mail_server_uuid,
}});
return(0);
}
}
}
}
# Are we saving?
if ($save)
{
# Have we confirmed?
if ($confirm)
{
# Save the changes.
}
else
{
# Ask them to confirm
}
}
return(0);
}
# This configures mail servers
sub process_email_server_page sub process_email_server_page
{ {
my ($anvil) = @_; my ($anvil) = @_;
# Prep the cgi variables. # Prep the cgi variables.
my $mail_server_uuid = defined $anvil->data->{cgi}{mail_server_uuid}{value} ? $anvil->data->{cgi}{mail_server_uuid}{value} : ""; my $mail_server_uuid = defined $anvil->data->{cgi}{mail_server_uuid}{value} ? $anvil->data->{cgi}{mail_server_uuid}{value} : "";
my $say_outgoing_mail_server = defined $anvil->data->{cgi}{outgoing_mail_server}{value} ? $anvil->data->{cgi}{outgoing_mail_server}{value} : ""; my $outgoing_mail_server = defined $anvil->data->{cgi}{outgoing_mail_server}{value} ? $anvil->data->{cgi}{outgoing_mail_server}{value} : "";
my $say_login_name = defined $anvil->data->{cgi}{login_name}{value} ? $anvil->data->{cgi}{login_name}{value} : ""; my $login_name = defined $anvil->data->{cgi}{login_name}{value} ? $anvil->data->{cgi}{login_name}{value} : "";
my $say_login_password = defined $anvil->data->{cgi}{login_password}{value} ? $anvil->data->{cgi}{login_password}{value} : ""; my $login_password = defined $anvil->data->{cgi}{login_password}{value} ? $anvil->data->{cgi}{login_password}{value} : "";
my $say_connection_security = defined $anvil->data->{cgi}{connection_security}{value} ? $anvil->data->{cgi}{connection_security}{value} : "ifn_link1"; my $connection_security = defined $anvil->data->{cgi}{connection_security}{value} ? $anvil->data->{cgi}{connection_security}{value} : "ifn_link1";
my $say_authentication_method = defined $anvil->data->{cgi}{authentication_method}{value} ? $anvil->data->{cgi}{authentication_method}{value} : "normal_password"; my $authentication_method = defined $anvil->data->{cgi}{authentication_method}{value} ? $anvil->data->{cgi}{authentication_method}{value} : "normal_password";
my $say_port = defined $anvil->data->{cgi}{port}{value} ? $anvil->data->{cgi}{port}{value} : "143"; my $port = defined $anvil->data->{cgi}{port}{value} ? $anvil->data->{cgi}{port}{value} : "143";
my $say_helo_domain = defined $anvil->data->{cgi}{helo_domain}{value} ? $anvil->data->{cgi}{helo_domain}{value} : ""; my $helo_domain = defined $anvil->data->{cgi}{helo_domain}{value} ? $anvil->data->{cgi}{helo_domain}{value} : "";
my $say_back = defined $anvil->data->{cgi}{back}{value} ? $anvil->data->{cgi}{back}{value} : ""; my $back = defined $anvil->data->{cgi}{back}{value} ? $anvil->data->{cgi}{back}{value} : "";
my $say_save = defined $anvil->data->{cgi}{save}{value} ? $anvil->data->{cgi}{save}{value} : ""; my $save = defined $anvil->data->{cgi}{save}{value} ? $anvil->data->{cgi}{save}{value} : "";
my $say_delete = defined $anvil->data->{cgi}{'delete'}{value} ? $anvil->data->{cgi}{'delete'}{value} : ""; my $delete = defined $anvil->data->{cgi}{'delete'}{value} ? $anvil->data->{cgi}{'delete'}{value} : "";
my $say_confirm = defined $anvil->data->{cgi}{confirm}{value} ? $anvil->data->{cgi}{confirm}{value} : ""; my $confirm = defined $anvil->data->{cgi}{confirm}{value} ? $anvil->data->{cgi}{confirm}{value} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
say_outgoing_mail_server => $say_outgoing_mail_server, outgoing_mail_server => $outgoing_mail_server,
say_login_name => $say_login_name, login_name => $login_name,
say_login_password => $say_login_password, login_password => $login_password,
say_connection_security => $say_connection_security, connection_security => $connection_security,
say_authentication_method => $say_authentication_method, authentication_method => $authentication_method,
say_back => $say_back, back => $back,
say_save => $say_save, save => $save,
say_delete => $say_delete, 'delete' => $delete,
say_confirm => $say_confirm, confirm => $confirm,
}}); }});
if ($say_back) if ($back)
{ {
$say_save = ""; $save = "";
$say_delete = ""; $delete = "";
$say_confirm = ""; $confirm = "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
say_save => $say_save, save => $save,
say_delete => $say_delete, 'delete' => $delete,
say_confirm => $say_confirm, confirm => $confirm,
}}); }});
} }
# Are we loading an existing record? # Are we loading an existing record?
if (($mail_server_uuid) && not ($say_save)) if (($mail_server_uuid) && not ($save))
{ {
# Load. If we're deleting, we'll check 'mail_server_helo_domain' to see if it already was. # Load. If we're deleting, we'll check 'mail_server_helo_domain' to see if it already was.
my $query = " my $query = "
@ -470,27 +607,27 @@ WHERE
}}); }});
foreach my $row (@{$results}) foreach my $row (@{$results})
{ {
$say_outgoing_mail_server = $row->[0]; $outgoing_mail_server = $row->[0];
$say_authentication_method = $row->[1]; $authentication_method = $row->[1];
$say_helo_domain = $row->[2]; $helo_domain = $row->[2];
$say_login_password = $row->[3]; $login_password = $row->[3];
$say_port = $row->[4]; $port = $row->[4];
$say_connection_security = $row->[5]; $connection_security = $row->[5];
$say_login_name = $row->[6]; $login_name = $row->[6];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
say_outgoing_mail_server => $say_outgoing_mail_server, outgoing_mail_server => $outgoing_mail_server,
say_authentication_method => $say_authentication_method, authentication_method => $authentication_method,
say_helo_domain => $say_helo_domain, helo_domain => $helo_domain,
say_login_password => $say_login_password, login_password => $login_password,
say_port => $say_port, port => $port,
say_connection_security => $say_connection_security, connection_security => $connection_security,
say_login_name => $say_login_name, login_name => $login_name,
}}); }});
if ($say_delete) if ($delete)
{ {
# Has the user confirmed? # Has the user confirmed?
if ($say_confirm) if ($confirm)
{ {
# Delete. # Delete.
$anvil->Database->insert_or_update_mail_servers({ $anvil->Database->insert_or_update_mail_servers({
@ -500,15 +637,15 @@ WHERE
}); });
# Saved successfully. # Saved successfully.
my $ok_message = $anvil->Words->string({key => "ok_0002", variables => { mail_server => $say_outgoing_mail_server }}); my $ok_message = $anvil->Words->string({key => "ok_0002", variables => { mail_server => $outgoing_mail_server }});
$anvil->data->{form}{ok_message} = $anvil->Template->get({file => "main.html", name => "ok_message", variables => { ok_message => $ok_message }}); $anvil->data->{form}{ok_message} = $anvil->Template->get({file => "main.html", name => "ok_message", variables => { ok_message => $ok_message }});
# Clear the form # Clear the form
$say_outgoing_mail_server = ""; $outgoing_mail_server = "";
$say_login_name = ""; $login_name = "";
$say_login_password = ""; $login_password = "";
$say_connection_security = ""; $connection_security = "";
$say_authentication_method = ""; $authentication_method = "";
} }
else else
{ {
@ -518,7 +655,7 @@ WHERE
$anvil->data->{form}{back_link} =~ s/save=.*?$//; $anvil->data->{form}{back_link} =~ s/save=.*?$//;
$anvil->data->{form}{refresh_link} = ""; $anvil->data->{form}{refresh_link} = "";
$anvil->data->{form}{body} = $anvil->Template->get({file => "email.html", name => "mail-server-delete-confirm", variables => { $anvil->data->{form}{body} = $anvil->Template->get({file => "email.html", name => "mail-server-delete-confirm", variables => {
outgoing_mail_server => $say_outgoing_mail_server, outgoing_mail_server => $outgoing_mail_server,
mail_server_uuid => $mail_server_uuid, mail_server_uuid => $mail_server_uuid,
}}); }});
return(0); return(0);
@ -529,47 +666,47 @@ WHERE
# if the user put a port on the mail server, break it off now and override any passed in port. # if the user put a port on the mail server, break it off now and override any passed in port.
# Normally, the port is set via a hidden variable when the security check box is changed. # Normally, the port is set via a hidden variable when the security check box is changed.
my $test_outgoing_mail_server = $say_outgoing_mail_server; my $test_outgoing_mail_server = $outgoing_mail_server;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { test_outgoing_mail_server => $test_outgoing_mail_server }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { test_outgoing_mail_server => $test_outgoing_mail_server }});
if ($test_outgoing_mail_server =~ /^(.*):(\d+)$/) if ($test_outgoing_mail_server =~ /^(.*):(\d+)$/)
{ {
$test_outgoing_mail_server = $1; $test_outgoing_mail_server = $1;
$say_port = $2; $port = $2;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
test_outgoing_mail_server => $test_outgoing_mail_server, test_outgoing_mail_server => $test_outgoing_mail_server,
say_port => $say_port, port => $port,
}}); }});
} }
elsif (not $say_port) elsif (not $port)
{ {
# Port wasn't passed. Use '143' unless $say_connection_security is 'ssl_tls' # Port wasn't passed. Use '143' unless $connection_security is 'ssl_tls'
$say_port = 143; $port = 143;
if ($say_connection_security eq "ssl_tls") if ($connection_security eq "ssl_tls")
{ {
$say_port = 993; $port = 993;
} }
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { say_port => $say_port }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { port => $port }});
} }
### NOTE: For now, the HELO domain is not configurable by the user. ### NOTE: For now, the HELO domain is not configurable by the user.
# If we don't have $say_helo_domain, use the host's domain # If we don't have $helo_domain, use the host's domain
if (not $say_helo_domain) if (not $helo_domain)
{ {
$say_helo_domain = $anvil->_domain_name(); $helo_domain = $anvil->_domain_name();
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { say_helo_domain => $say_helo_domain }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { helo_domain => $helo_domain }});
} }
if ($say_save) if ($save)
{ {
# Did the user give an outgoing mail server? # Did the user give an outgoing mail server?
if (not $say_outgoing_mail_server) if (not $outgoing_mail_server)
{ {
# Just silently send them back to the form. # Just silently send them back to the form.
$say_save = ""; $save = "";
$say_confirm = ""; $confirm = "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
say_save => $say_save, save => $save,
say_confirm => $say_confirm, confirm => $confirm,
}}); }});
} }
@ -581,51 +718,51 @@ WHERE
my $error_message = $anvil->Words->string({key => "warning_0023"}); my $error_message = $anvil->Words->string({key => "warning_0023"});
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $error_message }}); $anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $error_message }});
$anvil->data->{cgi}{outgoing_mail_server}{alert} = 1; $anvil->data->{cgi}{outgoing_mail_server}{alert} = 1;
$say_save = ""; $save = "";
$say_confirm = ""; $confirm = "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
error_message => $error_message, error_message => $error_message,
"form::error_massage" => $anvil->data->{form}{error_massage}, "form::error_massage" => $anvil->data->{form}{error_massage},
"cgi::outgoing_mail_server::alert" => $anvil->data->{cgi}{outgoing_mail_server}{alert}, "cgi::outgoing_mail_server::alert" => $anvil->data->{cgi}{outgoing_mail_server}{alert},
say_save => $say_save, save => $save,
say_confirm => $say_confirm, confirm => $confirm,
}}); }});
} }
if (not $anvil->Validate->is_port({port => $say_port})) if (not $anvil->Validate->is_port({port => $port}))
{ {
# Bad port # Bad port
my $error_message = $anvil->Words->string({key => "warning_0024"}); my $error_message = $anvil->Words->string({key => "warning_0024"});
$anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $error_message }}); $anvil->data->{form}{error_massage} = $anvil->Template->get({file => "main.html", name => "error_message", variables => { error_message => $error_message }});
$anvil->data->{cgi}{outgoing_mail_server}{alert} = 1; $anvil->data->{cgi}{outgoing_mail_server}{alert} = 1;
$say_save = ""; $save = "";
$say_confirm = ""; $confirm = "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
error_message => $error_message, error_message => $error_message,
"form::error_massage" => $anvil->data->{form}{error_massage}, "form::error_massage" => $anvil->data->{form}{error_massage},
"cgi::outgoing_mail_server::alert" => $anvil->data->{cgi}{outgoing_mail_server}{alert}, "cgi::outgoing_mail_server::alert" => $anvil->data->{cgi}{outgoing_mail_server}{alert},
say_save => $say_save, save => $save,
say_confirm => $say_confirm, confirm => $confirm,
}}); }});
} }
} }
# Still saving? # Still saving?
if ($say_save) if ($save)
{ {
# Confirmed? # Confirmed?
if ($say_confirm) if ($confirm)
{ {
# Save! # Save!
($mail_server_uuid) = $anvil->Database->insert_or_update_mail_servers({ ($mail_server_uuid) = $anvil->Database->insert_or_update_mail_servers({
debug => 2, debug => 2,
mail_server_uuid => $mail_server_uuid, mail_server_uuid => $mail_server_uuid,
mail_server_address => $test_outgoing_mail_server, mail_server_address => $test_outgoing_mail_server,
mail_server_authentication => $say_authentication_method, mail_server_authentication => $authentication_method,
mail_server_helo_domain => $say_helo_domain, mail_server_helo_domain => $helo_domain,
mail_server_password => $say_login_password, mail_server_password => $login_password,
mail_server_port => $say_port, mail_server_port => $port,
mail_server_security => $say_connection_security, mail_server_security => $connection_security,
mail_server_username => $say_login_name, mail_server_username => $login_name,
}); });
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { mail_server_uuid => $mail_server_uuid }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { mail_server_uuid => $mail_server_uuid }});
if ($mail_server_uuid) if ($mail_server_uuid)
@ -635,11 +772,11 @@ WHERE
$anvil->data->{form}{ok_message} = $anvil->Template->get({file => "main.html", name => "ok_message", variables => { ok_message => $ok_message }}); $anvil->data->{form}{ok_message} = $anvil->Template->get({file => "main.html", name => "ok_message", variables => { ok_message => $ok_message }});
# Clear the form # Clear the form
$say_outgoing_mail_server = ""; $outgoing_mail_server = "";
$say_login_name = ""; $login_name = "";
$say_login_password = ""; $login_password = "";
$say_connection_security = ""; $connection_security = "";
$say_authentication_method = ""; $authentication_method = "";
} }
else else
{ {
@ -656,14 +793,14 @@ WHERE
$anvil->data->{form}{back_link} =~ s/save=.*?$//; $anvil->data->{form}{back_link} =~ s/save=.*?$//;
$anvil->data->{form}{refresh_link} = ""; $anvil->data->{form}{refresh_link} = "";
$anvil->data->{form}{body} = $anvil->Template->get({file => "email.html", name => "mail-server-confirm", variables => { $anvil->data->{form}{body} = $anvil->Template->get({file => "email.html", name => "mail-server-confirm", variables => {
say_outgoing_mail_server => $test_outgoing_mail_server.":".$say_port, say_outgoing_mail_server => $test_outgoing_mail_server.":".$port,
outgoing_mail_server => $say_outgoing_mail_server, outgoing_mail_server => $outgoing_mail_server,
port => $say_port, port => $port,
login_name => $say_login_name, login_name => $login_name,
login_password => $say_login_password, login_password => $login_password,
connection_security => $say_connection_security, connection_security => $connection_security,
authentication_method => $say_authentication_method, authentication_method => $authentication_method,
helo_domain => $say_helo_domain, helo_domain => $helo_domain,
mail_server_uuid => $mail_server_uuid, mail_server_uuid => $mail_server_uuid,
}}); }});
return(0); return(0);
@ -709,7 +846,7 @@ WHERE
id => "outgoing_mail_server", id => "outgoing_mail_server",
field => "#!string!striker_0185!#", field => "#!string!striker_0185!#",
description => "#!string!striker_0169!#", description => "#!string!striker_0169!#",
value => $say_outgoing_mail_server, value => $outgoing_mail_server,
default_value => "", default_value => "",
class => $outgoing_mail_server_class, class => $outgoing_mail_server_class,
extra => "", extra => "",
@ -722,7 +859,7 @@ WHERE
id => "login_name", id => "login_name",
field => "#!string!striker_0170!#", field => "#!string!striker_0170!#",
description => "#!string!striker_0171!#", description => "#!string!striker_0171!#",
value => $say_login_name, value => $login_name,
default_value => "", default_value => "",
class => $login_name_class, class => $login_name_class,
extra => "", extra => "",
@ -735,7 +872,7 @@ WHERE
id => "login_password", id => "login_password",
field => "#!string!striker_0172!#", field => "#!string!striker_0172!#",
description => "#!string!striker_0173!#", description => "#!string!striker_0173!#",
value => $say_login_password, value => $login_password,
default_value => "", default_value => "",
class => $login_password_class, class => $login_password_class,
extra => "", extra => "",
@ -750,7 +887,7 @@ WHERE
"starttls#!#".$anvil->Words->string({key => "striker_0176"}) "starttls#!#".$anvil->Words->string({key => "striker_0176"})
], ],
blank => 0, blank => 0,
selected => $say_connection_security, selected => $connection_security,
class => $anvil->data->{cgi}{connection_security}{alert} ? "input_alert" : "input_clear", class => $anvil->data->{cgi}{connection_security}{alert} ? "input_alert" : "input_clear",
}); });
@ -766,7 +903,7 @@ WHERE
"oauth2#!#".$anvil->Words->string({key => "striker_0182"}) "oauth2#!#".$anvil->Words->string({key => "striker_0182"})
], ],
blank => 0, blank => 0,
selected => $say_authentication_method, selected => $authentication_method,
class => $anvil->data->{cgi}{authentication_method}{alert} ? "input_alert" : "input_clear", class => $anvil->data->{cgi}{authentication_method}{alert} ? "input_alert" : "input_clear",
}); });
@ -781,7 +918,7 @@ WHERE
connection_security => $connection_security_select, connection_security => $connection_security_select,
authentication_method => $authentication_method_select, authentication_method => $authentication_method_select,
mail_server_uuid => $mail_server_uuid, mail_server_uuid => $mail_server_uuid,
port => $say_port, port => $port,
}}); }});
return(0); return(0);

@ -308,3 +308,58 @@
</form> </form>
</table> </table>
<!-- end mail-server-delete-confirm --> <!-- end mail-server-delete-confirm -->
<!-- start recipient-delete-confirm -->
<table align="center">
<form name="recipient" action="" method="post">
<div id="recipient">
<tr>
<td colspan="2" class="title">
#!string!message_0156!#
</td>
</tr>
<tr>
<td colspan="2">
&nbsp;
</td>
</tr>
<tr>
<td colspan="2">
<table align="center">
<tr>
<td class="column_header">
#!string!striker_0189!#
</td>
<td class="column_row_value_fixed">
&nbsp; #!variable!recipient_name!# (#!variable!recipient_email!#)
<input type="hidden" name="recipient_uuid" id="recipient_uuid" value="#!variable!recipient_uuid!#"/>
</td>
</tr>
<tr>
<td colspan="2">
&nbsp;
</td>
</tr>
<tr>
<td class="no_border">
<input type="submit" name="back" id="back" class="button" value="#!string!striker_0098!#">
</td>
<td class="no_border_right">
<input type="submit" name="confirm" id="confirm" class="button" value="#!string!striker_0082!#">
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td colspan="2">
&nbsp;
</td>
</tr>
</div>
<input type="hidden" name="email" id="email" value="true" />
<input type="hidden" name="task" id="task" value="email_recipient" />
<input type="hidden" name="delete" id="delete" value="true"/>
</form>
</table>
<!-- end recipient-delete-confirm -->

@ -329,7 +329,7 @@ CREATE TABLE anvils (
anvil_uuid uuid not null primary key, anvil_uuid uuid not null primary key,
anvil_name text not null, anvil_name text not null,
anvil_description text not null, -- This is a short, one-line (usually) description of this particular Anvil!. It is displayed in the Anvil! selection list. anvil_description text not null, -- This is a short, one-line (usually) description of this particular Anvil!. It is displayed in the Anvil! selection list.
anvil_password text not null, -- This is the 'ricci' or 'hacluster' user password. It is also used to access nodes that don't have a specific password set. anvil_password text not null, -- This is the 'hacluster' user password. It is also used to access nodes that don't have a specific password set.
modified_date timestamp with time zone not null modified_date timestamp with time zone not null
); );
ALTER TABLE anvils OWNER TO admin; ALTER TABLE anvils OWNER TO admin;
@ -446,8 +446,9 @@ CREATE TABLE recipients (
recipient_uuid uuid not null primary key, recipient_uuid uuid not null primary key,
recipient_name text not null, -- This is the recipient's name recipient_name text not null, -- This is the recipient's name
recipient_email text not null, -- This is the recipient's email address or the file name, depending. recipient_email text not null, -- This is the recipient's email address or the file name, depending.
recipient_language text, -- If set, this is the language the user wants to receive alerts in. If not set, the default language is used. recipient_language text not null, -- If set, this is the language the user wants to receive alerts in. If not set, the default language is used.
recipient_new_level integer not null, -- This is the alert level to use when automatically adding watch links to new systems. '0' tells us to ignore new systems. recipient_units text not null, -- This can be set to 'imperial' if the user prefers temperatures in °F
recipient_new_level integer not null, -- This is the alert level to use when automatically adding watch links to new systems. '0' tells us to ignore new systems, 1 is critical, 2 is warning, and 3 is notice
modified_date timestamp with time zone not null modified_date timestamp with time zone not null
); );
ALTER TABLE recipients OWNER TO admin; ALTER TABLE recipients OWNER TO admin;
@ -458,6 +459,7 @@ CREATE TABLE history.recipients (
recipient_name text, recipient_name text,
recipient_email text, recipient_email text,
recipient_language text, recipient_language text,
recipient_units text,
recipient_new_level integer, recipient_new_level integer,
modified_date timestamp with time zone not null modified_date timestamp with time zone not null
); );
@ -474,6 +476,7 @@ BEGIN
recipient_name, recipient_name,
recipient_email, recipient_email,
recipient_language, recipient_language,
recipient_units,
recipient_new_level, recipient_new_level,
modified_date) modified_date)
VALUES VALUES
@ -481,6 +484,7 @@ BEGIN
history_recipients.recipient_name, history_recipients.recipient_name,
history_recipients.recipient_email, history_recipients.recipient_email,
history_recipients.recipient_language, history_recipients.recipient_language,
history_recipients.recipient_units,
history_recipients.recipient_new_level, history_recipients.recipient_new_level,
history_recipients.modified_date); history_recipients.modified_date);
RETURN NULL; RETURN NULL;

@ -260,6 +260,7 @@ About to try to download aproximately: [#!variable!packages!#] packages needed t
<key name="message_0153">Local repository</key> <key name="message_0153">Local repository</key>
<key name="message_0154">Mail Server Configuration</key> <key name="message_0154">Mail Server Configuration</key>
<key name="message_0155">When alert emails are sent, they are stored locally and then forwarded to a mail server. This is where you can configure the mail server that alerts are forwarded to for delivery to recipients.</key> <key name="message_0155">When alert emails are sent, they are stored locally and then forwarded to a mail server. This is where you can configure the mail server that alerts are forwarded to for delivery to recipients.</key>
<key name="message_0156">Alert recipient Configuration</key>
<!-- Log entries --> <!-- Log entries -->
<key name="log_0001">Starting: [#!variable!program!#].</key> <key name="log_0001">Starting: [#!variable!program!#].</key>
@ -1194,6 +1195,7 @@ Failure! The return code: [#!variable!return_code!#] was received ('0' was expec
<!-- Success messages shown to the user --> <!-- Success messages shown to the user -->
<key name="ok_0001">Saved the mail server information successfully!</key> <key name="ok_0001">Saved the mail server information successfully!</key>
<key name="ok_0002">The mail server: [#!variable!mail_server!#] has been deleted.</key> <key name="ok_0002">The mail server: [#!variable!mail_server!#] has been deleted.</key>
<key name="ok_0003">The alert recipient: [#!variable!recipient_email!#] has been deleted.</key>
<!-- Warnings --> <!-- Warnings -->
<key name="warning_0001">The IP address will change. You will need to reconnect after applying these changes.</key> <key name="warning_0001">The IP address will change. You will need to reconnect after applying these changes.</key>
@ -1345,6 +1347,7 @@ Failed to generate an RSA public key for the user: [#!variable!user!#]. The outp
<key name="error_0105">The file: [#!variable!file!#] was not found.</key> <key name="error_0105">The file: [#!variable!file!#] was not found.</key>
<key name="error_0106"><![CDATA[The method Network->find_matches() was given the hash key: [#!variable!key!#], but it does not reference a hash. Are any IPs associated with this target?]]></key> <key name="error_0106"><![CDATA[The method Network->find_matches() was given the hash key: [#!variable!key!#], but it does not reference a hash. Are any IPs associated with this target?]]></key>
<key name="error_0107">Failed to reconnect after reconfiguring the network, exiting.</key> <key name="error_0107">Failed to reconnect after reconfiguring the network, exiting.</key>
<key name="error_0108">The 'recipient_new_level': [#!variable!recipient_new_level!#] is invalid. It should be '0', '1', '2', or '3'.</key>
<!-- These are units, words and so on used when displaying information. --> <!-- These are units, words and so on used when displaying information. -->
<key name="unit_0001">Yes</key> <key name="unit_0001">Yes</key>

@ -66,3 +66,21 @@ see 'words.xml' for more information on how this file is structured.
NOTE: This file MUST be the same as the agent itself, with the file extension '.xml'. NOTE: This file MUST be the same as the agent itself, with the file extension '.xml'.
NOTE: To avoid namespace collisions, it is STRONGLY recommended that all string keys start with your agent NOTE: To avoid namespace collisions, it is STRONGLY recommended that all string keys start with your agent
name! Ie: 'scan_network_X'. name! Ie: 'scan_network_X'.
== Alert Levels ==
NOTE: Alert levels are separate from log levels!
Alerts trigger emails to recipients who are interested in monitoring a system. Alerts levels indicate severity and are set as one of three numeric valus;
* 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)
* 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)
* 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)

Loading…
Cancel
Save