Merge branch 'ent-9662-second-round' of brutus.artica.es:artica/pandorafms into ent-9662-second-round

This commit is contained in:
Pablo Aragon 2023-03-24 12:29:09 +01:00
commit be1fb9298b
36 changed files with 507 additions and 36 deletions

View File

@ -1,5 +1,5 @@
package: pandorafms-agent-unix
Version: 7.0NG.769-230323
Version: 7.0NG.769-230324
Architecture: all
Priority: optional
Section: admin

View File

@ -14,7 +14,7 @@
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
pandora_version="7.0NG.769-230323"
pandora_version="7.0NG.769-230324"
echo "Test if you has the tools for to make the packages."
whereis dpkg-deb | cut -d":" -f2 | grep dpkg-deb > /dev/null

View File

@ -1023,7 +1023,7 @@ my $Sem = undef;
my $ThreadSem = undef;
use constant AGENT_VERSION => '7.0NG.769';
use constant AGENT_BUILD => '230323';
use constant AGENT_BUILD => '230324';
# Agent log default file size maximum and instances
use constant DEFAULT_MAX_LOG_SIZE => 600000;

View File

@ -4,7 +4,7 @@
%global __os_install_post %{nil}
%define name pandorafms_agent_linux
%define version 7.0NG.769
%define release 230323
%define release 230324
Summary: Pandora FMS Linux agent, PERL version
Name: %{name}

View File

@ -4,7 +4,7 @@
%global __os_install_post %{nil}
%define name pandorafms_agent_linux
%define version 7.0NG.769
%define release 230323
%define release 230324
Summary: Pandora FMS Linux agent, PERL version
Name: %{name}

View File

@ -10,7 +10,7 @@
# **********************************************************************
PI_VERSION="7.0NG.769"
PI_BUILD="230323"
PI_BUILD="230324"
OS_NAME=`uname -s`
FORCE=0

View File

@ -186,7 +186,7 @@ UpgradeApplicationID
{}
Version
{230323}
{230324}
ViewReadme
{Yes}

View File

@ -30,7 +30,7 @@ using namespace Pandora;
using namespace Pandora_Strutils;
#define PATH_SIZE _MAX_PATH+1
#define PANDORA_VERSION ("7.0NG.769 Build 230323")
#define PANDORA_VERSION ("7.0NG.769 Build 230324")
string pandora_path;
string pandora_dir;

View File

@ -11,7 +11,7 @@ BEGIN
VALUE "LegalCopyright", "Artica ST"
VALUE "OriginalFilename", "PandoraAgent.exe"
VALUE "ProductName", "Pandora FMS Windows Agent"
VALUE "ProductVersion", "(7.0NG.769(Build 230323))"
VALUE "ProductVersion", "(7.0NG.769(Build 230324))"
VALUE "FileVersion", "1.0.0.0"
END
END

View File

@ -1,5 +1,5 @@
package: pandorafms-console
Version: 7.0NG.769-230323
Version: 7.0NG.769-230324
Architecture: all
Priority: optional
Section: admin

View File

@ -14,7 +14,7 @@
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
pandora_version="7.0NG.769-230323"
pandora_version="7.0NG.769-230324"
package_pear=0
package_pandora=1

View File

@ -1,5 +1,14 @@
START TRANSACTION;
ALTER TABLE `tdatabase` ADD COLUMN `ssh_status` TINYINT UNSIGNED DEFAULT 0;
ALTER TABLE `tdatabase` ADD COLUMN `db_status` TINYINT UNSIGNED DEFAULT 0;
ALTER TABLE `tdatabase` ADD COLUMN `replication_status` TINYINT UNSIGNED DEFAULT 0;
ALTER TABLE `tdatabase` ADD COLUMN `replication_delay` BIGINT DEFAULT 0;
ALTER TABLE `tdatabase` ADD COLUMN `master` TINYINT UNSIGNED DEFAULT 0;
ALTER TABLE `tdatabase` ADD COLUMN `utimestamp` BIGINT DEFAULT 0;
ALTER TABLE `tdatabase` ADD COLUMN `mysql_version` VARCHAR(10) DEFAULT '';
ALTER TABLE `tdatabase` ADD COLUMN `pandora_version` VARCHAR(10) DEFAULT '';
UPDATE tconfig_os SET `icon_name` = 'linux@os.svg' WHERE `id_os` = 1;
UPDATE tconfig_os SET `icon_name` = 'solaris@os.svg' WHERE `id_os` = 2;
UPDATE tconfig_os SET `icon_name` = 'aix@os.svg' WHERE `id_os` = 3;
@ -166,4 +175,6 @@ CREATE TABLE IF NOT EXISTS `tfavmenu_user` (
`section` VARCHAR(255) NOT NULL,
PRIMARY KEY (`id`));
INSERT INTO `tconfig` (`token`, `value`) VALUES ('legacy_database_ha', 1);
COMMIT;

