[pkg-nagios-changes] [Git][nagios-team/pkg-icingaweb2][upstream] New upstream version 2.9.3
Bas Couwenberg (@sebastic)
gitlab at salsa.debian.org
Thu Aug 12 15:25:46 BST 2021
Bas Couwenberg pushed to branch upstream at Debian Nagios Maintainer Group / pkg-icingaweb2
Commits:
7c663274 by Bas Couwenberg at 2021-08-12T16:15:39+02:00
New upstream version 2.9.3
- - - - -
21 changed files:
- CHANGELOG.md
- VERSION
- application/VERSION
- application/controllers/AuthenticationController.php
- application/forms/Authentication/LoginForm.php
- doc/02-Installation.md
- library/Icinga/Application/Version.php
- library/Icinga/Crypt/AesCrypt.php
- library/Icinga/Web/JavaScript.php
- library/Icinga/Web/RememberMe.php
- modules/doc/module.info
- modules/migrate/module.info
- modules/monitoring/application/forms/Command/Object/ScheduleHostDowntimeCommandForm.php
- + modules/monitoring/library/Monitoring/Command/Object/ApiScheduleHostDowntimeCommand.php
- modules/monitoring/library/Monitoring/Command/Object/ScheduleHostDowntimeCommand.php
- modules/monitoring/library/Monitoring/Command/Renderer/IcingaApiCommandRenderer.php
- modules/monitoring/module.info
- modules/setup/module.info
- modules/test/module.info
- modules/translation/module.info
- public/css/icinga/login.less
Changes:
=====================================
CHANGELOG.md
=====================================
@@ -4,6 +4,33 @@ Please make sure to always read our [Upgrading](doc/80-Upgrading.md) documentati
## What's New
+### What's New in Version 2.9.3
+
+You can also find the issues related to this release on our [Roadmap](https://github.com/Icinga/icingaweb2/milestone/66?closed=1).
+
+#### Staying remembered on RHEL/CentOS 7 now possible
+
+RHEL/CentOS 7 still relies on OpenSSL v1.0.2 by default. A change in v2.9.1 resulted in an error in combination with
+this when ticking `Stay Logged In` during authentication. Staying logged in now works fine also on this platform.
+
+* Stay Logged In - Unknown cipher algorithm [#4493](https://github.com/Icinga/icingaweb2/issues/4493)
+
+#### Missing icons with SLES/OpenSUSE 15
+
+If you're running Icinga Web 2 Version 2.9.x on a SLES/OpenSUSE 15.x, you may have noticed some missing icons in the UI.
+This is due to a missing PHP extension `fileinfo`. By upgrading to this release using packages, this dependency will now
+be installed automatically.
+
+* Missing fileinfo php extension on SLES/OpenSUSE 15+ [#4503](https://github.com/Icinga/icingaweb2/issues/4503)
+
+#### Child downtimes for services are now removed automatically
+
+With Icinga v2.13, Icinga Web 2 will now make sure that service downtimes that were created automatically are also
+removed automatically. This will only work for downtimes you create with the `All Services` option after upgrading
+to this release. It will not work for downtimes created with earlier versions of Icinga Web 2.
+
+* If appropriate, set the API parameter all_services for schedule-downtime [#4501](https://github.com/Icinga/icingaweb2/pull/4501)
+
### What's New in Version 2.9.2
This is a hotfix release. v2.9.1 included a change that wasn't compatible with PostgreSQL again. This has been fixed
=====================================
VERSION
=====================================
@@ -1 +1 @@
-v2.9.2
+v2.9.3
=====================================
application/VERSION
=====================================
@@ -1 +1 @@
-07e25a923bd80001e9ab52bbbbc1008aa8befb06 2021-07-28 09:34:07 +0200
+c757a17530c326c7d6daebd6171486cb8167a8a1 2021-08-10 10:12:17 +0200
=====================================
application/controllers/AuthenticationController.php
=====================================
@@ -45,15 +45,13 @@ class AuthenticationController extends Controller
if (RememberMe::hasCookie() && $this->hasDb()) {
$authenticated = false;
- $iv = null;
try {
$rememberMeOld = RememberMe::fromCookie();
- $iv = $rememberMeOld->getAesCrypt()->getIv();
$authenticated = $rememberMeOld->authenticate();
if ($authenticated) {
$rememberMe = $rememberMeOld->renew();
$this->getResponse()->setCookie($rememberMe->getCookie());
- $rememberMe->persist($iv);
+ $rememberMe->persist($rememberMeOld->getAesCrypt()->getIv());
}
} catch (RuntimeException $e) {
Logger::error("Can't authenticate user via remember me cookie: %s", $e->getMessage());
@@ -62,7 +60,6 @@ class AuthenticationController extends Controller
}
if (! $authenticated) {
- (new RememberMe())->remove(bin2hex($iv));
$this->getResponse()->setCookie(RememberMe::forget());
}
}
@@ -110,12 +107,6 @@ class AuthenticationController extends Controller
$this->getResponse()->setHttpResponseCode(401);
} else {
if (RememberMe::hasCookie() && $this->hasDb()) {
- try {
- (new RememberMe())->remove(bin2hex(RememberMe::fromCookie()->getAesCrypt()->getIV()));
- } catch (RuntimeException $e) {
- // pass
- }
-
$this->getResponse()->setCookie(RememberMe::forget());
}
=====================================
application/forms/Authentication/LoginForm.php
=====================================
@@ -3,8 +3,10 @@
namespace Icinga\Forms\Authentication;
+use Exception;
use Icinga\Application\Config;
use Icinga\Application\Hook\AuthenticationHook;
+use Icinga\Application\Logger;
use Icinga\Authentication\Auth;
use Icinga\Authentication\User\ExternalBackend;
use Icinga\Common\Database;
@@ -90,10 +92,13 @@ class LoginForm extends Form
]
]
);
- if (! $this->hasDb()) {
+ if (! RememberMe::isSupported()) {
$this->getElement('rememberme')
->setAttrib('disabled', true)
- ->setAttrib('title', "You can't stay logged in without a database configuration backend");
+ ->setDescription($this->translate(
+ 'Staying logged in requires a database configuration backend'
+ . ' and an appropriate OpenSSL encryption method'
+ ));
}
$this->addElement(
@@ -137,9 +142,13 @@ class LoginForm extends Form
if ($authenticated) {
$auth->setAuthenticated($user);
if ($this->getElement('rememberme')->isChecked()) {
- $rememberMe = RememberMe::fromCredentials($user->getUsername(), $password);
- $this->getResponse()->setCookie($rememberMe->getCookie());
- $rememberMe->persist();
+ try {
+ $rememberMe = RememberMe::fromCredentials($user->getUsername(), $password);
+ $this->getResponse()->setCookie($rememberMe->getCookie());
+ $rememberMe->persist();
+ } catch (Exception $e) {
+ Logger::error('Failed to let user "%s" stay logged in: %s', $user->getUsername(), $e);
+ }
}
// Call provided AuthenticationHook(s) after successful login
=====================================
doc/02-Installation.md
=====================================
@@ -18,7 +18,7 @@ chapter.
* Older versions (5.6+) are only supported up until version 2.11
* [Icinga PHP Library (ipl)](https://github.com/Icinga/icinga-php-library) (>= 0.6)
* [Icinga PHP Thirdparty](https://github.com/Icinga/icinga-php-thirdparty) (>= 0.10)
-* The following PHP modules must be installed: cURL, json, gettext, intl, dom, OpenSSL and xml
+* The following PHP modules must be installed: cURL, json, gettext, fileinfo, intl, dom, OpenSSL and xml
* For exports to PDF also the following PHP modules are required: mbstring, GD, Imagick
* LDAP PHP library when using Active Directory or LDAP for authentication
* MySQL or PostgreSQL PHP libraries
=====================================
library/Icinga/Application/Version.php
=====================================
@@ -8,7 +8,7 @@ namespace Icinga\Application;
*/
class Version
{
- const VERSION = '2.9.2';
+ const VERSION = '2.9.3';
/**
* Get the version of this instance of Icinga Web 2
=====================================
library/Icinga/Crypt/AesCrypt.php
=====================================
@@ -14,7 +14,7 @@ use RuntimeException;
* ```php
*
* // Encryption
- * $encryptedData = new AesCrypt()->encrypt($data); // Accepts a string
+ * $encryptedData = (new AesCrypt())->encrypt($data); // Accepts a string
*
*
* // Encrypt and encode to Base64
@@ -23,7 +23,7 @@ use RuntimeException;
*
* // Decryption
* $aesCrypt = (new AesCrypt())
- * ->setTag($tag)
+ * ->setTag($tag) // if exists
* ->setIV($iv)
* ->setKey($key);
*
@@ -35,15 +35,25 @@ use RuntimeException;
* ->setIV($iv)
* ->setKey($key);
*
- * $decryptedData = $aesCrypt->->decryptFromBase64($data);
+ * $decryptedData = $aesCrypt->decryptFromBase64($data);
* ```
*
*/
class AesCrypt
{
+ /** @var array The list of cipher methods */
+ const METHODS = [
+ 'aes-256-gcm',
+ 'aes-256-cbc',
+ 'aes-256-ctr'
+ ];
+
/** @var string The encryption key */
private $key;
+ /** @var int The length of the key */
+ private $keyLength;
+
/** @var string The initialization vector which is not NULL */
private $iv;
@@ -51,21 +61,15 @@ class AesCrypt
private $tag;
/** @var string The cipher method */
- private $method = 'AES-128-GCM';
-
- const GCM_SUPPORT_VERSION = '7.1';
+ private $method;
- public function __construct($random_bytes_len = 128)
+ public function __construct($keyLength = 128)
{
- if (version_compare(PHP_VERSION, self::GCM_SUPPORT_VERSION, '<')) {
- $this->method = 'AES-128-CBC';
- }
-
- $this->key = random_bytes($random_bytes_len);
+ $this->keyLength = $keyLength;
}
/**
- * Force set the method
+ * Set the method
*
* @return $this
*/
@@ -76,6 +80,45 @@ class AesCrypt
return $this;
}
+ /**
+ * Get the method
+ *
+ * @return string
+ */
+ public function getMethod()
+ {
+ if ($this->method === null) {
+ $this->method = $this->getSupportedMethod();
+ }
+
+ return $this->method;
+ }
+
+ /**
+ * Get supported method
+ *
+ * @return string
+ *
+ * @throws RuntimeException If none of the methods listed in the METHODS array is available
+ */
+ protected function getSupportedMethod()
+ {
+ $availableMethods = openssl_get_cipher_methods();
+ $methods = self::METHODS;
+
+ if (! $this->isAuthenticatedEncryptionSupported()) {
+ unset($methods[0]);
+ }
+
+ foreach ($methods as $method) {
+ if (in_array($method, $availableMethods)) {
+ return $method;
+ }
+ }
+
+ throw new RuntimeException('No supported method found');
+ }
+
/**
* Set the key
*
@@ -93,12 +136,11 @@ class AesCrypt
*
* @return string
*
- * @throws RuntimeException If the key is not set
*/
public function getKey()
{
if (empty($this->key)) {
- throw new RuntimeException('No key set');
+ $this->key = random_bytes($this->keyLength);
}
return $this->key;
@@ -121,12 +163,11 @@ class AesCrypt
*
* @return string
*
- * @throws RuntimeException If the IV is not set
*/
public function getIV()
{
if (empty($this->iv)) {
- $len = openssl_cipher_iv_length($this->method);
+ $len = openssl_cipher_iv_length($this->getMethod());
$this->iv = random_bytes($len);
}
@@ -137,9 +178,20 @@ class AesCrypt
* Set the Tag
*
* @return $this
+ *
+ * @throws RuntimeException If a tag is available but authenticated encryption (AE) is not supported.
+ *
+ * @throws UnexpectedValueException If tag length is less then 16
*/
public function setTag($tag)
{
+ if (! $this->isAuthenticatedEncryptionSupported()) {
+ throw new RuntimeException(sprintf(
+ "The given decryption method is not supported in php version '%s'",
+ PHP_VERSION
+ ));
+ }
+
if (strlen($tag) !== 16) {
throw new UnexpectedValueException(sprintf(
'expects tag length to be 16, got instead %s',
@@ -169,7 +221,7 @@ class AesCrypt
}
/**
- * Decrypt the given data using the key, iv and tag
+ * Decrypt the given string
*
* @param string $data
*
@@ -179,11 +231,11 @@ class AesCrypt
*/
public function decrypt($data)
{
- if ($this->method === 'AES-128-CBC') {
- return $this->decryptCBC($data);
+ if (! $this->isAuthenticatedEncryptionRequired()) {
+ return $this->nonAEDecrypt($data);
}
- $decrypt = openssl_decrypt($data, $this->method, $this->getKey(), 0, $this->getIV(), $this->getTag());
+ $decrypt = openssl_decrypt($data, $this->getMethod(), $this->getKey(), 0, $this->getIV(), $this->getTag());
if ($decrypt === false) {
throw new RuntimeException('Decryption failed');
@@ -193,11 +245,13 @@ class AesCrypt
}
/**
- * Decode from Base64 and decrypt the given data using the key, iv and tag
+ * Decode from Base64 and decrypt the given string
*
* @param string $data
*
- * @return string decrypted data
+ * @return string The base64 decoded and decrypted string
+ *
+ * @deprecated Use decrypt() instead as it also returns a base64 decoded string
*
* @throws RuntimeException If decryption fails
*/
@@ -207,21 +261,21 @@ class AesCrypt
}
/**
- * Encrypt the given data using the key, iv and tag
+ * Encrypt the given string
*
* @param string $data
*
- * @return string encrypted data
+ * @return string encrypted string
*
* @throws RuntimeException If decryption fails
*/
public function encrypt($data)
{
- if ($this->method === 'AES-128-CBC') {
- return $this->encryptCBC($data);
+ if (! $this->isAuthenticatedEncryptionRequired()) {
+ return $this->nonAEEncrypt($data);
}
- $encrypt = openssl_encrypt($data, $this->method, $this->getkey(), 0, $this->getIV(), $this->tag);
+ $encrypt = openssl_encrypt($data, $this->getMethod(), $this->getKey(), 0, $this->getIV(), $this->tag);
if ($encrypt === false) {
throw new RuntimeException('Encryption failed');
@@ -231,11 +285,13 @@ class AesCrypt
}
/**
- * Encrypt the given string using the the key, iv, tag and encode to Base64
+ * Encrypt the given string and encode to Base64
*
* @param string $data
*
- * @return string encrypted and encoded to Base64 data
+ * @return string encrypted and base64 encoded string
+ *
+ * @deprecated Use encrypt() instead as it also returns a base64 encoded string
*
* @throws RuntimeException If encryption fails
*/
@@ -244,18 +300,23 @@ class AesCrypt
return base64_encode($this->encrypt($data));
}
- private function decryptCBC($data)
+ /**
+ * Decrypt the given string with non Authenticated encryption (AE) cipher method
+ *
+ * @param string $data
+ *
+ * @return string decrypted string
+ *
+ * @throws RuntimeException If decryption fails
+ */
+ private function nonAEDecrypt($data)
{
- if (strlen($this->getIV()) !== 16) {
- throw new RuntimeException('Decryption failed');
- }
-
$c = base64_decode($data);
$hmac = substr($c, 0, 32);
$data = substr($c, 32);
- $decrypt = openssl_decrypt($data, $this->method, $this->getKey(), 0, $this->getIV());
- $calcHmac = hash_hmac('sha256', $data, $this->getKey(), true);
+ $decrypt = openssl_decrypt($data, $this->getMethod(), $this->getKey(), 0, $this->getIV());
+ $calcHmac = hash_hmac('sha256', $this->getIV() . $data, $this->getKey(), true);
if ($decrypt === false || ! hash_equals($hmac, $calcHmac)) {
throw new RuntimeException('Decryption failed');
@@ -264,16 +325,45 @@ class AesCrypt
return $decrypt;
}
- private function encryptCBC($data)
+ /**
+ * Encrypt the given string with non Authenticated encryption (AE) cipher method
+ *
+ * @param string $data
+ *
+ * @return string encrypted string
+ *
+ * @throws RuntimeException If encryption fails
+ */
+ private function nonAEEncrypt($data)
{
- $encrypt = openssl_encrypt($data, $this->method, $this->getkey(), 0, $this->getIV());
+ $encrypt = openssl_encrypt($data, $this->getMethod(), $this->getKey(), 0, $this->getIV());
if ($encrypt === false) {
throw new RuntimeException('Encryption failed');
}
- $hmac = hash_hmac('sha256', $encrypt, $this->getkey(), true);
+ $hmac = hash_hmac('sha256', $this->getIV() . $encrypt, $this->getKey(), true);
return base64_encode($hmac . $encrypt);
}
+
+ /**
+ * Whether the Authenticated encryption (a tag) is required
+ *
+ * @return bool True if required false otherwise
+ */
+ public function isAuthenticatedEncryptionRequired()
+ {
+ return $this->getMethod() === 'aes-256-gcm';
+ }
+
+ /**
+ * Whether the php version supports Authenticated encryption (AE) or not
+ *
+ * @return bool True if supported false otherwise
+ */
+ public function isAuthenticatedEncryptionSupported()
+ {
+ return PHP_VERSION_ID >= 70100;
+ }
}
=====================================
library/Icinga/Web/JavaScript.php
=====================================
@@ -226,7 +226,7 @@ class JavaScript
*/
public static function optimizeDefine($js, $filePath, $basePath, $packageName)
{
- if (! preg_match(self::DEFINE_RE, $js, $match)) {
+ if (! preg_match(self::DEFINE_RE, $js, $match) || strpos($js, 'define.amd') !== false) {
return $js;
}
@@ -245,12 +245,17 @@ class JavaScript
$assetName = Json::encode($assetName, JSON_UNESCAPED_SLASHES);
} catch (JsonDecodeException $_) {
$assetName = $match[1];
- Logger::error('Can\'t optimize name of "%s". Are single quotes used instead of double quotes?', $filePath);
+ Logger::debug('Can\'t optimize name of "%s". Are single quotes used instead of double quotes?', $filePath);
}
try {
$dependencies = $match[2] ? Json::decode($match[2]) : [];
foreach ($dependencies as &$dependencyName) {
+ if ($dependencyName === 'exports') {
+ // exports is a special keyword and doesn't need optimization
+ continue;
+ }
+
if (preg_match('~^((?:\.\.?/)+)*(.*)~', $dependencyName, $natch)) {
$dependencyName = join(DIRECTORY_SEPARATOR, array_filter([
$packageName,
@@ -266,7 +271,7 @@ class JavaScript
$dependencies = Json::encode($dependencies, JSON_UNESCAPED_SLASHES);
} catch (JsonDecodeException $_) {
$dependencies = $match[2];
- Logger::error(
+ Logger::debug(
'Can\'t optimize dependencies of "%s". Are single quotes used instead of double quotes?',
$filePath
);
=====================================
library/Icinga/Web/RememberMe.php
=====================================
@@ -39,6 +39,28 @@ class RememberMe
/** @var int Timestamp when the remember me cookie expires */
protected $expiresAt;
+ /**
+ * Get whether staying logged in is possible
+ *
+ * @return bool
+ */
+ public static function isSupported()
+ {
+ $self = new self();
+
+ if (! $self->hasDb()) {
+ return false;
+ }
+
+ try {
+ (new AesCrypt())->getMethod();
+ } catch (RuntimeException $_) {
+ return false;
+ }
+
+ return true;
+ }
+
/**
* Get whether the remember cookie is set
*
@@ -50,12 +72,18 @@ class RememberMe
}
/**
- * Unset the remember me cookie from PHP's `$_COOKIE` superglobal and return the invalidation cookie
+ * Remove the database entry if exists and unset the remember me cookie from PHP's `$_COOKIE` superglobal
*
- * @return Cookie Cookie which has to be sent to client in oder to remove the remember me cookie
+ * @return Cookie The invalidation cookie which has to be sent to client in oder to remove the remember me cookie
*/
public static function forget()
{
+ if (self::hasCookie()) {
+ $data = explode('|', $_COOKIE[static::COOKIE]);
+ $iv = base64_decode(array_pop($data));
+ (new self())->remove(bin2hex($iv));
+ }
+
unset($_COOKIE[static::COOKIE]);
return (new Cookie(static::COOKIE))
@@ -92,19 +120,15 @@ class RememberMe
->setKey(hex2bin($rs->passphrase))
->setIV($iv);
- if (version_compare(PHP_VERSION, AesCrypt::GCM_SUPPORT_VERSION, '>=')) {
- $tag = array_pop($data);
-
- if (empty($data)) {
- $rememberMe->aesCrypt = (new AesCrypt())
- ->setMethod('AES-128-CBC')
- ->setKey(hex2bin($rs->passphrase))
- ->setIV($iv);
-
- $data[0] = $tag; // encryptedPass
- } else {
- $rememberMe->aesCrypt->setTag(base64_decode($tag));
- }
+ if (count($data) > 1) {
+ $rememberMe->aesCrypt->setTag(
+ base64_decode(array_pop($data))
+ );
+ } elseif ($rememberMe->aesCrypt->isAuthenticatedEncryptionRequired()) {
+ throw new RuntimeException(
+ "The given decryption method needs a tag, but is not specified. "
+ . "You have probably updated the PHP version."
+ );
}
$rememberMe->username = $rs->username;
@@ -125,7 +149,7 @@ class RememberMe
{
$aesCrypt = new AesCrypt();
$rememberMe = new static();
- $rememberMe->encryptedPassword = $aesCrypt->encryptToBase64($password);
+ $rememberMe->encryptedPassword = $aesCrypt->encrypt($password);
$rememberMe->username = $username;
$rememberMe->aesCrypt = $aesCrypt;
@@ -159,7 +183,7 @@ class RememberMe
base64_encode($this->aesCrypt->getIV()),
];
- if (version_compare(PHP_VERSION, AesCrypt::GCM_SUPPORT_VERSION, '>=')) {
+ if ($this->aesCrypt->isAuthenticatedEncryptionRequired()) {
array_splice($values, 1, 0, base64_encode($this->aesCrypt->getTag()));
}
@@ -208,7 +232,6 @@ class RememberMe
*/
public function authenticate()
{
- $password = $this->aesCrypt->decryptFromBase64($this->encryptedPassword);
$auth = Auth::getInstance();
$authChain = $auth->getAuthChain();
$authChain->setSkipExternalBackends(true);
@@ -217,7 +240,11 @@ class RememberMe
$user->setDomain(Config::app()->get('authentication', 'default_domain'));
}
- $authenticated = $authChain->authenticate($user, $password);
+ $authenticated = $authChain->authenticate(
+ $user,
+ $this->aesCrypt->decrypt($this->encryptedPassword)
+ );
+
if ($authenticated) {
$auth->setAuthenticated($user);
}
@@ -228,9 +255,9 @@ class RememberMe
/**
* Persist the remember me information into the database
*
- * Any previous stored information is automatically removed.
+ * To remove any previous stored information, set the iv
*
- * @param string|null $iv
+ * @param string|null $iv To remove a specific iv record from the database
*
* @return $this
*/
@@ -254,7 +281,7 @@ class RememberMe
}
/**
- * Remove remember me information from the database
+ * Remove remember me information from the database on the basis of iv
*
* @param string $iv
*
@@ -278,14 +305,14 @@ class RememberMe
{
return static::fromCredentials(
$this->username,
- $this->aesCrypt->decryptFromBase64($this->encryptedPassword)
+ $this->aesCrypt->decrypt($this->encryptedPassword)
);
}
/**
- * Get all users using rememberme cookie
+ * Get all users using remember me cookie
*
- * @return array
+ * @return array Array of users
*/
public static function getAllUser()
{
@@ -303,11 +330,11 @@ class RememberMe
}
/**
- * Get all rememberme cookies of the given user
+ * Get all remember me entries from the database of the given user.
*
* @param $username
*
- * @return array
+ * @return array Array of database entries
*/
public static function getAllByUsername($username)
{
@@ -325,7 +352,7 @@ class RememberMe
}
/**
- * Get the encrypton/decryption instance
+ * Get the AesCrypt instance
*
* @return AesCrypt
*/
=====================================
modules/doc/module.info
=====================================
@@ -1,4 +1,4 @@
Module: doc
-Version: 2.9.2
+Version: 2.9.3
Description: Documentation module
Extracts, shows and exports documentation for Icinga Web 2 and its modules.
=====================================
modules/migrate/module.info
=====================================
@@ -1,5 +1,5 @@
Module: migrate
-Version: 2.9.2
+Version: 2.9.3
Description: Migrate module
This module was introduced with the domain-aware authentication feature in version 2.5.0.
It helps you migrating users and user configurations according to a given domain.
=====================================
modules/monitoring/application/forms/Command/Object/ScheduleHostDowntimeCommandForm.php
=====================================
@@ -6,9 +6,12 @@ namespace Icinga\Module\Monitoring\Forms\Command\Object;
use DateInterval;
use DateTime;
use Icinga\Application\Config;
+use Icinga\Module\Monitoring\Command\Object\ApiScheduleHostDowntimeCommand;
use Icinga\Module\Monitoring\Command\Object\PropagateHostDowntimeCommand;
use Icinga\Module\Monitoring\Command\Object\ScheduleHostDowntimeCommand;
use Icinga\Module\Monitoring\Command\Object\ScheduleServiceDowntimeCommand;
+use Icinga\Module\Monitoring\Command\Transport\ApiCommandTransport;
+use Icinga\Module\Monitoring\Command\Transport\CommandTransport;
use Icinga\Web\Notification;
/**
@@ -105,7 +108,37 @@ class ScheduleHostDowntimeCommandForm extends ScheduleServiceDowntimeCommandForm
return false;
}
+ // Send all_services API parameter if Icinga is equal to or greater than 2.11.0
+ $allServicesNative = version_compare($this->getBackend()->getProgramVersion(), '2.11.0', '>=');
+ // Use ApiScheduleHostDowntimeCommand only when Icinga is equal to or greater than 2.11.0 and
+ // when an API command transport is requested or only API command transports are configured:
+ $useApiDowntime = $allServicesNative;
+ if ($useApiDowntime) {
+ $transport = $this->getTransport($this->getRequest());
+ if ($transport instanceof CommandTransport) {
+ foreach ($transport::getConfig() as $config) {
+ if (strtolower($config->transport) !== 'api') {
+ $useApiDowntime = false;
+ break;
+ }
+ }
+ } elseif (! $transport instanceof ApiCommandTransport) {
+ $useApiDowntime = false;
+ }
+ }
+
foreach ($this->objects as $object) {
+ if ($useApiDowntime) {
+ $hostDowntime = (new ApiScheduleHostDowntimeCommand())
+ ->setForAllServices($this->getElement('all_services')->isChecked())
+ ->setChildOptions((int) $this->getElement('child_hosts')->getValue());
+ // Code duplicated for readability and scope
+ $hostDowntime->setObject($object);
+ $this->scheduleDowntime($hostDowntime, $this->request);
+
+ continue;
+ }
+
/** @var \Icinga\Module\Monitoring\Object\Host $object */
if (($childHostsEl = $this->getElement('child_hosts')) !== null) {
$childHosts = (int) $childHostsEl->getValue();
@@ -114,7 +147,8 @@ class ScheduleHostDowntimeCommandForm extends ScheduleServiceDowntimeCommandForm
}
$allServices = $this->getElement('all_services')->isChecked();
if ($childHosts === 0) {
- $hostDowntime = new ScheduleHostDowntimeCommand();
+ $hostDowntime = (new ScheduleHostDowntimeCommand())
+ ->setForAllServicesNative($allServicesNative);
if ($allServices === true) {
$hostDowntime->setForAllServices();
};
=====================================
modules/monitoring/library/Monitoring/Command/Object/ApiScheduleHostDowntimeCommand.php
=====================================
@@ -0,0 +1,40 @@
+<?php
+/* Icinga Web 2 | (c) 2021 Icinga GmbH | GPLv2+ */
+
+namespace Icinga\Module\Monitoring\Command\Object;
+
+/**
+ * Schedule host downtime command for API command transport and Icinga >= 2.11.0 that
+ * sends all_services and child_options in a single request
+ */
+class ApiScheduleHostDowntimeCommand extends ScheduleHostDowntimeCommand
+{
+ /** @var int Whether no, triggered, or non-triggered child downtimes should be scheduled */
+ protected $childOptions;
+
+ protected $forAllServicesNative = true;
+
+ /**
+ * Get child options, i.e. whether no, triggered, or non-triggered child downtimes should be scheduled
+ *
+ * @return int
+ */
+ public function getChildOptions()
+ {
+ return $this->childOptions;
+ }
+
+ /**
+ * Set child options, i.e. whether no, triggered, or non-triggered child downtimes should be scheduled
+ *
+ * @param int $childOptions
+ *
+ * @return $this
+ */
+ public function setChildOptions($childOptions)
+ {
+ $this->childOptions = $childOptions;
+
+ return $this;
+ }
+}
=====================================
modules/monitoring/library/Monitoring/Command/Object/ScheduleHostDowntimeCommand.php
=====================================
@@ -23,6 +23,9 @@ class ScheduleHostDowntimeCommand extends ScheduleServiceDowntimeCommand
*/
protected $forAllServices = false;
+ /** @var bool Whether to send the all_services API parameter */
+ protected $forAllServicesNative;
+
/**
* Set whether to schedule a downtime for all services associated with a particular host
*
@@ -45,4 +48,28 @@ class ScheduleHostDowntimeCommand extends ScheduleServiceDowntimeCommand
{
return $this->forAllServices;
}
+
+ /**
+ * Get whether to send the all_services API parameter
+ *
+ * @return bool
+ */
+ public function isForAllServicesNative()
+ {
+ return $this->forAllServicesNative;
+ }
+
+ /**
+ * Get whether to send the all_services API parameter
+ *
+ * @param bool $forAllServicesNative
+ *
+ * @return $this
+ */
+ public function setForAllServicesNative($forAllServicesNative = true)
+ {
+ $this->forAllServicesNative = (bool) $forAllServicesNative;
+
+ return $this;
+ }
}
=====================================
modules/monitoring/library/Monitoring/Command/Renderer/IcingaApiCommandRenderer.php
=====================================
@@ -3,10 +3,12 @@
namespace Icinga\Module\Monitoring\Command\Renderer;
+use Icinga\Module\Monitoring\Backend\MonitoringBackend;
use Icinga\Module\Monitoring\Command\IcingaApiCommand;
use Icinga\Module\Monitoring\Command\Instance\ToggleInstanceFeatureCommand;
use Icinga\Module\Monitoring\Command\Object\AcknowledgeProblemCommand;
use Icinga\Module\Monitoring\Command\Object\AddCommentCommand;
+use Icinga\Module\Monitoring\Command\Object\ApiScheduleHostDowntimeCommand;
use Icinga\Module\Monitoring\Command\Object\DeleteCommentCommand;
use Icinga\Module\Monitoring\Command\Object\DeleteDowntimeCommand;
use Icinga\Module\Monitoring\Command\Object\ProcessCheckResultCommand;
@@ -156,25 +158,40 @@ class IcingaApiCommandRenderer implements IcingaCommandRendererInterface
'trigger_name' => $command->getTriggerId()
);
$commandData = $data;
+
if ($command instanceof PropagateHostDowntimeCommand) {
- /** @var \Icinga\Module\Monitoring\Command\Object\PropagateHostDowntimeCommand $command */
$commandData['child_options'] = $command->getTriggered() ? 1 : 2;
+ } elseif ($command instanceof ApiScheduleHostDowntimeCommand) {
+ // We assume that it has previously been verified that the Icinga version is
+ // equal to or greater than 2.11.0
+ $commandData['child_options'] = $command->getChildOptions();
+ }
+
+ $allServicesCompat = false;
+ if ($command instanceof ScheduleHostDowntimeCommand) {
+ if ($command->isForAllServicesNative()) {
+ // We assume that it has previously been verified that the Icinga version is
+ // equal to or greater than 2.11.0
+ $commandData['all_services'] = $command->getForAllServices();
+ } else {
+ $allServicesCompat = $command->getForAllServices();
+ }
}
+
$this->applyFilter($commandData, $command->getObject());
$apiCommand = IcingaApiCommand::create($endpoint, $commandData);
- if ($command instanceof ScheduleHostDowntimeCommand
- /** @var \Icinga\Module\Monitoring\Command\Object\ScheduleHostDowntimeCommand $command */
- && $command->getForAllServices()
- ) {
- $commandData = $data + array(
- 'type' => 'Service',
- 'filter' => 'host.name == host_name',
- 'filter_vars' => array(
+
+ if ($allServicesCompat) {
+ $commandData = $data + [
+ 'type' => 'Service',
+ 'filter' => 'host.name == host_name',
+ 'filter_vars' => [
'host_name' => $command->getObject()->getName()
- )
- );
+ ]
+ ];
$apiCommand->setNext(IcingaApiCommand::create($endpoint, $commandData));
}
+
return $apiCommand;
}
=====================================
modules/monitoring/module.info
=====================================
@@ -1,5 +1,5 @@
Module: monitoring
-Version: 2.9.2
+Version: 2.9.3
Description: Icinga monitoring module
IDO accessor and UI for your monitoring. This is the initial instalment for a
graphical presentation of Icinga environments. The predecessor of Icinga DB.
=====================================
modules/setup/module.info
=====================================
@@ -1,5 +1,5 @@
Module: setup
-Version: 2.9.2
+Version: 2.9.3
Description: Setup module
Web based wizard for setting up Icinga Web 2 and its modules.
This includes the data backends (e.g. relational database, LDAP),
=====================================
modules/test/module.info
=====================================
@@ -1,5 +1,5 @@
Module: test
-Version: 2.9.2
+Version: 2.9.3
Description: Translation module
This module allows developers to run (unit) tests against Icinga Web 2 and
any of its modules. Usually you do not need to enable this.
=====================================
modules/translation/module.info
=====================================
@@ -1,5 +1,5 @@
Module: translation
-Version: 2.9.2
+Version: 2.9.3
Description: Translation module
This module allows developers and translators to translate modules for multiple
languages. You do not need this module to run an internationalized web frontend.
=====================================
public/css/icinga/login.less
=====================================
@@ -113,6 +113,11 @@
.toggle-switch {
margin-right: 1em;
}
+
+ .control-info {
+ line-height: 1.5;
+ margin-left: .5em;
+ }
}
}
View it on GitLab: https://salsa.debian.org/nagios-team/pkg-icingaweb2/-/commit/7c663274ac198d7654b722540605a26e861f37f2
--
View it on GitLab: https://salsa.debian.org/nagios-team/pkg-icingaweb2/-/commit/7c663274ac198d7654b722540605a26e861f37f2
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-nagios-changes/attachments/20210812/6bac95e5/attachment-0001.htm>
More information about the pkg-nagios-changes
mailing list