commit
f3a47553f8
|
@ -83,7 +83,8 @@ class DbAdapterFactory implements ConfigAwareFactory
|
|||
private static $defaultZendDbAdapterOptions = array(
|
||||
Zend_Db::AUTO_QUOTE_IDENTIFIERS => false,
|
||||
Zend_Db::CASE_FOLDING => Zend_Db::CASE_LOWER,
|
||||
Zend_Db::FETCH_MODE => Zend_Db::FETCH_OBJ
|
||||
// Zend_Db::FETCH_MODE => Zend_Db::FETCH_OBJ
|
||||
'fetchMode' => Zend_Db::FETCH_OBJ
|
||||
);
|
||||
|
||||
/**
|
||||
|
|
|
@ -149,12 +149,12 @@ class Manager
|
|||
$this->enabledDirs = array();
|
||||
while (false !== ($file = readdir($fh))) {
|
||||
|
||||
if ($file[0] === '.') {
|
||||
if ($file[0] === '.' || $file === 'README') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$link = $this->enableDir . '/' . $file;
|
||||
if (!is_link($link)) {
|
||||
if (! is_link($link)) {
|
||||
Logger::warn(
|
||||
'Found invalid module in enabledModule directory "%s": "%s" is not a symlink',
|
||||
$this->enableDir,
|
||||
|
|
|
@ -274,7 +274,10 @@ class Module
|
|||
|
||||
$this->app->getLoader()->registerNamespace('Icinga\\Module\\' . $moduleName, $moduleLibraryDir);
|
||||
if (is_dir($this->getFormDir())) {
|
||||
$this->app->getLoader()->registerNamespace('Icinga\\Module\\' . $moduleName. '\\Form', $this->getFormDir());
|
||||
$this->app->getLoader()->registerNamespace(
|
||||
'Icinga\\Module\\' . $moduleName. '\\Form',
|
||||
$this->getFormDir()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ namespace Icinga\Data;
|
|||
|
||||
use Icinga\Exception;
|
||||
|
||||
abstract class AbstractQuery
|
||||
abstract class AbstractQuery implements QueryInterface
|
||||
{
|
||||
/**
|
||||
* Sort ascending
|
||||
|
@ -72,6 +72,17 @@ abstract class AbstractQuery
|
|||
$this->init();
|
||||
}
|
||||
|
||||
public function addColumn($name, $alias = null)
|
||||
{
|
||||
// TODO: Fail if adding column twice, but allow same col with new alias
|
||||
if ($alias === null) {
|
||||
$this->columns[] = $name;
|
||||
} else {
|
||||
$this->columns[$alias] = $name;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDatasource()
|
||||
{
|
||||
return $this->ds;
|
||||
|
@ -158,7 +169,7 @@ abstract class AbstractQuery
|
|||
$col = substr($col, 0, $pos);
|
||||
}
|
||||
} else {
|
||||
if (strtoupper($dir) === 'DESC') {
|
||||
if ($dir === self::SORT_DESC || strtoupper($dir) === 'DESC') {
|
||||
$dir = self::SORT_DESC;
|
||||
} else {
|
||||
$dir = self::SORT_ASC;
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Data;
|
||||
namespace Icinga\Data\DataArray;
|
||||
|
||||
class ArrayDatasource implements DatasourceInterface
|
||||
use Icinga\Data\DatasourceInterface;
|
||||
|
||||
class Datasource implements DatasourceInterface
|
||||
{
|
||||
protected $data;
|
||||
|
||||
|
@ -17,16 +19,16 @@ class ArrayDatasource implements DatasourceInterface
|
|||
}
|
||||
|
||||
/**
|
||||
* Instantiate an ArrayQuery object
|
||||
* Instantiate a Query object
|
||||
*
|
||||
* @return ArrayQuery
|
||||
* @return Query
|
||||
*/
|
||||
public function select()
|
||||
{
|
||||
return new ArrayQuery($this);
|
||||
return new Query($this);
|
||||
}
|
||||
|
||||
public function fetchColumn(ArrayQuery $query)
|
||||
public function fetchColumn(Query $query)
|
||||
{
|
||||
$result = array();
|
||||
foreach ($this->getResult($query) as $row) {
|
||||
|
@ -36,7 +38,7 @@ class ArrayDatasource implements DatasourceInterface
|
|||
return $result;
|
||||
}
|
||||
|
||||
public function fetchPairs(ArrayQuery $query)
|
||||
public function fetchPairs(Query $query)
|
||||
{
|
||||
$result = array();
|
||||
$keys = null;
|
||||
|
@ -52,19 +54,19 @@ class ArrayDatasource implements DatasourceInterface
|
|||
return $result;
|
||||
}
|
||||
|
||||
public function fetchAll(ArrayQuery $query)
|
||||
public function fetchAll(Query $query)
|
||||
{
|
||||
$result = $this->getResult($query);
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function count(ArrayQuery $query)
|
||||
public function count(Query $query)
|
||||
{
|
||||
$this->createResult($query);
|
||||
return $query->getCount();
|
||||
}
|
||||
|
||||
protected function createResult(ArrayQuery $query)
|
||||
protected function createResult(Query $query)
|
||||
{
|
||||
if ($query->hasResult()) {
|
||||
return $this;
|
||||
|
@ -109,7 +111,7 @@ class ArrayDatasource implements DatasourceInterface
|
|||
return $this;
|
||||
}
|
||||
|
||||
protected function getResult(ArrayQuery $query)
|
||||
protected function getResult(Query $query)
|
||||
{
|
||||
if (! $query->hasResult()) {
|
||||
$this->createResult($query);
|
|
@ -1,8 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Data;
|
||||
namespace Icinga\Data\DataArray;
|
||||
|
||||
class ArrayQuery extends AbstractQuery
|
||||
use Icinga\Data\AbstractQuery;
|
||||
|
||||
class Query extends AbstractQuery
|
||||
{
|
||||
/**
|
||||
* Remember the last count
|
|
@ -117,6 +117,7 @@ class Connection implements DatasourceInterface
|
|||
} else {
|
||||
$this->dbType = strtolower(get_class($this->db->getConnection()));
|
||||
}
|
||||
$this->db->setFetchMode(Zend_Db::FETCH_OBJ);
|
||||
|
||||
if ($this->dbType === null) {
|
||||
Logger::warn('Could not determine database type');
|
||||
|
|
|
@ -32,6 +32,12 @@ class Query extends AbstractQuery
|
|||
*/
|
||||
protected $countColumns;
|
||||
|
||||
protected $uglySlowConservativeCount = false;
|
||||
|
||||
protected $countCache;
|
||||
|
||||
protected $maxCount;
|
||||
|
||||
protected function init()
|
||||
{
|
||||
$this->db = $this->ds->getConnection()->getDb();
|
||||
|
@ -62,6 +68,7 @@ class Query extends AbstractQuery
|
|||
{
|
||||
$this->beforeCreatingCountQuery();
|
||||
$this->beforeCreatingSelectQuery();
|
||||
|
||||
$this->selectQuery = clone($this->baseQuery);
|
||||
$this->selectQuery->columns($this->columns);
|
||||
if ($this->hasOrder()) {
|
||||
|
@ -74,11 +81,27 @@ class Query extends AbstractQuery
|
|||
}
|
||||
}
|
||||
|
||||
$this->countQuery = clone($this->baseQuery);
|
||||
if ($this->countColumns === null) {
|
||||
$this->countColumns = array('cnt' => 'COUNT(*)');
|
||||
if ($this->uglySlowConservativeCount) {
|
||||
$query = clone($this->selectQuery);
|
||||
if ($this->maxCount === null) {
|
||||
$this->countQuery = $this->db->select()->from(
|
||||
$query,
|
||||
'COUNT(*)'
|
||||
);
|
||||
} else {
|
||||
$this->countQuery = $this->db->select()->from(
|
||||
$query->reset('order')->limit($this->maxCount),
|
||||
'COUNT(*)'
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$this->countQuery = clone($this->baseQuery);
|
||||
if ($this->countColumns === null) {
|
||||
$this->countColumns = array('cnt' => 'COUNT(*)');
|
||||
}
|
||||
$this->countQuery->columns($this->countColumns);
|
||||
}
|
||||
$this->countQuery->columns($this->countColumns);
|
||||
|
||||
}
|
||||
|
||||
protected function beforeCreatingCountQuery()
|
||||
|
@ -91,7 +114,10 @@ class Query extends AbstractQuery
|
|||
|
||||
public function count()
|
||||
{
|
||||
return $this->db->fetchOne($this->getCountQuery());
|
||||
if ($this->countCache === null) {
|
||||
$this->countCache = $this->db->fetchOne($this->getCountQuery());
|
||||
}
|
||||
return $this->countCache;
|
||||
}
|
||||
|
||||
public function fetchAll()
|
||||
|
@ -104,6 +130,11 @@ class Query extends AbstractQuery
|
|||
return $this->db->fetchRow($this->getSelectQuery());
|
||||
}
|
||||
|
||||
public function fetchColumn()
|
||||
{
|
||||
return $this->db->fetchCol($this->getSelectQuery());
|
||||
}
|
||||
|
||||
public function fetchOne()
|
||||
{
|
||||
return $this->db->fetchOne($this->getSelectQuery());
|
||||
|
|
|
@ -37,7 +37,7 @@ class Filter extends ArrayIterator
|
|||
}
|
||||
|
||||
/**
|
||||
* Get filtere as key-value array
|
||||
* Get filter as key-value array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,135 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Data;
|
||||
|
||||
class PivotTable
|
||||
{
|
||||
protected $query;
|
||||
|
||||
protected $verticalColumn;
|
||||
|
||||
protected $horizontalColumn;
|
||||
|
||||
protected $limit;
|
||||
|
||||
protected $offset;
|
||||
|
||||
protected $verticalLimit;
|
||||
|
||||
protected $horizontalLimit;
|
||||
|
||||
public function __construct(QueryInterface $query, $verticalColumn, $horizontalColumn)
|
||||
{
|
||||
$this->query = $query;
|
||||
$this->verticalColumn = $verticalColumn;
|
||||
$this->horizontalColumn = $horizontalColumn;
|
||||
}
|
||||
|
||||
public function limit($limit = null, $offset = null)
|
||||
{
|
||||
$this->limit = $limit;
|
||||
$this->offset = $offset;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getLimit()
|
||||
{
|
||||
if ($this->limit === null) {
|
||||
return 20;
|
||||
}
|
||||
return $this->limit;
|
||||
}
|
||||
|
||||
public function getOffset()
|
||||
{
|
||||
if ($this->limit === null) {
|
||||
return 20;
|
||||
}
|
||||
return $this->offset;
|
||||
}
|
||||
|
||||
public function verticalLimit($limit = null, $offset = null)
|
||||
{
|
||||
// TODO: Trigger limit by calling $this->limit()?
|
||||
if ($limit === null) {
|
||||
$limit = $this->getLimit();
|
||||
}
|
||||
if ($offset === null) {
|
||||
$offset = $this->getOffset();
|
||||
}
|
||||
$this->verticalLimit = $limit;
|
||||
$this->verticalOffset = $offset;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function paginateVertical($limit = null, $offset = null)
|
||||
{
|
||||
$this->verticalLimit($limit, $offset);
|
||||
return Paginator($this);
|
||||
}
|
||||
|
||||
public function getVerticalLimit()
|
||||
{
|
||||
if ($this->verticalLimit === null) {
|
||||
return 20;
|
||||
}
|
||||
return $this->verticalLimit;
|
||||
}
|
||||
|
||||
public function getVerticalOffset()
|
||||
{
|
||||
if ($this->verticalLimit === null) {
|
||||
return 20;
|
||||
}
|
||||
return $this->verticalOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch all columns
|
||||
*/
|
||||
public function fetchAll()
|
||||
{
|
||||
$xcol = $this->horizontalColumn;
|
||||
$ycol = $this->verticalColumn;
|
||||
$queryX = clone($this->query);
|
||||
$queryX->columns($xcol);
|
||||
if ($this->limit !== null) {
|
||||
$queryX->limit($this->getLimit(), $this->getOffset());
|
||||
}
|
||||
$queryX->limit(40);
|
||||
$listX = $queryX->fetchColumn();
|
||||
$queryY = clone($this->query);
|
||||
|
||||
$queryY->columns($ycol);
|
||||
if ($this->verticalLimit !== null) {
|
||||
$queryY->limit($this->getVerticalLimit(), $this->getVerticalOffset());
|
||||
}
|
||||
$queryY->limit(50);
|
||||
$listY = $queryY->fetchColumn();
|
||||
|
||||
// TODO: resetOrder
|
||||
$this->query
|
||||
->where($ycol, $listY)
|
||||
->where($xcol, $listX)
|
||||
->order($ycol)
|
||||
->order($xcol);
|
||||
$pivot = array();
|
||||
$emptyrow = (object) array();
|
||||
foreach ($this->query->listColumns() as $col) {
|
||||
$emptyrow->$col = null;
|
||||
}
|
||||
foreach ($listY as $y) {
|
||||
foreach ($listX as $x) {
|
||||
$row = clone($emptyrow);
|
||||
$row->$xcol = $x;
|
||||
$row->$ycol = $y;
|
||||
$pivot[$y][$x] = $row;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->query->fetchAll() as $row) {
|
||||
$pivot[$row->$ycol][$row->$xcol] = $row;
|
||||
}
|
||||
return $pivot;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,162 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Data;
|
||||
|
||||
use Countable;
|
||||
|
||||
interface QueryInterface extends Countable
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param DatasourceInterface $ds Your data source
|
||||
*/
|
||||
public function __construct(DatasourceInterface $ds, $columns = null);
|
||||
|
||||
public function getDatasource();
|
||||
|
||||
/**
|
||||
* Choose a table and the colums you are interested in
|
||||
*
|
||||
* Query will return all available columns if none are given here
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function from($table, $columns = null);
|
||||
|
||||
public function columns($columns);
|
||||
|
||||
/**
|
||||
* Use once or multiple times to filter result set
|
||||
*
|
||||
* Multiple where calls will be combined by a logical AND operation
|
||||
*
|
||||
* @param string $key Column or backend-specific search expression
|
||||
* @param string $val Search value, must be escaped automagically
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function where($key, $val = null);
|
||||
|
||||
/**
|
||||
* Sort query result by the given column name
|
||||
*
|
||||
* Sort direction can be ascending (self::SORT_ASC, being the default)
|
||||
* or descending (self::SORT_DESC).
|
||||
*
|
||||
* Preferred usage:
|
||||
* <code>
|
||||
* $query->sort('column_name ASC')
|
||||
* </code>
|
||||
*
|
||||
* @param string $col Column, may contain direction separated by space
|
||||
* @param int $dir Sort direction
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function order($col, $dir = null);
|
||||
|
||||
/**
|
||||
* Limit the result set
|
||||
*
|
||||
* @param int $count Return not more than that many rows
|
||||
* @param int $offset Result starts with this row
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function limit($count = null, $offset = null);
|
||||
|
||||
/**
|
||||
* Wheter at least one order column has been applied to this Query
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasOrder();
|
||||
|
||||
/**
|
||||
* Wheter a limit has been applied to this Query
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasLimit();
|
||||
|
||||
/**
|
||||
* Wheter a starting offset been applied to this Query
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasOffset();
|
||||
|
||||
/**
|
||||
* Get the query limit
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getLimit();
|
||||
|
||||
/**
|
||||
* Get the query starting offset
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getOffset();
|
||||
|
||||
/**
|
||||
* Get the columns that have been asked for with this query
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function listColumns();
|
||||
|
||||
public function getColumns();
|
||||
|
||||
/**
|
||||
* Get the filters that have been applied to this query
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function listFilters();
|
||||
|
||||
|
||||
/**
|
||||
* Fetch result as an array of objects
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function fetchAll();
|
||||
|
||||
/**
|
||||
* Fetch first result row
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function fetchRow();
|
||||
|
||||
/**
|
||||
* Fetch first result column
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function fetchColumn();
|
||||
|
||||
/**
|
||||
* Fetch first column value from first result row
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function fetchOne();
|
||||
|
||||
/**
|
||||
* Fetch result as a key/value pair array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function fetchPairs();
|
||||
|
||||
/**
|
||||
* Return a pagination adapter for this query
|
||||
*
|
||||
* @return \Zend_Paginator
|
||||
*/
|
||||
public function paginate($limit = null, $page = null);
|
||||
}
|
|
@ -6,17 +6,14 @@ use TCPDF;
|
|||
use Icinga\Web\Url;
|
||||
use Icinga\Application\Icinga;
|
||||
|
||||
// $_SERVER['DOCUMENT_ROOT'] = '/';
|
||||
$_SERVER['DOCUMENT_ROOT'] = Icinga::app()->getApplicationDir() . '/../public';
|
||||
define('K_TCPDF_EXTERNAL_CONFIG', true);
|
||||
|
||||
//define('K_PATH_URL', 'http://net-test-icinga-vm1.adm.netways.de/develop/'); // ???
|
||||
// define('K_PATH_URL', '/var/www/net-test-icinga-vm1.adm.netways.de/develop/public'); // ???
|
||||
define('K_PATH_URL', (string) Url::fromPath('/') === '/' ? '' : (string) Url::fromPath('/')); // ???'/'));
|
||||
define('K_PATH_URL', (string) Url::create('/'));
|
||||
define('K_PATH_MAIN', dirname(ICINGA_LIBDIR) . '/public');
|
||||
define('K_PATH_FONTS', ICINGA_LIBDIR . '/vendor/tcpdf/fonts/');
|
||||
define('K_PATH_CACHE', ICINGA_LIBDIR . '/vendor/tcpdf/cache/');
|
||||
define('K_PATH_URL_CACHE', ICINGA_LIBDIR . '/vendor/tcpdf/cache/');
|
||||
// define('K_PATH_CACHE', ICINGA_LIBDIR . '/vendor/tcpdf/cache/');
|
||||
// define('K_PATH_URL_CACHE', ICINGA_LIBDIR . '/vendor/tcpdf/cache/');
|
||||
define('K_PATH_CACHE', '/tmp/');
|
||||
define('K_PATH_URL_CACHE', '/tmp/');
|
||||
//define('K_PATH_IMAGES', K_PATH_MAIN . 'images/'); // ???
|
||||
define('K_PATH_IMAGES', dirname(ICINGA_LIBDIR) . '/public'); // ???
|
||||
define('K_BLANK_IMAGE', K_PATH_IMAGES.'_blank.png'); // COULD be anything?
|
||||
|
@ -41,6 +38,7 @@ class Pdf extends TCPDF
|
|||
$diskcache = false,
|
||||
$pdfa = false
|
||||
) {
|
||||
unset($_SERVER['DOCUMENT_ROOT']);
|
||||
parent::__construct(
|
||||
$orientation,
|
||||
$unit,
|
||||
|
|
|
@ -151,9 +151,14 @@ class IniStore implements LoadInterface, FlushObserverInterface
|
|||
*/
|
||||
private function createDefaultIniFile()
|
||||
{
|
||||
touch($this->preferencesFile);
|
||||
// TODO: We should be able to work without preferences. Also we shouldn't store any
|
||||
// prefs as long as we didn't change some.
|
||||
if (! is_writable($this->configPath) || touch($this->preferencesFile) === false) {
|
||||
throw new ConfigurationError(
|
||||
sprintf('Unable to store "%s"', $this->preferencesFile)
|
||||
);
|
||||
}
|
||||
chmod($this->preferencesFile, 0664);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -28,11 +28,13 @@
|
|||
|
||||
namespace Icinga\Web\Paginator\Adapter;
|
||||
|
||||
use Zend_Paginator_Adapter_Interface;
|
||||
|
||||
/**
|
||||
* @see Zend_Paginator_Adapter_Interface
|
||||
*/
|
||||
|
||||
class QueryAdapter implements \Zend_Paginator_Adapter_Interface
|
||||
class QueryAdapter implements Zend_Paginator_Adapter_Interface
|
||||
{
|
||||
/**
|
||||
* Array
|
||||
|
@ -53,9 +55,7 @@ class QueryAdapter implements \Zend_Paginator_Adapter_Interface
|
|||
*
|
||||
* @param array $query Query to paginate
|
||||
*/
|
||||
// TODO: Re-add abstract Query type as soon as a more generic one
|
||||
// is available. Should fit Protocol-Queries too.
|
||||
// public function __construct(\Icinga\Backend\Query $query)
|
||||
// TODO: This might be ready for (QueryInterface $query)
|
||||
public function __construct($query)
|
||||
{
|
||||
$this->query = $query;
|
||||
|
|
|
@ -162,7 +162,7 @@ class Monitoring_ListController extends ActionController
|
|||
'host_name' => 'Host Name',
|
||||
'host_address' => 'Host Address',
|
||||
'host_last_check' => 'Last Host Check'
|
||||
));
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -244,10 +244,14 @@ class Monitoring_ListController extends ActionController
|
|||
-1,
|
||||
PREG_SPLIT_NO_EMPTY
|
||||
);
|
||||
|
||||
if (empty($extra)) {
|
||||
$cols = $columns;
|
||||
} else {
|
||||
$cols = array_merge($columns, $extra);
|
||||
}
|
||||
$this->view->extraColumns = $extra;
|
||||
$query = $this->backend->select()
|
||||
->from($view, array_merge($columns, $extra))
|
||||
->from($view, $cols)
|
||||
->applyRequest($this->_request);
|
||||
$this->handleFormatRequest($query);
|
||||
return $query;
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
<?php
|
||||
// @codingStandardsIgnoreStart
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/**
|
||||
* This file is part of Icinga 2 Web.
|
||||
|
@ -27,6 +26,7 @@
|
|||
*/
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
// @codingStandardsIgnoreStart
|
||||
use \Icinga\Module\Monitoring\Backend;
|
||||
use Icinga\Web\Controller\ActionController;
|
||||
use Icinga\Web\Hook;
|
||||
|
@ -199,7 +199,6 @@ class Monitoring_ShowController extends ActionController
|
|||
->fetchPairs();
|
||||
Benchmark::measure('Service action done');
|
||||
$object = $this->view->object->prefetch();
|
||||
$this->prepareGrapherHook();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -300,7 +299,6 @@ class Monitoring_ShowController extends ActionController
|
|||
->where('object_type', 'host')
|
||||
->fetchPairs();
|
||||
$this->view->object->prefetch();
|
||||
$this->prepareGrapherHook();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -356,21 +354,6 @@ class Monitoring_ShowController extends ActionController
|
|||
));
|
||||
}
|
||||
|
||||
protected function prepareGrapherHook()
|
||||
{
|
||||
if ($grapher = Hook::get('grapher')) {
|
||||
$object = $this->view->object;
|
||||
if ($grapher->hasGraph(
|
||||
$object->host_name,
|
||||
$object->service_description
|
||||
)) {
|
||||
$this->view->preview_image = $grapher->getPreviewImage(
|
||||
$object->host_name,
|
||||
$object->service_description
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Creating tabs for this controller
|
||||
* @return \Icinga\Web\Widget\AbstractWidget
|
||||
|
@ -444,5 +427,4 @@ class Monitoring_ShowController extends ActionController
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
// @codingStandardsIgnoreEnd
|
||||
|
|
|
@ -18,8 +18,15 @@ use Icinga\Data\Db\Connection;
|
|||
*
|
||||
* Other possible (history-related) indexes, still subject to tests:
|
||||
* CREATE INDEX web2_index ON icinga_statehistory (object_id, state_time DESC);
|
||||
* CREATE INDEX web2_index ON icinga_notifications (object_id, instance_id, start_time DESC);
|
||||
* CREATE INDEX web2_index ON icinga_downtimehistory (object_id, actual_start_time, actual_end_time);
|
||||
* CREATE INDEX web2_time ON icinga_statehistory (state_time DESC);
|
||||
* CREATE INDEX web2_index ON icinga_notifications (object_id, start_time DESC);
|
||||
* CREATE INDEX web2_start ON icinga_downtimehistory (actual_start_time);
|
||||
* CREATE INDEX web2_end ON icinga_downtimehistory (actual_end_time);
|
||||
* CREATE INDEX web2_index ON icinga_commenthistory (object_id, comment_time);
|
||||
* CREATE INDEX web2_object ON icinga_commenthistory (object_id);
|
||||
* CREATE INDEX web2_time ON icinga_commenthistory (comment_time DESC);
|
||||
*
|
||||
* CREATE INDEX web2_notification_contact ON icinga_contactnotifications (contact_object_id, notification_id);
|
||||
*
|
||||
* These should be unique:
|
||||
* CREATE INDEX web2_index ON icinga_host_contacts (host_id, contact_object_id);
|
||||
|
|
|
@ -20,12 +20,21 @@ abstract class AbstractQuery extends Query
|
|||
|
||||
protected $object_id = 'object_id';
|
||||
protected $host_id = 'host_id';
|
||||
protected $service_id = 'service_id';
|
||||
protected $hostgroup_id = 'hostgroup_id';
|
||||
protected $service_id = 'service_id';
|
||||
protected $servicegroup_id = 'servicegroup_id';
|
||||
protected $contact_id = 'contact_id';
|
||||
protected $contactgroup_id = 'contactgroup_id';
|
||||
|
||||
protected $aggregateColumnIdx = array();
|
||||
|
||||
protected $allowCustomVars = false;
|
||||
|
||||
protected function isAggregateColumn($column)
|
||||
{
|
||||
return array_key_exists($column, $this->aggregateColumnIdx);
|
||||
}
|
||||
|
||||
protected function init()
|
||||
{
|
||||
parent::init();
|
||||
|
@ -33,7 +42,9 @@ abstract class AbstractQuery extends Query
|
|||
$this->prefix = $this->ds->getPrefix();
|
||||
|
||||
if ($this->ds->getConnection()->getDbType() === 'oracle') {
|
||||
$this->object_id = $this->host_id = $this->service_id = $this->hostgroup_id = $this->servicegroup_id = 'id'; // REALLY?
|
||||
$this->object_id = $this->host_id = $this->service_id
|
||||
= $this->hostgroup_id = $this->servicegroup_id
|
||||
= $this->contact_id = $this->contactgroup_id = 'id'; // REALLY?
|
||||
foreach ($this->columnMap as $table => & $columns) {
|
||||
foreach ($columns as $key => & $value) {
|
||||
$value = preg_replace('/UNIX_TIMESTAMP/', 'localts2unixts', $value);
|
||||
|
@ -45,12 +56,13 @@ abstract class AbstractQuery extends Query
|
|||
foreach ($this->columnMap as $table => & $columns) {
|
||||
foreach ($columns as $key => & $value) {
|
||||
$value = preg_replace('/ COLLATE .+$/', '', $value);
|
||||
$value = preg_replace('/inet_aton\(([[:word:].]+)\)/i', '$1::inet - \'0.0.0.0\'', $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->prepareAliasIndexes();
|
||||
$this->joinBaseTables();
|
||||
$this->prepareAliasIndexes();
|
||||
}
|
||||
|
||||
protected function isCustomVar($alias)
|
||||
|
@ -103,7 +115,21 @@ abstract class AbstractQuery extends Query
|
|||
|
||||
protected function getDefaultColumns()
|
||||
{
|
||||
return $this->columnMap['hostgroups'];
|
||||
$table = array_shift(array_keys($this->columnMap));
|
||||
return array_keys($this->columnMap[$table]);
|
||||
}
|
||||
|
||||
protected function joinBaseTables()
|
||||
{
|
||||
reset($this->columnMap);
|
||||
$table = key($this->columnMap);
|
||||
|
||||
$this->baseQuery = $this->db->select()->from(
|
||||
array($table => $this->prefix . $table),
|
||||
array()
|
||||
);
|
||||
|
||||
$this->joinedVirtualTables = array($table => true);
|
||||
}
|
||||
|
||||
protected function beforeCreatingCountQuery()
|
||||
|
@ -121,18 +147,12 @@ abstract class AbstractQuery extends Query
|
|||
protected function applyAllFilters()
|
||||
{
|
||||
$filters = array();
|
||||
// TODO: Handle $special in a more generic way
|
||||
$special = array('hostgroups', 'servicegroups');
|
||||
foreach ($this->filters as $f) {
|
||||
$alias = $f[0];
|
||||
$value = $f[1];
|
||||
$this->requireColumn($alias);
|
||||
|
||||
if ($alias === 'hostgroups') {
|
||||
$col = 'hg.alias';
|
||||
} elseif ($alias === 'servicegroups') {
|
||||
$col = 'sg.alias';
|
||||
} elseif ($this->isCustomvar($alias)) {
|
||||
if ($this->isCustomvar($alias)) {
|
||||
$col = $this->getCustomvarColumnName($alias);
|
||||
} elseif ($this->hasAliasName($alias)) {
|
||||
$col = $this->aliasToColumnName($alias);
|
||||
|
@ -141,7 +161,17 @@ abstract class AbstractQuery extends Query
|
|||
'If you finished here, code has been messed up'
|
||||
);
|
||||
}
|
||||
$this->baseQuery->where($this->prepareFilterStringForColumn($col, $value));
|
||||
|
||||
$func = 'filter' . ucfirst($alias);
|
||||
if (method_exists($this, $func)) {
|
||||
$this->$func($value);
|
||||
return;
|
||||
}
|
||||
if ($this->isAggregateColumn($alias)) {
|
||||
$this->baseQuery->having($this->prepareFilterStringForColumn($col, $value));
|
||||
} else {
|
||||
$this->baseQuery->where($this->prepareFilterStringForColumn($col, $value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -257,6 +287,15 @@ abstract class AbstractQuery extends Query
|
|||
return $this->customVars[$customvar] . '.varvalue';
|
||||
}
|
||||
|
||||
protected function createSubQuery($queryName, $columns = array())
|
||||
{
|
||||
$class = '\\'
|
||||
. substr(__CLASS__, 0, strrpos(__CLASS__, '\\') + 1)
|
||||
. ucfirst($queryName) . 'Query';
|
||||
$query = new $class($this->ds, $columns);
|
||||
return $query;
|
||||
}
|
||||
|
||||
protected function customvarNameToTypeName($customvar)
|
||||
{
|
||||
// TODO: Improve this:
|
||||
|
@ -279,8 +318,11 @@ abstract class AbstractQuery extends Query
|
|||
$or = array();
|
||||
$and = array();
|
||||
|
||||
if (! is_array($value) && strpos($value, ',') !== false) {
|
||||
$value = preg_split('~,~', $value, -1, PREG_SPLIT_NO_EMPTY);
|
||||
if (
|
||||
! is_array($value) &&
|
||||
(strpos($value, ',') !== false || strpos($value, '|') !== false)
|
||||
) {
|
||||
$value = preg_split('~[,|]~', $value, -1, PREG_SPLIT_NO_EMPTY);
|
||||
}
|
||||
if (! is_array($value)) {
|
||||
$value = array($value);
|
||||
|
@ -292,38 +334,56 @@ abstract class AbstractQuery extends Query
|
|||
// TODO: REALLY??
|
||||
continue;
|
||||
}
|
||||
// Value starting with minus: negation
|
||||
if ($val[0] === '-') {
|
||||
$not = false;
|
||||
$force = false;
|
||||
$op = '=';
|
||||
$wildcard = false;
|
||||
|
||||
if ($val[0] === '-' || $val[0] === '!') {
|
||||
// Value starting with minus or !: negation
|
||||
$val = substr($val, 1);
|
||||
if (strpos($val, '*') === false) {
|
||||
$and[] = $this->db->quoteInto($column . ' != ?', $val);
|
||||
} else {
|
||||
$and[] = $this->db->quoteInto(
|
||||
$column . ' NOT LIKE ?',
|
||||
str_replace('*', '%', $val)
|
||||
);
|
||||
}
|
||||
} elseif ($val[0] === '+') { // Value starting with +: enforces AND
|
||||
$not = true;
|
||||
}
|
||||
|
||||
if ($val[0] === '+') {
|
||||
// Value starting with +: enforces AND
|
||||
// TODO: depends on correct URL handling, not given in all
|
||||
// ZF versions
|
||||
// ZF versions.
|
||||
$val = substr($val, 1);
|
||||
if (strpos($val, '*') === false) {
|
||||
$and[] = $this->db->quoteInto($column . ' = ?', $val);
|
||||
} else {
|
||||
$and[] = $this->db->quoteInto(
|
||||
$column . ' LIKE ?',
|
||||
str_replace('*', '%', $val)
|
||||
);
|
||||
}
|
||||
} else { // All others ar ORs:
|
||||
if (strpos($val, '*') === false) {
|
||||
$or[] = $this->db->quoteInto($column . ' = ?', $val);
|
||||
} else {
|
||||
$or[] = $this->db->quoteInto(
|
||||
$column . ' LIKE ?',
|
||||
str_replace('*', '%', $val)
|
||||
);
|
||||
}
|
||||
$force = true;
|
||||
}
|
||||
if ($val[0] === '<' || $val[0] === '>') {
|
||||
$op = $val[0];
|
||||
$val = substr($val, 1);
|
||||
}
|
||||
if (strpos($val, '*') !== false) {
|
||||
$wildcard = true;
|
||||
$val = str_replace('*', '%', $val);
|
||||
}
|
||||
|
||||
$operator = null;
|
||||
switch ($op) {
|
||||
case '=':
|
||||
if ($not) {
|
||||
$operator = $wildcard ? 'NOT LIKE' : '!=';
|
||||
} else {
|
||||
$operator = $wildcard ? 'LIKE' : '=';
|
||||
}
|
||||
break;
|
||||
case '>':
|
||||
$operator = $not ? '<=' : '>';
|
||||
break;
|
||||
case '<':
|
||||
$operator = $not ? '>=' : '<';
|
||||
break;
|
||||
default:
|
||||
throw new ProgrammingError("'$op' is not a valid operator");
|
||||
}
|
||||
|
||||
if ($not || $force) {
|
||||
$and[] = $this->db->quoteInto($column . ' ' . $operator . ' ?', $val);
|
||||
} else {
|
||||
$or[] = $this->db->quoteInto($column . ' ' . $operator . ' ?', $val);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Monitoring\Backend\Ido\Query;
|
||||
|
||||
use Zend_Db_Select;
|
||||
|
||||
class AllcontactsQuery extends AbstractQuery
|
||||
{
|
||||
protected $columnMap = array(
|
||||
'contacts' => array(
|
||||
'contact_name' => 'c.contact_name',
|
||||
'host_object_id' => 'c.host_object_id',
|
||||
'host_name' => 'c.host_name',
|
||||
'service_object_id' => 'c.service_object_id',
|
||||
'service_host_name' => 'c.service_host_name',
|
||||
'service_description' => 'c.service_description',
|
||||
|
||||
'contact_alias' => 'c.contact_alias',
|
||||
'contact_email' => 'c.contact_email',
|
||||
'contact_pager' => 'c.contact_pager',
|
||||
'contact_has_host_notfications' => 'c.contact_has_host_notfications',
|
||||
'contact_has_service_notfications' => 'c.contact_has_service_notfications',
|
||||
'contact_can_submit_commands' => 'c.contact_can_submit_commands',
|
||||
'contact_notify_service_recovery' => 'c.notify_service_recovery',
|
||||
'contact_notify_service_warning' => 'c.notify_service_warning',
|
||||
'contact_notify_service_critical' => 'c.notify_service_critical',
|
||||
'contact_notify_service_unknown' => 'c.notify_service_unknown',
|
||||
'contact_notify_service_flapping' => 'c.notify_service_flapping',
|
||||
'contact_notify_service_downtime' => 'c.notify_service_recovery',
|
||||
'contact_notify_host_recovery' => 'c.notify_host_recovery',
|
||||
'contact_notify_host_down' => 'c.notify_host_down',
|
||||
'contact_notify_host_unreachable' => 'c.notify_host_unreachable',
|
||||
'contact_notify_host_flapping' => 'c.notify_host_flapping',
|
||||
'contact_notify_host_downtime' => 'c.notify_host_downtime',
|
||||
|
||||
|
||||
)
|
||||
);
|
||||
|
||||
protected $contacts;
|
||||
protected $contactgroups;
|
||||
protected $uglySlowConservativeCount = true;
|
||||
|
||||
protected function requireColumn($alias)
|
||||
{
|
||||
$this->contacts->addColumn($alias);
|
||||
$this->contactgroups->addColumn($alias);
|
||||
return parent::requireColumn($alias);
|
||||
}
|
||||
|
||||
protected function joinBaseTables()
|
||||
{
|
||||
$this->contacts = $this->createSubQuery(
|
||||
'contact',
|
||||
array('contact_name')
|
||||
);
|
||||
$this->contactgroups = $this->createSubQuery(
|
||||
'contactgroup',
|
||||
array('contact_name')
|
||||
);
|
||||
$sub = $this->db->select()->union(
|
||||
array($this->contacts, $this->contactgroups),
|
||||
Zend_Db_Select::SQL_UNION_ALL
|
||||
);
|
||||
|
||||
$this->baseQuery = $this->db->select()->distinct()->from(
|
||||
array('c' => $sub),
|
||||
array()
|
||||
);
|
||||
|
||||
$this->joinedVirtualTables = array('contacts' => true);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Monitoring\Backend\Ido\Query;
|
||||
|
||||
class CommenthistoryQuery extends AbstractQuery
|
||||
{
|
||||
protected $columnMap = array(
|
||||
'commenthistory' => array(
|
||||
'state_time' => 'comment_time',
|
||||
'timestamp' => 'UNIX_TIMESTAMP(comment_time)',
|
||||
'raw_timestamp' => 'comment_time',
|
||||
'object_id' => 'object_id',
|
||||
'type' => "(CASE entry_type WHEN 1 THEN 'comment' WHEN 2 THEN 'dt_comment' WHEN 3 THEN 'flapping' WHEN 4 THEN 'ack' END)",
|
||||
'state' => '(NULL)',
|
||||
'state_type' => '(NULL)',
|
||||
'output' => "('[' || author_name || '] ' || comment_data)",
|
||||
'attempt' => '(NULL)',
|
||||
'max_attempts' => '(NULL)',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
@ -4,17 +4,35 @@ namespace Icinga\Module\Monitoring\Backend\Ido\Query;
|
|||
|
||||
class ContactQuery extends AbstractQuery
|
||||
{
|
||||
// TODO: join host/service timeperiod
|
||||
|
||||
protected $columnMap = array(
|
||||
'contacts' => array(
|
||||
'contact_name' => 'co.name1 COLLATE latin1_general_ci',
|
||||
'contact_alias' => 'c.alias',
|
||||
'contact_email' => 'c.email_address',
|
||||
'contact_pager' => 'c.pager_address',
|
||||
'contact_has_host_notfications' => 'c.host_notifications_enabled',
|
||||
'contact_has_service_notfications' => 'c.service_notifications_enabled',
|
||||
'contact_can_submit_commands' => 'c.can_submit_commands',
|
||||
'contact_notify_service_recovery' => 'c.notify_service_recovery',
|
||||
'contact_notify_service_warning' => 'c.notify_service_warning',
|
||||
'contact_notify_service_critical' => 'c.notify_service_critical',
|
||||
'contact_notify_service_unknown' => 'c.notify_service_unknown',
|
||||
'contact_notify_service_flapping' => 'c.notify_service_flapping',
|
||||
'contact_notify_service_downtime' => 'c.notify_service_recovery',
|
||||
'contact_notify_host_recovery' => 'c.notify_host_recovery',
|
||||
'contact_notify_host_down' => 'c.notify_host_down',
|
||||
'contact_notify_host_unreachable' => 'c.notify_host_unreachable',
|
||||
'contact_notify_host_flapping' => 'c.notify_host_flapping',
|
||||
'contact_notify_host_downtime' => 'c.notify_host_downtime',
|
||||
),
|
||||
'hosts' => array(
|
||||
'host_name' => 'ho.name1 COLLATE latin1_general_ci',
|
||||
'host_object_id' => 'ho.object_id',
|
||||
'host_name' => 'ho.name1 COLLATE latin1_general_ci',
|
||||
),
|
||||
'services' => array(
|
||||
'service_object_id' => 'so.object_id',
|
||||
'service_host_name' => 'so.name1 COLLATE latin1_general_ci',
|
||||
'service_description' => 'so.name2 COLLATE latin1_general_ci',
|
||||
)
|
||||
|
|
|
@ -10,16 +10,36 @@ class ContactgroupQuery extends AbstractQuery
|
|||
'contactgroup_alias' => 'cg.alias',
|
||||
),
|
||||
'contacts' => array(
|
||||
'contact_name' => 'co.name1 COLLATE latin1_general_ci',
|
||||
'contact_name' => 'co.name1 COLLATE latin1_general_ci',
|
||||
'contact_alias' => 'c.alias',
|
||||
'contact_email' => 'c.email_address',
|
||||
'contact_pager' => 'c.pager_address',
|
||||
'contact_has_host_notfications' => 'c.host_notifications_enabled',
|
||||
'contact_has_service_notfications' => 'c.service_notifications_enabled',
|
||||
'contact_can_submit_commands' => 'c.can_submit_commands',
|
||||
'contact_notify_service_recovery' => 'c.notify_service_recovery',
|
||||
'contact_notify_service_warning' => 'c.notify_service_warning',
|
||||
'contact_notify_service_critical' => 'c.notify_service_critical',
|
||||
'contact_notify_service_unknown' => 'c.notify_service_unknown',
|
||||
'contact_notify_service_flapping' => 'c.notify_service_flapping',
|
||||
'contact_notify_service_downtime' => 'c.notify_service_recovery',
|
||||
'contact_notify_host_recovery' => 'c.notify_host_recovery',
|
||||
'contact_notify_host_down' => 'c.notify_host_down',
|
||||
'contact_notify_host_unreachable' => 'c.notify_host_unreachable',
|
||||
'contact_notify_host_flapping' => 'c.notify_host_flapping',
|
||||
'contact_notify_host_downtime' => 'c.notify_host_downtime',
|
||||
),
|
||||
'hosts' => array(
|
||||
'host_name' => 'ho.name1',
|
||||
'host_object_id' => 'ho.object_id',
|
||||
'host_name' => 'ho.name1',
|
||||
),
|
||||
'services' => array(
|
||||
'service_host_name' => 'so.name1 COLLATE latin1_general_ci',
|
||||
'service_object_id' => 'so.object_id',
|
||||
'service_host_name' => 'so.name1 COLLATE latin1_general_ci',
|
||||
'service_description' => 'so.name2 COLLATE latin1_general_ci',
|
||||
)
|
||||
);
|
||||
protected $uglySlowConservativeCount = true;
|
||||
|
||||
protected function joinBaseTables()
|
||||
{
|
||||
|
@ -38,7 +58,7 @@ class ContactgroupQuery extends AbstractQuery
|
|||
|
||||
protected function joinContacts()
|
||||
{
|
||||
$this->baseQuery->join(
|
||||
$this->baseQuery->distinct()->join(
|
||||
array('cgm' => $this->prefix . 'contactgroup_members'),
|
||||
'cgm.contactgroup_id = cg.contactgroup_id',
|
||||
array()
|
||||
|
@ -46,12 +66,16 @@ class ContactgroupQuery extends AbstractQuery
|
|||
array('co' => $this->prefix . 'objects'),
|
||||
'cgm.contact_object_id = co.object_id AND co.is_active = 1',
|
||||
array()
|
||||
)->join(
|
||||
array('c' => $this->prefix . 'contacts'),
|
||||
'c.contact_object_id = co.object_id',
|
||||
array()
|
||||
);
|
||||
}
|
||||
|
||||
protected function joinHosts()
|
||||
{
|
||||
$this->baseQuery->join(
|
||||
$this->baseQuery->distinct()->join(
|
||||
array('hcg' => $this->prefix . 'host_contactgroups'),
|
||||
'hcg.contactgroup_object_id = cg.contactgroup_object_id',
|
||||
array()
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Monitoring\Backend\Ido\Query;
|
||||
|
||||
class DowntimeendhistoryQuery extends AbstractQuery
|
||||
{
|
||||
protected $columnMap = array(
|
||||
'downtimehistory' => array(
|
||||
'state_time' => 'actual_end_time',
|
||||
'timestamp' => 'UNIX_TIMESTAMP(actual_end_time)',
|
||||
'raw_timestamp' => 'actual_end_time',
|
||||
'object_id' => 'object_id',
|
||||
'type' => "('dt_end')",
|
||||
'state' => '(NULL)',
|
||||
'state_type' => '(NULL)',
|
||||
'output' => "('[' || author_name || '] ' || comment_data)",
|
||||
'attempt' => '(NULL)',
|
||||
'max_attempts' => '(NULL)',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Monitoring\Backend\Ido\Query;
|
||||
|
||||
class DowntimestarthistoryQuery extends AbstractQuery
|
||||
{
|
||||
protected $columnMap = array(
|
||||
'downtimehistory' => array(
|
||||
'state_time' => 'actual_start_time',
|
||||
'timestamp' => 'UNIX_TIMESTAMP(actual_start_time)',
|
||||
'raw_timestamp' => 'actual_start_time',
|
||||
'object_id' => 'object_id',
|
||||
'type' => "('dt_end')",
|
||||
'state' => '(NULL)',
|
||||
'state_type' => '(NULL)',
|
||||
'output' => "('[' || author_name || '] ' || comment_data)",
|
||||
'attempt' => '(NULL)',
|
||||
'max_attempts' => '(NULL)',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Icinga\Module\Monitoring\Backend\Ido\Query;
|
||||
|
||||
use \Zend_Db_Select;
|
||||
use Icinga\Exception\ProgrammingError;
|
||||
|
||||
class EventHistoryQuery extends AbstractQuery
|
||||
|
@ -10,195 +11,73 @@ class EventHistoryQuery extends AbstractQuery
|
|||
|
||||
protected $columnMap = array(
|
||||
'eventhistory' => array(
|
||||
'cnt_notification' => "SUM(CASE eh.type WHEN 'notify' THEN 1 ELSE 0 END)",
|
||||
'cnt_hard_state' => "SUM(CASE eh.type WHEN 'hard_state' THEN 1 ELSE 0 END)",
|
||||
'cnt_soft_state' => "SUM(CASE eh.type WHEN 'hard_state' THEN 1 ELSE 0 END)",
|
||||
'cnt_downtime_start' => "SUM(CASE eh.type WHEN 'dt_start' THEN 1 ELSE 0 END)",
|
||||
'cnt_downtime_end' => "SUM(CASE eh.type WHEN 'dt_end' THEN 1 ELSE 0 END)",
|
||||
'host' => 'eho.name1 COLLATE latin1_general_ci',
|
||||
'service' => 'eho.name2 COLLATE latin1_general_ci',
|
||||
'host_name' => 'eho.name1 COLLATE latin1_general_ci',
|
||||
'service_description' => 'eho.name2 COLLATE latin1_general_ci',
|
||||
'object_type' => "CASE WHEN eho.objecttype_id = 1 THEN 'host' ELSE 'service' END",
|
||||
'timestamp' => 'UNIX_TIMESTAMP(eh.state_time)',
|
||||
'raw_timestamp' => 'eh.state_time',
|
||||
'timestamp' => 'eh.timestamp',
|
||||
'raw_timestamp' => 'eh.raw_timestamp',
|
||||
'state' => 'eh.state',
|
||||
// 'last_state' => 'eh.last_state',
|
||||
// 'last_hard_state' => 'eh.last_hard_state',
|
||||
'attempt' => 'eh.attempt',
|
||||
'max_attempts' => 'eh.max_attempts',
|
||||
'output' => 'eh.output', // we do not want long_output
|
||||
'problems' => 'CASE WHEN eh.state = 0 OR eh.state IS NULL THEN 0 ELSE 1 END',
|
||||
//'problems' => 'CASE WHEN eh.state = 0 OR eh.state IS NULL THEN 0 ELSE 1 END',
|
||||
'type' => 'eh.type',
|
||||
)
|
||||
),
|
||||
'hostgroups' => array(
|
||||
'hostgroup' => 'hgo.name1 COLLATE latin1_general_ci',
|
||||
),
|
||||
);
|
||||
|
||||
protected function getDefaultColumns()
|
||||
{
|
||||
return $this->columnMap['eventhistory'];
|
||||
}
|
||||
protected $uglySlowConservativeCount = true;
|
||||
protected $maxCount = 1000;
|
||||
|
||||
protected function joinBaseTables()
|
||||
{
|
||||
$start = date('Y-m-d H:i:s', time() - 3600 * 24 * 30);
|
||||
// $start = date('Y-m-d H:i:s', time() - 3600 * 24 * 1);
|
||||
$start = date('Y-m-d H:i:s', time() - 3600 * 24 * 2);
|
||||
$end = date('Y-m-d H:i:s');
|
||||
$start = null;
|
||||
$end = null;
|
||||
|
||||
$history = $this->db->select()->from(
|
||||
$this->prefix . 'statehistory',
|
||||
array(
|
||||
'state_time' => 'state_time',
|
||||
'object_id' => 'object_id',
|
||||
'type' => "(CASE WHEN state_type = 1 THEN 'hard_state' ELSE 'soft_state' END)",
|
||||
'state' => 'state',
|
||||
'state_type' => 'state_type',
|
||||
'output' => 'output',
|
||||
'attempt' => 'current_check_attempt',
|
||||
'max_attempts' => 'max_check_attempts',
|
||||
)
|
||||
// TODO: $this->dbTime(...)
|
||||
//$start = null;
|
||||
//$end = null;
|
||||
$columns = array(
|
||||
'raw_timestamp',
|
||||
'timestamp',
|
||||
'object_id',
|
||||
'type',
|
||||
'output',
|
||||
'state',
|
||||
'state_type',
|
||||
'attempt',
|
||||
'max_attempts',
|
||||
);
|
||||
if ($start !== null) {
|
||||
$history->where('state_time >= ?', $start);
|
||||
}
|
||||
// ->where('state_type = 1') ??
|
||||
if ($end !== null) {
|
||||
$history->where('state_time <= ?', $end);
|
||||
}
|
||||
|
||||
$dt_start = $this->db->select()->from(
|
||||
$this->prefix . 'downtimehistory',
|
||||
array(
|
||||
'state_time' => 'actual_start_time',
|
||||
'object_id' => 'object_id',
|
||||
'type' => "('dt_start')",
|
||||
'state' => '(NULL)',
|
||||
'state_type' => '(NULL)',
|
||||
// 'output' => "CONCAT('[', author_name, '] ', comment_data)",
|
||||
'output' => "('[' || author_name || '] ' || comment_data)",
|
||||
'attempt' => '(NULL)',
|
||||
'max_attempts' => '(NULL)',
|
||||
)
|
||||
);
|
||||
if ($start !== null) {
|
||||
$dt_start->where('actual_start_time >= ?', $start);
|
||||
}
|
||||
if ($end !== null) {
|
||||
$dt_start->where('actual_start_time <= ?', $end);
|
||||
}
|
||||
|
||||
// TODO: check was_cancelled
|
||||
$dt_end = $this->db->select()->from(
|
||||
$this->prefix . 'downtimehistory',
|
||||
array(
|
||||
'state_time' => 'actual_end_time',
|
||||
'object_id' => 'object_id',
|
||||
'type' => "('dt_end')",
|
||||
'state' => '(NULL)',
|
||||
'state_type' => '(NULL)',
|
||||
// 'output' => "CONCAT('[', author_name, '] ', comment_data)",
|
||||
'output' => "('[' || author_name || '] ' || comment_data)",
|
||||
'attempt' => '(NULL)',
|
||||
'max_attempts' => '(NULL)',
|
||||
)
|
||||
);
|
||||
if ($start !== null) {
|
||||
$dt_end->where('actual_end_time >= ?', $start);
|
||||
}
|
||||
if ($end !== null) {
|
||||
$dt_end->where('actual_end_time <= ?', $end);
|
||||
}
|
||||
|
||||
$comments = $this->db->select()->from(
|
||||
$this->prefix . 'commenthistory',
|
||||
array(
|
||||
'state_time' => 'comment_time',
|
||||
'object_id' => 'object_id',
|
||||
'type' => "(CASE entry_type WHEN 1 THEN 'comment' WHEN 2 THEN 'dt_comment' WHEN 3 THEN 'flapping' WHEN 4 THEN 'ack' END)",
|
||||
'state' => '(NULL)',
|
||||
'state_type' => '(NULL)',
|
||||
// 'output' => "CONCAT('[', author_name, '] ', comment_data)",
|
||||
'output' => "('[' || author_name || '] ' || comment_data)",
|
||||
'attempt' => '(NULL)',
|
||||
'max_attempts' => '(NULL)',
|
||||
)
|
||||
);
|
||||
|
||||
if ($start !== null) {
|
||||
$comments->where('comment_time >= ?', $start);
|
||||
}
|
||||
if ($end !== null) {
|
||||
$comments->where('comment_time <= ?', $end);
|
||||
}
|
||||
|
||||
// This is one of the db-specific workarounds that could be abstracted
|
||||
// in a better way:
|
||||
switch ($this->ds->getConnection()->getDbType()) {
|
||||
case 'mysql':
|
||||
$concat_contacts = "GROUP_CONCAT(c.alias ORDER BY c.alias SEPARATOR ', ')";
|
||||
break;
|
||||
case 'pgsql':
|
||||
// TODO: Find a way to "ORDER" these:
|
||||
$concat_contacts = "ARRAY_TO_STRING(ARRAY_AGG(c.alias), ', ')";
|
||||
break;
|
||||
case 'oracle':
|
||||
// TODO: This is only valid for Oracle >= 11g Release 2.
|
||||
$concat_contacts = "LISTAGG(c.alias, ', ') WITHIN GROUP (ORDER BY c.alias)";
|
||||
// Alternatives:
|
||||
//
|
||||
// RTRIM(XMLAGG(XMLELEMENT(e, column_name, ',').EXTRACT('//text()')),
|
||||
//
|
||||
// not supported and not documented but works since 10.1,
|
||||
// however it is NOT always present;
|
||||
// WM_CONCAT(c.alias)
|
||||
break;
|
||||
default:
|
||||
die('Not yet'); // TODO: Proper Exception
|
||||
}
|
||||
|
||||
$cndetails = $this->db->select()->from(
|
||||
array('cn' => $this->prefix . 'contactnotifications'),
|
||||
array(
|
||||
'notification_id' => 'notification_id',
|
||||
'cnt' => 'COUNT(*)',
|
||||
'contacts' => $concat_contacts
|
||||
)
|
||||
)->join(
|
||||
array('c' => $this->prefix . 'contacts'),
|
||||
'cn.contact_object_id = c.contact_object_id',
|
||||
array()
|
||||
)->group('notification_id');
|
||||
|
||||
$notifications = $this->db->select()->from(
|
||||
array('n' => $this->prefix . 'notifications'),
|
||||
array(
|
||||
'state_time' => 'start_time',
|
||||
'object_id' => 'object_id',
|
||||
'type' => "('notify')",
|
||||
'state' => 'state',
|
||||
'state_type' => '(NULL)',
|
||||
// 'output' => "CONCAT('[', cndetails.contacts, '] ', n.output)",
|
||||
'output' => "('[' || cndetails.contacts || '] ' || n.output)",
|
||||
'attempt' => '(NULL)',
|
||||
'max_attempts' => '(NULL)',
|
||||
)
|
||||
)->join(
|
||||
array('cndetails' => $cndetails),
|
||||
'cndetails.notification_id = n.notification_id',
|
||||
array()
|
||||
);
|
||||
|
||||
if ($start !== null) {
|
||||
$notifications->where('start_time >= ?', $start);
|
||||
}
|
||||
if ($end !== null) {
|
||||
$notifications->where('start_time <= ?', $end);
|
||||
}
|
||||
|
||||
$this->subQueries = array(
|
||||
$history,
|
||||
$dt_start,
|
||||
$dt_end,
|
||||
$comments,
|
||||
$notifications
|
||||
$this->createSubQuery('Statehistory', $columns),
|
||||
$this->createSubQuery('Downtimestarthistory', $columns),
|
||||
$this->createSubQuery('Downtimeendhistory', $columns),
|
||||
$this->createSubQuery('Commenthistory', $columns),
|
||||
$this->createSubQuery('Notificationhistory', $columns)
|
||||
);
|
||||
$sub = $this->db->select()->union($this->subQueries, \Zend_Db_Select::SQL_UNION_ALL);
|
||||
|
||||
if ($start) {
|
||||
foreach ($this->subQueries as $query) {
|
||||
$query->where('raw_timestamp', '>' . $start);
|
||||
}
|
||||
}
|
||||
if ($end) {
|
||||
foreach ($this->subQueries as $query) {
|
||||
$query->where('raw_timestamp', '<' . $start);
|
||||
}
|
||||
}
|
||||
$sub = $this->db->select()->union($this->subQueries, Zend_Db_Select::SQL_UNION_ALL);
|
||||
$this->baseQuery = $this->db->select()->from(
|
||||
array('eho' => $this->prefix . 'objects'),
|
||||
array()
|
||||
|
@ -213,58 +92,24 @@ class EventHistoryQuery extends AbstractQuery
|
|||
$this->joinedVirtualTables = array('eventhistory' => true);
|
||||
}
|
||||
|
||||
// TODO: This duplicates code from AbstractQuery
|
||||
protected function applyAllFilters()
|
||||
protected function joinHostgroups()
|
||||
{
|
||||
$filters = array();
|
||||
$this->baseQuery->join(
|
||||
array('hgm' => $this->prefix . 'hostgroup_members'),
|
||||
'hgm.host_object_id = eho.object_id',
|
||||
array()
|
||||
)->join(
|
||||
array('hg' => $this->prefix . 'hostgroups'),
|
||||
"hgm.hostgroup_id = hg.$this->hostgroup_id",
|
||||
array()
|
||||
)->join(
|
||||
array('hgo' => $this->prefix . 'objects'),
|
||||
'hgo.' . $this->object_id. ' = hg.hostgroup_object_id'
|
||||
. ' AND hgo.is_active = 1',
|
||||
array()
|
||||
);
|
||||
|
||||
$host = null;
|
||||
$service = null;
|
||||
|
||||
foreach ($this->filters as $f) {
|
||||
$alias = $f[0];
|
||||
$value = $f[1];
|
||||
$this->requireColumn($alias);
|
||||
|
||||
if ($this->hasAliasName($alias)) {
|
||||
$col = $this->aliasToColumnName($alias);
|
||||
} else {
|
||||
throw new ProgrammingError(
|
||||
'If you finished here, code has been messed up'
|
||||
);
|
||||
}
|
||||
|
||||
if (in_array($alias, array('host', 'host_name'))) {
|
||||
$host = $value;
|
||||
continue;
|
||||
}
|
||||
if (in_array($alias, array('service', 'service_description'))) {
|
||||
$service = $value;
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->baseQuery->where($this->prepareFilterStringForColumn($col, $value));
|
||||
}
|
||||
|
||||
$objectQuery = $this->db->select()->from(
|
||||
$this->prefix . 'objects',
|
||||
$this->object_id
|
||||
)->where('is_active = 1');
|
||||
|
||||
if ($service === '*') {
|
||||
$objectQuery->where('name1 = ?', $host)
|
||||
->where('objecttype_id IN (1, 2)');
|
||||
} elseif ($service) {
|
||||
$objectQuery->where('name1 = ?', $host)
|
||||
->where('name2 = ?', $service)
|
||||
->where('objecttype_id = 2');
|
||||
} else {
|
||||
$objectQuery->where('name1 = ?', $host)
|
||||
->where('objecttype_id = 1');
|
||||
}
|
||||
$objectId = $this->db->fetchCol($objectQuery);
|
||||
foreach ($this->subQueries as $query) {
|
||||
$query->where('object_id IN (?)', $objectId);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ class HostgroupQuery extends AbstractQuery
|
|||
{
|
||||
protected $columnMap = array(
|
||||
'hostgroups' => array(
|
||||
'hostgroups' => 'hgo.name1 COLLATE latin1_general_ci',
|
||||
'hostgroup_name' => 'hgo.name1 COLLATE latin1_general_ci',
|
||||
'hostgroup_alias' => 'hg.alias',
|
||||
'id' => 'hg.hostgroup_id',
|
||||
|
|
|
@ -17,6 +17,9 @@ class HoststatusQuery extends AbstractQuery
|
|||
'host_icon_image' => 'h.icon_image',
|
||||
),
|
||||
'hoststatus' => array(
|
||||
'problems' => 'CASE WHEN hs.current_state = 0 THEN 0 ELSE 1 END',
|
||||
'handled' => 'CASE WHEN (hs.problem_has_been_acknowledged + hs.scheduled_downtime_depth) > 0 THEN 1 ELSE 0 END',
|
||||
'unhandled' => 'CASE WHEN (hs.problem_has_been_acknowledged + hs.scheduled_downtime_depth) = 0 THEN 1 ELSE 0 END',
|
||||
'host_state' => 'CASE WHEN hs.has_been_checked = 0 OR hs.has_been_checked IS NULL THEN 99 ELSE hs.current_state END',
|
||||
'host_output' => 'hs.output',
|
||||
'host_long_output' => 'hs.long_output',
|
||||
|
@ -72,10 +75,42 @@ class HoststatusQuery extends AbstractQuery
|
|||
END',
|
||||
),
|
||||
'hostgroups' => array(
|
||||
'hostgroups' => 'hgo.name1',
|
||||
'hostgroup' => 'hgo.name1 COLLATE latin1_general_ci',
|
||||
),
|
||||
'contactgroups' => array(
|
||||
'contactgroup' => 'contactgroup',
|
||||
),
|
||||
'contacts' => array(
|
||||
'contact' => 'hco.name1 COLLATE latin1_general_ci',
|
||||
),
|
||||
'services' => array(
|
||||
'services_cnt' => 'SUM(1)',
|
||||
'services_ok' => 'SUM(CASE WHEN ss.current_state = 0 THEN 1 ELSE 0 END)',
|
||||
'services_warning' => 'SUM(CASE WHEN ss.current_state = 1 THEN 1 ELSE 0 END)',
|
||||
'services_critical' => 'SUM(CASE WHEN ss.current_state = 2 THEN 1 ELSE 0 END)',
|
||||
'services_unknown' => 'SUM(CASE WHEN ss.current_state = 3 THEN 1 ELSE 0 END)',
|
||||
'services_pending' => 'SUM(CASE WHEN ss.has_been_checked = 0 OR ss.has_been_checked IS NULL THEN 1 ELSE 0 END)',
|
||||
'services_problem' => 'SUM(CASE WHEN ss.current_state > 0 THEN 1 ELSE 0 END)',
|
||||
'services_problem_handled' => 'SUM(CASE WHEN ss.current_state > 0 AND (ss.problem_has_been_acknowledged = 1 OR ss.scheduled_downtime_depth > 0) THEN 1 ELSE 0 END)',
|
||||
'services_problem_unhandled' => 'SUM(CASE WHEN ss.current_state > 0 AND (ss.problem_has_been_acknowledged = 0 AND ss.scheduled_downtime_depth = 0) THEN 1 ELSE 0 END)',
|
||||
'services_warning_handled' => 'SUM(CASE WHEN ss.current_state = 1 AND (ss.problem_has_been_acknowledged = 1 OR ss.scheduled_downtime_depth > 0) THEN 1 ELSE 0 END)',
|
||||
'services_critical_handled' => 'SUM(CASE WHEN ss.current_state = 2 AND (ss.problem_has_been_acknowledged = 1 OR ss.scheduled_downtime_depth > 0) THEN 1 ELSE 0 END)',
|
||||
'services_unknown_handled' => 'SUM(CASE WHEN ss.current_state = 3 AND (ss.problem_has_been_acknowledged = 1 OR ss.scheduled_downtime_depth > 0) THEN 1 ELSE 0 END)',
|
||||
'services_warning_unhandled' => 'SUM(CASE WHEN ss.current_state = 1 AND (ss.problem_has_been_acknowledged = 0 AND ss.scheduled_downtime_depth = 0) THEN 1 ELSE 0 END)',
|
||||
'services_critical_unhandled' => 'SUM(CASE WHEN ss.current_state = 2 AND (ss.problem_has_been_acknowledged = 0 AND ss.scheduled_downtime_depth = 0) THEN 1 ELSE 0 END)',
|
||||
'services_unknown_unhandled' => 'SUM(CASE WHEN ss.current_state = 3 AND (ss.problem_has_been_acknowledged = 0 AND ss.scheduled_downtime_depth = 0) THEN 1 ELSE 0 END)',
|
||||
),
|
||||
);
|
||||
|
||||
protected $aggregateColumnIdx = array(
|
||||
'services_cnt' => true,
|
||||
'services_problem' => true,
|
||||
'services_problem_handled' => true,
|
||||
'services_problem_unhandled' => true,
|
||||
);
|
||||
|
||||
protected $hcgSub;
|
||||
|
||||
protected function getDefaultColumns()
|
||||
{
|
||||
return $this->columnMap['hosts']
|
||||
|
@ -128,6 +163,14 @@ class HoststatusQuery extends AbstractQuery
|
|||
"so.$this->object_id = ss.service_object_id",
|
||||
array()
|
||||
);
|
||||
foreach ($this->columns as $col) {
|
||||
$real = $this->aliasToColumnName($col);
|
||||
if (substr($real, 0, 4) === 'SUM(') {
|
||||
continue;
|
||||
}
|
||||
$this->baseQuery->group($real);
|
||||
}
|
||||
$this->uglySlowConservativeCount = true;
|
||||
}
|
||||
|
||||
protected function joinHostgroups()
|
||||
|
@ -139,6 +182,121 @@ class HoststatusQuery extends AbstractQuery
|
|||
}
|
||||
}
|
||||
|
||||
protected function joinContacts()
|
||||
{
|
||||
$this->hcgcSub = $this->db->select()->distinct()->from(
|
||||
array('hcgc' => $this->prefix . 'host_contactgroups'),
|
||||
array('host_name' => 'ho.name1')
|
||||
)->join(
|
||||
array('cgo' => $this->prefix . 'objects'),
|
||||
'hcg.contactgroup_object_id = cgo.' . $this->object_id
|
||||
. ' AND cgo.is_active = 1',
|
||||
array()
|
||||
)->join(
|
||||
array('h' => $this->prefix . 'hosts'),
|
||||
'hcg.host_id = h.host_id',
|
||||
array()
|
||||
)->join(
|
||||
array('ho' => $this->prefix . 'objects'),
|
||||
'h.host_object_id = ho.' . $this->object_id . ' AND ho.is_active = 1',
|
||||
array()
|
||||
);
|
||||
$this->baseQuery->join(
|
||||
array('hcg' => $this->hcgSub),
|
||||
'hcg.host_name = ho.name1',
|
||||
array()
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
protected function joinContacts()
|
||||
{
|
||||
|
||||
|
||||
$this->baseQuery->join(
|
||||
array('hc' => $this->prefix . 'host_contacts'),
|
||||
'hc.host_id = h.host_id',
|
||||
array()
|
||||
)->join(
|
||||
array('hco' => $this->prefix . 'objects'),
|
||||
'hco.' . $this->object_id. ' = hc.contact_object_id'
|
||||
. ' AND hco.is_active = 1',
|
||||
array()
|
||||
);
|
||||
|
||||
$this->baseQuery->join(
|
||||
array('hcg' => $this->prefix . 'host_contactgroups'),
|
||||
'hcg.host_id = h.host_id',
|
||||
array()
|
||||
)->join(
|
||||
array('hcgo' => $this->prefix . 'objects'),
|
||||
'hcgo.' . $this->object_id. ' = hcg.contactgroup_object_id'
|
||||
. ' AND hcgo.is_active = 1',
|
||||
array()
|
||||
);
|
||||
$this->baseQuery->join(
|
||||
array('cgm' => $this->prefix . 'contactgroup_members'),
|
||||
'cgm.contactgroup_id = cg.contactgroup_id',
|
||||
array()
|
||||
)->join(
|
||||
array('co' => $this->prefix . 'objects'),
|
||||
'cgm.contact_object_id = co.object_id AND co.is_active = 1',
|
||||
array()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
return $this;
|
||||
}
|
||||
*/
|
||||
protected function filterContactgroup($value)
|
||||
{
|
||||
$this->hcgSub->where(
|
||||
$this->prepareFilterStringForColumn(
|
||||
'cgo.name1 COLLATE latin1_general_ci',
|
||||
$value
|
||||
)
|
||||
);
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
protected function createContactgroupFilterSubselect()
|
||||
{
|
||||
die((string) $this->db->select()->distinct()->from(
|
||||
array('hcg' => $this->prefix . 'host_contactgroups'),
|
||||
array('object_id' => 'ho.object_id')
|
||||
)->join(
|
||||
array('cgo' => $this->prefix . 'objects'),
|
||||
'hcg.contactgroup_object_id = cgo.' . $this->object_id
|
||||
. ' AND cgo.is_active = 1',
|
||||
array()
|
||||
)->join(
|
||||
array('h' => $this->prefix . 'hosts'),
|
||||
'hcg.host_id = h.host_id',
|
||||
array()
|
||||
)->join(
|
||||
array('ho' => $this->prefix . 'objects'),
|
||||
'h.host_object_id = ho.' . $this->object_id . ' AND ho.is_active = 1',
|
||||
array()
|
||||
));
|
||||
}
|
||||
|
||||
protected function joinContactgroups()
|
||||
{
|
||||
$this->hcgSub = $this->createContactgroupFilterSubselect();
|
||||
$this->baseQuery->join(
|
||||
array('hcg' => $this->hcgSub),
|
||||
'hcg.object_id = ho.object_id',
|
||||
array()
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function joinHostHostgroups()
|
||||
{
|
||||
$this->baseQuery->join(
|
||||
|
@ -149,6 +307,11 @@ class HoststatusQuery extends AbstractQuery
|
|||
array('hg' => $this->prefix . 'hostgroups'),
|
||||
"hgm.hostgroup_id = hg.$this->hostgroup_id",
|
||||
array()
|
||||
)->join(
|
||||
array('hgo' => $this->prefix . 'objects'),
|
||||
'hgo.' . $this->object_id. ' = hg.hostgroup_object_id'
|
||||
. ' AND hgo.is_active = 1',
|
||||
array()
|
||||
);
|
||||
|
||||
return $this;
|
||||
|
@ -176,6 +339,7 @@ class HoststatusQuery extends AbstractQuery
|
|||
|
||||
protected function joinServicegroups()
|
||||
{
|
||||
// TODO: Only hosts with services having such servicegroups
|
||||
$this->requireVirtualTable('services');
|
||||
$this->baseQuery->join(
|
||||
array('sgm' => $this->prefix . 'servicegroup_members'),
|
||||
|
|
|
@ -119,7 +119,7 @@ class NotificationQuery extends AbstractQuery
|
|||
array(
|
||||
'cmd_m' => $this->prefix . 'contactnotificationmethods'
|
||||
),
|
||||
'cmd_c.notification_id = cmd_m.contactnotification_id',
|
||||
'cmd_c.contactnotification_id = cmd_m.contactnotification_id',
|
||||
array()
|
||||
);
|
||||
$this->baseQuery->join(
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Monitoring\Backend\Ido\Query;
|
||||
|
||||
class NotificationhistoryQuery extends AbstractQuery
|
||||
{
|
||||
protected $columnMap = array(
|
||||
'history' => array(
|
||||
'timestamp' => 'UNIX_TIMESTAMP(n.start_time)',
|
||||
'raw_timestamp' => 'n.start_time',
|
||||
'state_time' => 'n.start_time',
|
||||
'object_id' => 'object_id',
|
||||
'type' => "('notify')",
|
||||
'state' => 'state',
|
||||
'state_type' => '(NULL)',
|
||||
'output' => null,
|
||||
'attempt' => '(NULL)',
|
||||
'max_attempts' => '(NULL)',
|
||||
)
|
||||
);
|
||||
|
||||
protected function joinBaseTables()
|
||||
{
|
||||
//"('[' || cndetails.contacts || '] ' || n.output)"
|
||||
// This is one of the db-specific workarounds that could be abstracted
|
||||
// in a better way:
|
||||
switch ($this->ds->getConnection()->getDbType()) {
|
||||
case 'mysql':
|
||||
$concat_contacts = "GROUP_CONCAT(c.alias ORDER BY c.alias SEPARATOR ', ')";
|
||||
break;
|
||||
case 'pgsql':
|
||||
// TODO: Find a way to "ORDER" these:
|
||||
$concat_contacts = "ARRAY_TO_STRING(ARRAY_AGG(c.alias), ', ')";
|
||||
break;
|
||||
case 'oracle':
|
||||
// TODO: This is only valid for Oracle >= 11g Release 2.
|
||||
$concat_contacts = "LISTAGG(c.alias, ', ') WITHIN GROUP (ORDER BY c.alias)";
|
||||
// Alternatives:
|
||||
//
|
||||
// RTRIM(XMLAGG(XMLELEMENT(e, column_name, ',').EXTRACT('//text()')),
|
||||
//
|
||||
// not supported and not documented but works since 10.1,
|
||||
// however it is NOT always present;
|
||||
// WM_CONCAT(c.alias)
|
||||
break;
|
||||
default:
|
||||
die('Not yet'); // TODO: Proper Exception
|
||||
}
|
||||
$this->columnMap['history']['output'] = "('[' || $concat_contacts || '] ' || n.output)";
|
||||
/*
|
||||
$cndetails = $this->db->select()->from(
|
||||
array('cn' => $this->prefix . 'contactnotifications'),
|
||||
array(
|
||||
'notification_id' => 'notification_id',
|
||||
'cnt' => 'COUNT(*)',
|
||||
'contacts' => $concat_contacts
|
||||
)
|
||||
)->join(
|
||||
array('c' => $this->prefix . 'contacts'),
|
||||
'cn.contact_object_id = c.contact_object_id',
|
||||
array()
|
||||
)->group('notification_id');
|
||||
*/
|
||||
$this->baseQuery = $this->db->select()->from(
|
||||
array('n' => $this->prefix . 'notifications'),
|
||||
array()
|
||||
)->join(
|
||||
array('cn' => $this->prefix . 'contactnotifications'),
|
||||
'cn.notification_id = n.notification_id',
|
||||
array()
|
||||
)->joinLeft(
|
||||
array('c' => $this->prefix . 'contacts'),
|
||||
'cn.contact_object_id = c.contact_object_id',
|
||||
array()
|
||||
)->group('cn.notification_id')
|
||||
|
||||
/*->join(
|
||||
array('cndetails' => $cndetails),
|
||||
'cndetails.notification_id = n.notification_id',
|
||||
array()
|
||||
)*/
|
||||
;
|
||||
|
||||
$this->joinedVirtualTables = array('history' => true);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Monitoring\Backend\Ido\Query;
|
||||
|
||||
class StatehistoryQuery extends AbstractQuery
|
||||
{
|
||||
protected $columnMap = array(
|
||||
'statehistory' => array(
|
||||
'raw_timestamp' => 'state_time',
|
||||
'timestamp' => 'UNIX_TIMESTAMP(state_time)',
|
||||
'state_time' => 'state_time',
|
||||
'object_id' => 'object_id',
|
||||
'type' => "(CASE WHEN state_type = 1 THEN 'hard_state' ELSE 'soft_state' END)",
|
||||
'state' => 'state',
|
||||
'state_type' => 'state_type',
|
||||
'output' => 'output',
|
||||
'attempt' => 'current_check_attempt',
|
||||
'max_attempts' => 'max_check_attempts',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
@ -22,33 +22,36 @@ class StatusQuery extends AbstractQuery
|
|||
'host_notes_url' => 'h.notes_url'
|
||||
),
|
||||
'hoststatus' => array(
|
||||
'host_state' => 'CASE WHEN hs.has_been_checked = 0 OR hs.has_been_checked IS NULL THEN 99 ELSE hs.current_state END',
|
||||
'host_output' => 'hs.output',
|
||||
'host_long_output' => 'hs.long_output',
|
||||
'host_perfdata' => 'hs.perfdata',
|
||||
'host_acknowledged' => 'hs.problem_has_been_acknowledged',
|
||||
'host_in_downtime' => 'CASE WHEN (hs.scheduled_downtime_depth = 0) THEN 0 ELSE 1 END',
|
||||
'host_handled' => 'CASE WHEN (hs.problem_has_been_acknowledged + hs.scheduled_downtime_depth) > 0 THEN 1 ELSE 0 END',
|
||||
'host_does_active_checks' => 'hs.active_checks_enabled',
|
||||
'host_state' => 'CASE WHEN hs.has_been_checked = 0 OR hs.has_been_checked IS NULL THEN 99 ELSE hs.current_state END',
|
||||
'host_output' => 'hs.output',
|
||||
'host_long_output' => 'hs.long_output',
|
||||
'host_perfdata' => 'hs.perfdata',
|
||||
'host_acknowledged' => 'hs.problem_has_been_acknowledged',
|
||||
'host_in_downtime' => 'CASE WHEN (hs.scheduled_downtime_depth = 0) THEN 0 ELSE 1 END',
|
||||
'host_handled' => 'CASE WHEN (hs.problem_has_been_acknowledged + hs.scheduled_downtime_depth) > 0 THEN 1 ELSE 0 END',
|
||||
'host_does_active_checks' => 'hs.active_checks_enabled',
|
||||
'host_accepts_passive_checks' => 'hs.passive_checks_enabled',
|
||||
'host_last_state_change' => 'UNIX_TIMESTAMP(hs.last_state_change)',
|
||||
'host_check_command' => 'hs.check_command',
|
||||
'host_current_check_attempt' => 'hs.current_check_attempt',
|
||||
'host_max_check_attempts' => 'hs.max_check_attempts',
|
||||
'host_attempt' => 'hs.current_check_attempt || \'/\' || hs.max_check_attempts',
|
||||
'host_last_check' => 'hs.last_check',
|
||||
'host_next_check' => 'hs.next_check',
|
||||
'host_last_state_change' => 'UNIX_TIMESTAMP(hs.last_state_change)',
|
||||
'host_last_hard_state' => 'hs.last_hard_state',
|
||||
'host_last_hard_state_change' => 'UNIX_TIMESTAMP(hs.last_hard_state_change)',
|
||||
'host_check_command' => 'hs.check_command',
|
||||
'host_last_check' => 'UNIX_TIMESTAMP(hs.last_check)',
|
||||
'host_next_check' => 'CASE hs.should_be_scheduled WHEN 1 THEN UNIX_TIMESTAMP(hs.next_check) ELSE NULL END',
|
||||
'host_check_execution_time' => 'hs.execution_time',
|
||||
'host_check_latency' => 'hs.latency',
|
||||
'host_problem' => 'CASE WHEN hs.current_state = 0 THEN 0 ELSE 1 END',
|
||||
'host_notifications_enabled' => 'hs.notifications_enabled',
|
||||
'host_last_time_up' => 'UNIX_TIMESTAMP(hs.last_time_up)',
|
||||
'host_last_time_down' => 'UNIX_TIMESTAMP(hs.last_time_down)',
|
||||
'host_last_time_unreachable' => 'UNIX_TIMESTAMP(hs.last_time_unreachable)',
|
||||
'host_current_check_attempt' => 'hs.current_check_attempt',
|
||||
'host_max_check_attempts' => 'hs.max_check_attempts',
|
||||
'host_attempt' => 'hs.current_check_attempt || \'/\' || hs.max_check_attempts',
|
||||
'host_check_type' => 'hs.check_type',
|
||||
'host_last_hard_state_change' => 'hs.last_hard_state_change',
|
||||
'host_last_hard_state' => 'hs.last_hard_state',
|
||||
'host_last_time_up' => 'hs.last_time_up',
|
||||
'host_last_time_down' => 'hs.last_time_down',
|
||||
'host_last_time_unreachable' => 'hs.last_time_unreachable',
|
||||
'host_state_type' => 'hs.state_type',
|
||||
'host_last_notification' => 'hs.last_notification',
|
||||
'host_next_notification' => 'hs.next_notification',
|
||||
'host_no_more_notifications' => 'hs.no_more_notifications',
|
||||
'host_notifications_enabled' => 'hs.notifications_enabled',
|
||||
'host_problem_has_been_acknowledged' => 'hs.problem_has_been_acknowledged',
|
||||
'host_acknowledgement_type' => 'hs.acknowledgement_type',
|
||||
'host_current_notification_number' => 'hs.current_notification_number',
|
||||
|
@ -58,8 +61,6 @@ class StatusQuery extends AbstractQuery
|
|||
'host_flap_detection_enabled' => 'hs.flap_detection_enabled',
|
||||
'host_is_flapping' => 'hs.is_flapping',
|
||||
'host_percent_state_change' => 'hs.percent_state_change',
|
||||
'host_check_latency' => 'hs.latency',
|
||||
'host_check_execution_time' => 'hs.execution_time',
|
||||
'host_scheduled_downtime_depth' => 'hs.scheduled_downtime_depth',
|
||||
'host_failure_prediction_enabled' => 'hs.failure_prediction_enabled',
|
||||
'host_process_performance_data' => 'hs.process_performance_data',
|
||||
|
@ -71,7 +72,6 @@ class StatusQuery extends AbstractQuery
|
|||
'host_retry_check_interval' => 'hs.retry_check_interval',
|
||||
'host_check_timeperiod_object_id' => 'hs.check_timeperiod_object_id',
|
||||
'host_status_update_time' => 'hs.status_update_time',
|
||||
'host_problem' => 'CASE WHEN hs.current_state = 0 THEN 0 ELSE 1 END',
|
||||
'host_severity' => 'CASE WHEN hs.current_state = 0
|
||||
THEN
|
||||
CASE WHEN hs.has_been_checked = 0 OR hs.has_been_checked IS NULL
|
||||
|
@ -121,21 +121,23 @@ class StatusQuery extends AbstractQuery
|
|||
|
||||
),
|
||||
'servicestatus' => array(
|
||||
'service_state' => 'CASE WHEN ss.has_been_checked = 0 OR ss.has_been_checked IS NULL THEN 99 ELSE ss.current_state END',
|
||||
'service_output' => 'ss.output',
|
||||
'service_long_output' => 'ss.long_output',
|
||||
'service_perfdata' => 'ss.perfdata',
|
||||
'service_acknowledged' => 'ss.problem_has_been_acknowledged',
|
||||
'service_in_downtime' => 'CASE WHEN (ss.scheduled_downtime_depth = 0) THEN 0 ELSE 1 END',
|
||||
'service_handled' => 'CASE WHEN (ss.problem_has_been_acknowledged + ss.scheduled_downtime_depth) > 0 THEN 1 ELSE 0 END',
|
||||
'service_does_active_checks' => 'ss.active_checks_enabled',
|
||||
'service_state' => 'CASE WHEN ss.has_been_checked = 0 OR ss.has_been_checked IS NULL THEN 99 ELSE ss.current_state END',
|
||||
'service_hard_state' => 'CASE WHEN ss.has_been_checked = 0 OR ss.has_been_checked IS NULL THEN 99 ELSE CASE WHEN ss.state_type = 1 THEN ss.current_state ELSE ss.last_hard_state END END',
|
||||
'service_state_type' => 'ss.state_type',
|
||||
'service_output' => 'ss.output',
|
||||
'service_long_output' => 'ss.long_output',
|
||||
'service_perfdata' => 'ss.perfdata',
|
||||
'service_acknowledged' => 'ss.problem_has_been_acknowledged',
|
||||
'service_in_downtime' => 'CASE WHEN (ss.scheduled_downtime_depth = 0) THEN 0 ELSE 1 END',
|
||||
'service_handled' => 'CASE WHEN (ss.problem_has_been_acknowledged + ss.scheduled_downtime_depth + COALESCE(hs.current_state, 0)) > 0 THEN 1 ELSE 0 END',
|
||||
'service_does_active_checks' => 'ss.active_checks_enabled',
|
||||
'service_accepts_passive_checks' => 'ss.passive_checks_enabled',
|
||||
'service_last_state_change' => 'UNIX_TIMESTAMP(ss.last_state_change)',
|
||||
'service_check_command' => 'ss.check_command',
|
||||
'service_last_time_ok' => 'ss.last_time_ok',
|
||||
'service_last_time_warning' => 'ss.last_time_warning',
|
||||
'service_last_time_critical' => 'ss.last_time_critical',
|
||||
'service_last_time_unknown' => 'ss.last_time_unknown',
|
||||
'service_last_state_change' => 'UNIX_TIMESTAMP(ss.last_state_change)',
|
||||
'service_check_command' => 'ss.check_command',
|
||||
'service_last_time_ok' => 'ss.last_time_ok',
|
||||
'service_last_time_warning' => 'ss.last_time_warning',
|
||||
'service_last_time_critical' => 'ss.last_time_critical',
|
||||
'service_last_time_unknown' => 'ss.last_time_unknown',
|
||||
'service_current_check_attempt' => 'ss.current_check_attempt',
|
||||
'service_max_check_attempts' => 'ss.max_check_attempts',
|
||||
'service_attempt' => 'ss.current_check_attempt || \'/\' || ss.max_check_attempts',
|
||||
|
@ -144,7 +146,6 @@ class StatusQuery extends AbstractQuery
|
|||
'service_check_type' => 'ss.check_type',
|
||||
'service_last_hard_state_change' => 'ss.last_hard_state_change',
|
||||
'service_last_hard_state' => 'ss.last_hard_state',
|
||||
'service_state_type' => 'ss.state_type',
|
||||
'service_last_notification' => 'ss.last_notification',
|
||||
'service_next_notification' => 'ss.next_notification',
|
||||
'service_no_more_notifications' => 'ss.no_more_notifications',
|
||||
|
@ -182,9 +183,10 @@ class StatusQuery extends AbstractQuery
|
|||
'service_last_comment' => 'slc.comment_id'
|
||||
),
|
||||
'status' => array(
|
||||
'service_problems' => 'CASE WHEN ss.current_state = 0 THEN 0 ELSE 1 END',
|
||||
'service_handled' => 'CASE WHEN ss.problem_has_been_acknowledged = 1 OR ss.scheduled_downtime_depth > 0 THEN 1 ELSE 0 END',
|
||||
'service_severity' => 'CASE WHEN ss.current_state = 0
|
||||
'service_problems' => 'CASE WHEN ss.current_state = 0 THEN 0 ELSE 1 END',
|
||||
'service_handled' => 'CASE WHEN ss.problem_has_been_acknowledged = 1 OR ss.scheduled_downtime_depth > 0 THEN 1 ELSE 0 END',
|
||||
'service_unhandled' => 'CASE WHEN ss.problem_has_been_acknowledged = 0 AND ss.scheduled_downtime_depth = 0 THEN 1 ELSE 0 END',
|
||||
'service_severity' => 'CASE WHEN ss.current_state = 0
|
||||
THEN
|
||||
CASE WHEN ss.has_been_checked = 0 OR ss.has_been_checked IS NULL
|
||||
THEN 16
|
||||
|
@ -219,21 +221,6 @@ class StatusQuery extends AbstractQuery
|
|||
),
|
||||
);
|
||||
|
||||
public function group($col)
|
||||
{
|
||||
$this->baseQuery->group($col);
|
||||
}
|
||||
|
||||
protected function getDefaultColumns()
|
||||
{
|
||||
return $this->columnMap['hosts'];
|
||||
/*
|
||||
+ $this->columnMap['services']
|
||||
+ $this->columnMap['hoststatus']
|
||||
+ $this->columnMap['servicestatus']
|
||||
;*/
|
||||
}
|
||||
|
||||
protected function joinBaseTables()
|
||||
{
|
||||
// TODO: Shall we always add hostobject?
|
||||
|
@ -248,9 +235,9 @@ class StatusQuery extends AbstractQuery
|
|||
array('h' => $this->prefix . 'hosts'),
|
||||
'hs.host_object_id = h.host_object_id',
|
||||
array()
|
||||
);
|
||||
);
|
||||
$this->joinedVirtualTables = array(
|
||||
'hosts' => true,
|
||||
'hosts' => true,
|
||||
'hoststatus' => true,
|
||||
);
|
||||
}
|
||||
|
@ -273,16 +260,15 @@ class StatusQuery extends AbstractQuery
|
|||
array()
|
||||
)->join(
|
||||
array('so' => $this->prefix . 'objects'),
|
||||
'so.'.$this->object_id.' = s.service_object_id AND so.is_active = 1',
|
||||
'so.' . $this->object_id . ' = s.service_object_id AND so.is_active = 1',
|
||||
array()
|
||||
)->joinLeft(
|
||||
array('ss' => $this->prefix . 'servicestatus'),
|
||||
'so.'.$this->object_id.' = ss.service_object_id',
|
||||
'so.' . $this->object_id . ' = ss.service_object_id',
|
||||
array()
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: Test this one, doesn't seem to work right now
|
||||
protected function joinHostgroups()
|
||||
{
|
||||
if ($this->hasJoinedVirtualTable('services')) {
|
||||
|
@ -300,7 +286,7 @@ class StatusQuery extends AbstractQuery
|
|||
array()
|
||||
)->join(
|
||||
array('hg' => $this->prefix . 'hostgroups'),
|
||||
'hgm.hostgroup_id = hg'.$this->hostgroup_id,
|
||||
'hgm.hostgroup_id = hg' . $this->hostgroup_id,
|
||||
array()
|
||||
);
|
||||
|
||||
|
@ -341,13 +327,15 @@ class StatusQuery extends AbstractQuery
|
|||
)->join(
|
||||
array('sgo' => $this->prefix . 'objects'),
|
||||
'sgo.' . $this->object_id. ' = sg.servicegroup_object_id'
|
||||
. ' AND sgo.is_active = 1',
|
||||
. ' AND sgo.is_active = 1',
|
||||
array()
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
// TODO: This will be obsolete once status is based on the new hoststatus, offering much more
|
||||
// columns in a more efficient way
|
||||
protected function joinServiceproblemsummary()
|
||||
{
|
||||
$this->baseQuery->joinleft(
|
||||
|
@ -363,6 +351,7 @@ class StatusQuery extends AbstractQuery
|
|||
);
|
||||
}
|
||||
|
||||
// TODO: Terribly slow. As I have no idea of how to fix this we should remove it.
|
||||
protected function joinLasthostcomment()
|
||||
{
|
||||
$this->baseQuery->joinleft(
|
||||
|
@ -375,6 +364,7 @@ class StatusQuery extends AbstractQuery
|
|||
);
|
||||
}
|
||||
|
||||
// TODO: Terribly slow. As I have no idea of how to fix this we should remove it.
|
||||
protected function joinLastservicecomment()
|
||||
{
|
||||
$this->baseQuery->joinleft(
|
||||
|
|
|
@ -6,7 +6,7 @@ use Icinga\Data\AbstractQuery;
|
|||
use Icinga\Data\Filter;
|
||||
|
||||
/**
|
||||
* MonitoringView provides consistent views to our Icinga Backends
|
||||
* AbstractView provides consistent views to our Icinga Backends
|
||||
*
|
||||
* TODO: * This could be renamed to AbstractView
|
||||
* * We might need more complex filters (let's do the simple ones first)
|
||||
|
@ -32,7 +32,7 @@ use Icinga\Data\Filter;
|
|||
* * you can (and should) use a defined set of columns when issueing a query
|
||||
* * you can use proper alias names to have an influence on column names
|
||||
* in the result set
|
||||
* * the MonitoringView behaves like any Query object and provides useful
|
||||
* * the AbstractView behaves like any Query object and provides useful
|
||||
* methods such as fetchAll, count, fetchPairs and so on
|
||||
*
|
||||
* If you want to fill a dropdown form element with all your hostgroups
|
||||
|
@ -48,11 +48,11 @@ use Icinga\Data\Filter;
|
|||
* $formElement->setMultiOptions($pairs);
|
||||
* </code>
|
||||
*
|
||||
* MonitoringView is a proxy to your Backend Query. While both are Query objects
|
||||
* AbstractView is a proxy to your Backend Query. While both are Query objects
|
||||
* providing partially the same interface, they are not directly related to
|
||||
* each other.
|
||||
*/
|
||||
class MonitoringView extends AbstractQuery
|
||||
class AbstractView extends AbstractQuery
|
||||
{
|
||||
/**
|
||||
* Stores the backend-specific Query Object
|
||||
|
@ -89,6 +89,16 @@ class MonitoringView extends AbstractQuery
|
|||
*/
|
||||
protected $sortDefaults = array();
|
||||
|
||||
/**
|
||||
* Filters that will be enforced (e.g. AND for SQL), will be used for auth
|
||||
* restrictions
|
||||
*
|
||||
* TODO: rename to enforcedFilters?
|
||||
*
|
||||
* @var Array
|
||||
*/
|
||||
protected $forcedFilters = array();
|
||||
|
||||
/**
|
||||
* Whether this view provides a specific column name
|
||||
*
|
||||
|
@ -100,6 +110,12 @@ class MonitoringView extends AbstractQuery
|
|||
return in_array($column, $this->availableColumns);
|
||||
}
|
||||
|
||||
// TODO: Not sure about this yet
|
||||
public function getDefaultColumns()
|
||||
{
|
||||
return $this->availableColumns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of all available column names
|
||||
*
|
||||
|
@ -139,7 +155,7 @@ class MonitoringView extends AbstractQuery
|
|||
return $this->order(
|
||||
// TODO: Use first sortDefaults entry if available, fall back to
|
||||
// column if not
|
||||
$request->getParam('sort', $this->availableColumns[0]),
|
||||
$request->getParam('sort', $this->getDefaultSortColumn()),
|
||||
$request->getParam('dir')
|
||||
);
|
||||
}
|
||||
|
@ -177,8 +193,9 @@ class MonitoringView extends AbstractQuery
|
|||
}
|
||||
|
||||
// TODO: applyAuthFilters(Auth $auth = null)
|
||||
// MonitoringView will enforce restrictions as provided by the Auth
|
||||
// backend
|
||||
// AbstractView will enforce restrictions as provided by the Auth
|
||||
// backend. Those filters work like normal ones and have to be stored
|
||||
// by applyAuthFilters to $this->forcedFilters
|
||||
|
||||
/**
|
||||
* Apply an array of filters. This might become obsolete or even improved
|
||||
|
@ -209,6 +226,26 @@ class MonitoringView extends AbstractQuery
|
|||
return new Filter($this->filters);
|
||||
}
|
||||
|
||||
public function hasSingleSortColumn()
|
||||
{
|
||||
return count($this->order_columns) === 1;
|
||||
}
|
||||
|
||||
public function getFirstSortColumn()
|
||||
{
|
||||
return $this->order_columns[0];
|
||||
}
|
||||
|
||||
protected function getDefaultSortColumn()
|
||||
{
|
||||
if (empty($this->sortDefaults)) {
|
||||
return $this->availableColumns[0];
|
||||
} else {
|
||||
reset($this->sortDefaults);
|
||||
return key($this->sortDefaults);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Default sort direction for given column, ASCending if not defined
|
||||
*
|
||||
|
@ -244,6 +281,9 @@ class MonitoringView extends AbstractQuery
|
|||
foreach ($this->filters as $f) {
|
||||
$query->where($f[0], $f[1]);
|
||||
}
|
||||
foreach ($this->forcedFilters as $col => $filter) {
|
||||
$query->where($col, $filter);
|
||||
}
|
||||
foreach ($this->order_columns as $col) {
|
||||
|
||||
if (isset($this->sortDefaults[$col[0]]['columns'])) {
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Monitoring\View;
|
||||
|
||||
class AllcontactsView extends AbstractView
|
||||
{
|
||||
protected $query;
|
||||
|
||||
protected $availableColumns = array(
|
||||
'host_name',
|
||||
'contact_name',
|
||||
'contact_alias',
|
||||
'contact_email',
|
||||
'contact_pager',
|
||||
'contact_notify_hosts',
|
||||
'contact_notify_services',
|
||||
'contact_has_host_notfications',
|
||||
'contact_has_service_notfications',
|
||||
'contact_can_submit_commands',
|
||||
'contact_notify_service_recovery',
|
||||
'contact_notify_service_warning',
|
||||
'contact_notify_service_critical',
|
||||
'contact_notify_service_unknown',
|
||||
'contact_notify_service_flapping',
|
||||
'contact_notify_service_downtime',
|
||||
'contact_notify_host_recovery',
|
||||
'contact_notify_host_down',
|
||||
'contact_notify_host_unreachable',
|
||||
'contact_notify_host_flapping',
|
||||
'contact_notify_host_downtime',
|
||||
'host_object_id',
|
||||
'host_name',
|
||||
'service_object_id',
|
||||
'service_host_name',
|
||||
'service_description',
|
||||
/* 'contact_alias',
|
||||
'contact_email',
|
||||
'contact_pager',
|
||||
'contact_notify_hosts',
|
||||
'contact_notify_services',
|
||||
*/
|
||||
);
|
||||
|
||||
/*
|
||||
protected $sortDefaults = array(
|
||||
'contact_alias' => array(
|
||||
'default_dir' => self::SORT_ASC
|
||||
)
|
||||
);*/
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace Icinga\Module\Monitoring\View;
|
||||
|
||||
class CommentView extends MonitoringView
|
||||
class CommentView extends AbstractView
|
||||
{
|
||||
protected $query;
|
||||
|
||||
|
|
|
@ -2,16 +2,36 @@
|
|||
|
||||
namespace Icinga\Module\Monitoring\View;
|
||||
|
||||
class ContactView extends MonitoringView
|
||||
class ContactView extends AbstractView
|
||||
{
|
||||
protected $query;
|
||||
|
||||
protected $availableColumns = array(
|
||||
'contact_name',
|
||||
'contact_alias',
|
||||
'contact_email',
|
||||
'contact_pager',
|
||||
'contact_notify_hosts',
|
||||
'contact_notify_services',
|
||||
'contact_has_host_notfications',
|
||||
'contact_has_service_notfications',
|
||||
'contact_can_submit_commands',
|
||||
'contact_notify_service_recovery',
|
||||
'contact_notify_service_warning',
|
||||
'contact_notify_service_critical',
|
||||
'contact_notify_service_unknown',
|
||||
'contact_notify_service_flapping',
|
||||
'contact_notify_service_downtime',
|
||||
'contact_notify_host_recovery',
|
||||
'contact_notify_host_down',
|
||||
'contact_notify_host_unreachable',
|
||||
'contact_notify_host_flapping',
|
||||
'contact_notify_host_downtime',
|
||||
'host_object_id',
|
||||
'host_name',
|
||||
'service_object_id',
|
||||
'service_host_name',
|
||||
'service_description',
|
||||
);
|
||||
|
||||
protected $specialFilters = array();
|
||||
|
|
|
@ -2,13 +2,37 @@
|
|||
|
||||
namespace Icinga\Module\Monitoring\View;
|
||||
|
||||
class ContactgroupView extends MonitoringView
|
||||
class ContactgroupView extends AbstractView
|
||||
{
|
||||
protected $query;
|
||||
|
||||
protected $availableColumns = array(
|
||||
'contactgroup_name',
|
||||
'contactgroup_alias',
|
||||
|
||||
'contact_name',
|
||||
'contact_alias',
|
||||
'contact_email',
|
||||
'contact_pager',
|
||||
'contact_notify_hosts',
|
||||
'contact_notify_services',
|
||||
'contact_has_host_notfications',
|
||||
'contact_has_service_notfications',
|
||||
'contact_can_submit_commands',
|
||||
'contact_notify_service_recovery',
|
||||
'contact_notify_service_warning',
|
||||
'contact_notify_service_critical',
|
||||
'contact_notify_service_unknown',
|
||||
'contact_notify_service_flapping',
|
||||
'contact_notify_service_downtime',
|
||||
'contact_notify_host_recovery',
|
||||
'contact_notify_host_down',
|
||||
'contact_notify_host_unreachable',
|
||||
'contact_notify_host_flapping',
|
||||
'contact_notify_host_downtime',
|
||||
|
||||
|
||||
'host_object_id',
|
||||
'host_name',
|
||||
'service_description'
|
||||
);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace Icinga\Module\Monitoring\View;
|
||||
|
||||
class CustomvarView extends MonitoringView
|
||||
class CustomvarView extends AbstractView
|
||||
{
|
||||
protected $query;
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace Icinga\Module\Monitoring\View;
|
|||
/**
|
||||
* Class DowntimeView
|
||||
*/
|
||||
class DowntimeView extends MonitoringView
|
||||
class DowntimeView extends AbstractView
|
||||
{
|
||||
/**
|
||||
* Query object
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace Icinga\Module\Monitoring\View;
|
||||
|
||||
class EventHistoryView extends MonitoringView
|
||||
class EventHistoryView extends AbstractView
|
||||
{
|
||||
protected $query;
|
||||
|
||||
|
@ -21,7 +21,9 @@ class EventHistoryView extends MonitoringView
|
|||
'type'
|
||||
);
|
||||
|
||||
protected $specialFilters = array();
|
||||
protected $specialFilters = array(
|
||||
'hostgroup',
|
||||
);
|
||||
|
||||
protected $sortDefaults = array(
|
||||
'raw_timestamp' => array(
|
||||
|
|
|
@ -2,11 +2,12 @@
|
|||
|
||||
namespace Icinga\Module\Monitoring\View;
|
||||
|
||||
class HostgroupView extends MonitoringView
|
||||
class HostgroupView extends AbstractView
|
||||
{
|
||||
protected $query;
|
||||
|
||||
protected $availableColumns = array(
|
||||
'hostgroups',
|
||||
'hostgroup_name',
|
||||
'hostgroup_alias',
|
||||
);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace Icinga\Module\Monitoring\View;
|
||||
|
||||
class HoststatusView extends MonitoringView
|
||||
class HoststatusView extends AbstractView
|
||||
{
|
||||
protected $query;
|
||||
protected $searchColumn = 'host';
|
||||
|
@ -37,11 +37,19 @@ class HoststatusView extends MonitoringView
|
|||
'host_last_time_up',
|
||||
'host_last_time_down',
|
||||
'host_last_time_unreachable',
|
||||
|
||||
// Services
|
||||
'services_cnt',
|
||||
'services_problem',
|
||||
'services_problem_handled',
|
||||
'services_problem_unhandled',
|
||||
);
|
||||
|
||||
protected $specialFilters = array(
|
||||
'hostgroups',
|
||||
'servicegroups'
|
||||
'hostgroup',
|
||||
'servicegroup',
|
||||
'contact',
|
||||
'contactgroup',
|
||||
);
|
||||
|
||||
protected $sortDefaults = array(
|
||||
|
|
|
@ -28,7 +28,7 @@ namespace Icinga\Module\Monitoring\View;
|
|||
/**
|
||||
* NotificationView
|
||||
*/
|
||||
class NotificationView extends MonitoringView
|
||||
class NotificationView extends AbstractView
|
||||
{
|
||||
/**
|
||||
* Available columns provided by this view
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace Icinga\Module\Monitoring\View;
|
||||
|
||||
class ServicegroupView extends MonitoringView
|
||||
class ServicegroupView extends AbstractView
|
||||
{
|
||||
protected $query;
|
||||
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Monitoring\View;
|
||||
|
||||
use Icinga\Module\Monitoring\View\AbstractView;
|
||||
|
||||
class StatehistoryView extends AbstractView
|
||||
{
|
||||
protected $availableColumns = array(
|
||||
'raw_timestamp',
|
||||
'timestamp',
|
||||
'state',
|
||||
'attempt',
|
||||
'max_attempts',
|
||||
'output',
|
||||
'type'
|
||||
);
|
||||
|
||||
protected $sortDefaults = array(
|
||||
'timestamp' => array(
|
||||
'columns' => array('raw_timestamp'),
|
||||
'default_dir' => self::SORT_DESC
|
||||
),
|
||||
);
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace Icinga\Module\Monitoring\View;
|
||||
|
||||
class StatusView extends MonitoringView
|
||||
class StatusView extends AbstractView
|
||||
{
|
||||
protected $query;
|
||||
// protected $searchColumn = 'host'; -> besser in der Query, 'search' mitgeben
|
||||
|
|
|
@ -170,7 +170,7 @@ abstract class MonitoringControllerTest extends Zend_Test_PHPUnit_ControllerTest
|
|||
private function requireViews()
|
||||
{
|
||||
$module = $this->moduleDir;
|
||||
require_once($module.'library/Monitoring/View/MonitoringView.php');
|
||||
require_once($module.'library/Monitoring/View/AbstractView.php');
|
||||
$this->requireFolder('library/Monitoring/View/');
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ $less = new lessc;
|
|||
$cssdir = dirname(__FILE__) . '/css';
|
||||
|
||||
echo $less->compileFile($cssdir . '/base.less');
|
||||
foreach ($app->moduleManager()->getLoadedModules() as $name => $module) {
|
||||
foreach ($app->getModuleManager()->getLoadedModules() as $name => $module) {
|
||||
if ($module->hasCss()) {
|
||||
echo $less->compile(
|
||||
'.icinga-module.module-'
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Icinga\Protocol\Statusdat;
|
||||
require_once("../../library/Icinga/Data/QueryInterface.php");
|
||||
require_once("../../library/Icinga/Data/AbstractQuery.php");
|
||||
require_once("../../library/Icinga/Protocol/Statusdat/Query.php");
|
||||
require_once(dirname(__FILE__)."/ReaderMock.php");
|
||||
|
|
|
@ -20,7 +20,7 @@ require_once '../../modules/monitoring/library/Monitoring/Backend/Statusdat/Quer
|
|||
require_once '../../modules/monitoring/library/Monitoring/Backend/Statusdat.php';
|
||||
require_once '../../modules/monitoring/library/Monitoring/Backend/Statusdat/Query/StatusQuery.php';
|
||||
require_once '../../modules/monitoring/library/Monitoring/Backend/Statusdat/DataView/HostStatusView.php';
|
||||
require_once '../../modules/monitoring/library/Monitoring/View/MonitoringView.php';
|
||||
require_once '../../modules/monitoring/library/Monitoring/View/AbstractView.php';
|
||||
require_once '../../modules/monitoring/library/Monitoring/View/StatusView.php';
|
||||
|
||||
require_once '../../library/Icinga/Protocol/AbstractQuery.php';
|
||||
|
|
|
@ -24,7 +24,7 @@ require_once '../../modules/monitoring/library/Monitoring/Backend/Statusdat/Quer
|
|||
require_once '../../modules/monitoring/library/Monitoring/Backend/Statusdat.php';
|
||||
require_once '../../modules/monitoring/library/Monitoring/Backend/Statusdat/Query/StatusQuery.php';
|
||||
require_once '../../modules/monitoring/library/Monitoring/Backend/Statusdat/DataView/HostStatusView.php';
|
||||
require_once '../../modules/monitoring/library/Monitoring/View/MonitoringView.php';
|
||||
require_once '../../modules/monitoring/library/Monitoring/View/AbstractView.php';
|
||||
require_once '../../modules/monitoring/library/Monitoring/View/StatusView.php';
|
||||
require_once '../../library/Icinga/Web/Paginator/ScrollingStyle/SlidingWithBorder.php';
|
||||
|
||||
|
|
Loading…
Reference in New Issue