View File

@ -115,6 +115,7 @@ $exception_condition_value = 10;
$modulegroup = 0;
$period = SECONDS_1DAY;
$search = '';
$full_text = 0;
$log_number = 1000;
// Added support for projection graphs.
$period_pg = SECONDS_5DAY;
@ -316,6 +317,7 @@ switch ($action) {
$source = $es['source'];
$search = $es['search'];
$log_number = empty($es['log_number']) ? $log_number : $es['log_number'];
$full_text = empty($es['full_text']) ? 0 : $es['full_text'];
break;
case 'simple_graph':
@ -1313,6 +1315,14 @@ $class = 'databox filters';
<td >
<?php
html_print_input_text('search', $search, '', 40, 100);
html_print_checkbox(
'full_text',
1,
$full_text,
false,
false
);
ui_print_help_tip(__('Full context'), false);
?>
</td>
</tr>

View File

@ -1597,11 +1597,13 @@ switch ($action) {
$agents_to_report = get_parameter('id_agents3');
$source = get_parameter('source', '');
$search = get_parameter('search', '');
$full_text = (integer) get_parameter('full_text', 0);
$log_number = get_parameter('log_number', '');
$es['source'] = $source;
$es['id_agents'] = $agents_to_report;
$es['search'] = $search;
$es['full_text'] = $full_text;
$es['log_number'] = $log_number;
$values['external_source'] = json_encode($es);
@ -2542,11 +2544,13 @@ switch ($action) {
$agents_to_report = get_parameter('id_agents3');
$source = get_parameter('source', '');
$search = get_parameter('search', '');
$full_text = (integer) get_parameter('full_text', 0);
$log_number = get_parameter('log_number', '');
$es['source'] = $source;
$es['id_agents'] = $agents_to_report;
$es['search'] = $search;
$es['full_text'] = $full_text;
$es['log_number'] = $log_number;
$values['external_source'] = json_encode($es);

View File

@ -20,7 +20,7 @@
/**
* Pandora build version and version
*/
$build_version = 'PC230323';
$build_version = 'PC230324';
$pandora_version = 'v7.0NG.769';
// Do not overwrite default timezone set if defined.
@ -153,6 +153,19 @@ if (! defined('ENTERPRISE_DIR')) {
}
db_select_engine();
if (empty($config['remote_config']) === false
&& file_exists($config['remote_config'].'/conf/'.PANDORA_HA_FILE)
&& filesize($config['remote_config'].'/conf/'.PANDORA_HA_FILE) > 0
) {
$data = file_get_contents($config['remote_config'].'/conf/'.PANDORA_HA_FILE);
if (empty($data) === false) {
$ip_list = explode(',', $data);
// Connects to the first pandora_ha_dbs.conf database.
$config['dbhost'] = trim($ip_list[0]);
}
}
$config['dbconnection'] = db_connect();
require_once $ownDir.'functions_config.php';

View File

@ -1,4 +1,5 @@
<?php
/**
* Constants definitions.
*
@ -703,6 +704,11 @@ define('HA_ACTION_ENABLE', 6);
define('HA_ACTION_CLEANUP', 7);
define('HA_ACTION_RESYNC', 8);
define('HA_RESYNC', 1);
define('HA_DISABLE', 5);
define('HA_ENABLE', 6);
define('HA_UNINITIALIZED', 0);
define('HA_ONLINE', 1);
define('HA_PENDING', 2);
@ -864,6 +870,8 @@ define(
// Pandora FMS Enterprise license.
define('LICENSE_FILE', 'customer_key');
// Pandora HA database list.
define('PANDORA_HA_FILE', 'pandora_ha_hosts.conf');
// Home screen values for user definition.
define('HOME_SCREEN_DEFAULT', 'default');

View File

@ -456,6 +456,10 @@ function config_update_config()
$error_update[] = __('Enable Update Manager');
}
if (config_update_value('legacy_database_ha', get_parameter('legacy_database_ha'), true) === false) {
$error_update[] = __('Legacy database HA');
}
if (config_update_value('ipam_ocuppied_critical_treshold', get_parameter('ipam_ocuppied_critical_treshold'), true) === false) {
$error_update[] = __('Ipam Ocuppied Manager Critical');
}
@ -2237,6 +2241,10 @@ function config_process_config()
config_update_value('enable_update_manager', 1);
}
if (!isset($config['legacy_database_ha'])) {
config_update_value('legacy_database_ha', 0);
}
if (!isset($config['disabled_newsletter'])) {
config_update_value('disabled_newsletter', 0);
}

View File

@ -3261,6 +3261,7 @@ function html_print_input_image($name, $src, $value, $style='', $return=false, $
'onkeyup',
'class',
'form',
'disabled',
];
foreach ($attrs as $attribute) {

View File

@ -11582,6 +11582,12 @@ div[role="dialog"] {
margin: 0 auto;
}
.database_background_state {
mask: url(../../images/database@groups.svg) no-repeat center / contain;
-webkit-mask: url(../../images/database@groups.svg) no-repeat center / contain;
margin: 0 auto;
}
.filter-list-adv .wizard li {
display: grid;
}

View File

@ -131,7 +131,7 @@
<div style='padding-bottom: 50px'>
<?php
$version = '7.0NG.769';
$build = '230323';
$build = '230324';
$banner = "v$version Build $build";
error_reporting(0);

View File

@ -3,7 +3,7 @@
#
%define name pandorafms_console
%define version 7.0NG.769
%define release 230323
%define release 230324
# User and Group under which Apache is running
%define httpd_name httpd

View File

@ -3,7 +3,7 @@
#
%define name pandorafms_console
%define version 7.0NG.769
%define release 230323
%define release 230324
# User and Group under which Apache is running
%define httpd_name httpd

View File

@ -3,7 +3,7 @@
#
%define name pandorafms_console
%define version 7.0NG.769
%define release 230323
%define release 230324
%define httpd_name httpd
# User and Group under which Apache is running
%define httpd_name apache2

View File

@ -2634,9 +2634,17 @@ CREATE TABLE IF NOT EXISTS `tdatabase` (
`action` TINYINT UNSIGNED DEFAULT 0,
`ssh_key` TEXT,
`ssh_pubkey` TEXT,
`ssh_status` TINYINT UNSIGNED DEFAULT 0,
`last_error` TEXT,
`db_status` TINYINT UNSIGNED DEFAULT 0,
`replication_status` TINYINT UNSIGNED DEFAULT 0,
`replication_delay` BIGINT DEFAULT 0,
`master` TINYINT UNSIGNED DEFAULT 0,
`utimestamp` BIGINT DEFAULT 0,
`mysql_version` VARCHAR(10) DEFAULT '',
`pandora_version` VARCHAR(10) DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4 ;
) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4;
-- -----------------------------------------------------
-- Table `twidget`

View File

@ -1,5 +1,5 @@
package: pandorafms-server
Version: 7.0NG.769-230323
Version: 7.0NG.769-230324
Architecture: all
Priority: optional
Section: admin

View File

@ -14,7 +14,7 @@
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
pandora_version="7.0NG.769-230323"
pandora_version="7.0NG.769-230324"
package_cpan=0
package_pandora=1

View File

@ -702,8 +702,35 @@ ncm_ssh_utility /usr/share/pandora_server/util/ncm_ssh_extension
# Pandora FMS Daemon Watchdog execution interval in seconds (PANDORA FMS ENTERPRISE ONLY).
ha_interval 30
# Pandora FMS Daemon Watchdog monitoring interval in seconds. Must be a multiple of ha_interval (PANDORA FMS ENTERPRISE ONLY).
ha_monitoring_interval 60
# HA operation mode. For backward compatibility with pacemaker. Do not change this value (PANDORA FMS ENTERPRISE ONLY).
ha_mode pandora
# Comma separated list of HA host IPs or FQDNs (PANDORA FMS ENTERPRISE ONLY).
#ha_hosts 172.16.0.8,172.168.0.16
# Database username for pandora_ha (PANDORA FMS ENTERPRISE ONLY).
#ha_dbuser pandora
# Database password for pandora_ha (PANDORA FMS ENTERPRISE ONLY).
#ha_dbpass pandora
# SSH username for pandora_ha (PANDORA FMS ENTERPRISE ONLY).
#ha_sshuser pandora
# SSH port for pandora_ha (PANDORA FMS ENTERPRISE ONLY).
#ha_sshport 22
# Absolute path to the HA slave resync script (PANDORA FMS ENTERPRISE ONLY).
#ha_resync /usr/share/pandora_server/util/pandora_ha_resync_slave.sh
# Database username for HA replication (PANDORA FMS ENTERPRISE ONLY).
#repl_dbuser pandora
# Database password for HA replication (PANDORA FMS ENTERPRISE ONLY).
#repl_dbpass pandora
# Number of retries for connection attempts to HA databases.
#ha_connect_retries 2
# Enable (1) or disable (0) Pandora FMS Alert Server.
alertserver 0

View File

@ -46,7 +46,7 @@ our @EXPORT = qw(
# version: Defines actual version of Pandora Server for this module only
my $pandora_version = "7.0NG.769";
my $pandora_build = "230323";
my $pandora_build = "230324";
our $VERSION = $pandora_version." ".$pandora_build;
# Setup hash
@ -553,6 +553,25 @@ sub pandora_load_config {
$pa_config->{"unknown_block_size"} = 1000; # 7.0.769
$pa_config->{"ha_mode"} = "pacemaker"; # 7.0.770
$pa_config->{"ha_file"} = undef; # 7.0.770
$pa_config->{"ha_hosts_file"} = '/var/spool/pandora/data_in/conf/pandora_ha_hosts.conf'; # 7.0.770
$pa_config->{"ha_connect_retries"} = 2; # 7.0.770
$pa_config->{"ha_connect_delay"} = 1; # 7.0.770
$pa_config->{"ha_dbuser"} = undef; # 7.0.770
$pa_config->{"ha_dbpass"} = undef; # 7.0.770
$pa_config->{"ha_hosts"} = undef; # 7.0.770
$pa_config->{"ha_resync"} = '/usr/share/pandora_server/util/pandora_ha_resync_slave.sh'; # 7.0.770
$pa_config->{"ha_resync_log"} = '/var/log/pandora/pandora_ha_resync.log'; # 7.0.770
$pa_config->{"ha_sshuser"} = 'pandora'; # 7.0.770
$pa_config->{"ha_sshport"} = 22; # 7.0.770
$pa_config->{"ha_max_splitbrain_retries"} = 2;
$pa_config->{"ha_resync_sleep"} = 10;
$pa_config->{"repl_dbuser"} = undef; # 7.0.770
$pa_config->{"repl_dbpass"} = undef; # 7.0.770
# Check for UID0
if ($pa_config->{"quiet"} != 0){
if ($> == 0){
@ -1283,9 +1302,36 @@ sub pandora_load_config {
}
# Pandora HA extra
elsif ($parametro =~ m/^ha_mode\s(.*)/i) {
$pa_config->{'ha_mode'} = clean_blank($1);
}
elsif ($parametro =~ m/^ha_file\s(.*)/i) {
$pa_config->{'ha_file'} = clean_blank($1);
}
elsif ($parametro =~ m/^ha_hosts_file\s(.*)/i) {
$pa_config->{'ha_hosts_file'} = clean_blank($1);
}
elsif ($parametro =~ m/^ha_dbuser\s(.*)/i) {
$pa_config->{'ha_dbuser'} = clean_blank($1);
}
elsif ($parametro =~ m/^ha_dbpass\s(.*)/i) {
$pa_config->{'ha_dbpass'} = clean_blank($1);
}
elsif ($parametro =~ m/^ha_sshuser\s(.*)/i) {
$pa_config->{'ha_sshuser'} = clean_blank($1);
}
elsif ($parametro =~ m/^ha_sshport\s(.*)/i) {
$pa_config->{'ha_sshport'} = clean_blank($1);
}
elsif ($parametro =~ m/^ha_hosts\s(.*)/i) {
$pa_config->{'ha_hosts'} = clean_blank($1);
}
elsif ($parametro =~ m/^ha_resync\s(.*)/i) {
$pa_config->{'ha_resync'} = clean_blank($1);
}
elsif ($parametro =~ m/^ha_resync_log\s(.*)/i) {
$pa_config->{'ha_resync_log'} = clean_blank($1);
}
elsif ($parametro =~ m/^ha_pid_file\s(.*)/i) {
$pa_config->{'ha_pid_file'} = clean_blank($1);
}
@ -1313,9 +1359,42 @@ sub pandora_load_config {
elsif ($parametro =~ m/^dataserver_smart_queue\s([0-1])/i) {
$pa_config->{'dataserver_smart_queue'} = clean_blank($1);
}
elsif ($parametro =~ m/^ha_connect_retries\s+([0-9]*)/i) {
$pa_config->{'ha_connect_retries'} = clean_blank($1);
}
elsif ($parametro =~ m/^ha_connect_delay\s+([0-9]*)/i) {
$pa_config->{'ha_connect_delay'} = clean_blank($1);
}
elsif ($parametro =~ m/^repl_dbuser\s(.*)/i) {
$pa_config->{'repl_dbuser'} = clean_blank($1);
}
elsif ($parametro =~ m/^repl_dbpass\s(.*)/i) {
$pa_config->{'repl_dbpass'} = clean_blank($1);
}
} # end of loop for parameter #
# The DB host was overridden by pandora_ha.
if (-f $pa_config->{'ha_hosts_file'}) {
eval {
open(my $fh, '<', $pa_config->{'ha_hosts_file'}) or return;
my $dbhost = <$fh>;
chomp($dbhost);
if (defined($dbhost) && $dbhost ne '') {
$pa_config->{'dbhost'} = $dbhost;
}
close($fh);
};
}
print " [*] DB Host is " . $pa_config->{'dbhost'} . "\n";
# ha_dbuser and ha_dbpass default to dbuser and dbpass respectively.
$pa_config->{'ha_dbuser'} = $pa_config->{'dbuser'} unless defined($pa_config->{'ha_dbuser'});
$pa_config->{'ha_dbpass'} = $pa_config->{'dbpass'} unless defined($pa_config->{'ha_dbpass'});
# repl_dbuser and repl_dbpass default to dbuser and dbpass respectively.
$pa_config->{'repl_dbuser'} = $pa_config->{'dbuser'} unless defined($pa_config->{'repl_dbuser'});
$pa_config->{'repl_dbpass'} = $pa_config->{'dbpass'} unless defined($pa_config->{'repl_dbpass'});
# Generate the encryption key after reading the passphrase.
$pa_config->{"encryption_key"} = enterprise_hook('pandora_get_encryption_key', [$pa_config, $pa_config->{"encryption_passphrase"}]);

View File

@ -54,6 +54,8 @@ Exported Functions:
=item * C<pandora_event>
=item * C<pandora_timed_event>
=item * C<pandora_execute_alert>
=item * C<pandora_execute_action>
@ -194,6 +196,7 @@ our @EXPORT = qw(
pandora_evaluate_alert
pandora_evaluate_snmp_alerts
pandora_event
pandora_timed_event
pandora_extended_event
pandora_execute_alert
pandora_execute_action
@ -3996,7 +3999,8 @@ Generate an event.
=cut
##########################################################################
sub pandora_event ($$$$$$$$$$;$$$$$$$$$$$$) {
#sub pandora_event ($$$$$$$$$$;$$$$$$$$$$$$) {
sub pandora_event {
my ($pa_config, $evento, $id_grupo, $id_agente, $severity,
$id_alert_am, $id_agentmodule, $event_type, $event_status, $dbh,
$source, $user_name, $comment, $id_extra, $tags,
@ -4113,6 +4117,28 @@ sub pandora_event ($$$$$$$$$$;$$$$$$$$$$$$) {
return $event_id;
}
##########################################################################
=head2 C<< pandora_timed_event (I<$time_limit>, I<@event>) >>
Generate an event, but no more than one every $time_limit seconds.
=cut
##########################################################################
my %TIMED_EVENTS :shared;
sub pandora_timed_event ($@) {
my ($time_limit, @event) = @_;
# Match events by message.
my $event_msg = $event[1];
# Do not generate more than one event every $time_limit seconds.
my $now = time();
if (!defined($TIMED_EVENTS{$event_msg}) || $TIMED_EVENTS{$event_msg} + $time_limit < $now) {
$TIMED_EVENTS{$event_msg} = $now;
pandora_event(@event);
}
}
##########################################################################
=head2 C<< pandora_extended_event (I<$pa_config>, I<$dbh>, I<$event_id>, I<$description>) >>

View File

@ -34,7 +34,7 @@ our @ISA = qw(Exporter);
# version: Defines actual version of Pandora Server for this module only
my $pandora_version = "7.0NG.769";
my $pandora_build = "230323";
my $pandora_build = "230324";
our $VERSION = $pandora_version." ".$pandora_build;
our %EXPORT_TAGS = ( 'all' => [ qw() ] );

View File

@ -4,7 +4,7 @@
%global __os_install_post %{nil}
%define name pandorafms_server
%define version 7.0NG.769
%define release 230323
%define release 230324
Summary: Pandora FMS Server
Name: %{name}

View File

@ -4,7 +4,7 @@
%global __os_install_post %{nil}
%define name pandorafms_server
%define version 7.0NG.769
%define release 230323
%define release 230324
Summary: Pandora FMS Server
Name: %{name}

View File

@ -9,7 +9,7 @@
# **********************************************************************
PI_VERSION="7.0NG.769"
PI_BUILD="230323"
PI_BUILD="230324"
MODE=$1
if [ $# -gt 1 ]; then

View File

@ -35,7 +35,7 @@ use PandoraFMS::Config;
use PandoraFMS::DB;
# version: define current version
my $version = "7.0NG.769 Build 230323";
my $version = "7.0NG.769 Build 230324";
# Pandora server configuration
my %conf;
@ -629,6 +629,21 @@ sub pandora_load_config_pdb ($) {
$conf->{'errorlogfile'} = $conf->{'errorlog_file'};
$conf->{'errorlogfile'} = "/var/log/pandora_server.error" unless defined ($conf->{'errorlogfile'});
# The DB host was overridden by pandora_ha.
$conf->{'ha_hosts_file'} = '/var/spool/pandora/data_in/conf/pandora_ha_hosts.conf' unless defined($conf->{'ha_hosts_file'});
if (-f $conf->{'ha_hosts_file'}) {
eval {
open(my $fh, '<', $conf->{'ha_hosts_file'}) or return;
my $dbhost = <$fh>;
chomp($dbhost);
if (defined($dbhost) && $dbhost ne '') {
$conf->{'dbhost'} = $dbhost;
}
close($fh);
};
}
print " [*] DB Host is " . $conf->{'dbhost'} . "\n";
# Read additional tokens from the DB
my $dbh = db_connect ($conf->{'dbengine'}, $conf->{'dbname'}, $conf->{'dbhost'}, $conf->{'dbport'}, $conf->{'dbuser'}, $conf->{'dbpass'});

View File

@ -34,15 +34,27 @@ my %Opts;
# Run as a daemon.
my $DAEMON = 0;
# Timeout for the HA DB lock.
my $LOCK_TIMEOUT = 300;
# Avoid retry old processing orders.
my $First_Cleanup = 1;
# List of known HA DB hosts.
my @HA_DB_Hosts;
# Current master node.
my $DB_Host = '';
# PID file.
my $PID_FILE = '/var/run/pandora_ha.pid';
# Server service handler.
my $Pandora_Service;
# Restart the Pandora FMS Server.
my $Restart = 0;
# Controlled exit
my $Running = 0;
@ -55,6 +67,10 @@ sub log_message($$$;$) {
my $level = $verbosity_level;
$level = 5 unless defined($level);
if ($source eq 'DEBUG' && !defined($ENV{'PANDORA_DEBUG'})) {
return;
}
if (ref($conf) eq "HASH") {
logger($conf, 'HA (' . $source . ') ' . "$message", $level);
}
@ -169,6 +185,17 @@ sub ha_keep_pandora_running($$) {
my ($conf, $dbh) = @_;
my $OSNAME = $^O;
my $control_command;
$Pandora_Service = $conf->{'pandora_service_cmd'};
# A restart was requested.
if ($Restart == 1) {
$Restart = 0;
log_message($conf, 'LOG', 'Restarting Pandora service');
$control_command = $^O eq "freebsd" ? "restart_server" : 'restart-server';
`$Pandora_Service $control_command $ENV{'PANDORA_DBHOST'} 2>/dev/null`;
return;
}
# Check if all servers are running
# Restart if crashed or keep interval is over.
@ -185,8 +212,6 @@ sub ha_keep_pandora_running($$) {
my $nservers = get_db_value ($dbh, 'SELECT count(*) FROM tserver where name = ?', $conf->{'servername'});
$Pandora_Service = $conf->{'pandora_service_cmd'};
# Check if service is running
$control_command = "status-server";
if ($OSNAME eq "freebsd") {
@ -308,6 +333,37 @@ sub ha_update_server($$) {
}
################################################################################
# Dump the list of known databases to disk.
################################################################################
sub ha_dump_databases($) {
my ($conf) = @_;
# HA is not configured.
return unless defined($conf->{'ha_hosts'});
eval {
open(my $fh, '>', $conf->{'ha_hosts_file'});
print $fh $DB_Host; # The console only needs the master DB.
close($fh);
log_message($conf, 'DEBUG', "Dumped master database $DB_Host to disk");
};
log_message($conf, 'WARNING', $@) if ($@);
}
################################################################################
# Read the list of known databases from disk.
################################################################################
sub ha_load_databases($) {
my ($conf) = @_;
# HA is not configured.
return unless defined($conf->{'ha_hosts'});
@HA_DB_Hosts = grep { !/^#/ } map { s/^\s+|\s+$//g; $_; } split(/,/, $conf->{'ha_hosts'});
log_message($conf, 'DEBUG', "Loaded databases from disk (@HA_DB_Hosts)");
}
###############################################################################
# Connect to ha database, falling back to direct connection to db.
###############################################################################
@ -324,9 +380,111 @@ sub ha_database_connect($) {
}
###############################################################################
# Main
# Connect to ha database, falling back to direct connection to db.
###############################################################################
sub ha_main($) {
sub ha_database_connect_pandora($) {
my $conf = shift;
my $dbhost = $conf->{'dbhost'};
# Load the list of HA databases.
ha_load_databases($conf);
# Select a new master database.
my ($dbh, $utimestamp, $max_utimestamp) = (undef, undef, -1);
foreach my $ha_dbhost (@HA_DB_Hosts) {
# Retry each database ha_connect_retries times.
for (my $i = 0; $i < $conf->{'ha_connect_retries'}; $i++) {
eval {
log_message($conf, 'DEBUG', "Trying database $ha_dbhost...");
$dbh= db_connect('mysql',
$conf->{'dbname'},
$ha_dbhost,
$conf->{'dbport'},
$conf->{'ha_dbuser'},
$conf->{'ha_dbpass'});
log_message($conf, 'DEBUG', "Connected to database $ha_dbhost");
};
log_message($conf, 'WARNING', $@) if ($@);
# Connection successful.
last if defined($dbh);
# Wait for the next retry.
sleep($conf->{'ha_connect_delay'});
}
# No luck. Try the next database.
next unless defined($dbh);
eval {
# Get the most recent utimestamp from the database.
$utimestamp = get_db_value($dbh, 'SELECT UNIX_TIMESTAMP(MAX(keepalive)) FROM tserver');
db_disconnect($dbh);
# Did we find a more recent database?
$utimestamp = 0 unless defined($utimestamp);
if ($utimestamp > $max_utimestamp) {
$dbhost = $ha_dbhost;
$max_utimestamp = $utimestamp;
}
};
log_message($conf, 'WARNING', $@) if ($@);
}
# Return a connection to the selected master.
eval {
log_message($conf, 'DEBUG', "Connecting to selected master $dbhost...");
$dbh = db_connect('mysql',
$conf->{'dbname'},
$dbhost,
$conf->{'dbport'},
$conf->{'ha_dbuser'},
$conf->{'ha_dbpass'});
# Restart if a new master was selected.
if ($dbhost ne $DB_Host) {
log_message($conf, 'DEBUG', "Setting master database to $dbhost");
$DB_Host = $dbhost;
$Restart = 1;
}
};
log_message($conf, 'WARNING', $@) if ($@);
# Save the list of HA databases.
ha_dump_databases($conf);
return $dbh;
}
###############################################################################
# Return 1 if the given DB is read-only, 0 otherwise.
###############################################################################
sub ha_read_only($$) {
my ($conf, $dbh) = @_;
my $read_only = get_db_value($dbh, 'SELECT @@global.read_only');
return 1 if (defined($read_only) && $read_only == 1);
return 0;
}
###############################################################################
# Restart the Pandora FMS Server.
###############################################################################
sub ha_restart_pandora($) {
my ($config) = @_;
my $control_command = $^O eq 'freebsd' ?
'restart_server' :
'restart-server';
`$config->{'pandora_service_cmd'} $control_command 2>/dev/null`;
}
###############################################################################
# Main (Pacemaker)
###############################################################################
sub ha_main_pacemaker($) {
my ($conf) = @_;
# Set the PID file.
@ -404,6 +562,100 @@ sub ha_main($) {
}
}
###############################################################################
# Main (Pandora)
###############################################################################
sub ha_main_pandora($) {
my ($conf) = @_;
# Set the PID file.
$conf->{'PID'} = $PID_FILE;
# Log to a separate file if needed.
$conf->{'log_file'} = $conf->{'ha_log_file'} if defined ($conf->{'ha_log_file'});
# Run in the background.
ha_daemonize($conf) if ($DAEMON == 1);
# Main loop.
$Running = 1;
while ($Running) {
my $dbh = undef;
eval {
# Connect to a DB.
log_message($conf, 'LOG', "Looking for databases");
$dbh = ha_database_connect_pandora($conf);
if (!defined($dbh)) {
log_message($conf, 'LOG', 'No databases available');
return;
}
# Make the DB host available to the Pandora FMS Server.
$ENV{'PANDORA_DBHOST'} = $DB_Host;
# Needed for the Enterprise module.
$conf->{'dbhost'} = $DB_Host;
# Enterprise capabilities need access to the DB.
eval {
local $SIG{__DIE__};
# Load enterprise components.
enterprise_load($conf, 1);
# Register Enterprise logger
enterprise_hook('pandoraha_logger', [\&log_message]);
log_message($conf, 'LOG', 'Enterprise capabilities loaded');
};
log_message($conf, 'LOG', "No enterprise capabilities: $@") if ($@);
log_message($conf, 'LOG', "Connected to database $DB_Host");
enterprise_hook('pandoraha_stop_slave', [$conf, $dbh]);
if (ha_read_only($conf, $dbh) == 1) {
log_message($conf, 'LOG', "The database is read-only.");
return;
}
# Check if there are updates pending.
ha_update_server($conf, $dbh);
# Keep pandora running
ha_keep_pandora_running($conf, $dbh);
# Keep Tentacle running
ha_keep_tentacle_running($conf, $dbh);
# Are we the master?
pandora_set_master($conf, $dbh);
if (!pandora_is_master($conf)) {
log_message($conf, 'LOG', $conf->{'servername'} . ' is not the current master. Skipping DB-HA actions and monitoring.');
return;
}
# Check the status of slave databases.
enterprise_hook('pandoraha_check_slaves', [$conf, $dbh, $DB_Host, \@HA_DB_Hosts]);
# Update the status of HA databases.
enterprise_hook('pandoraha_update_dbs', [$conf, $dbh, $DB_Host, \@HA_DB_Hosts]);
# Execute resync actions.
enterprise_hook('pandoraha_resync_dbs', [$conf, $dbh, $DB_Host, \@HA_DB_Hosts]);
};
log_message($conf, 'WARNING', $@) if ($@);
# Cleanup.
eval {
db_disconnect($dbh) if defined($dbh);
};
# Go to sleep.
log_message($conf, 'LOG', "Sleep.");
sleep($conf->{'ha_interval'});
}
}
################################################################################
# Stop pandora server
################################################################################
@ -429,7 +681,6 @@ END {
stop();
}
$SIG{INT} = \&stop;
$SIG{TERM} = \&stop;
@ -440,6 +691,10 @@ ha_init_pandora(\%Conf);
ha_load_pandora_conf (\%Conf);
# Main
ha_main(\%Conf);
if (defined($Conf{'ha_mode'}) && lc($Conf{'ha_mode'}) eq 'pandora') {
ha_main_pandora(\%Conf);
} else {
ha_main_pacemaker(\%Conf);
}
exit 0;

View File

@ -36,7 +36,7 @@ use Encode::Locale;
Encode::Locale::decode_argv;
# version: define current version
my $version = "7.0NG.769 Build 230323";
my $version = "7.0NG.769 Build 230324";
# save program name for logging
my $progname = basename($0);