From b517117bc1ebc92652c004bf04df2454afd75b05 Mon Sep 17 00:00:00 2001 From: Digimer Date: Tue, 23 Nov 2021 20:41:29 -0500 Subject: [PATCH] * Did more work on trying to figure out why iniital setup of the database was failing. I believe it was because, in anvil-daemon, after calling 'prep_database' we called ->connect() _without_ 'check_if_configured' set. Next round of function testing should help confirm is this was the case. * Added 'configure_firewall()' to 'striker-prep-database' to explicitely open the postgresql service for all active zones. * Did some general logging changes and cleanup around the same. Signed-off-by: Digimer --- Anvil/Tools/Database.pm | 24 +++++-- share/words.xml | 2 + tools/anvil-daemon | 10 +-- tools/striker-prep-database | 128 ++++++++++++++++++++++++++++++++++-- 4 files changed, 149 insertions(+), 15 deletions(-) diff --git a/Anvil/Tools/Database.pm b/Anvil/Tools/Database.pm index bea1e655..479bb386 100644 --- a/Anvil/Tools/Database.pm +++ b/Anvil/Tools/Database.pm @@ -1344,20 +1344,23 @@ sub connect foreach my $uuid (sort {$a cmp $b} keys %{$anvil->data->{database}}) { # Periodically, autovivication causes and empty key to appear. - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { uuid => $uuid }}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { uuid => $uuid }}); next if ((not $uuid) or (not $anvil->Validate->uuid({uuid => $uuid}))); if (($db_uuid) && ($db_uuid ne $uuid)) { - $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0191", variables => { db_uuid => $db_uuid, uuid => $uuid }}); + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0191", variables => { + db_uuid => $db_uuid, + uuid => $uuid, + }}); next; } # Make sure values are set. - $anvil->data->{database}{$uuid}{port} = 5432 if not $anvil->data->{database}{$uuid}{port}; - $anvil->data->{database}{$uuid}{name} = $anvil->data->{sys}{database}{name} if not $anvil->data->{database}{$uuid}{name}; - $anvil->data->{database}{$uuid}{user} = $anvil->data->{sys}{database}{user} if not $anvil->data->{database}{$uuid}{user}; - $anvil->data->{database}{$uuid}{password} = "" if not defined $anvil->data->{database}{$uuid}{password}; + $anvil->data->{database}{$uuid}{port} = 5432 if not defined $anvil->data->{database}{$uuid}{port}; + $anvil->data->{database}{$uuid}{name} = "anvil" if not $anvil->data->{database}{$uuid}{name}; + $anvil->data->{database}{$uuid}{user} = "admin" if not $anvil->data->{database}{$uuid}{user}; + $anvil->data->{database}{$uuid}{password} = "" if not defined $anvil->data->{database}{$uuid}{password}; my $driver = "DBI:Pg"; my $host = $anvil->data->{database}{$uuid}{host}; # This should fail if not set @@ -1365,7 +1368,7 @@ sub connect my $name = $anvil->data->{database}{$uuid}{name}; my $user = $anvil->data->{database}{$uuid}{user}; my $password = $anvil->data->{database}{$uuid}{password}; - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { host => $host, port => $port, name => $name, @@ -1373,6 +1376,13 @@ sub connect password => $anvil->Log->is_secure($password), }}); + # If there's no password, skip. + if (not $password) + { + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0668", variables => { uuid => $uuid }}); + next; + } + # Some places will want to pull up the database user, so in case it isn't set (which is # usual), set it as if we had read it from the config file using the default. if (not $anvil->data->{database}{$uuid}{name}) diff --git a/share/words.xml b/share/words.xml index 69dc0058..4bc526a2 100644 --- a/share/words.xml +++ b/share/words.xml @@ -2057,6 +2057,8 @@ The file: [#!variable!file!#] needs to be updated. The difference is: [ Note ] - The IP address: [#!variable!ip!#] with 'ip_address_uuid': [#!variable!uuid!#] is a duplicate, removing it from the database(s). The database dump file: [#!variable!file!#] exists, skipping database setup. query() was asked to query the database with UUID: [#!variable!old_uuid!#] but there is no file handle open to the database. Switched the read to: [#!variable!new_uuid!#].]]> + Opening the firewall zone: [#!variable!zone!#] to allow the service: [#!variable!service!#]. + No password for the database on the host with UUID: [#!variable!uuid!#], skipping it. The host name: [#!variable!target!#] does not resolve to an IP address. diff --git a/tools/anvil-daemon b/tools/anvil-daemon index c7fb3226..a258adf7 100755 --- a/tools/anvil-daemon +++ b/tools/anvil-daemon @@ -105,8 +105,7 @@ if (not $anvil->data->{sys}{database}{connections}) prep_database($anvil); # Try connecting again - $anvil->refresh(); - $anvil->Database->connect(); + $anvil->Database->connect({debug => 2, check_if_configured => 1, check_for_resync => 1}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0132"}); if (not $anvil->data->{sys}{database}{connections}) { @@ -1176,8 +1175,11 @@ sub prep_database { ### NOTE: This failed once, in case / until it happens again, we'll force log level 2 and secure logging. #my ($database_output, $return_code) = $anvil->System->call({debug => 2, shell_call => $anvil->data->{path}{exe}{'striker-prep-database'}.$anvil->Log->switches, source => $THIS_FILE, line => __LINE__ }); - my ($database_output, $return_code) = $anvil->System->call({debug => 2, shell_call => $anvil->data->{path}{exe}{'striker-prep-database'}." -vv --log-secure", source => $THIS_FILE, line => __LINE__ }); - $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { + my $shell_call = $anvil->data->{path}{exe}{'striker-prep-database'}." -vv --log-secure"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }}); + + my ($database_output, $return_code) = $anvil->System->call({debug => 2, shell_call => $shell_call, source => $THIS_FILE, line => __LINE__ }); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => { database_output => $database_output, return_code => $return_code, }}); diff --git a/tools/striker-prep-database b/tools/striker-prep-database index a534effa..b8d22f9e 100755 --- a/tools/striker-prep-database +++ b/tools/striker-prep-database @@ -33,7 +33,7 @@ $anvil->Get->switches; $anvil->Log->level({set => 2}); $anvil->Log->secure({set => 1}); -$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, secure => 0, key => "log_0115", variables => { program => $THIS_FILE }}); +$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0115", variables => { program => $THIS_FILE }}); $anvil->System->_check_anvil_conf({debug => 2}); @@ -53,6 +53,9 @@ if ($local_uuid) # Start checks $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "sys::service::postgresql" => $anvil->data->{sys}{daemon}{postgresql} }}); + # Check that the firewall is open. + configure_firewall($anvil); + my $running = $anvil->System->check_daemon({debug => 2, daemon => $anvil->data->{sys}{daemon}{postgresql}}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { running => $running }}); if ($running eq "2") @@ -495,6 +498,117 @@ $anvil->nice_exit({exit_code => 0}); # Functions # ############################################################################################################# +sub configure_firewall +{ + my ($anvil) = @_; + + # What zones are there? + my $in_zone = ""; + my $shell_call = $anvil->data->{path}{exe}{'firewall-cmd'}." --get-active-zones"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }}); + my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call, debug => 2, source => $THIS_FILE, line => __LINE__}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + output => $output, + return_code => $return_code, + }}); + foreach my $line (split/\n/, $output) + { + if ($line =~ /^\S/) + { + $in_zone = $line; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { in_zone => $in_zone }}); + + $anvil->data->{firewall}{zone}{$in_zone}{active} = 1; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + "firewall::zone::${in_zone}::active" => $anvil->data->{firewall}{zone}{$in_zone}{active}, + }}); + } + elsif ($line =~ /^\s+interfaces: (.*)$/) + { + my $interfaces = $1; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { interfaces => $interfaces }}); + + $anvil->data->{firewall}{zone}{$in_zone}{interfaces} = $1; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + "firewall::zone::${in_zone}::interfaces" => $anvil->data->{firewall}{zone}{$in_zone}{interfaces}, + }}); + } + } + + my $reload = 0; + foreach my $zone (sort {$a cmp $b} keys %{$anvil->data->{firewall}{zone}}) + { + my $shell_call = $anvil->data->{path}{exe}{'firewall-cmd'}." --permanent --info-zone=".$zone; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }}); + + my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call, debug => 2, source => $THIS_FILE, line => __LINE__}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + output => $output, + return_code => $return_code, + }}); + foreach my $line (split/\n/, $output) + { + if ($line =~ /^\s+services: (.*)$/) + { + my $services = $1; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { services => $services }}); + + foreach my $service (split/ /, $services) + { + $anvil->data->{firewall}{zone}{$in_zone}{service}{$service} = 1; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + "firewall::zone::${in_zone}::service::${service}" => $anvil->data->{firewall}{zone}{$in_zone}{service}{$service}, + }}); + } + } + } + + # Is postgres open? + if ((not exists $anvil->data->{firewall}{zone}{$in_zone}{service}{postgresql}) or (not $anvil->data->{firewall}{zone}{$in_zone}{service}{postgresql})) + { + ### TODO: Switch this to System->manage_firewall(). + # Enable it. + my $service = "postgresql"; + $reload = 1; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + service => $service, + reload => $reload, + }}); + + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0667", variables => { + zone => $zone, + service => $service, + }}); + + my $shell_call = $anvil->data->{path}{exe}{'firewall-cmd'}." --zone=".$zone." --permanent --add-service=".$service; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }}); + + my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call, debug => 2, source => $THIS_FILE, line => __LINE__}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + output => $output, + return_code => $return_code, + }}); + } + } + + # Reload the firewall? + if ($reload) + { + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "message_0139"}); + + my $shell_call = $anvil->data->{path}{exe}{'firewall-cmd'}." --reload"; + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }}); + + my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call, debug => 2, source => $THIS_FILE, line => __LINE__}); + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + output => $output, + return_code => $return_code, + }}); + } + + return(0); +} + # This adds this machine to the local anvil.conf file. sub add_to_local_config { @@ -518,7 +632,7 @@ sub add_to_local_config host_uuid => $host_uuid, shell_call => $shell_call, }}); - my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call, debug => 2, source => $THIS_FILE, line => __LINE__}); + my ($output, $return_code) = $anvil->System->call({shell_call => $shell_call, source => $THIS_FILE, line => __LINE__}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { output => $output, return_code => $return_code, @@ -528,12 +642,18 @@ sub add_to_local_config unlink $password_file; # Re-read the config and make sure we have our own entry. - $anvil->Storage->read_config({file => $anvil->data->{path}{configs}{'anvil.conf'}}); + $anvil->refresh(); # If we still don't have a local_uuid, something went wrong. + $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { + "database::${host_uuid}::host" => $anvil->data->{database}{$host_uuid}{host}, + "database::${host_uuid}::port" => $anvil->data->{database}{$host_uuid}{port}, + "database::${host_uuid}::password" => $anvil->Log->is_secure($anvil->data->{database}{$host_uuid}{password}), + "database::${host_uuid}::ping" => $anvil->data->{database}{$host_uuid}{ping}, + }}); if (not $anvil->data->{database}{$host_uuid}{host}) { - print $anvil->Words->string({key => "error_0010"})."\n"; + $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, 'print' => 1, key => "error_0010"}); $anvil->nice_exit({exit_code => 1}); }