mirror of
https://github.com/Icinga/icingadb-web.git
synced 2026-02-20 00:10:09 -05:00
There are multiple possible outputs for an Icinga DB version. The package version contain the git tag, with a leading "v". The development version mimics git-describe(1), including a commit hash separated by a dash after the semantic version. The current version comparison uses PHP's builtin version_compare(). This results in leading "v"s to return invalid results. Furthermore, it treats everything behind the version as an "any string"[^0], which is smaller than dev, alpha, beta, and so on. Thus, any git-describe(1) version of Icinga DB 1.4.0 would be considered smaller as 1.4.0. Fixes #1230. [^0]: https://www.php.net/manual/en/function.version-compare.php
158 lines
5.6 KiB
PHP
158 lines
5.6 KiB
PHP
<?php
|
|
|
|
// Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2
|
|
|
|
namespace Icinga\Module\Icingadb\ProvidedHook;
|
|
|
|
use Icinga\Application\Hook\HealthHook;
|
|
use Icinga\Module\Icingadb\Common\Backend;
|
|
use Icinga\Module\Icingadb\Common\Database;
|
|
use Icinga\Module\Icingadb\Model\Instance;
|
|
use ipl\Web\Url;
|
|
|
|
class IcingaHealth extends HealthHook
|
|
{
|
|
use Database;
|
|
|
|
public const REQUIRED_ICINGADB_VERSION = '1.4.0';
|
|
|
|
/**
|
|
* normalizeVersion extracts a version string from Icinga DB's reported
|
|
* version comparable with REQUIRED_ICINGADB_VERSION via version_compare.
|
|
*
|
|
* @param string $version Icinga DB version string to normalize.
|
|
*
|
|
* @return string Normalized Icinga DB version string.
|
|
*/
|
|
public static function normalizeVersion(string $version): string
|
|
{
|
|
// Ignore leading "v" when the git tag is used, e.g., "v1.4.0".
|
|
$version = ltrim($version, 'v');
|
|
// Ignore everything after "-" used by git describe, e.g., "1.4.0-g...".
|
|
$version = explode('-', $version, 2)[0];
|
|
|
|
return $version;
|
|
}
|
|
|
|
/** @var Instance */
|
|
protected $instance;
|
|
|
|
public function getName(): string
|
|
{
|
|
return 'Icinga DB';
|
|
}
|
|
|
|
public function getUrl(): Url
|
|
{
|
|
return Url::fromPath('icingadb/health');
|
|
}
|
|
|
|
public function checkHealth()
|
|
{
|
|
$instance = $this->getInstance();
|
|
|
|
if ($instance === null) {
|
|
$this->setState(self::STATE_UNKNOWN);
|
|
$this->setMessage(t(
|
|
'Icinga DB is not running or not writing into the database'
|
|
. ' (make sure the icinga feature "icingadb" is enabled)'
|
|
));
|
|
} elseif ($instance->heartbeat->getTimestamp() < time() - 60) {
|
|
$this->setState(self::STATE_CRITICAL);
|
|
$this->setMessage(t(
|
|
'Icinga DB is not running or not writing into the database'
|
|
. ' (make sure the icinga feature "icingadb" is enabled)'
|
|
));
|
|
} elseif (
|
|
! isset($instance->icingadb_version)
|
|
|| version_compare(
|
|
self::normalizeVersion($instance->icingadb_version),
|
|
self::REQUIRED_ICINGADB_VERSION,
|
|
'<'
|
|
)
|
|
) {
|
|
$this->setState(self::STATE_CRITICAL);
|
|
$this->setMessage(sprintf(
|
|
t('Icinga DB is outdated, please upgrade to version %s or later.'),
|
|
self::REQUIRED_ICINGADB_VERSION
|
|
));
|
|
} else {
|
|
$this->setState(self::STATE_OK);
|
|
$warningMessages = [];
|
|
|
|
if (! $instance->icinga2_active_host_checks_enabled) {
|
|
$this->setState(self::STATE_WARNING);
|
|
$warningMessages[] = t('Active host checks are disabled');
|
|
}
|
|
|
|
if (! $instance->icinga2_active_service_checks_enabled) {
|
|
$this->setState(self::STATE_WARNING);
|
|
$warningMessages[] = t('Active service checks are disabled');
|
|
}
|
|
|
|
if (! $instance->icinga2_notifications_enabled) {
|
|
$this->setState(self::STATE_WARNING);
|
|
$warningMessages[] = t('Notifications are disabled');
|
|
}
|
|
|
|
if ($this->getState() === self::STATE_WARNING) {
|
|
$this->setMessage(implode("; ", $warningMessages));
|
|
} else {
|
|
$this->setMessage(sprintf(
|
|
t('Icinga DB is running and writing into the database. (Version: %s)'),
|
|
$instance->icingadb_version
|
|
));
|
|
}
|
|
}
|
|
|
|
if ($instance !== null) {
|
|
$this->setMetrics([
|
|
'heartbeat' => $instance->heartbeat->getTimestamp(),
|
|
'responsible' => $instance->responsible,
|
|
'icinga2_active_host_checks_enabled' => $instance->icinga2_active_host_checks_enabled,
|
|
'icinga2_active_service_checks_enabled' => $instance->icinga2_active_service_checks_enabled,
|
|
'icinga2_event_handlers_enabled' => $instance->icinga2_event_handlers_enabled,
|
|
'icinga2_flap_detection_enabled' => $instance->icinga2_flap_detection_enabled,
|
|
'icinga2_notifications_enabled' => $instance->icinga2_notifications_enabled,
|
|
'icinga2_performance_data_enabled' => $instance->icinga2_performance_data_enabled,
|
|
'icinga2_start_time' => $instance->icinga2_start_time->getTimestamp(),
|
|
'icinga2_version' => $instance->icinga2_version,
|
|
'icingadb_version' => $instance->icingadb_version ?? null,
|
|
'endpoint' => ['name' => $instance->endpoint->name]
|
|
]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get an Icinga DB instance
|
|
*
|
|
* @return ?Instance
|
|
*/
|
|
protected function getInstance()
|
|
{
|
|
if ($this->instance === null) {
|
|
$query = Instance::on($this->getDb())
|
|
->with('endpoint')
|
|
->columns([
|
|
'heartbeat',
|
|
'responsible',
|
|
'icinga2_active_host_checks_enabled',
|
|
'icinga2_active_service_checks_enabled',
|
|
'icinga2_event_handlers_enabled',
|
|
'icinga2_flap_detection_enabled',
|
|
'icinga2_notifications_enabled',
|
|
'icinga2_performance_data_enabled',
|
|
'icinga2_start_time',
|
|
'icinga2_version',
|
|
'endpoint.name'
|
|
]);
|
|
if (Backend::supportsDependencies()) {
|
|
$query->withColumns('icingadb_version');
|
|
}
|
|
|
|
$this->instance = $query->first();
|
|
}
|
|
|
|
return $this->instance;
|
|
}
|
|
}
|