Merge branch 'master' into feature/custom-menu-items-5600
Conflicts: modules/monitoring/application/views/scripts/list/comments.phtml modules/monitoring/application/views/scripts/list/downtimes.phtml
This commit is contained in:
commit
a55cced039
|
@ -33,7 +33,23 @@ class DbResourceForm extends Form
|
||||||
if (Platform::hasPostgresqlSupport()) {
|
if (Platform::hasPostgresqlSupport()) {
|
||||||
$dbChoices['pgsql'] = 'PostgreSQL';
|
$dbChoices['pgsql'] = 'PostgreSQL';
|
||||||
}
|
}
|
||||||
|
if (Platform::hasMssqlSupport()) {
|
||||||
|
$dbChoices['mssql'] = 'MSSQL';
|
||||||
|
}
|
||||||
|
if (Platform::hasOracleSupport()) {
|
||||||
|
$dbChoices['oracle'] = 'Oracle';
|
||||||
|
}
|
||||||
|
if (Platform::hasOciSupport()) {
|
||||||
|
$dbChoices['oci'] = 'Oracle (OCI8)';
|
||||||
|
}
|
||||||
|
$offerPostgres = false;
|
||||||
|
if (isset($formData['db'])) {
|
||||||
|
if ($formData['db'] === 'pgsql') {
|
||||||
|
$offerPostgres = true;
|
||||||
|
}
|
||||||
|
} elseif (key($dbChoices) === 'pgsql') {
|
||||||
|
$offerPostgres = true;
|
||||||
|
}
|
||||||
$this->addElement(
|
$this->addElement(
|
||||||
'text',
|
'text',
|
||||||
'name',
|
'name',
|
||||||
|
@ -68,11 +84,11 @@ class DbResourceForm extends Form
|
||||||
'number',
|
'number',
|
||||||
'port',
|
'port',
|
||||||
array(
|
array(
|
||||||
'required' => true,
|
|
||||||
'preserveDefault' => true,
|
|
||||||
'label' => $this->translate('Port'),
|
|
||||||
'description' => $this->translate('The port to use'),
|
'description' => $this->translate('The port to use'),
|
||||||
'value' => ! array_key_exists('db', $formData) || $formData['db'] === 'mysql' ? 3306 : 5432
|
'label' => $this->translate('Port'),
|
||||||
|
'preserveDefault' => true,
|
||||||
|
'required' => $offerPostgres,
|
||||||
|
'value' => $offerPostgres ? 5432 : null
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
$this->addElement(
|
$this->addElement(
|
||||||
|
@ -103,6 +119,17 @@ class DbResourceForm extends Form
|
||||||
'description' => $this->translate('The password to use for authentication')
|
'description' => $this->translate('The password to use for authentication')
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
$this->addElement(
|
||||||
|
'checkbox',
|
||||||
|
'persistent',
|
||||||
|
array(
|
||||||
|
'description' => $this->translate(
|
||||||
|
'Check this box for persistent database connections. Persistent connections are not closed at the'
|
||||||
|
. ' end of a request, but are cached and re-used. This is experimental'
|
||||||
|
),
|
||||||
|
'label' => $this->translate('Persistent')
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -236,10 +236,10 @@ class ResourceConfigForm extends ConfigForm
|
||||||
'livestatus' => 'Livestatus',
|
'livestatus' => 'Livestatus',
|
||||||
'ssh' => $this->translate('SSH Identity'),
|
'ssh' => $this->translate('SSH Identity'),
|
||||||
);
|
);
|
||||||
if ($resourceType === 'ldap' || Platform::extensionLoaded('ldap')) {
|
if ($resourceType === 'ldap' || Platform::hasLdapSupport()) {
|
||||||
$resourceTypes['ldap'] = 'LDAP';
|
$resourceTypes['ldap'] = 'LDAP';
|
||||||
}
|
}
|
||||||
if ($resourceType === 'db' || Platform::hasMysqlSupport() || Platform::hasPostgresqlSupport()) {
|
if ($resourceType === 'db' || Platform::hasDatabaseSupport()) {
|
||||||
$resourceTypes['db'] = $this->translate('SQL Database');
|
$resourceTypes['db'] = $this->translate('SQL Database');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,20 +53,6 @@ class DbBackendForm extends Form
|
||||||
'label' => $this->translate('Backend Name'),
|
'label' => $this->translate('Backend Name'),
|
||||||
'description' => $this->translate(
|
'description' => $this->translate(
|
||||||
'The name of this authentication provider that is used to differentiate it from others'
|
'The name of this authentication provider that is used to differentiate it from others'
|
||||||
),
|
|
||||||
'validators' => array(
|
|
||||||
array(
|
|
||||||
'Regex',
|
|
||||||
false,
|
|
||||||
array(
|
|
||||||
'pattern' => '/^[^\\[\\]:]+$/',
|
|
||||||
'messages' => array(
|
|
||||||
'regexNotMatch' => $this->translate(
|
|
||||||
'The name cannot contain \'[\', \']\' or \':\'.'
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
|
@ -32,20 +32,6 @@ class ExternalBackendForm extends Form
|
||||||
'label' => $this->translate('Backend Name'),
|
'label' => $this->translate('Backend Name'),
|
||||||
'description' => $this->translate(
|
'description' => $this->translate(
|
||||||
'The name of this authentication provider that is used to differentiate it from others'
|
'The name of this authentication provider that is used to differentiate it from others'
|
||||||
),
|
|
||||||
'validators' => array(
|
|
||||||
array(
|
|
||||||
'Regex',
|
|
||||||
false,
|
|
||||||
array(
|
|
||||||
'pattern' => '/^[^\\[\\]:]+$/',
|
|
||||||
'messages' => array(
|
|
||||||
'regexNotMatch' => $this->translate(
|
|
||||||
'The backend name cannot contain \'[\', \']\' or \':\'.'
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
|
@ -57,20 +57,6 @@ class LdapBackendForm extends Form
|
||||||
'label' => $this->translate('Backend Name'),
|
'label' => $this->translate('Backend Name'),
|
||||||
'description' => $this->translate(
|
'description' => $this->translate(
|
||||||
'The name of this authentication provider that is used to differentiate it from others.'
|
'The name of this authentication provider that is used to differentiate it from others.'
|
||||||
),
|
|
||||||
'validators' => array(
|
|
||||||
array(
|
|
||||||
'Regex',
|
|
||||||
false,
|
|
||||||
array(
|
|
||||||
'pattern' => '/^[^\\[\\]:]+$/',
|
|
||||||
'messages' => array(
|
|
||||||
'regexNotMatch' => $this->translate(
|
|
||||||
'The name cannot contain \'[\', \']\' or \':\'.'
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
|
@ -34,20 +34,6 @@ class DbUserGroupBackendForm extends Form
|
||||||
'label' => $this->translate('Backend Name'),
|
'label' => $this->translate('Backend Name'),
|
||||||
'description' => $this->translate(
|
'description' => $this->translate(
|
||||||
'The name of this user group backend that is used to differentiate it from others'
|
'The name of this user group backend that is used to differentiate it from others'
|
||||||
),
|
|
||||||
'validators' => array(
|
|
||||||
array(
|
|
||||||
'Regex',
|
|
||||||
false,
|
|
||||||
array(
|
|
||||||
'pattern' => '/^[^\\[\\]:]+$/',
|
|
||||||
'messages' => array(
|
|
||||||
'regexNotMatch' => $this->translate(
|
|
||||||
'The name cannot contain \'[\', \']\' or \':\'.'
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
|
@ -39,20 +39,6 @@ class LdapUserGroupBackendForm extends Form
|
||||||
'label' => $this->translate('Backend Name'),
|
'label' => $this->translate('Backend Name'),
|
||||||
'description' => $this->translate(
|
'description' => $this->translate(
|
||||||
'The name of this user group backend that is used to differentiate it from others'
|
'The name of this user group backend that is used to differentiate it from others'
|
||||||
),
|
|
||||||
'validators' => array(
|
|
||||||
array(
|
|
||||||
'Regex',
|
|
||||||
false,
|
|
||||||
array(
|
|
||||||
'pattern' => '/^[^\\[\\]:]+$/',
|
|
||||||
'messages' => array(
|
|
||||||
'regexNotMatch' => $this->translate(
|
|
||||||
'The name cannot contain \'[\', \']\' or \':\'.'
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
|
@ -77,21 +77,7 @@ class DashletForm extends Form
|
||||||
array(
|
array(
|
||||||
'required' => true,
|
'required' => true,
|
||||||
'label' => $this->translate('Dashlet Title'),
|
'label' => $this->translate('Dashlet Title'),
|
||||||
'description' => $this->translate('Enter a title for the dashlet.'),
|
'description' => $this->translate('Enter a title for the dashlet.')
|
||||||
'validators' => array(
|
|
||||||
array(
|
|
||||||
'Regex',
|
|
||||||
false,
|
|
||||||
array(
|
|
||||||
'pattern' => '/^[^\\[\\]]+$/',
|
|
||||||
'messages' => array(
|
|
||||||
'regexNotMatch' => $this->translate(
|
|
||||||
'The name cannot contain \'[\' or \']\'.'
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
$this->addElement(
|
$this->addElement(
|
||||||
|
|
|
@ -12,6 +12,7 @@ use Icinga\Data\ConfigObject;
|
||||||
use Icinga\Data\Selectable;
|
use Icinga\Data\Selectable;
|
||||||
use Icinga\Data\SimpleQuery;
|
use Icinga\Data\SimpleQuery;
|
||||||
use Icinga\File\Ini\IniWriter;
|
use Icinga\File\Ini\IniWriter;
|
||||||
|
use Icinga\File\Ini\IniParser;
|
||||||
use Icinga\Exception\NotReadableError;
|
use Icinga\Exception\NotReadableError;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -313,9 +314,7 @@ class Config implements Countable, Iterator, Selectable
|
||||||
if ($filepath === false) {
|
if ($filepath === false) {
|
||||||
$emptyConfig->setConfigFile($file);
|
$emptyConfig->setConfigFile($file);
|
||||||
} elseif (is_readable($filepath)) {
|
} elseif (is_readable($filepath)) {
|
||||||
$config = new static(new ConfigObject(parse_ini_file($filepath, true)));
|
return IniParser::parseIniFile($filepath);
|
||||||
$config->setConfigFile($filepath);
|
|
||||||
return $config;
|
|
||||||
} elseif (@file_exists($filepath)) {
|
} elseif (@file_exists($filepath)) {
|
||||||
throw new NotReadableError(t('Cannot read config file "%s". Permission denied'), $filepath);
|
throw new NotReadableError(t('Cannot read config file "%s". Permission denied'), $filepath);
|
||||||
}
|
}
|
||||||
|
|
|
@ -318,6 +318,41 @@ class Platform
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return whether it's possible to connect to a LDAP server
|
||||||
|
*
|
||||||
|
* Checks whether the ldap extension is loaded
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function hasLdapSupport()
|
||||||
|
{
|
||||||
|
return static::extensionLoaded('ldap');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return whether it's possible to connect to any of the supported database servers
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function hasDatabaseSupport()
|
||||||
|
{
|
||||||
|
return static::hasMssqlSupport() || static::hasMysqlSupport() || static::hasOciSupport()
|
||||||
|
|| static::hasOracleSupport() || static::hasPostgresqlSupport();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return whether it's possible to connect to a MSSQL database
|
||||||
|
*
|
||||||
|
* Checks whether the mssql pdo extension has been loaded and Zend framework adapter for MSSQL is available
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function hasMssqlSupport()
|
||||||
|
{
|
||||||
|
return static::extensionLoaded('mssql') && static::classExists('Zend_Db_Adapter_Pdo_Mssql');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return whether it's possible to connect to a MySQL database
|
* Return whether it's possible to connect to a MySQL database
|
||||||
*
|
*
|
||||||
|
@ -330,6 +365,30 @@ class Platform
|
||||||
return static::extensionLoaded('mysql') && static::classExists('Zend_Db_Adapter_Pdo_Mysql');
|
return static::extensionLoaded('mysql') && static::classExists('Zend_Db_Adapter_Pdo_Mysql');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return whether it's possible to connect to a Oracle database using OCI8
|
||||||
|
*
|
||||||
|
* Checks whether the OCI8 extension has been loaded and the Zend framework adapter for Oracle is available
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function hasOciSupport()
|
||||||
|
{
|
||||||
|
return static::extensionLoaded('oci8') && static::classExists('Zend_Db_Adapter_Oracle');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return whether it's possible to connect to a Oracle database using PDO_OCI
|
||||||
|
*
|
||||||
|
* Checks whether the OCI PDO extension has been loaded and the Zend framework adapter for Oci is available
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function hasOracleSupport()
|
||||||
|
{
|
||||||
|
return static::extensionLoaded('pdo_oci') && static::classExists('Zend_Db_Adapter_Pdo_Mysql');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return whether it's possible to connect to a PostgreSQL database
|
* Return whether it's possible to connect to a PostgreSQL database
|
||||||
*
|
*
|
||||||
|
|
|
@ -364,7 +364,12 @@ class LdapUserBackend extends LdapRepository implements UserBackendInterface, In
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->ds->testCredentials($userDn, $password);
|
$testCredentialsResult = $this->ds->testCredentials($userDn, $password);
|
||||||
|
if ($testCredentialsResult) {
|
||||||
|
$user->setAdditional('ldap_dn', $userDn);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $testCredentialsResult;
|
||||||
} catch (LdapException $e) {
|
} catch (LdapException $e) {
|
||||||
throw new AuthenticationException(
|
throw new AuthenticationException(
|
||||||
'Failed to authenticate user "%s" against backend "%s". An exception was thrown:',
|
'Failed to authenticate user "%s" against backend "%s". An exception was thrown:',
|
||||||
|
|
|
@ -12,6 +12,7 @@ use Icinga\Protocol\Ldap\Expression;
|
||||||
use Icinga\Repository\LdapRepository;
|
use Icinga\Repository\LdapRepository;
|
||||||
use Icinga\Repository\RepositoryQuery;
|
use Icinga\Repository\RepositoryQuery;
|
||||||
use Icinga\User;
|
use Icinga\User;
|
||||||
|
use Icinga\Application\Logger;
|
||||||
|
|
||||||
class LdapUserGroupBackend /*extends LdapRepository*/ implements UserGroupBackendInterface
|
class LdapUserGroupBackend /*extends LdapRepository*/ implements UserGroupBackendInterface
|
||||||
{
|
{
|
||||||
|
@ -532,18 +533,26 @@ class LdapUserGroupBackend /*extends LdapRepository*/ implements UserGroupBacken
|
||||||
*/
|
*/
|
||||||
public function getMemberships(User $user)
|
public function getMemberships(User $user)
|
||||||
{
|
{
|
||||||
$userQuery = $this->ds
|
if ($this->groupClass === 'posixGroup') {
|
||||||
->select()
|
// Posix group only uses simple user name
|
||||||
->from($this->userClass)
|
$userDn = $user->getUsername();
|
||||||
->where($this->userNameAttribute, $user->getUsername())
|
} else {
|
||||||
->setBase($this->userBaseDn)
|
// LDAP groups use the complete DN
|
||||||
->setUsePagedResults(false);
|
if (($userDn = $user->getAdditional('ldap_dn')) === null) {
|
||||||
if ($this->userFilter) {
|
$userQuery = $this->ds
|
||||||
$userQuery->where(new Expression($this->userFilter));
|
->select()
|
||||||
}
|
->from($this->userClass)
|
||||||
|
->where($this->userNameAttribute, $user->getUsername())
|
||||||
|
->setBase($this->userBaseDn)
|
||||||
|
->setUsePagedResults(false);
|
||||||
|
if ($this->userFilter) {
|
||||||
|
$userQuery->where(new Expression($this->userFilter));
|
||||||
|
}
|
||||||
|
|
||||||
if (($userDn = $userQuery->fetchDn()) === null) {
|
if (($userDn = $userQuery->fetchDn()) === null) {
|
||||||
return array();
|
return array();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$groupQuery = $this->ds
|
$groupQuery = $this->ds
|
||||||
|
@ -555,10 +564,12 @@ class LdapUserGroupBackend /*extends LdapRepository*/ implements UserGroupBacken
|
||||||
$groupQuery->where(new Expression($this->groupFilter));
|
$groupQuery->where(new Expression($this->groupFilter));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Logger::debug('Fetching groups for user %s using filter %s.', $user->getUsername(), $groupQuery->__toString());
|
||||||
$groups = array();
|
$groups = array();
|
||||||
foreach ($groupQuery as $row) {
|
foreach ($groupQuery as $row) {
|
||||||
$groups[] = $row->{$this->groupNameAttribute};
|
$groups[] = $row->{$this->groupNameAttribute};
|
||||||
}
|
}
|
||||||
|
Logger::debug('Fetched %d groups: %s.', count($groups), join(', ', $groups));
|
||||||
|
|
||||||
return $groups;
|
return $groups;
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,8 +62,7 @@ class DbConnection implements Selectable, Extensible, Updatable, Reducible, Insp
|
||||||
private static $driverOptions = array(
|
private static $driverOptions = array(
|
||||||
PDO::ATTR_TIMEOUT => 10,
|
PDO::ATTR_TIMEOUT => 10,
|
||||||
PDO::ATTR_CASE => PDO::CASE_LOWER,
|
PDO::ATTR_CASE => PDO::CASE_LOWER,
|
||||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
|
||||||
// TODO: allow configurable PDO::ATTR_PERSISTENT => true
|
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -131,11 +130,16 @@ class DbConnection implements Selectable, Extensible, Updatable, Reducible, Insp
|
||||||
'username' => $this->config->username,
|
'username' => $this->config->username,
|
||||||
'password' => $this->config->password,
|
'password' => $this->config->password,
|
||||||
'dbname' => $this->config->dbname,
|
'dbname' => $this->config->dbname,
|
||||||
|
'persistent' => (bool) $this->config->get('persistent', false),
|
||||||
'options' => & $genericAdapterOptions,
|
'options' => & $genericAdapterOptions,
|
||||||
'driver_options' => & $driverOptions
|
'driver_options' => & $driverOptions
|
||||||
);
|
);
|
||||||
$this->dbType = strtolower($this->config->get('db', 'mysql'));
|
$this->dbType = strtolower($this->config->get('db', 'mysql'));
|
||||||
switch ($this->dbType) {
|
switch ($this->dbType) {
|
||||||
|
case 'mssql':
|
||||||
|
$adapter = 'Pdo_Mssql';
|
||||||
|
$adapterParamaters['pdoType'] = $this->config->get('pdoType', 'dblib');
|
||||||
|
break;
|
||||||
case 'mysql':
|
case 'mysql':
|
||||||
$adapter = 'Pdo_Mysql';
|
$adapter = 'Pdo_Mysql';
|
||||||
/*
|
/*
|
||||||
|
@ -150,19 +154,21 @@ class DbConnection implements Selectable, Extensible, Updatable, Reducible, Insp
|
||||||
. 'NO_AUTO_CREATE_USER,ANSI_QUOTES,PIPES_AS_CONCAT,NO_ENGINE_SUBSTITUTION\';';
|
. 'NO_AUTO_CREATE_USER,ANSI_QUOTES,PIPES_AS_CONCAT,NO_ENGINE_SUBSTITUTION\';';
|
||||||
$adapterParamaters['port'] = $this->config->get('port', 3306);
|
$adapterParamaters['port'] = $this->config->get('port', 3306);
|
||||||
break;
|
break;
|
||||||
|
case 'oci':
|
||||||
|
$adapter = 'Oracle';
|
||||||
|
unset($adapterParamaters['options']);
|
||||||
|
unset($adapterParamaters['driver_options']);
|
||||||
|
$adapterParamaters['driver_options'] = array(
|
||||||
|
'lob_as_string' => true
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'oracle':
|
||||||
|
$adapter = 'Pdo_Oci';
|
||||||
|
break;
|
||||||
case 'pgsql':
|
case 'pgsql':
|
||||||
$adapter = 'Pdo_Pgsql';
|
$adapter = 'Pdo_Pgsql';
|
||||||
$adapterParamaters['port'] = $this->config->get('port', 5432);
|
$adapterParamaters['port'] = $this->config->get('port', 5432);
|
||||||
break;
|
break;
|
||||||
/*case 'oracle':
|
|
||||||
if ($this->dbtype === 'oracle') {
|
|
||||||
$attributes['persistent'] = true;
|
|
||||||
}
|
|
||||||
$this->db = ZfDb::factory($adapter, $attributes);
|
|
||||||
if ($adapter === 'Oracle') {
|
|
||||||
$this->db->setLobAsString(false);
|
|
||||||
}
|
|
||||||
break;*/
|
|
||||||
default:
|
default:
|
||||||
throw new ConfigurationError(
|
throw new ConfigurationError(
|
||||||
'Backend "%s" is not supported',
|
'Backend "%s" is not supported',
|
||||||
|
|
|
@ -115,4 +115,18 @@ class Document
|
||||||
}
|
}
|
||||||
return $str;
|
return $str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert $this to an array
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function toArray()
|
||||||
|
{
|
||||||
|
$a = array();
|
||||||
|
foreach ($this->sections as $section) {
|
||||||
|
$a[$section->getName()] = $section->toArray();
|
||||||
|
}
|
||||||
|
return $a;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -169,4 +169,18 @@ class Section
|
||||||
$str = str_replace(';', '\\;', $str);
|
$str = str_replace(';', '\\;', $str);
|
||||||
return str_replace(PHP_EOL, ' ', $str);
|
return str_replace(PHP_EOL, ' ', $str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert $this to an array
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function toArray()
|
||||||
|
{
|
||||||
|
$a = array();
|
||||||
|
foreach ($this->directives as $directive) {
|
||||||
|
$a[$directive->getKey()] = $directive->getValue();
|
||||||
|
}
|
||||||
|
return $a;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,8 @@ use Icinga\File\Ini\Dom\Document;
|
||||||
use Icinga\File\Ini\Dom\Directive;
|
use Icinga\File\Ini\Dom\Directive;
|
||||||
use Icinga\Application\Logger;
|
use Icinga\Application\Logger;
|
||||||
use Icinga\Exception\ConfigurationError;
|
use Icinga\Exception\ConfigurationError;
|
||||||
|
use Icinga\Exception\NotReadableError;
|
||||||
|
use Icinga\Application\Config;
|
||||||
|
|
||||||
class IniParser
|
class IniParser
|
||||||
{
|
{
|
||||||
|
@ -239,4 +241,25 @@ class IniParser
|
||||||
}
|
}
|
||||||
return $doc;
|
return $doc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the ini file and parse it with ::parseIni()
|
||||||
|
*
|
||||||
|
* @param string $file The ini file to read
|
||||||
|
*
|
||||||
|
* @return Config
|
||||||
|
* @throws NotReadableError When the file cannot be read
|
||||||
|
*/
|
||||||
|
public static function parseIniFile($file)
|
||||||
|
{
|
||||||
|
if (($path = realpath($file)) === false) {
|
||||||
|
throw new NotReadableError('Couldn\'t compute the absolute path of `%s\'', $file);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (($content = file_get_contents($path)) === false) {
|
||||||
|
throw new NotReadableError('Couldn\'t read the file `%s\'', $path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Config::fromArray(self::parseIni($content)->toArray())->setConfigFile($file);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -667,17 +667,20 @@ class LdapConnection implements Selectable, Inspectable
|
||||||
$ds = $this->getConnection();
|
$ds = $this->getConnection();
|
||||||
|
|
||||||
$serverSorting = $this->getCapabilities()->hasOid(LdapCapabilities::LDAP_SERVER_SORT_OID);
|
$serverSorting = $this->getCapabilities()->hasOid(LdapCapabilities::LDAP_SERVER_SORT_OID);
|
||||||
if ($serverSorting && $query->hasOrder()) {
|
|
||||||
ldap_set_option($ds, LDAP_OPT_SERVER_CONTROLS, array(
|
if ($query->hasOrder()) {
|
||||||
array(
|
if ($serverSorting) {
|
||||||
'oid' => LdapCapabilities::LDAP_SERVER_SORT_OID,
|
ldap_set_option($ds, LDAP_OPT_SERVER_CONTROLS, array(
|
||||||
'value' => $this->encodeSortRules($query->getOrder())
|
array(
|
||||||
)
|
'oid' => LdapCapabilities::LDAP_SERVER_SORT_OID,
|
||||||
));
|
'value' => $this->encodeSortRules($query->getOrder())
|
||||||
} elseif ($query->hasOrder()) {
|
)
|
||||||
foreach ($query->getOrder() as $rule) {
|
));
|
||||||
if (! in_array($rule[0], $fields)) {
|
} else {
|
||||||
$fields[] = $rule[0];
|
foreach ($query->getOrder() as $rule) {
|
||||||
|
if (! in_array($rule[0], $fields)) {
|
||||||
|
$fields[] = $rule[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -778,7 +781,7 @@ class LdapConnection implements Selectable, Inspectable
|
||||||
// server to return results even if the paged search request cannot be satisfied
|
// server to return results even if the paged search request cannot be satisfied
|
||||||
ldap_control_paged_result($ds, $pageSize, false, $cookie);
|
ldap_control_paged_result($ds, $pageSize, false, $cookie);
|
||||||
|
|
||||||
if ($serverSorting) {
|
if ($serverSorting && $query->hasOrder()) {
|
||||||
ldap_set_option($ds, LDAP_OPT_SERVER_CONTROLS, array(
|
ldap_set_option($ds, LDAP_OPT_SERVER_CONTROLS, array(
|
||||||
array(
|
array(
|
||||||
'oid' => LdapCapabilities::LDAP_SERVER_SORT_OID,
|
'oid' => LdapCapabilities::LDAP_SERVER_SORT_OID,
|
||||||
|
|
|
@ -8,6 +8,7 @@ use Icinga\Exception\NotReadableError;
|
||||||
use Icinga\Exception\NotWritableError;
|
use Icinga\Exception\NotWritableError;
|
||||||
use Icinga\User\Preferences;
|
use Icinga\User\Preferences;
|
||||||
use Icinga\User\Preferences\PreferencesStore;
|
use Icinga\User\Preferences\PreferencesStore;
|
||||||
|
use Icinga\File\Ini\IniParser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load and save user preferences from and to INI files
|
* Load and save user preferences from and to INI files
|
||||||
|
@ -57,7 +58,7 @@ class IniStore extends PreferencesStore
|
||||||
$this->getUser()->getUsername()
|
$this->getUser()->getUsername()
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
$this->preferences = parse_ini_file($this->preferencesFile, true);
|
$this->preferences = IniParser::parseIniFile($this->preferencesFile)->toArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -134,8 +134,8 @@ class Number extends FormElement
|
||||||
{
|
{
|
||||||
$this->setValue($value);
|
$this->setValue($value);
|
||||||
$value = $this->getValue();
|
$value = $this->getValue();
|
||||||
if (! is_numeric($value)) {
|
if ($value !== '' && ! is_numeric($value)) {
|
||||||
$this->addError(sprintf($this->translate('\'%s\' is not a valid number'), $value));
|
$this->addError(sprintf(t('\'%s\' is not a valid number'), $value));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return parent::isValid($value, $context);
|
return parent::isValid($value, $context);
|
||||||
|
|
|
@ -57,7 +57,9 @@ class AlertsummaryController extends Controller
|
||||||
$this->view->title = $this->translate('Alert Summary');
|
$this->view->title = $this->translate('Alert Summary');
|
||||||
|
|
||||||
$this->view->intervalBox = $this->createIntervalBox();
|
$this->view->intervalBox = $this->createIntervalBox();
|
||||||
$this->view->recentAlerts = $this->createRecentAlerts();
|
list($recentAlerts, $recentAlertsUrl) = $this->createRecentAlerts();
|
||||||
|
$this->view->recentAlerts = $recentAlerts;
|
||||||
|
$this->view->recentAlertsUrl = $recentAlertsUrl;
|
||||||
$this->view->interval = $this->getInterval();
|
$this->view->interval = $this->getInterval();
|
||||||
$this->view->defectChart = $this->createDefectImage();
|
$this->view->defectChart = $this->createDefectImage();
|
||||||
$this->view->healingChart = $this->createHealingChart();
|
$this->view->healingChart = $this->createHealingChart();
|
||||||
|
@ -80,6 +82,7 @@ class AlertsummaryController extends Controller
|
||||||
);
|
);
|
||||||
$this->applyRestriction('monitoring/filter/objects', $query);
|
$this->applyRestriction('monitoring/filter/objects', $query);
|
||||||
$this->view->notifications = $query;
|
$this->view->notifications = $query;
|
||||||
|
$this->view->notificationsUrl = 'monitoring/list/notifications';
|
||||||
|
|
||||||
$this->setupLimitControl();
|
$this->setupLimitControl();
|
||||||
$this->setupPaginationControl($this->view->notifications);
|
$this->setupPaginationControl($this->view->notifications);
|
||||||
|
@ -487,7 +490,7 @@ class AlertsummaryController extends Controller
|
||||||
/**
|
/**
|
||||||
* Top recent alerts
|
* Top recent alerts
|
||||||
*
|
*
|
||||||
* @return mixed
|
* @return array
|
||||||
*/
|
*/
|
||||||
private function createRecentAlerts()
|
private function createRecentAlerts()
|
||||||
{
|
{
|
||||||
|
@ -508,7 +511,10 @@ class AlertsummaryController extends Controller
|
||||||
|
|
||||||
$query->order('notification_start_time', 'desc');
|
$query->order('notification_start_time', 'desc');
|
||||||
|
|
||||||
return $query->limit(5);
|
return array(
|
||||||
|
$query->limit(5),
|
||||||
|
'monitoring/list/notifications?sort=notification_start_time&dir=desc'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -193,20 +193,6 @@ class BackendConfigForm extends ConfigForm
|
||||||
'label' => $this->translate('Backend Name'),
|
'label' => $this->translate('Backend Name'),
|
||||||
'description' => $this->translate(
|
'description' => $this->translate(
|
||||||
'The name of this monitoring backend that is used to differentiate it from others'
|
'The name of this monitoring backend that is used to differentiate it from others'
|
||||||
),
|
|
||||||
'validators' => array(
|
|
||||||
array(
|
|
||||||
'Regex',
|
|
||||||
false,
|
|
||||||
array(
|
|
||||||
'pattern' => '/^[^\\[\\]:]+$/',
|
|
||||||
'messages' => array(
|
|
||||||
'regexNotMatch' => $this->translate(
|
|
||||||
'The name cannot contain \'[\', \']\' or \':\'.'
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
|
@ -217,20 +217,6 @@ class TransportConfigForm extends ConfigForm
|
||||||
'label' => $this->translate('Transport Name'),
|
'label' => $this->translate('Transport Name'),
|
||||||
'description' => $this->translate(
|
'description' => $this->translate(
|
||||||
'The name of this command transport that is used to differentiate it from others'
|
'The name of this command transport that is used to differentiate it from others'
|
||||||
),
|
|
||||||
'validators' => array(
|
|
||||||
array(
|
|
||||||
'Regex',
|
|
||||||
false,
|
|
||||||
array(
|
|
||||||
'pattern' => '/^[^\\[\\]:]+$/',
|
|
||||||
'messages' => array(
|
|
||||||
'regexNotMatch' => $this->translate(
|
|
||||||
'The name cannot contain \'[\', \']\' or \':\'.'
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
|
@ -59,8 +59,9 @@
|
||||||
<div class="alertsummary-flex-container">
|
<div class="alertsummary-flex-container">
|
||||||
<div class="alertsummary-flex">
|
<div class="alertsummary-flex">
|
||||||
<?= $this->partial('list/notifications.phtml', array(
|
<?= $this->partial('list/notifications.phtml', array(
|
||||||
'notifications' => $this->recentAlerts,
|
'notifications' => $this->recentAlerts,
|
||||||
'compact' => true
|
'compact' => true,
|
||||||
|
'notificationsUrl' => $recentAlertsUrl
|
||||||
)); ?>
|
)); ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -70,8 +71,9 @@
|
||||||
<div class="alertsummary-flex-container">
|
<div class="alertsummary-flex-container">
|
||||||
<div class="alertsummary-flex">
|
<div class="alertsummary-flex">
|
||||||
<?= $this->partial('list/notifications.phtml', array(
|
<?= $this->partial('list/notifications.phtml', array(
|
||||||
'notifications' => $this->notifications,
|
'notifications' => $this->notifications,
|
||||||
'compact' => true
|
'compact' => true,
|
||||||
|
'notificationsUrl' => $notificationsUrl
|
||||||
)); ?>
|
)); ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
<table data-base-target="_next"
|
<table data-base-target="_next"
|
||||||
class="action comments multiselect"
|
class="action comments multiselect"
|
||||||
data-icinga-multiselect-url="<?= $this->href('monitoring/comments/show'); ?>"
|
data-icinga-multiselect-url="<?= $this->href('monitoring/comments/show'); ?>"
|
||||||
|
data-icinga-multiselect-related="<?= $this->href("monitoring/comments") ?>"
|
||||||
data-icinga-multiselect-data="comment_id">
|
data-icinga-multiselect-data="comment_id">
|
||||||
<tbody>
|
<tbody>
|
||||||
<?php foreach ($comments->peekAhead($this->compact) as $comment): ?>
|
<?php foreach ($comments->peekAhead($this->compact) as $comment): ?>
|
||||||
|
@ -46,7 +47,8 @@
|
||||||
'title' => sprintf(
|
'title' => sprintf(
|
||||||
$this->translate('Show detailed information for this comment about host %s'),
|
$this->translate('Show detailed information for this comment about host %s'),
|
||||||
$comment->host_display_name
|
$comment->host_display_name
|
||||||
)
|
),
|
||||||
|
'class' => 'rowaction'
|
||||||
)
|
)
|
||||||
); ?>
|
); ?>
|
||||||
<?php endif ?>
|
<?php endif ?>
|
||||||
|
|
|
@ -21,6 +21,7 @@ if (! $this->compact): ?>
|
||||||
<table data-base-target="_next"
|
<table data-base-target="_next"
|
||||||
class="action multiselect"
|
class="action multiselect"
|
||||||
data-icinga-multiselect-url="<?= $this->href('monitoring/downtimes/show'); ?>"
|
data-icinga-multiselect-url="<?= $this->href('monitoring/downtimes/show'); ?>"
|
||||||
|
data-icinga-multiselect-controllers="<?= $this->href("monitoring/downtimes") ?>"
|
||||||
data-icinga-multiselect-data="downtime_id">
|
data-icinga-multiselect-data="downtime_id">
|
||||||
<tbody>
|
<tbody>
|
||||||
<?php foreach ($downtimes as $downtime): ?>
|
<?php foreach ($downtimes as $downtime): ?>
|
||||||
|
|
|
@ -23,6 +23,7 @@ if (! $this->compact): ?>
|
||||||
data-base-target="_next"
|
data-base-target="_next"
|
||||||
class="action multiselect"
|
class="action multiselect"
|
||||||
data-icinga-multiselect-url="<?= $this->href('monitoring/hosts/show') ?>"
|
data-icinga-multiselect-url="<?= $this->href('monitoring/hosts/show') ?>"
|
||||||
|
data-icinga-multiselect-controllers="<?= $this->href("monitoring/hosts") ?>"
|
||||||
data-icinga-multiselect-data="host"
|
data-icinga-multiselect-data="host"
|
||||||
>
|
>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
|
|
@ -72,7 +72,7 @@ if (! $this->compact): ?>
|
||||||
<?php elseif ($notifications->hasMore()): ?>
|
<?php elseif ($notifications->hasMore()): ?>
|
||||||
<?= $this->qlink(
|
<?= $this->qlink(
|
||||||
$this->translate('Show More'),
|
$this->translate('Show More'),
|
||||||
$this->url()->without(array('view', 'limit')),
|
$this->url(isset($notificationsUrl) ? $notificationsUrl : null)->without(array('view', 'limit')),
|
||||||
null,
|
null,
|
||||||
array(
|
array(
|
||||||
'data-base-target' => '_next',
|
'data-base-target' => '_next',
|
||||||
|
|
|
@ -24,6 +24,7 @@ if (! $this->compact): ?>
|
||||||
<table data-base-target="_next"
|
<table data-base-target="_next"
|
||||||
class="action multiselect <?php if ($this->compact): ?> compact<?php endif ?>" style="table-layout: auto;"
|
class="action multiselect <?php if ($this->compact): ?> compact<?php endif ?>" style="table-layout: auto;"
|
||||||
data-icinga-multiselect-url="<?= $this->href("monitoring/services/show") ?>"
|
data-icinga-multiselect-url="<?= $this->href("monitoring/services/show") ?>"
|
||||||
|
data-icinga-multiselect-controllers="<?= $this->href("monitoring/services") ?>"
|
||||||
data-icinga-multiselect-data="service,host">
|
data-icinga-multiselect-data="service,host">
|
||||||
<tbody>
|
<tbody>
|
||||||
<?php foreach ($services as $service):
|
<?php foreach ($services as $service):
|
||||||
|
|
|
@ -181,6 +181,10 @@ class HostcommentQuery extends IdoQuery
|
||||||
if ($this->hasJoinedVirtualTable('hoststatus')) {
|
if ($this->hasJoinedVirtualTable('hoststatus')) {
|
||||||
$group[] = 'hs.hoststatus_id';
|
$group[] = 'hs.hoststatus_id';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->hasJoinedVirtualTable('instances')) {
|
||||||
|
$group[] = 'i.instance_id';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $group;
|
return $group;
|
||||||
|
|
|
@ -187,6 +187,10 @@ class HostdowntimeQuery extends IdoQuery
|
||||||
if ($this->hasJoinedVirtualTable('hoststatus')) {
|
if ($this->hasJoinedVirtualTable('hoststatus')) {
|
||||||
$group[] = 'hs.hoststatus_id';
|
$group[] = 'hs.hoststatus_id';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->hasJoinedVirtualTable('instances')) {
|
||||||
|
$group[] = 'i.instance_id';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $group;
|
return $group;
|
||||||
|
|
|
@ -265,6 +265,10 @@ class HostnotificationQuery extends IdoQuery
|
||||||
if ($this->hasJoinedVirtualTable('acknowledgements')) {
|
if ($this->hasJoinedVirtualTable('acknowledgements')) {
|
||||||
$group[] = 'a.acknowledgement_id';
|
$group[] = 'a.acknowledgement_id';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->hasJoinedVirtualTable('instances')) {
|
||||||
|
$group[] = 'i.instance_id';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $group;
|
return $group;
|
||||||
|
|
|
@ -289,26 +289,26 @@ class HoststatusQuery extends IdoQuery
|
||||||
}
|
}
|
||||||
$groupedTables = array();
|
$groupedTables = array();
|
||||||
if ($this->hasJoinedVirtualTable('servicegroups')) {
|
if ($this->hasJoinedVirtualTable('servicegroups')) {
|
||||||
|
$group[] = 'ho.object_id';
|
||||||
|
$group[] = 'h.host_id';
|
||||||
|
$groupedTables['hosts'] = true;
|
||||||
$serviceGroupColumns = array_keys($this->columnMap['servicegroups']);
|
$serviceGroupColumns = array_keys($this->columnMap['servicegroups']);
|
||||||
$selectedServiceGroupColumns = array_intersect($serviceGroupColumns, array_keys($this->columns));
|
$selectedServiceGroupColumns = array_intersect($serviceGroupColumns, array_keys($this->columns));
|
||||||
if (! empty($selectedServiceGroupColumns)) {
|
if (! empty($selectedServiceGroupColumns)) {
|
||||||
$group[] = 'ho.object_id';
|
|
||||||
$group[] = 'h.host_id';
|
|
||||||
$group[] = 'sgo.object_id';
|
$group[] = 'sgo.object_id';
|
||||||
$group[] = 'sg.servicegroup_id';
|
$group[] = 'sg.servicegroup_id';
|
||||||
$groupedTables['hosts'] = true;
|
|
||||||
$groupedTables['servicegroups'] = true;
|
$groupedTables['servicegroups'] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($this->hasJoinedVirtualTable('hostgroups')) {
|
if ($this->hasJoinedVirtualTable('hostgroups')) {
|
||||||
|
if (! isset($groupedTables['hosts'])) {
|
||||||
|
$group[] = 'ho.object_id';
|
||||||
|
$group[] = 'h.host_id';
|
||||||
|
$groupedTables['hosts'] = true;
|
||||||
|
}
|
||||||
$hostGroupColumns = array_keys($this->columnMap['hostgroups']);
|
$hostGroupColumns = array_keys($this->columnMap['hostgroups']);
|
||||||
$selectedHostGroupColumns = array_intersect($hostGroupColumns, array_keys($this->columns));
|
$selectedHostGroupColumns = array_intersect($hostGroupColumns, array_keys($this->columns));
|
||||||
if (! empty($selectedHostGroupColumns)) {
|
if (! empty($selectedHostGroupColumns)) {
|
||||||
if (! isset($groupedTables['hosts'])) {
|
|
||||||
$group[] = 'ho.object_id';
|
|
||||||
$group[] = 'h.host_id';
|
|
||||||
$groupedTables['hosts'] = true;
|
|
||||||
}
|
|
||||||
$group[] = 'hgo.object_id';
|
$group[] = 'hgo.object_id';
|
||||||
$group[] = 'hg.hostgroup_id';
|
$group[] = 'hg.hostgroup_id';
|
||||||
$groupedTables['hostgroups'] = true;
|
$groupedTables['hostgroups'] = true;
|
||||||
|
@ -336,6 +336,9 @@ class HoststatusQuery extends IdoQuery
|
||||||
$group[] = 'so.object_id';
|
$group[] = 'so.object_id';
|
||||||
$group[] = 's.service_id';
|
$group[] = 's.service_id';
|
||||||
break;
|
break;
|
||||||
|
case 'instances':
|
||||||
|
$group[] = 'i.instance_id';
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
continue 2;
|
continue 2;
|
||||||
}
|
}
|
||||||
|
|
|
@ -203,6 +203,10 @@ class ServicecommentQuery extends IdoQuery
|
||||||
if ($this->hasJoinedVirtualTable('servicestatus')) {
|
if ($this->hasJoinedVirtualTable('servicestatus')) {
|
||||||
$group[] = 'ss.servicestatus_id';
|
$group[] = 'ss.servicestatus_id';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->hasJoinedVirtualTable('instances')) {
|
||||||
|
$group[] = 'i.instance_id';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $group;
|
return $group;
|
||||||
|
|
|
@ -210,6 +210,10 @@ class ServicedowntimeQuery extends IdoQuery
|
||||||
if ($this->hasJoinedVirtualTable('servicestatus')) {
|
if ($this->hasJoinedVirtualTable('servicestatus')) {
|
||||||
$group[] = 'ss.servicestatus_id';
|
$group[] = 'ss.servicestatus_id';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->hasJoinedVirtualTable('instances')) {
|
||||||
|
$group[] = 'i.instance_id';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $group;
|
return $group;
|
||||||
|
|
|
@ -268,6 +268,10 @@ class ServicenotificationQuery extends IdoQuery
|
||||||
if ($this->hasJoinedVirtualTable('acknowledgements')) {
|
if ($this->hasJoinedVirtualTable('acknowledgements')) {
|
||||||
$group[] = 'a.acknowledgement_id';
|
$group[] = 'a.acknowledgement_id';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->hasJoinedVirtualTable('instances')) {
|
||||||
|
$group[] = 'i.instance_id';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $group;
|
return $group;
|
||||||
|
|
|
@ -409,26 +409,26 @@ class ServicestatusQuery extends IdoQuery
|
||||||
}
|
}
|
||||||
$groupedTables = array();
|
$groupedTables = array();
|
||||||
if ($this->hasJoinedVirtualTable('servicegroups')) {
|
if ($this->hasJoinedVirtualTable('servicegroups')) {
|
||||||
|
$group[] = 'so.object_id';
|
||||||
|
$group[] = 's.service_id';
|
||||||
|
$groupedTables['services'] = true;
|
||||||
$serviceGroupColumns = array_keys($this->columnMap['servicegroups']);
|
$serviceGroupColumns = array_keys($this->columnMap['servicegroups']);
|
||||||
$selectedServiceGroupColumns = array_intersect($serviceGroupColumns, array_keys($this->columns));
|
$selectedServiceGroupColumns = array_intersect($serviceGroupColumns, array_keys($this->columns));
|
||||||
if (! empty($selectedServiceGroupColumns)) {
|
if (! empty($selectedServiceGroupColumns)) {
|
||||||
$group[] = 'so.object_id';
|
|
||||||
$group[] = 's.service_id';
|
|
||||||
$group[] = 'sgo.object_id';
|
$group[] = 'sgo.object_id';
|
||||||
$group[] = 'sg.servicegroup_id';
|
$group[] = 'sg.servicegroup_id';
|
||||||
$groupedTables['services'] = true;
|
|
||||||
$groupedTables['servicegroups'] = true;
|
$groupedTables['servicegroups'] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($this->hasJoinedVirtualTable('hostgroups')) {
|
if ($this->hasJoinedVirtualTable('hostgroups')) {
|
||||||
|
if (! isset($groupedTables['services'])) {
|
||||||
|
$group[] = 'so.object_id';
|
||||||
|
$group[] = 's.service_id';
|
||||||
|
$groupedTables['services'] = true;
|
||||||
|
}
|
||||||
$hostGroupColumns = array_keys($this->columnMap['hostgroups']);
|
$hostGroupColumns = array_keys($this->columnMap['hostgroups']);
|
||||||
$selectedHostGroupColumns = array_intersect($hostGroupColumns, array_keys($this->columns));
|
$selectedHostGroupColumns = array_intersect($hostGroupColumns, array_keys($this->columns));
|
||||||
if (! empty($selectedHostGroupColumns)) {
|
if (! empty($selectedHostGroupColumns)) {
|
||||||
if (! isset($groupedTables['services'])) {
|
|
||||||
$group[] = 'so.object_id';
|
|
||||||
$group[] = 's.service_id';
|
|
||||||
$groupedTables['services'] = true;
|
|
||||||
}
|
|
||||||
$group[] = 'hgo.object_id';
|
$group[] = 'hgo.object_id';
|
||||||
$group[] = 'hg.hostgroup_id';
|
$group[] = 'hg.hostgroup_id';
|
||||||
$groupedTables['hostgroups'] = true;
|
$groupedTables['hostgroups'] = true;
|
||||||
|
@ -452,6 +452,9 @@ class ServicestatusQuery extends IdoQuery
|
||||||
case 'hoststatus':
|
case 'hoststatus':
|
||||||
$group[] = 'hs.hoststatus_id';
|
$group[] = 'hs.hoststatus_id';
|
||||||
break;
|
break;
|
||||||
|
case 'instances':
|
||||||
|
$group[] = 'i.instance_id';
|
||||||
|
break;
|
||||||
case 'servicestatus':
|
case 'servicestatus':
|
||||||
$group[] = 'ss.servicestatus_id';
|
$group[] = 'ss.servicestatus_id';
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -50,6 +50,7 @@
|
||||||
var Selection = function(table, icinga) {
|
var Selection = function(table, icinga) {
|
||||||
this.$el = $(table);
|
this.$el = $(table);
|
||||||
this.icinga = icinga;
|
this.icinga = icinga;
|
||||||
|
this.col = this.$el.closest('div.container').attr('id');
|
||||||
|
|
||||||
if (this.hasMultiselection()) {
|
if (this.hasMultiselection()) {
|
||||||
if (! this.getMultiselectionKeys().length) {
|
if (! this.getMultiselectionKeys().length) {
|
||||||
|
@ -63,6 +64,11 @@
|
||||||
|
|
||||||
Selection.prototype = {
|
Selection.prototype = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The container id in which this selection happens
|
||||||
|
*/
|
||||||
|
col: null,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return all rows as jQuery selector
|
* Return all rows as jQuery selector
|
||||||
*
|
*
|
||||||
|
@ -110,7 +116,7 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the target URL that is used when multi selecting rows
|
* Return the main target URL that is used when multi selecting rows
|
||||||
*
|
*
|
||||||
* This URL may differ from the url that is used when applying single rows
|
* This URL may differ from the url that is used when applying single rows
|
||||||
*
|
*
|
||||||
|
@ -120,6 +126,28 @@
|
||||||
return this.$el.data('icinga-multiselect-url');
|
return this.$el.data('icinga-multiselect-url');
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether the given url is
|
||||||
|
*
|
||||||
|
* @param {String} url
|
||||||
|
*/
|
||||||
|
hasMultiselectionUrl: function(url) {
|
||||||
|
var urls = this.$el.data('icinga-multiselect-url').split(' ');
|
||||||
|
|
||||||
|
var related = this.$el.data('icinga-multiselect-controllers');
|
||||||
|
if (related && related.length) {
|
||||||
|
urls = urls.concat(this.$el.data('icinga-multiselect-controllers').split(' '));
|
||||||
|
}
|
||||||
|
|
||||||
|
var hasSelection = false;
|
||||||
|
$.each(urls, function (i, object) {
|
||||||
|
if (url.indexOf(object) === 0) {
|
||||||
|
hasSelection = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return hasSelection;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read all filter data from the given row
|
* Read all filter data from the given row
|
||||||
*
|
*
|
||||||
|
@ -227,7 +255,17 @@
|
||||||
* @param url {String} The target url
|
* @param url {String} The target url
|
||||||
*/
|
*/
|
||||||
selectUrl: function(url) {
|
selectUrl: function(url) {
|
||||||
this.rows().filter('[href="' + url + '"]').addClass('active');
|
var $row = this.rows().filter('[href="' + url + '"]');
|
||||||
|
if ($row.length) {
|
||||||
|
$row.addClass('active');
|
||||||
|
} else {
|
||||||
|
// rows sometimes need to be displayed as active when related actions
|
||||||
|
// like command actions are being opened. Do not do this for col2, as it
|
||||||
|
// would always select the opened URL itself.
|
||||||
|
if (this.col !== 'col2') {
|
||||||
|
this.rows().filter('[href$="' + icinga.utils.parseUrl(url).query + '"]').addClass('active');
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -264,7 +302,7 @@
|
||||||
var hash = icinga.history.getCol2State().replace(/^#!/, '');
|
var hash = icinga.history.getCol2State().replace(/^#!/, '');
|
||||||
if (this.hasMultiselection()) {
|
if (this.hasMultiselection()) {
|
||||||
var query = parseSelectionQuery(hash);
|
var query = parseSelectionQuery(hash);
|
||||||
if (query.length > 1 && this.getMultiselectionUrl() === this.icinga.utils.parseUrl(hash).path) {
|
if (query.length > 1 && this.hasMultiselectionUrl(this.icinga.utils.parseUrl(hash).path)) {
|
||||||
// select all rows with matching filters
|
// select all rows with matching filters
|
||||||
var self = this;
|
var self = this;
|
||||||
$.each(query, function(i, selection) {
|
$.each(query, function(i, selection) {
|
||||||
|
|
Loading…
Reference in New Issue