Add tested Backend ressource
Only statusdat is currently tested refs #4212
This commit is contained in:
parent
8abfd0a2d0
commit
f6b5f5d405
|
@ -0,0 +1,95 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Icinga Backend Abstract
|
||||
*
|
||||
* @package Icinga\Backend
|
||||
*/
|
||||
namespace Icinga\Backend;
|
||||
use Icinga\Application\Config;
|
||||
|
||||
abstract class AbstractBackend
|
||||
{
|
||||
protected $config;
|
||||
protected $extensions = array();
|
||||
|
||||
/**
|
||||
* Backend constructor, should not be overwritten
|
||||
*
|
||||
* Makes sure that $this->config exists. Config is a Zend_Config
|
||||
* object right now, only the main Config is an Icinga one
|
||||
*
|
||||
* return void
|
||||
*/
|
||||
final public function __construct(\Zend_Config $config = null)
|
||||
{
|
||||
if ($config == null)
|
||||
$config = new \Zend_Config(array());
|
||||
$this->config = $config;
|
||||
$this->init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this function for initialization tasks
|
||||
*
|
||||
* return void
|
||||
*/
|
||||
protected function init() {}
|
||||
|
||||
/**
|
||||
* Dummy function for fluent code
|
||||
*
|
||||
* return \Icinga\Backend\Ido
|
||||
*/
|
||||
public function select()
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Query object instance for given virtual table and desired fields
|
||||
*
|
||||
* Leave fields empty to get all available properties
|
||||
*
|
||||
* @param string Virtual table name
|
||||
* @param array Fields
|
||||
* return \Icinga\Backend\Ido\Query
|
||||
*/
|
||||
public function from($virtual_table, $fields = array())
|
||||
{
|
||||
$classname = $this->tableToClassName($virtual_table);
|
||||
if (! class_exists($classname)) {
|
||||
throw new \Exception(sprintf('Asking for invalid virtual table %s', $classname));
|
||||
}
|
||||
$query = new $classname($this, $fields);
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function hasView($virtual_table)
|
||||
{
|
||||
return class_exists($this->tableToClassName($virtual_table));
|
||||
}
|
||||
|
||||
protected function tableToClassName($virtual_table)
|
||||
{
|
||||
if (strpos($virtual_table,"/") !== false) {
|
||||
list($module, $classname) = explode("/",$virtual_table,2);
|
||||
$class = array_pop(explode("\\",get_class($this)));
|
||||
return 'Icinga\\'.ucfirst($module).'\\Backend\\'.$class.'\\'.ucfirst($classname).'Query';
|
||||
} else {
|
||||
return get_class($this) . '\\' . ucfirst($virtual_table . 'Query');
|
||||
}
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return preg_replace('~^.+\\\(.+?)$~', '$1', get_class($this));
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return $this->getName();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Backend\Criteria;
|
||||
|
||||
/**
|
||||
* Constants for filter definitions.
|
||||
* These only describe logical filter operations without going into storage specific
|
||||
* details, like which fields are used for querying. It's completely up to the query to determine what to do with these
|
||||
* constants (although the result should be consistent among the different storage apis).
|
||||
*
|
||||
*/
|
||||
class Filter
|
||||
{
|
||||
/**
|
||||
* Whether to remove or keep handled objects
|
||||
* This means objects that are currently in a downtime or problems that have been acknowledged
|
||||
*/
|
||||
const HANDLED = "handled";
|
||||
|
||||
/**
|
||||
* Whether to display problems
|
||||
* This means objects with a state higher than 0
|
||||
*/
|
||||
const PROBLEMS = "problems";
|
||||
|
||||
/**
|
||||
* Whether to limit the result to a specific hostgroup.
|
||||
* Filters usually accept an array of hostgroup names
|
||||
*/
|
||||
const HOSTGROUPS = "hostgroups";
|
||||
|
||||
/**
|
||||
* Whether to limit the result to a specific servicegroup.
|
||||
* Filters usually accept an array of servicegroup names
|
||||
*/
|
||||
const SERVICEGROUPS = "servicegroups";
|
||||
|
||||
/**
|
||||
* Defines a string based search.
|
||||
* Which objects and criterias are used have to be decided in the backend
|
||||
*/
|
||||
const SEARCH = "search";
|
||||
|
||||
const STATE = "state";
|
||||
const HOSTSTATE = "hoststate";
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Backend\Criteria;
|
||||
|
||||
/**
|
||||
* Constants for order definitions.
|
||||
* These only describe logical orders without going into storage specific
|
||||
* details, like which fields are used for ordering. It's completely up to the query to determine what to do with these
|
||||
* constants (although the result should be consistent among the different storage apis).
|
||||
*
|
||||
*/
|
||||
class Order
|
||||
{
|
||||
/**
|
||||
* Order by the newest events. What this means has to be determined in the context.
|
||||
* Mostly this affects last_state_change
|
||||
*/
|
||||
const STATE_CHANGE = "state_change";
|
||||
|
||||
/**
|
||||
* Order by the state of service objects. Mostly this is critical->unknown->warning->ok,
|
||||
* but also might take acknowledgments and downtimes in account
|
||||
*/
|
||||
const SERVICE_STATE = "service_state";
|
||||
|
||||
/**
|
||||
* Order by the state of host objects. Mostly this is critical->unknown->warning->ok,
|
||||
* but also might take acknowledgments and downtimes in account
|
||||
*/
|
||||
const HOST_STATE = "host_state";
|
||||
|
||||
const HOST_NAME = "host_name";
|
||||
const SERVICE_NAME = "service_description";
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Backend\DataView;
|
||||
|
||||
/**
|
||||
* Basic interface for views.
|
||||
* The name sound weirder than it is: Views define special get and exists operations for fields that are not
|
||||
* directly available in a resultset, but exist under another name or can be accessed by loading an additional object
|
||||
* during runtime.
|
||||
*
|
||||
* @see Icinga\Backend\DataView\ObjectRemappingView For an implementation of mapping field names
|
||||
* to storage specific names, e.g. service_state being status.current_state in status.dat views.
|
||||
*
|
||||
* @see Icinga\Backend\MonitoringObjectList For the typical usage of this class. It is not wrapped
|
||||
* around the monitoring object, so we don't use __get() or __set() and always have to give the item we'd like to access.
|
||||
*
|
||||
*/
|
||||
interface AbstractAccessorStrategy {
|
||||
/**
|
||||
* Returns a field for the item, or throws an Exception if the field doesn't exist
|
||||
*
|
||||
* @param $item The item to access
|
||||
* @param $field The field of the item that should be accessed
|
||||
* @return string The content of the field
|
||||
*
|
||||
* @throws \InvalidArgumentException when the field does not exist
|
||||
*/
|
||||
public function get(&$item,$field);
|
||||
|
||||
/**
|
||||
* Returns the name that the field has in the specific backend. Might not be available for every field/view
|
||||
* @param $field The field name that should be translated
|
||||
* @return string The real name of this field
|
||||
*/
|
||||
public function getNormalizedFieldName($field);
|
||||
|
||||
/**
|
||||
* Returns true if the field exists on the specific item, otherwise false
|
||||
*
|
||||
* @param $item The item to access
|
||||
* @param $field The field to check on the $item
|
||||
* @return bool True when the field exists, otherwise false
|
||||
*/
|
||||
public function exists(&$item,$field);
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Backend\DataView;
|
||||
/**
|
||||
* Dataview that maps generic field names to storage specific fields or requests them via handlers.
|
||||
*
|
||||
* When accessing objects, every storage api returns them with other names. You can't simply say $object->service_state,
|
||||
* because this field is, e.g. under status.current_state in the status.dat view, while IDO uses servicestate->current_state.
|
||||
*
|
||||
* This view is intended for normalizing these changes, so a request of service_state returns the right field for the backend.
|
||||
* When implementing it, you have to fill the mappedParameters and/or the handlerParameters array. While mappedParameters
|
||||
* simply translate logic field names to storage specific ones, handlerParameters determins functions that handle data
|
||||
* retrieval for the specific fields.
|
||||
*
|
||||
*/
|
||||
class ObjectRemappingView implements AbstractAccessorStrategy
|
||||
{
|
||||
|
||||
/**
|
||||
* When implementing your own Mapper, this contains the static mapping rules.
|
||||
* @see Icinga\Backend\Statusdat\DataView\StatusdatServiceView for an example
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $mappedParameters = array();
|
||||
|
||||
/**
|
||||
* When implementing your own Mapper, this contains the handler for specific fields and allows you to lazy load
|
||||
* different fields if necessary. The methods are strings that will be mapped to methods of this class
|
||||
*
|
||||
* @see Icinga\Backend\Statusdat\DataView\StatusdatServiceView for an example
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $handlerParameters = array();
|
||||
|
||||
/**
|
||||
*
|
||||
* @see Icinga\Backend\DataView\AbstractAccessorStrategy
|
||||
*
|
||||
* @param The $item
|
||||
* @param The $field
|
||||
* @return The|string
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function get(&$item, $field)
|
||||
{
|
||||
|
||||
if (isset($item->$field))
|
||||
return $item->$field;
|
||||
if (isset($this->mappedParameters[$field])) {
|
||||
$mapped = explode(".",$this->mappedParameters[$field]);
|
||||
$res = $item;
|
||||
|
||||
foreach($mapped as $map) {
|
||||
if(!isset($res->$map))
|
||||
return "";
|
||||
$res = $res->$map;
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
if (isset($this->handlerParameters[$field])) {
|
||||
$hdl = $this->handlerParameters[$field];
|
||||
return $this->$hdl($item);
|
||||
}
|
||||
throw new \InvalidArgumentException("Field $field does not exist for status.dat services");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @see Icinga\Backend\DataView\AbstractAccessorStrategy
|
||||
*
|
||||
* @param The $field
|
||||
* @return The|string
|
||||
*/
|
||||
public function getNormalizedFieldName($field)
|
||||
{
|
||||
if(isset($this->mappedParameters[$field]))
|
||||
return $this->mappedParameters[$field];
|
||||
return $field;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @see Icinga\Backend\DataView\AbstractAccessorStrategy
|
||||
*
|
||||
* @param The $item
|
||||
* @param The $field
|
||||
* @return bool
|
||||
*/
|
||||
public function exists(&$item, $field)
|
||||
{
|
||||
return (isset($item->$field)
|
||||
|| isset($this->mappedParameters[$field])
|
||||
|| isset($this->handlerParameters[$field])
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Backend;
|
||||
abstract class Query
|
||||
{
|
||||
|
||||
protected $backend;
|
||||
protected $columns = array();
|
||||
protected $available_columns = array();
|
||||
|
||||
abstract public function limit($count = null, $offset = null);
|
||||
abstract public function where($column, $value = null);
|
||||
abstract public function order($column = '', $dir = null);
|
||||
abstract public function fetchAll();
|
||||
abstract public function fetchRow();
|
||||
abstract public function fetchPairs();
|
||||
abstract public function fetchOne();
|
||||
abstract public function count();
|
||||
|
||||
public function __construct(\Icinga\Backend\AbstractBackend $backend, $columns = array())
|
||||
{
|
||||
$this->backend = $backend;
|
||||
if (empty($columns) || $columns === '*') {
|
||||
$this->columns = $this->available_columns;
|
||||
} else {
|
||||
$this->columns = $columns;
|
||||
}
|
||||
$this->init();
|
||||
}
|
||||
|
||||
public function applyFilters($filters = array())
|
||||
{
|
||||
foreach ($filters as $key => $val) {
|
||||
$this->where($key, $val);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
abstract protected function init();
|
||||
|
||||
protected function finalize() {}
|
||||
|
||||
/**
|
||||
* Return a pagination adapter for the current query
|
||||
*
|
||||
* @return \Zend_Paginator
|
||||
*/
|
||||
public function paginate($limit = null, $page = null)
|
||||
{
|
||||
$this->finalize();
|
||||
$request = \Zend_Controller_Front::getInstance()->getRequest();
|
||||
if ($page === null) {
|
||||
$page = $request->getParam('page', 0);
|
||||
}
|
||||
if ($limit === null) {
|
||||
$limit = $request->getParam('limit', 20);
|
||||
}
|
||||
$paginator = new \Zend_Paginator(
|
||||
new \Icinga\Web\Paginator\Adapter\QueryAdapter($this)
|
||||
);
|
||||
$paginator->setItemCountPerPage($limit);
|
||||
$paginator->setCurrentPageNumber($page);
|
||||
return $paginator;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Backend;
|
||||
|
||||
use Icinga\Protocol\Statusdat as StatusdatProtocol;
|
||||
|
||||
|
||||
class Statusdat extends AbstractBackend
|
||||
{
|
||||
private $reader = null;
|
||||
|
||||
public function init()
|
||||
{
|
||||
$this->reader = new StatusdatProtocol\Reader($this->config);
|
||||
}
|
||||
|
||||
public function getReader()
|
||||
{
|
||||
return $this->reader;
|
||||
}
|
||||
|
||||
public function listServices($filter = array(), $flags = array())
|
||||
{
|
||||
$query = $this->select()->from("servicelist");
|
||||
return $query->fetchAll();
|
||||
}
|
||||
|
||||
|
||||
public function fetchHost($host)
|
||||
{
|
||||
$objs = & $this->reader->getObjects();
|
||||
|
||||
if (!isset($objs["host"][$host]))
|
||||
return null;
|
||||
$result = array($objs["host"][$host]);
|
||||
return new MonitoringObjectList(
|
||||
$result,
|
||||
new \Icinga\Backend\Statusdat\DataView\StatusdatHostView($this->reader)
|
||||
);
|
||||
}
|
||||
|
||||
public function fetchService($host, $service)
|
||||
{
|
||||
$idxName = $host . ";" . $service;
|
||||
$objs = & $this->reader->getObjects();
|
||||
|
||||
if (!isset($objs["service"][$idxName]))
|
||||
return null;
|
||||
$result = array($objs["service"][$idxName]);
|
||||
return new MonitoringObjectList(
|
||||
$result,
|
||||
new \Icinga\Backend\Statusdat\DataView\StatusdatServiceView($this->reader)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
namespace Icinga\Backend\Statusdat\DataView;
|
||||
use \Icinga\Protocol\Statusdat\IReader;
|
||||
class StatusdatHostView extends \Icinga\Backend\DataView\ObjectRemappingView
|
||||
{
|
||||
private $state;
|
||||
|
||||
protected $handlerParameters = array(
|
||||
"host" => "getHost",
|
||||
"downtimes_with_info" => "getDowntimes",
|
||||
"comments_with_info" => "getComments"
|
||||
);
|
||||
|
||||
protected $mappedParameters = array(
|
||||
"host_address" => "host_name",
|
||||
"host_name" => "host_name",
|
||||
"host_state" => "status.current_state",
|
||||
"host_output" => "status.plugin_output",
|
||||
"host_perfdata" => "status.long_plugin_output",
|
||||
"host_state" => "status.current_state",
|
||||
"host_perfdata" => "status.long_plugin_output",
|
||||
"host_last_state_change" => "status.last_state_change",
|
||||
"host_output" => "status.plugin_output",
|
||||
"host_check_command" => "check_command",
|
||||
"host_last_check" => "status.last_check",
|
||||
"host_next_check" => "status.next_check",
|
||||
"host_check_latency" => "status.check_latency",
|
||||
"host_check_execution_time" => "status.check_execution_time",
|
||||
"active_checks_enabled" => "status.active_checks_enabled",
|
||||
|
||||
"acknowledged" => "status.problem_has_been_acknowledged",
|
||||
"host_acknowledged" => "status.problem_has_been_acknowledged",
|
||||
// "state" => "current_state"
|
||||
);
|
||||
|
||||
|
||||
public function getHost(&$item) {
|
||||
if(!isset($this->state["host"][$item->host_name]))
|
||||
return null;
|
||||
if(!isset($this->state["host"][$item->host_name]))
|
||||
return null;
|
||||
return $this->state["host"][$item->host_name];
|
||||
}
|
||||
|
||||
public function __construct(IReader $reader) {
|
||||
$this->state = &$reader->getState();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
namespace Icinga\Backend\Statusdat\DataView;
|
||||
use \Icinga\Protocol\Statusdat\IReader;
|
||||
|
||||
class StatusdatServiceView extends \Icinga\Backend\DataView\ObjectRemappingView
|
||||
{
|
||||
private $state;
|
||||
|
||||
protected $handlerParameters = array(
|
||||
"host" => "getHost",
|
||||
"downtimes_with_info" => "getDowntimes"
|
||||
);
|
||||
|
||||
protected $mappedParameters = array(
|
||||
"host_address" => "parenthost.address",
|
||||
"host_name" => "host_name",
|
||||
"active_checks_enabled" => "status.active_checks_enabled",
|
||||
"passive_checks_enabled" => "status.passive_checks_enabled",
|
||||
"service_state" => "status.current_state",
|
||||
"service_perfdata" => "status.performance_data",
|
||||
"service_last_state_change" => "status.last_state_change",
|
||||
"service_output" => "status.plugin_output",
|
||||
"service_long_output" => "status.long_plugin_output",
|
||||
"service_check_command" => "check_command",
|
||||
"service_last_check" => "status.last_check",
|
||||
"service_next_check" => "status.next_check",
|
||||
"service_check_latency" => "status.check_latency",
|
||||
"service_check_execution_time" => "status.check_execution_time",
|
||||
"service_acknowledged" => "status.problem_has_been_acknowledged",
|
||||
"service_comments" => "comment"
|
||||
|
||||
);
|
||||
|
||||
public function get(&$item, $field)
|
||||
{
|
||||
if(!isset($item->parenthost) && isset($this->state["host"]))
|
||||
$item->parenthost = $this->state["host"];
|
||||
|
||||
return parent::get($item,$field);
|
||||
}
|
||||
public function exists(&$item, $field)
|
||||
{
|
||||
if(!isset($item->parenthost))
|
||||
$item->parenthost = $this->state["host"];
|
||||
|
||||
return parent::exists($item,$field);
|
||||
}
|
||||
|
||||
public function getHost(&$item)
|
||||
{
|
||||
if (!isset($this->state["host"][$item->host_name]))
|
||||
return null;
|
||||
if (!isset($this->state["host"][$item->host_name]))
|
||||
return null;
|
||||
return $this->state["host"][$item->host_name];
|
||||
}
|
||||
|
||||
public function __construct(IReader $reader)
|
||||
{
|
||||
$this->state = & $reader->getState();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,139 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Backend\Statusdat;
|
||||
abstract class GroupsummaryQuery extends Query
|
||||
{
|
||||
protected $reader;
|
||||
protected $groupType = "servicegroup";
|
||||
protected $base = "services";
|
||||
|
||||
protected $available_columns = array(
|
||||
'ok' => 'SUM(CASE WHEN state = 0 THEN 1 ELSE 0 END)',
|
||||
'critical' => 'SUM(CASE WHEN state = 2 AND downtime = 0 AND ack = 0 THEN 1 ELSE 0 END)',
|
||||
'critical_dt' => 'SUM(CASE WHEN state = 2 AND downtime = 1 THEN 1 ELSE 0 END)',
|
||||
'critical_ack' => 'SUM(CASE WHEN state = 2 AND downtime = 0 AND ack = 1 THEN 1 ELSE 0 END)',
|
||||
'unknown' => 'SUM(CASE WHEN state = 3 AND downtime = 0 AND ack = 0 THEN 1 ELSE 0 END)',
|
||||
'unknown_dt' => 'SUM(CASE WHEN state = 3 AND downtime = 1 THEN 1 ELSE 0 END)',
|
||||
'unknown_ack' => 'SUM(CASE WHEN state = 3 AND downtime = 0 AND ack = 1 THEN 1 ELSE 0 END)',
|
||||
'warning' => 'SUM(CASE WHEN state = 1 AND downtime = 0 AND ack = 0 THEN 1 ELSE 0 END)',
|
||||
'warning_dt' => 'SUM(CASE WHEN state = 1 AND downtime = 1 THEN 1 ELSE 0 END)',
|
||||
'warning_ack' => 'SUM(CASE WHEN state = 1 AND downtime = 0 AND ack = 1 THEN 1 ELSE 0 END)',
|
||||
);
|
||||
|
||||
protected $order_columns = array(
|
||||
'state' => array(
|
||||
'ASC' => array(
|
||||
'ok ASC',
|
||||
'warning_dt ASC',
|
||||
'warning_ack ASC',
|
||||
'warning ASC',
|
||||
'unknown_dt ASC',
|
||||
'unknown_ack ASC',
|
||||
'unknown ASC',
|
||||
'critical_dt ASC',
|
||||
'critical_ack ASC',
|
||||
'critical ASC',
|
||||
),
|
||||
'DESC' => array(
|
||||
'critical DESC',
|
||||
'critical_ack DESC',
|
||||
'critical_dt DESC',
|
||||
'unknown DESC',
|
||||
'unknown_ack DESC',
|
||||
'unknown_dt DESC',
|
||||
'warning DESC',
|
||||
'warning_ack DESC',
|
||||
'warning_dt DESC',
|
||||
'ok DESC',
|
||||
),
|
||||
'default' => 'DESC'
|
||||
)
|
||||
);
|
||||
|
||||
private function getStateType(&$obj)
|
||||
{
|
||||
|
||||
if ($obj->status->current_state == 0)
|
||||
return "ok";
|
||||
$typeBase = "";
|
||||
if ($obj->status->current_state == 1) {
|
||||
$typeBase = 'warning';
|
||||
} else if ($obj->status->current_state == 2) {
|
||||
$typeBase = 'critical';
|
||||
} else if ($obj->status->current_state == 3) {
|
||||
$typeBase = 'unknown';
|
||||
}
|
||||
if ($obj->status->problem_has_been_acknowledged) {
|
||||
return $typeBase . "_ack";
|
||||
|
||||
} else if (isset($obj->status->downtime)) {
|
||||
return $typeBase . "_dt";
|
||||
}
|
||||
return $typeBase;
|
||||
}
|
||||
|
||||
public function groupByProblemType(&$indices)
|
||||
{
|
||||
|
||||
|
||||
$typename = $this->groupType."_name";
|
||||
$result = array();
|
||||
foreach ($indices as $type=>$subIndices) {
|
||||
|
||||
foreach ($subIndices as $objName) {
|
||||
|
||||
$obj = &$this->reader->getObjectByName($type,$objName);
|
||||
$statetype = $this->getStateType($obj);
|
||||
foreach($obj->group as $group) {
|
||||
if(!isset($result[$group])) {
|
||||
$result[$group] = (object) array(
|
||||
$typename => $group,
|
||||
'ok' => 0,
|
||||
'critical' => 0,
|
||||
'critical_dt' => 0,
|
||||
'critical_ack' => 0,
|
||||
'unknown' => 0,
|
||||
'unknown_dt' => 0,
|
||||
'unknown_ack' => 0,
|
||||
'warning' => 0,
|
||||
'warning_dt' => 0,
|
||||
'warning_ack' => 0
|
||||
);
|
||||
}
|
||||
$result[$group]->$statetype++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array_values($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @var \Icinga\Protocol\Statusdat\Query
|
||||
*/
|
||||
|
||||
|
||||
public function init() {
|
||||
$this->reader = $this->backend->getReader();
|
||||
$this->query = $this->reader->select()->from($this->base,array())->groupByFunction("groupByProblemType",$this)->where("COUNT{group} > 0");
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function where($column, $value = null)
|
||||
{
|
||||
if ($column === 'problems') {
|
||||
if ($value === 'true') {
|
||||
//$this->where("COUNT{downtime} == 0 AND status.problem_has_been_acknowledged == 0 AND status.current_state > 0");
|
||||
}
|
||||
} elseif ($column === 'search') {
|
||||
if ($value) {
|
||||
$this->where($this->name_alias . ' LIKE ?', '%' . $value . '%');
|
||||
}
|
||||
} else {
|
||||
parent::where($column, $value);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Backend\Statusdat;
|
||||
class HostgroupsummaryQuery extends GroupsummaryQuery
|
||||
{
|
||||
protected $groupType = "hostgroup";
|
||||
protected $base = "hosts";
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
/**
|
||||
* Created by JetBrains PhpStorm.
|
||||
* User: moja
|
||||
* Date: 1/29/13
|
||||
* Time: 11:36 AM
|
||||
* To change this template use File | Settings | File Templates.
|
||||
*/
|
||||
namespace Icinga\Backend\Statusdat;
|
||||
use Icinga\Protocol\Statusdat;
|
||||
use Icinga\Exception;
|
||||
|
||||
|
||||
class HostListQuery extends Query
|
||||
{
|
||||
/**
|
||||
* @var \Icinga\Protocol\Statusdat\Query
|
||||
*/
|
||||
protected $query;
|
||||
protected $view = 'Icinga\Backend\Statusdat\DataView\StatusdatHostView';
|
||||
|
||||
public function init() {
|
||||
$this->reader = $this->backend->getReader();
|
||||
$this->query = $this->reader->select()->from("hosts",array());
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,214 @@
|
|||
<?php
|
||||
namespace Icinga\Backend\Statusdat;
|
||||
use Icinga\Backend\MonitoringObjectList as MList;
|
||||
use Icinga\Protocol\Statusdat;
|
||||
use Icinga\Exception;
|
||||
|
||||
|
||||
/**
|
||||
* Base class for statusdat queries, contains most of the filter/order logic
|
||||
*
|
||||
*/
|
||||
abstract class Query extends \Icinga\Backend\Query
|
||||
{
|
||||
protected $cursor = null;
|
||||
protected $view = 'Icinga\Backend\Statusdat\DataView\StatusdatServiceView';
|
||||
/**
|
||||
* @var array Mapping of order to field names
|
||||
* @todo Is not complete right now
|
||||
*/
|
||||
protected $orderColumns = array(
|
||||
\Icinga\Backend\Criteria\Order::SERVICE_STATE => "status.current_state",
|
||||
\Icinga\Backend\Criteria\Order::STATE_CHANGE => "status.last_state_change",
|
||||
\Icinga\Backend\Criteria\Order::HOST_STATE => "status.current_state",
|
||||
\Icinga\Backend\Criteria\Order::HOST_NAME => "host_name",
|
||||
\Icinga\Backend\Criteria\Order::SERVICE_NAME => "service_description"
|
||||
);
|
||||
|
||||
/**
|
||||
* Calls the apply%Filtername%Filter() method for the given filter, or simply calls
|
||||
* where(), if the method is not available.
|
||||
*
|
||||
* @see \Icinga\Backend\Query For the parent definition
|
||||
*
|
||||
* @param array $filters An array of "filtername"=>"value" definitions
|
||||
*
|
||||
* @return Query Returns the query object to allow fluent calls
|
||||
*/
|
||||
public function applyFilters(array $filters = array())
|
||||
{
|
||||
foreach ($filters as $filter => $value) {
|
||||
$filter[0] = strtoupper($filter[0]);
|
||||
$filterMethod = "apply" . $filter . "Filter";
|
||||
if (method_exists($this, $filterMethod))
|
||||
$this->$filterMethod($filter, $value);
|
||||
else
|
||||
$this->where($filter, $value);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a filter to only show open problems, or non problems, depending whether value is true or false
|
||||
*
|
||||
* @param $type ignored
|
||||
* @param $value Whether problems should be shown (1) or non problems (0)
|
||||
*/
|
||||
public function applyProblemsFilter($type, $value)
|
||||
{
|
||||
if ($value) { // Status.dat only contains active downtimes
|
||||
$value = array(1, 0);
|
||||
$this->where("(status.current_state >= ? and COUNT{status.downtime} = ? )", $value);
|
||||
} else {
|
||||
$value = array(0, 1);
|
||||
$this->where("(status.current_state < 1 or COUNT{status.downtime} > ? )", $value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic object search by host name, service description and plugin output
|
||||
*
|
||||
* @param $type ignored
|
||||
* @param $value The string to search for
|
||||
*/
|
||||
public function applySearchFilter($type, $value)
|
||||
{
|
||||
$text = "%$value%";
|
||||
$val = array($text, $text, $text);
|
||||
|
||||
$this->query->where("(host_name LIKE ? OR service_description LIKE ? OR status.plugin_output LIKE ?)", $val);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a hostgroup filter on this object
|
||||
*
|
||||
* @param $type ignored
|
||||
* @param $value The hostgroup to filter for
|
||||
*/
|
||||
public function applyHostgroupsFilter($type, $value)
|
||||
{
|
||||
$filter = array($value);
|
||||
$this->query->where("host.group IN ?", $filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a servicegroup filter on this object
|
||||
*
|
||||
* @param $type ignored
|
||||
* @param $value The servicegroup to filter for
|
||||
*/
|
||||
public function applyServicegroupsFilter($type, $value)
|
||||
{
|
||||
$filter = array($value);
|
||||
$this->query->where("group IN ?", $filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters by handled problems or unhandled
|
||||
*
|
||||
* @todo: Add downtime
|
||||
* @param $type
|
||||
* @param $value Whether to search for unhandled (0) or handled (1)
|
||||
*/
|
||||
public function applyHandledFilter($type, $value)
|
||||
{
|
||||
$val = array($value, $value);
|
||||
$this->query->where("(status.problem_has_been_acknowledged = ? )", $val);
|
||||
}
|
||||
|
||||
public function applyHostnameFilter($type, $value)
|
||||
{
|
||||
if (!is_array($value))
|
||||
$value = array($value);
|
||||
$this->query->where("host_name LIKE ?", $value);
|
||||
}
|
||||
|
||||
public function applyStateFilter($type, $value)
|
||||
{
|
||||
$this->query->where("status.current_state = $value");
|
||||
}
|
||||
|
||||
public function applyHoststateFilter($type, $value)
|
||||
{
|
||||
$this->query->where("host.status.current_state = $value");
|
||||
}
|
||||
|
||||
public function applyServiceDescriptionFilter($type, $value)
|
||||
{
|
||||
if (!is_array($value))
|
||||
$value = array($value);
|
||||
$this->query->where("service_description LIKE ?", $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Limits this query and offsets it
|
||||
* @param null|integer $count The maximum element count to display
|
||||
* @param null|integer $offset The offset to start counting
|
||||
* @return Query This object, for fluent interface
|
||||
*/
|
||||
public function limit($count = null, $offset = null)
|
||||
{
|
||||
$this->query->limit($count, $offset);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Orders the resultset
|
||||
*
|
||||
* @param string $column Either a string in the 'FIELD ASC/DESC format or only the field
|
||||
* @param null $dir 'asc' or 'desc'
|
||||
* @return Query Returns this query,for fluent interface
|
||||
*/
|
||||
public function order($column = '', $dir = null)
|
||||
{
|
||||
|
||||
if ($column)
|
||||
$this->query->order($this->orderColumns[$column], strtolower($dir));
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a filter on this query by calling the statusdat where() function
|
||||
*
|
||||
* @param $column The (statusdat!) column to filter in "field operator ?" format. (@example status.current_state > ?)
|
||||
* @param mixed $value The value to filter for
|
||||
* @return Query Returns this query,for fluent interface
|
||||
*/
|
||||
public function where($column, $value = null)
|
||||
{
|
||||
if (!is_array($value))
|
||||
$value = array($value);
|
||||
$this->query->where($column, $value);
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function fetchAll()
|
||||
{
|
||||
$view = $this->view;
|
||||
if (!$this->cursor)
|
||||
$this->cursor = new MList($this->query->getResult(), new $view($this->reader));
|
||||
return $this->cursor;
|
||||
}
|
||||
|
||||
public function fetchRow()
|
||||
{
|
||||
return next($this->fetchAll());
|
||||
}
|
||||
|
||||
public function fetchPairs()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function fetchOne()
|
||||
{
|
||||
return next($this->fetchAll());
|
||||
}
|
||||
|
||||
public function count()
|
||||
{
|
||||
return count($this->query->getResult());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Backend\Statusdat;
|
||||
class ServicegroupsummaryQuery extends GroupsummaryQuery
|
||||
{
|
||||
protected $groupType = "servicegroup";
|
||||
protected $base = "services";
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
/**
|
||||
* Created by JetBrains PhpStorm.
|
||||
* User: moja
|
||||
* Date: 1/29/13
|
||||
* Time: 11:36 AM
|
||||
* To change this template use File | Settings | File Templates.
|
||||
*/
|
||||
namespace Icinga\Backend\Statusdat;
|
||||
use Icinga\Backend\MonitoringObjectList as MList;
|
||||
use Icinga\Protocol\Statusdat;
|
||||
use Icinga\Backend\Statusdat\DataView\StatusdatServiceView as StatusdatServiceView;
|
||||
use Icinga\Exception;
|
||||
|
||||
|
||||
class ServicelistQuery extends Query
|
||||
{
|
||||
/**
|
||||
* @var \Icinga\Protocol\Statusdat\Query
|
||||
*/
|
||||
protected $query;
|
||||
protected $view = 'Icinga\Backend\Statusdat\DataView\StatusdatServiceView';
|
||||
|
||||
|
||||
public function init() {
|
||||
$this->reader = $this->backend->getReader();
|
||||
$this->query = $this->reader->select()->from("services",array());
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
Binary file not shown.
|
@ -2,14 +2,14 @@
|
|||
|
||||
namespace Tests\Icinga\Backend\Statusdat;
|
||||
use Tests\Icinga\Protocol\Statusdat\ReaderMock as ReaderMock;
|
||||
|
||||
require_once("Zend/Config.php");
|
||||
require_once("./library/Icinga/Protocol/Statusdat/ReaderMock.php");
|
||||
require_once("../library/Icinga/Backend/Query.php");
|
||||
require_once("../library/Icinga/Backend/Criteria/Order.php");
|
||||
require_once("../library/Icinga/Backend/AbstractBackend.php");
|
||||
require_once("../library/Icinga/Backend/Statusdat/Query.php");
|
||||
require_once("../library/Icinga/Backend/Statusdat/GroupsummaryQuery.php");
|
||||
require_once("../library/Icinga/Backend/Statusdat/ServicegroupsummaryQuery.php");
|
||||
require_once("../../library/Icinga/Backend/Query.php");
|
||||
require_once("../../library/Icinga/Backend/Criteria/Order.php");
|
||||
require_once("../../library/Icinga/Backend/AbstractBackend.php");
|
||||
require_once("../../library/Icinga/Backend/Statusdat/Query.php");
|
||||
require_once("../../library/Icinga/Backend/Statusdat/GroupsummaryQuery.php");
|
||||
require_once("../../library/Icinga/Backend/Statusdat/ServicegroupsummaryQuery.php");
|
||||
|
||||
class BackendMock extends \Icinga\Backend\AbstractBackend{
|
||||
public $reader;
|
||||
|
|
Loading…
Reference in New Issue