monitoring: Don't support status.dat as backend
Icinga Web 2 will not support status.dat for now and maybe forever.
This commit is contained in:
parent
2126b8c341
commit
1b23fd7fbe
|
@ -1,54 +0,0 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Form\Config\Resource;
|
||||
|
||||
use Icinga\Web\Form;
|
||||
use Icinga\Application\Icinga;
|
||||
use Icinga\Web\Form\Validator\ReadablePathValidator;
|
||||
|
||||
/**
|
||||
* Form class for adding/modifying statusdat resources
|
||||
*/
|
||||
class StatusdatResourceForm extends Form
|
||||
{
|
||||
/**
|
||||
* Initialize this form
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
$this->setName('form_config_resource_statusdat');
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Form::createElements()
|
||||
*/
|
||||
public function createElements(array $formData)
|
||||
{
|
||||
$this->addElement(
|
||||
'text',
|
||||
'status_file',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Filepath'),
|
||||
'description' => t('Location of your icinga status.dat file'),
|
||||
'value' => realpath(Icinga::app()->getApplicationDir() . '/../var/status.dat'),
|
||||
'validators' => array(new ReadablePathValidator())
|
||||
)
|
||||
);
|
||||
$this->addElement(
|
||||
'text',
|
||||
'object_file',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Filepath'),
|
||||
'description' => t('Location of your icinga objects.cache file'),
|
||||
'value' => realpath(Icinga::app()->getApplicationDir() . '/../var/objects.cache'),
|
||||
'validators' => array(new ReadablePathValidator())
|
||||
)
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
|
@ -12,7 +12,6 @@ use Icinga\Form\Config\Resource\DbResourceForm;
|
|||
use Icinga\Form\Config\Resource\FileResourceForm;
|
||||
use Icinga\Form\Config\Resource\LdapResourceForm;
|
||||
use Icinga\Form\Config\Resource\LivestatusResourceForm;
|
||||
use Icinga\Form\Config\Resource\StatusdatResourceForm;
|
||||
use Icinga\Application\Platform;
|
||||
use Icinga\Exception\ConfigurationError;
|
||||
|
||||
|
@ -42,8 +41,6 @@ class ResourceConfigForm extends ConfigForm
|
|||
return new LdapResourceForm();
|
||||
} elseif ($type === 'livestatus') {
|
||||
return new LivestatusResourceForm();
|
||||
} elseif ($type === 'statusdat') {
|
||||
return new StatusdatResourceForm();
|
||||
} elseif ($type === 'file') {
|
||||
return new FileResourceForm();
|
||||
} else {
|
||||
|
@ -214,7 +211,6 @@ class ResourceConfigForm extends ConfigForm
|
|||
|
||||
$resourceTypes = array(
|
||||
'file' => t('File'),
|
||||
'statusdat' => 'Status.dat',
|
||||
'livestatus' => 'Livestatus',
|
||||
);
|
||||
if ($resourceType === 'ldap' || Platform::extensionLoaded('ldap')) {
|
||||
|
|
|
@ -10,7 +10,6 @@ use Icinga\Util\ConfigAwareFactory;
|
|||
use Icinga\Exception\ConfigurationError;
|
||||
use Icinga\Data\Db\DbConnection;
|
||||
use Icinga\Protocol\Livestatus\Connection as LivestatusConnection;
|
||||
use Icinga\Protocol\Statusdat\Reader as StatusdatReader;
|
||||
use Icinga\Protocol\Ldap\Connection as LdapConnection;
|
||||
use Icinga\Protocol\File\FileReader;
|
||||
|
||||
|
@ -102,7 +101,7 @@ class ResourceFactory implements ConfigAwareFactory
|
|||
*
|
||||
* @param Zend_Config $config The configuration for the created resource.
|
||||
*
|
||||
* @return DbConnection|LdapConnection|LivestatusConnection|StatusdatReader An objects that can be used to access
|
||||
* @return DbConnection|LdapConnection|LivestatusConnection An object that can be used to access
|
||||
* the given resource. The returned class depends on the configuration property 'type'.
|
||||
* @throws ConfigurationError When an unsupported type is given
|
||||
*/
|
||||
|
@ -115,9 +114,6 @@ class ResourceFactory implements ConfigAwareFactory
|
|||
case 'ldap':
|
||||
$resource = new LdapConnection($config);
|
||||
break;
|
||||
case 'statusdat':
|
||||
$resource = new StatusdatReader($config);
|
||||
break;
|
||||
case 'livestatus':
|
||||
$resource = new LivestatusConnection($config->socket);
|
||||
break;
|
||||
|
@ -137,7 +133,7 @@ class ResourceFactory implements ConfigAwareFactory
|
|||
* Create a resource from name
|
||||
*
|
||||
* @param string $resourceName
|
||||
* @return DbConnection|LdapConnection|LivestatusConnection|StatusdatReader
|
||||
* @return DbConnection|LdapConnection|LivestatusConnection
|
||||
*/
|
||||
public static function create($resourceName)
|
||||
{
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Protocol\Statusdat\Exception;
|
||||
|
||||
/**
|
||||
* Class ParsingException
|
||||
* @package Icinga\Protocol\Statusdat\Exception
|
||||
*/
|
||||
class ParsingException extends \RuntimeException
|
||||
{
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Protocol\Statusdat;
|
||||
|
||||
interface IReader
|
||||
{
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getState();
|
||||
|
||||
/**
|
||||
* @param $type
|
||||
* @param $name
|
||||
* @return mixed
|
||||
*/
|
||||
public function getObjectByName($type, $name);
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Protocol\Statusdat;
|
||||
|
||||
/**
|
||||
* Class ObjectContainer
|
||||
* @package Icinga\Protocol\Statusdat
|
||||
*/
|
||||
class ObjectContainer extends \stdClass
|
||||
{
|
||||
/**
|
||||
* @var \stdClass
|
||||
*/
|
||||
public $ref;
|
||||
|
||||
/**
|
||||
* @var IReader
|
||||
*/
|
||||
public $reader;
|
||||
|
||||
/**
|
||||
* @param \stdClass $obj
|
||||
* @param IReader $reader
|
||||
*/
|
||||
public function __construct(&$obj, IReader &$reader)
|
||||
{
|
||||
$this->ref = & $obj;
|
||||
$this->reader = & $reader;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $attribute
|
||||
* @return \stdClass
|
||||
*/
|
||||
public function __get($attribute)
|
||||
{
|
||||
$exploded = explode(".", $attribute);
|
||||
$result = $this->ref;
|
||||
|
||||
foreach ($exploded as $elem) {
|
||||
if (isset($result->$elem)) {
|
||||
$result = $result->$elem;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
|
@ -1,422 +0,0 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Protocol\Statusdat;
|
||||
|
||||
use Icinga\Util\File;
|
||||
use Icinga\Exception\ProgrammingError;
|
||||
use Icinga\Protocol\Statusdat\Exception\ParsingException as ParsingException;
|
||||
|
||||
/**
|
||||
* Status.dat and object.cache parser implementation
|
||||
*/
|
||||
class Parser
|
||||
{
|
||||
/**
|
||||
* An array of objects that couldn't be resolved yet due to missing dependencies
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $deferred = array();
|
||||
|
||||
/**
|
||||
* The currently read file
|
||||
*
|
||||
* @var File
|
||||
*/
|
||||
private $file;
|
||||
|
||||
/**
|
||||
* String representation of the currently parsed object type
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $currentObjectType;
|
||||
|
||||
/**
|
||||
* The current state type (host, service)
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $currentStateType;
|
||||
|
||||
/**
|
||||
* The internal representation of the icinga statue
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $icingaState;
|
||||
|
||||
/**
|
||||
* The current line being read
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $lineCtr = 0;
|
||||
|
||||
/**
|
||||
* Create a new parser using the given file
|
||||
*
|
||||
* @param File $file The file to parse
|
||||
* @param array $baseState The state to use for the base
|
||||
*/
|
||||
public function __construct(File $file, $baseState = null)
|
||||
{
|
||||
$this->file = $file;
|
||||
$this->icingaState = $baseState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the given file handle as an objects file and read object information
|
||||
*/
|
||||
public function parseObjectsFile()
|
||||
{
|
||||
$DEFINE = strlen('define ');
|
||||
$this->icingaState = array();
|
||||
foreach ($this->file as $line) {
|
||||
$line = trim($line);
|
||||
$this->lineCtr++;
|
||||
if ($line === '' || $line[0] === '#') {
|
||||
continue;
|
||||
}
|
||||
$this->currentObjectType = trim(substr($line, $DEFINE, -1));
|
||||
if (!isset($this->icingaState[$this->currentObjectType])) {
|
||||
$this->icingaState[$this->currentObjectType] = array();
|
||||
}
|
||||
$this->readCurrentObject();
|
||||
}
|
||||
$this->processDeferred();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the given file as an status.dat file and read runtime information
|
||||
*
|
||||
* @param File $file The file to parse or null to parse the one passed to the constructor
|
||||
*/
|
||||
public function parseRuntimeState(File $file = null)
|
||||
{
|
||||
if ($file != null) {
|
||||
$this->file = $file;
|
||||
} else {
|
||||
$file = $this->file;
|
||||
}
|
||||
|
||||
if (!$this->icingaState) {
|
||||
throw new ProgrammingError('Tried to read runtime state without existing objects data');
|
||||
}
|
||||
$this->overwrites = array();
|
||||
foreach ($file as $line) {
|
||||
$line = trim($line);
|
||||
$this->lineCtr++;
|
||||
if ($line === '' || $line[0] === '#') {
|
||||
continue;
|
||||
}
|
||||
$this->currentStateType = trim(substr($line, 0, -1));
|
||||
$this->readCurrentState();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the next object from the object.cache file handle
|
||||
*
|
||||
* @throws ParsingException
|
||||
*/
|
||||
private function readCurrentObject()
|
||||
{
|
||||
$monitoringObject = new PrintableObject();
|
||||
foreach ($this->file as $line) {
|
||||
$line = explode("\t", trim($line), 2);
|
||||
$this->lineCtr++;
|
||||
if (!$line) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// End of object
|
||||
if ($line[0] === '}') {
|
||||
$this->registerObject($monitoringObject);
|
||||
return;
|
||||
}
|
||||
if (!isset($line[1])) {
|
||||
$line[1] = '';
|
||||
}
|
||||
$monitoringObject->{$line[0]} = trim($line[1]);
|
||||
}
|
||||
throw new ParsingException('Unexpected EOF in objects.cache, line ' . $this->lineCtr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the next state from the status.dat file handler
|
||||
*
|
||||
* @throws Exception\ParsingException
|
||||
*/
|
||||
private function readCurrentState()
|
||||
{
|
||||
$statusdatObject = new RuntimeStateContainer();
|
||||
|
||||
$objectType = $this->getObjectTypeForState();
|
||||
|
||||
if ($objectType != 'host' && $objectType != 'service') {
|
||||
$this->skipObject(); // ignore unknown objects
|
||||
return;
|
||||
}
|
||||
if (!isset($this->icingaState[$this->currentObjectType])) {
|
||||
throw new ParsingException("No $this->currentObjectType objects registered in objects.cache");
|
||||
}
|
||||
$base = & $this->icingaState[$this->currentObjectType];
|
||||
$state = $this->skipObject(true);
|
||||
$statusdatObject->runtimeState = & $state;
|
||||
$name = $this->getObjectIdentifier($statusdatObject);
|
||||
|
||||
if (!isset($base[$name])) {
|
||||
throw new ParsingException(
|
||||
"Unknown object $name " . $this->currentObjectType . ' - '
|
||||
. print_r(
|
||||
$statusdatObject,
|
||||
true
|
||||
)
|
||||
. "\n" . print_r($base, true)
|
||||
);
|
||||
}
|
||||
$type = substr($this->currentStateType, strlen($objectType));
|
||||
|
||||
if ($type == 'status') {
|
||||
// directly set the status to the status field of the given object
|
||||
$base[$name]->status = & $statusdatObject;
|
||||
} else {
|
||||
if (!isset($base[$name]->$type) || !in_array($base[$name]->$type, $this->overwrites)) {
|
||||
$base[$name]->$type = array();
|
||||
$this->overwrites[] = & $base[$name]->$type;
|
||||
}
|
||||
array_push($base[$name]->$type, $statusdatObject);
|
||||
$this->currentObjectType = $type;
|
||||
if (!isset($this->icingaState[$type])) {
|
||||
$this->icingaState[$type] = array();
|
||||
}
|
||||
$this->icingaState[$type][] = &$statusdatObject;
|
||||
$id = $this->getObjectIdentifier($statusdatObject);
|
||||
if ($id !== false && isset($this->icingaState[$objectType][$id])) {
|
||||
$statusdatObject->$objectType = $this->icingaState[$objectType][$id];
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the corresponding object type name for the given state
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getObjectTypeForState()
|
||||
{
|
||||
$pos = strpos($this->currentStateType, 'service');
|
||||
|
||||
if ($pos === false) {
|
||||
$pos = strpos($this->currentStateType, 'host');
|
||||
} else {
|
||||
$this->currentObjectType = 'service';
|
||||
return 'service';
|
||||
}
|
||||
|
||||
if ($pos === false) {
|
||||
return $this->currentStateType;
|
||||
} else {
|
||||
$this->currentObjectType = 'host';
|
||||
return 'host';
|
||||
}
|
||||
|
||||
return $this->currentObjectType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip the current object definition
|
||||
*
|
||||
* @param bool $returnString If true, the object string will be returned
|
||||
* @return string The skipped object if $returnString is true
|
||||
*/
|
||||
protected function skipObject($returnString = false)
|
||||
{
|
||||
if (!$returnString) {
|
||||
while (trim($this->file->fgets()) !== '}') {
|
||||
}
|
||||
return null;
|
||||
} else {
|
||||
$str = '';
|
||||
while (($val = trim($this->file->fgets())) !== '}') {
|
||||
$str .= $val . "\n";
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the given object in the icinga state
|
||||
*
|
||||
* @param object $object The monitoring object to register
|
||||
*/
|
||||
protected function registerObject(&$object)
|
||||
{
|
||||
|
||||
$name = $this->getObjectIdentifier($object);
|
||||
if ($name !== false) {
|
||||
$this->icingaState[$this->currentObjectType][$name] = &$object;
|
||||
}
|
||||
$this->registerObjectAsProperty($object);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the given object as a property in related objects
|
||||
*
|
||||
* This registers for example hosts underneath their hostgroup and vice cersa
|
||||
*
|
||||
* @param object $object The object to register as a property
|
||||
*/
|
||||
protected function registerObjectAsProperty(&$object)
|
||||
{
|
||||
if ($this->currentObjectType == 'service'
|
||||
|| $this->currentObjectType == 'host'
|
||||
|| $this->currentObjectType == 'contact') {
|
||||
return null;
|
||||
}
|
||||
$isService = strpos($this->currentObjectType, 'service') !== false;
|
||||
$isHost = strpos($this->currentObjectType, 'host') !== false;
|
||||
$isContact = strpos($this->currentObjectType, 'contact') !== false;
|
||||
$name = $this->getObjectIdentifier($object);
|
||||
|
||||
if ($isService === false && $isHost === false && $isContact === false) {
|
||||
// this would be error in the parser implementation
|
||||
return null;
|
||||
}
|
||||
$property = $this->currentObjectType;
|
||||
if ($isService) {
|
||||
$this->currentObjectType = 'service';
|
||||
$property = substr($property, strlen('service'));
|
||||
} elseif ($isHost) {
|
||||
$this->currentObjectType = 'host';
|
||||
$property = substr($property, strlen('host'));
|
||||
} elseif ($isContact) {
|
||||
$this->currentObjectType = 'contact';
|
||||
$property = substr($property, strlen('contact'));
|
||||
}
|
||||
|
||||
if (!isset($this->icingaState[$this->currentObjectType])) {
|
||||
return $this->deferRegistration($object, $this->currentObjectType . $property);
|
||||
}
|
||||
|
||||
// @TODO: Clean up, this differates between 1:n and 1:1 references
|
||||
if (strpos($property, 'group') !== false) {
|
||||
$sourceIdentifier = $this->getMembers($object);
|
||||
foreach ($sourceIdentifier as $id) {
|
||||
$source = $this->icingaState[$this->currentObjectType][$id];
|
||||
if (!isset($source->$property)) {
|
||||
$source->$property = array();
|
||||
}
|
||||
$type = $this->currentObjectType;
|
||||
if (!isset($object->$type)) {
|
||||
$object->$type = array();
|
||||
}
|
||||
// add the member to the group object
|
||||
array_push($object->$type, $source);
|
||||
// add the group to the member object
|
||||
array_push($source->$property, $name);
|
||||
}
|
||||
} else {
|
||||
$source = $this->icingaState[$this->currentObjectType][$this->getObjectIdentifier($object)];
|
||||
if (!isset($source->$property)) {
|
||||
$source->$property = array();
|
||||
}
|
||||
|
||||
array_push($source->$property, $object);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defer registration of the given object
|
||||
*
|
||||
* @param object $object The object to defer
|
||||
* @param String $objType The name of the object type
|
||||
*/
|
||||
protected function deferRegistration($object, $objType)
|
||||
{
|
||||
$this->deferred[] = array($object, $objType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process deferred objects
|
||||
*/
|
||||
protected function processDeferred()
|
||||
{
|
||||
foreach ($this->deferred as $obj) {
|
||||
$this->currentObjectType = $obj[1];
|
||||
$this->registerObjectAsProperty($obj[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the resolved members directive of an object
|
||||
*
|
||||
* @param object $object The object to get the members from
|
||||
* @return array An array of member names
|
||||
*/
|
||||
protected function getMembers(&$object)
|
||||
{
|
||||
if (!isset($object->members)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$members = explode(',', $object->members);
|
||||
|
||||
if ($this->currentObjectType == 'service') {
|
||||
$res = array();
|
||||
for ($i = 0; $i < count($members); $i += 2) {
|
||||
$res[] = $members[$i] . ';' . $members[$i + 1];
|
||||
}
|
||||
return $res;
|
||||
} else {
|
||||
return $members;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the unique name of the given object
|
||||
*
|
||||
* @param object $object The object to retrieve the name from
|
||||
* @return string The name of the object or null if no name can be retrieved
|
||||
*/
|
||||
protected function getObjectIdentifier(&$object)
|
||||
{
|
||||
if ($this->currentObjectType == 'contact') {
|
||||
return $object->contact_name;
|
||||
}
|
||||
|
||||
if ($this->currentObjectType == 'service') {
|
||||
return $object->host_name . ';' . $object->service_description;
|
||||
}
|
||||
$name = $this->currentObjectType . '_name';
|
||||
if (isset($object->{$name})) {
|
||||
return $object->{$name};
|
||||
}
|
||||
if (isset($object->service_description)) {
|
||||
return $object->host_name . ';' . $object->service_description;
|
||||
} elseif (isset($object->host_name)) {
|
||||
return $object->host_name;
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the internal state of the parser
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function getRuntimeState()
|
||||
{
|
||||
return $this->icingaState;
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Protocol\Statusdat;
|
||||
|
||||
class PrintableObject
|
||||
{
|
||||
public function __toString()
|
||||
{
|
||||
if (isset($this->contact_name)) {
|
||||
return $this->contact_name;
|
||||
} elseif (isset($this->service_description)) {
|
||||
return $this->service_description;
|
||||
} elseif (isset($this->host_name)) {
|
||||
return $this->host_name;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
}
|
|
@ -1,460 +0,0 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Protocol\Statusdat;
|
||||
|
||||
use Exception;
|
||||
use Icinga\Exception\ProgrammingError;
|
||||
use Icinga\Data\SimpleQuery;
|
||||
use Icinga\Protocol\Statusdat\View\MonitoringObjectList;
|
||||
use Icinga\Protocol\Statusdat\Query\IQueryPart;
|
||||
use Icinga\Exception\IcingaException;
|
||||
|
||||
/**
|
||||
* Base implementation for Statusdat queries.
|
||||
*/
|
||||
class Query extends SimpleQuery
|
||||
{
|
||||
/**
|
||||
* An array denoting valid targets by mapping the query target to
|
||||
* the 'define' directives found in the status.dat/objects.cache files
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $VALID_TARGETS = array(
|
||||
'hosts' => array('host'),
|
||||
'services' => array('service'),
|
||||
'downtimes' => array('downtime'),
|
||||
'groups' => array('hostgroup', 'servicegroup'),
|
||||
'hostgroups' => array('hostgroup'),
|
||||
'servicegroups' => array('servicegroup'),
|
||||
'comments' => array('comment'),
|
||||
'contacts' => array('contact'),
|
||||
'contactgroups' => array('contactgroup')
|
||||
);
|
||||
|
||||
/**
|
||||
* The current StatusDat query that will be applied upon calling fetchAll
|
||||
*
|
||||
* @var IQueryPart
|
||||
*/
|
||||
private $queryFilter = null;
|
||||
|
||||
/**
|
||||
* The current query source being used
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $source = '';
|
||||
|
||||
/**
|
||||
* An array containing all columns used for sorting
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $orderColumns = array();
|
||||
|
||||
/**
|
||||
* An array containig all columns used for (simple) grouping
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $groupColumns = array();
|
||||
|
||||
/**
|
||||
* An optional function callback to use for more specific grouping
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $groupByFn = null;
|
||||
|
||||
/**
|
||||
* The scope index for the callback function
|
||||
*/
|
||||
const FN_SCOPE = 0;
|
||||
|
||||
/**
|
||||
* The name index for the callback function
|
||||
*/
|
||||
const FN_NAME = 1;
|
||||
|
||||
/**
|
||||
* Return true if columns are set for this query
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasColumns()
|
||||
{
|
||||
$columns = $this->getColumns();
|
||||
return !empty($columns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the status.dat specific IQueryPart filter to use
|
||||
*
|
||||
* @param IQueryPart $filter
|
||||
*/
|
||||
public function setQueryFilter($filter)
|
||||
{
|
||||
$this->queryFilter = $filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Order the query result by the given columns
|
||||
*
|
||||
* @param String|array $columns An array of columns to order by
|
||||
* @param String $dir The direction (asc or desc) in string form
|
||||
*
|
||||
* @return $this Fluent interface
|
||||
*/
|
||||
public function order($columns, $dir = null, $isFunction = false)
|
||||
{
|
||||
if ($dir && strtolower($dir) == 'desc') {
|
||||
$dir = self::SORT_DESC;
|
||||
} else {
|
||||
$dir = self::SORT_ASC;
|
||||
}
|
||||
if (!is_array($columns)) {
|
||||
$columns = array($columns);
|
||||
}
|
||||
|
||||
foreach ($columns as $col) {
|
||||
if (($pos = strpos($col, ' ')) !== false) {
|
||||
$dir = strtoupper(substr($col, $pos + 1));
|
||||
if ($dir === 'DESC') {
|
||||
$dir = self::SORT_DESC;
|
||||
} else {
|
||||
$dir = self::SORT_ASC;
|
||||
}
|
||||
$col = substr($col, 0, $pos);
|
||||
} else {
|
||||
$col = $col;
|
||||
}
|
||||
|
||||
$this->orderColumns[] = array($col, $dir);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Order the query result using the callback to retrieve values for items
|
||||
*
|
||||
* @param array $columns A scope, function array to use for retrieving the values when ordering
|
||||
* @param String $dir The direction (asc or desc) in string form
|
||||
*
|
||||
* @return $this Fluent interface
|
||||
*/
|
||||
public function orderByFn(array $callBack, $dir = null)
|
||||
{
|
||||
if ($dir && strtolower($dir) == 'desc') {
|
||||
$dir = self::SORT_DESC;
|
||||
} else {
|
||||
$dir = self::SORT_ASC;
|
||||
}
|
||||
$this->orderColumns[] = array($callBack, $dir);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set the query target
|
||||
*
|
||||
* @param String $table The table/target to select the query from
|
||||
* @param array $columns An array of attributes to use (required for fetchPairs())
|
||||
*
|
||||
* @return $this Fluent interface
|
||||
* @throws IcingaException If the target is unknonw
|
||||
*/
|
||||
public function from($table, array $attributes = null)
|
||||
{
|
||||
if (!$this->getColumns() && $attributes) {
|
||||
$this->setColumns($attributes);
|
||||
}
|
||||
if (isset(self::$VALID_TARGETS[$table])) {
|
||||
$this->source = $table;
|
||||
} else {
|
||||
throw new IcingaException(
|
||||
'Unknown from target for status.dat :%s',
|
||||
$table
|
||||
);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an index of all objects matching the filter of this query
|
||||
*
|
||||
* This index will be used for ordering, grouping and limiting
|
||||
*/
|
||||
private function getFilteredIndices($classType = '\Icinga\Protocol\Statusdat\Query\Group')
|
||||
{
|
||||
$baseGroup = $this->queryFilter;
|
||||
$state = $this->ds->getState();
|
||||
$result = array();
|
||||
$source = self::$VALID_TARGETS[$this->source];
|
||||
|
||||
foreach ($source as $target) {
|
||||
|
||||
if (! isset($state[$target])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$indexes = array_keys($state[$target]);
|
||||
if ($baseGroup) {
|
||||
$baseGroup->setQuery($this);
|
||||
$idx = array_keys($state[$target]);
|
||||
$indexes = $baseGroup->filter($state[$target], $idx);
|
||||
}
|
||||
if (!isset($result[$target])) {
|
||||
$result[$target] = $indexes;
|
||||
} else {
|
||||
array_merge($result[$target], $indexes);
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Order the given result set
|
||||
*
|
||||
* @param array $indices The result set of the query that should be ordered
|
||||
*/
|
||||
private function orderIndices(array &$indices)
|
||||
{
|
||||
if (!empty($this->orderColumns)) {
|
||||
foreach ($indices as $type => &$subindices) {
|
||||
$this->currentType = $type;
|
||||
usort($subindices, array($this, 'orderResult'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a query
|
||||
*
|
||||
* This is just a dummy function to allow a more convenient syntax
|
||||
*
|
||||
* @return self Fluent interface
|
||||
*/
|
||||
public function select()
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Order implementation called by usort
|
||||
*
|
||||
* @param String $a The left object index
|
||||
* @param Strinv $b The right object index
|
||||
* @return int 0, 1 or -1, see usort for detail
|
||||
*/
|
||||
private function orderResult($a, $b)
|
||||
{
|
||||
$o1 = $this->ds->getObjectByName($this->currentType, $a);
|
||||
$o2 = $this->ds->getObjectByName($this->currentType, $b);
|
||||
$result = 0;
|
||||
|
||||
foreach ($this->orderColumns as &$col) {
|
||||
if (is_array($col[0])) {
|
||||
// sort by function
|
||||
$result += $col[1] * strnatcasecmp(
|
||||
$col[0][0]->$col[0][1]($o1),
|
||||
$col[0][0]->$col[0][1]($o2)
|
||||
);
|
||||
} else {
|
||||
$result += $col[1] * strnatcasecmp($o1->{$col[0]}, $o2->{$col[0]});
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Limit the given resultset
|
||||
*
|
||||
* @param array $indices The filtered, ordered indices
|
||||
*/
|
||||
private function limitIndices(array &$indices)
|
||||
{
|
||||
foreach ($indices as $type => $subindices) {
|
||||
$indices[$type] = array_slice($subindices, $this->getOffset(), $this->getLimit());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the given function for grouping the result
|
||||
*
|
||||
* @param String $fn The function to use for grouping
|
||||
* @param Object $scope An optional scope to use instead of $this
|
||||
*
|
||||
* @return self Fluent interface
|
||||
*/
|
||||
public function groupByFunction($fn, $scope = null)
|
||||
{
|
||||
$this->groupByFn = array($scope ? $scope : $this, $fn);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Group by the given column
|
||||
*
|
||||
* @param array|string $columns The columns to use for grouping
|
||||
* @return self Fluent interface
|
||||
* @see Query::columnGroupFn() The implementation used for grouping
|
||||
*/
|
||||
public function groupByColumns($columns)
|
||||
{
|
||||
if (!is_array($columns)) {
|
||||
$columns = array($columns);
|
||||
}
|
||||
$this->groupColumns = $columns;
|
||||
$this->groupByFn = array($this, 'columnGroupFn');
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The internal handler function used by the group function
|
||||
*
|
||||
* @param array $indices The indices to group
|
||||
* @return array The grouped result set
|
||||
*/
|
||||
private function columnGroupFn(array &$indices)
|
||||
{
|
||||
$cols = $this->groupColumns;
|
||||
$result = array();
|
||||
foreach ($indices as $type => $subindices) {
|
||||
foreach ($subindices as $objectIndex) {
|
||||
$r = $this->ds->getObjectByName($type, $objectIndex);
|
||||
$hash = '';
|
||||
$cols = array();
|
||||
foreach ($this->groupColumns as $col) {
|
||||
$hash = md5($hash . $r->$col);
|
||||
$cols[$col] = $r->$col;
|
||||
}
|
||||
if (!isset($result[$hash])) {
|
||||
$result[$hash] = (object)array(
|
||||
'columns' => (object)$cols,
|
||||
'count' => 0
|
||||
);
|
||||
}
|
||||
$result[$hash]->count++;
|
||||
}
|
||||
}
|
||||
return array_values($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query Filter, Order, Group, Limit and return the result set
|
||||
*
|
||||
* @return array The resultset matching this query
|
||||
*/
|
||||
public function getResult()
|
||||
{
|
||||
$indices = $this->getFilteredIndices();
|
||||
$this->orderIndices($indices);
|
||||
if ($this->groupByFn) {
|
||||
$scope = $this->groupByFn[self::FN_SCOPE];
|
||||
$fn = $this->groupByFn[self::FN_NAME];
|
||||
|
||||
return $scope->$fn($indices);
|
||||
}
|
||||
|
||||
$this->limitIndices($indices);
|
||||
|
||||
$result = array();
|
||||
$state = $this->ds->getState();
|
||||
|
||||
foreach ($indices as $type => $subindices) {
|
||||
foreach ($subindices as $index) {
|
||||
$result[] = & $state[$type][$index];
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Apply all filters of this filterable on the datasource
|
||||
*/
|
||||
public function applyFilter()
|
||||
{
|
||||
$parser = new TreeToStatusdatQueryParser();
|
||||
if ($this->getFilter()) {
|
||||
$query = $parser->treeToQuery($this->getFilter(), $this);
|
||||
$this->setQueryFilter($query);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Return only the first row fetched from the result set
|
||||
*
|
||||
* @return MonitoringObjectList The monitoring object matching this query
|
||||
*/
|
||||
public function fetchRow()
|
||||
{
|
||||
$rs = $this->fetchAll();
|
||||
$rs->rewind();
|
||||
return $rs->current();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the result as an associative array using the first column as the key and the second as the value
|
||||
*
|
||||
* @return array An associative array with the result
|
||||
* @throws IcingaException If no attributes are defined
|
||||
*/
|
||||
public function fetchPairs()
|
||||
{
|
||||
$result = array();
|
||||
if (count($this->getColumns()) < 2) {
|
||||
throw new IcingaException(
|
||||
'Status.dat "fetchPairs()" query expects at least columns to be set in the query expression'
|
||||
);
|
||||
}
|
||||
$attributes = $this->getColumns();
|
||||
|
||||
$param1 = $attributes[0];
|
||||
$param2 = $attributes[1];
|
||||
foreach ($this->fetchAll() as $resultList) {
|
||||
$result[$resultList->$param1] = $resultList->$param2;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch all results
|
||||
*
|
||||
* @return MonitoringObjectList An MonitoringObjectList wrapping the given resultset
|
||||
*/
|
||||
public function fetchAll()
|
||||
{
|
||||
$this->applyFilter();
|
||||
if (!isset($this->cursor)) {
|
||||
$result = $this->getResult();
|
||||
$this->cursor = new MonitoringObjectList($result, $this);
|
||||
}
|
||||
return $this->cursor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value of the first column for the first row fetched from the result set
|
||||
*/
|
||||
public function fetchOne()
|
||||
{
|
||||
throw new ProgrammingError('Statusdat/Query::fetchOne() is not implemented yet');
|
||||
}
|
||||
|
||||
/**
|
||||
* Count the number of results
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
$q = clone $this;
|
||||
$q->limit(null, null);
|
||||
return count($q->fetchAll());
|
||||
}
|
||||
}
|
|
@ -1,415 +0,0 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Protocol\Statusdat\Query;
|
||||
|
||||
use Icinga\Exception\IcingaException;
|
||||
|
||||
class Expression implements IQueryPart
|
||||
{
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const ENC_NUMERIC = 0;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const ENC_SET = 0;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const ENC_STRING = 0;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $expression;
|
||||
|
||||
/**
|
||||
* @var null
|
||||
*/
|
||||
private $field = null;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $basedata = array();
|
||||
|
||||
/**
|
||||
* @var null
|
||||
*/
|
||||
private $function = null;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $value = "";
|
||||
|
||||
/**
|
||||
* @var null
|
||||
*/
|
||||
private $operator = null;
|
||||
|
||||
/**
|
||||
* Optional query information
|
||||
*
|
||||
* @var null
|
||||
*/
|
||||
private $query = null;
|
||||
|
||||
/**
|
||||
* @var null
|
||||
*/
|
||||
private $name = null;
|
||||
|
||||
/**
|
||||
* @var null
|
||||
*/
|
||||
public $CB = null;
|
||||
|
||||
/**
|
||||
* @param $token
|
||||
* @throws IcingaException
|
||||
*/
|
||||
private function getOperatorType($token)
|
||||
{
|
||||
switch (strtoupper($token)) {
|
||||
case ">":
|
||||
$this->CB = "isGreater";
|
||||
break;
|
||||
case "<":
|
||||
$this->CB = "isLess";
|
||||
break;
|
||||
case ">=":
|
||||
$this->CB = "isGreaterEq";
|
||||
break;
|
||||
case "<=":
|
||||
$this->CB = "isLessEq";
|
||||
break;
|
||||
case "=":
|
||||
$this->CB = "isEqual";
|
||||
break;
|
||||
case "LIKE":
|
||||
$this->CB = "isLike";
|
||||
break;
|
||||
case "NOT_LIKE":
|
||||
$this->CB = "isNotLike";
|
||||
break;
|
||||
case "!=":
|
||||
$this->CB = "isNotEqual";
|
||||
break;
|
||||
case "IN":
|
||||
$this->CB = "isIn";
|
||||
break;
|
||||
case "NOT_IN":
|
||||
$this->CB = "isNotIn";
|
||||
break;
|
||||
default:
|
||||
throw new IcingaException(
|
||||
'Unknown operator %s in expression %s !',
|
||||
$token,
|
||||
$this->expression
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $tokens
|
||||
* @return mixed
|
||||
*/
|
||||
private function extractAggregationFunction(&$tokens)
|
||||
{
|
||||
$token = $tokens[0];
|
||||
$value = array();
|
||||
if (preg_match("/COUNT\{(.*)\}/", $token, $value) == false) {
|
||||
return $token;
|
||||
}
|
||||
$this->function = "count";
|
||||
$tokens[0] = $value[1];
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $values
|
||||
*/
|
||||
private function parseExpression(&$values)
|
||||
{
|
||||
$tokenized = preg_split("/ +/", trim($this->expression), 3);
|
||||
$this->extractAggregationFunction($tokenized);
|
||||
if (count($tokenized) != 3) {
|
||||
echo(
|
||||
"Currently statusdat query expressions must be in "
|
||||
. "the format FIELD OPERATOR ? or FIELD OPERATOR :value_name"
|
||||
);
|
||||
}
|
||||
|
||||
$this->fields = explode(".", trim($tokenized[0]));
|
||||
$this->field = $this->fields[count($this->fields) - 1];
|
||||
|
||||
$this->getOperatorType(trim($tokenized[1]));
|
||||
$tokenized[2] = trim($tokenized[2]);
|
||||
|
||||
if ($tokenized[2][0] === ":") {
|
||||
$this->name = substr($tokenized, 1);
|
||||
$this->value = $values[$this->name];
|
||||
} else {
|
||||
if ($tokenized[2] === "?") {
|
||||
$this->value = array_shift($values);
|
||||
} else {
|
||||
$this->value = trim($tokenized[2]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $expression
|
||||
* @param $values
|
||||
* @return $this
|
||||
*/
|
||||
public function fromString($expression, &$values)
|
||||
{
|
||||
$this->expression = $expression;
|
||||
$this->parseExpression($values);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null $expression
|
||||
* @param array $values
|
||||
*/
|
||||
public function __construct($expression = null, &$values = array())
|
||||
{
|
||||
if ($expression) {
|
||||
if (!is_array($values)) {
|
||||
$values = array($values);
|
||||
}
|
||||
$this->fromString($expression, $values);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $base
|
||||
* @param array $idx
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function filter(array &$base, &$idx = array())
|
||||
{
|
||||
if (!$idx) {
|
||||
$idx = array_keys($base);
|
||||
}
|
||||
$this->basedata = $base;
|
||||
return array_filter($idx, array($this, "filterFn"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getValue()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null
|
||||
*/
|
||||
public function getField()
|
||||
{
|
||||
return $this->field;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $idx
|
||||
* @return bool
|
||||
*/
|
||||
protected function filterFn($idx)
|
||||
{
|
||||
$values = $this->getFieldValues($idx);
|
||||
|
||||
if ($values === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->CB == "isIn" || $this->CB == "isNotIn") {
|
||||
$cmpValues = is_array($this->value) ? $this->value : array($this->value);
|
||||
foreach ($cmpValues as $cmpValue) {
|
||||
$this->value = $cmpValue;
|
||||
foreach ($values as $value) {
|
||||
if ($this->CB == "isIn" && $this->isLike($value)) {
|
||||
$this->value = $cmpValues;
|
||||
return true;
|
||||
} elseif ($this->CB == "isNotIn" && $this->isNotLike($value)) {
|
||||
$this->value = $cmpValues;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->value = $cmpValues;
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->function) {
|
||||
$values = call_user_func($this->function, $values);
|
||||
if (!is_array($values)) {
|
||||
$values = array($values);
|
||||
}
|
||||
}
|
||||
foreach ($values as $val) {
|
||||
|
||||
if (!is_string($val) && !is_numeric($val) && is_object($val)) {
|
||||
if (isset($val->service_description)) {
|
||||
$val = $val->service_description;
|
||||
} elseif (isset($val->host_name)) {
|
||||
$val = $val->host_name;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if ($this->{$this->CB}($val)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $idx
|
||||
* @return array
|
||||
*/
|
||||
private function getFieldValues($idx)
|
||||
{
|
||||
$res = $this->basedata[$idx];
|
||||
|
||||
foreach ($this->fields as $field) {
|
||||
if (!is_array($res)) {
|
||||
if ($this->query) {
|
||||
$res = $this->query->get($res, $field);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($res->$field)) {
|
||||
$res = array();
|
||||
break;
|
||||
}
|
||||
$res = $res->$field;
|
||||
continue;
|
||||
}
|
||||
|
||||
// it can be that an element contains more than one value, like it
|
||||
// happens when using comments, in this case we have to create a new
|
||||
// array that contains the values/objects we're searching
|
||||
$swap = array();
|
||||
foreach ($res as $sub) {
|
||||
if ($this->query) {
|
||||
$swap[] = $this->query->get($sub, $field);
|
||||
continue;
|
||||
}
|
||||
if (!isset($sub->$field)) {
|
||||
continue;
|
||||
}
|
||||
if (!is_array($sub->$field)) {
|
||||
$swap[] = $sub->$field;
|
||||
} else {
|
||||
$swap = array_merge($swap, $sub->$field);
|
||||
}
|
||||
}
|
||||
$res = $swap;
|
||||
}
|
||||
if (!is_array($res)) {
|
||||
return array($res);
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @return bool
|
||||
*/
|
||||
public function isGreater($value)
|
||||
{
|
||||
return $value > $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @return bool
|
||||
*/
|
||||
public function isLess($value)
|
||||
{
|
||||
return $value < $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @return bool
|
||||
*/
|
||||
public function isLike($value)
|
||||
{
|
||||
return preg_match("/^" . str_replace("%", ".*", $this->value) . "$/", $value) ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @return bool
|
||||
*/
|
||||
public function isNotLike($value)
|
||||
{
|
||||
return !preg_match("/^" . str_replace("%", ".*", $this->value) . "$/", $value) ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @return bool
|
||||
*/
|
||||
public function isEqual($value)
|
||||
{
|
||||
if (!is_numeric($value)) {
|
||||
return strtolower($value) == strtolower($this->value);
|
||||
}
|
||||
return $value == $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @return bool
|
||||
*/
|
||||
public function isNotEqual($value)
|
||||
{
|
||||
return $value != $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @return bool
|
||||
*/
|
||||
public function isGreaterEq($value)
|
||||
{
|
||||
return $value >= $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @return bool
|
||||
*/
|
||||
public function isLessEq($value)
|
||||
{
|
||||
return $value <= $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add additional information about the query this filter belongs to
|
||||
*
|
||||
* @param $query
|
||||
* @return mixed
|
||||
*/
|
||||
public function setQuery($query)
|
||||
{
|
||||
$this->query = $query;
|
||||
}
|
||||
}
|
|
@ -1,397 +0,0 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Protocol\Statusdat\Query;
|
||||
|
||||
use Icinga\Exception\IcingaException;
|
||||
|
||||
/**
|
||||
* Class Group
|
||||
* @package Icinga\Protocol\Statusdat\Query
|
||||
*/
|
||||
class Group implements IQueryPart
|
||||
{
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const GROUP_BEGIN = "(";
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const GROUP_END = ")";
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const CONJUNCTION_AND = "AND ";
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const CONJUNCTION_OR = "OR ";
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const EXPRESSION = 0;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const EOF = -1;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const TYPE_AND = "AND";
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const TYPE_OR = "OR";
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $items = array();
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $parsePos = 0;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $expression = "";
|
||||
|
||||
/**
|
||||
* @var null
|
||||
*/
|
||||
private $expressionClass = null;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $type = "";
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $subExpressionStart = 0;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $subExpressionLength = 0;
|
||||
|
||||
/**
|
||||
* Optional query to use
|
||||
*
|
||||
* @var Query
|
||||
*/
|
||||
private $query = null;
|
||||
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
private $value;
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
*/
|
||||
public function setValue($value)
|
||||
{
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getItems()
|
||||
{
|
||||
return $this->items;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return $this->type ? $this->type : self::TYPE_AND;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $type
|
||||
*/
|
||||
public function setType($type)
|
||||
{
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws IcingaException
|
||||
*/
|
||||
private function tokenize()
|
||||
{
|
||||
$token = 0;
|
||||
$subgroupCount = 0;
|
||||
while ($token != self::EOF) {
|
||||
|
||||
$token = $this->getNextToken();
|
||||
|
||||
if ($token === self::GROUP_BEGIN) {
|
||||
|
||||
/**
|
||||
* check if this is a nested group, if so then it's
|
||||
* considered part of the subexpression
|
||||
*/
|
||||
if ($subgroupCount == 0) {
|
||||
$this->startNewSubExpression();
|
||||
}
|
||||
$subgroupCount++;
|
||||
continue;
|
||||
}
|
||||
if ($token === self::GROUP_END) {
|
||||
if ($subgroupCount < 1) {
|
||||
throw new IcingaException(
|
||||
'Invalid Query: unexpected \')\' at pos %s',
|
||||
$this->parsePos
|
||||
);
|
||||
}
|
||||
$subgroupCount--;
|
||||
/*
|
||||
* check if this is a nested group, if so then it's
|
||||
* considered part of the subexpression
|
||||
*/
|
||||
if ($subgroupCount == 0) {
|
||||
$this->addSubgroupFromExpression();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($token === self::CONJUNCTION_AND && $subgroupCount == 0) {
|
||||
$this->startNewSubExpression();
|
||||
if ($this->type != self::TYPE_AND && $this->type != "") {
|
||||
$this->createImplicitGroup(self::TYPE_AND);
|
||||
break;
|
||||
} else {
|
||||
$this->type = self::TYPE_AND;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if ($token === self::CONJUNCTION_OR && $subgroupCount == 0) {
|
||||
$this->startNewSubExpression();
|
||||
if ($this->type != self::TYPE_OR && $this->type != "") {
|
||||
$this->createImplicitGroup(self::TYPE_OR);
|
||||
break;
|
||||
} else {
|
||||
|
||||
$this->type = self::TYPE_OR;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->subExpressionLength = $this->parsePos - $this->subExpressionStart;
|
||||
}
|
||||
if ($subgroupCount > 0) {
|
||||
throw new IcingaException('Unexpected end of query, are you missing a parenthesis?');
|
||||
}
|
||||
|
||||
$this->startNewSubExpression();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $type
|
||||
*/
|
||||
private function createImplicitGroup($type)
|
||||
{
|
||||
$group = new Group();
|
||||
$group->setType($type);
|
||||
$group->addItem(array_pop($this->items));
|
||||
|
||||
$group->fromString(substr($this->expression, $this->parsePos), $this->value, $this->expressionClass);
|
||||
$this->items[] = $group;
|
||||
$this->parsePos = strlen($this->expression);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function startNewSubExpression()
|
||||
{
|
||||
if ($this->getCurrentSubExpression() != "") {
|
||||
if (!$this->expressionClass) {
|
||||
$this->items[] = new Expression($this->getCurrentSubExpression(), $this->value);
|
||||
} else {
|
||||
$this->items[] = new $this->expressionClass($this->getCurrentSubExpression(), $this->value);
|
||||
}
|
||||
}
|
||||
|
||||
$this->subExpressionStart = $this->parsePos;
|
||||
$this->subExpressionLength = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function getCurrentSubExpression()
|
||||
{
|
||||
|
||||
return substr($this->expression, $this->subExpressionStart, $this->subExpressionLength);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function addSubgroupFromExpression()
|
||||
{
|
||||
|
||||
if (!$this->expressionClass) {
|
||||
$this->items[] = new Group($this->getCurrentSubExpression(), $this->value);
|
||||
} else {
|
||||
$group = new Group();
|
||||
$group->fromString($this->getCurrentSubExpression(), $this->value, $this->expressionClass);
|
||||
$this->items[] = $group;
|
||||
}
|
||||
$this->subExpressionStart = $this->parsePos;
|
||||
$this->subExpressionLength = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function isEOF()
|
||||
{
|
||||
if ($this->parsePos >= strlen($this->expression)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|string
|
||||
*/
|
||||
private function getNextToken()
|
||||
{
|
||||
if ($this->isEOF()) {
|
||||
return self::EOF;
|
||||
}
|
||||
|
||||
// skip whitespaces
|
||||
while ($this->expression[$this->parsePos] == " ") {
|
||||
$this->parsePos++;
|
||||
if ($this->isEOF()) {
|
||||
return self::EOF;
|
||||
}
|
||||
}
|
||||
if ($this->expression[$this->parsePos] == self::GROUP_BEGIN) {
|
||||
$this->parsePos++;
|
||||
return self::GROUP_BEGIN;
|
||||
}
|
||||
if ($this->expression[$this->parsePos] == self::GROUP_END) {
|
||||
$this->parsePos++;
|
||||
return self::GROUP_END;
|
||||
}
|
||||
if (substr_compare(
|
||||
$this->expression,
|
||||
self::CONJUNCTION_AND,
|
||||
$this->parsePos,
|
||||
strlen(self::CONJUNCTION_AND),
|
||||
true
|
||||
) === 0) {
|
||||
$this->parsePos += strlen(self::CONJUNCTION_AND);
|
||||
return self::CONJUNCTION_AND;
|
||||
}
|
||||
if (substr_compare(
|
||||
$this->expression,
|
||||
self::CONJUNCTION_OR,
|
||||
$this->parsePos,
|
||||
strlen(self::CONJUNCTION_OR),
|
||||
true
|
||||
) === 0) {
|
||||
$this->parsePos += strlen(self::CONJUNCTION_OR);
|
||||
return self::CONJUNCTION_OR;
|
||||
}
|
||||
$this->parsePos++;
|
||||
return self::EXPRESSION;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $ex
|
||||
* @return $this
|
||||
*/
|
||||
public function addItem($ex)
|
||||
{
|
||||
$this->items[] = $ex;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $expression
|
||||
* @param array $value
|
||||
* @param null $expressionClass
|
||||
* @return $this
|
||||
*/
|
||||
public function fromString($expression, &$value = array(), $expressionClass = null)
|
||||
{
|
||||
$this->expression = $expression;
|
||||
$this->value = & $value;
|
||||
$this->expressionClass = $expressionClass;
|
||||
|
||||
$this->tokenize();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null $expression
|
||||
* @param array $value
|
||||
*/
|
||||
public function __construct($expression = null, &$value = array())
|
||||
{
|
||||
if ($expression) {
|
||||
$this->fromString($expression, $value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $base
|
||||
* @param null $idx
|
||||
* @return array|null
|
||||
*/
|
||||
public function filter(array &$base, &$idx = null)
|
||||
{
|
||||
if ($this->type == self::TYPE_OR) {
|
||||
$idx = array();
|
||||
foreach ($this->items as &$subFilter) {
|
||||
$baseKeys = array_keys($base);
|
||||
$subFilter->setQuery($this->query);
|
||||
$idx += $subFilter->filter($base, $baseKeys);
|
||||
}
|
||||
} else {
|
||||
if (!$idx) {
|
||||
$idx = array_keys($base);
|
||||
}
|
||||
foreach ($this->items as $subFilter) {
|
||||
$subFilter->setQuery($this->query);
|
||||
$idx = array_intersect($idx, $subFilter->filter($base, $idx));
|
||||
}
|
||||
}
|
||||
|
||||
return $idx;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add additional information about the query this filter belongs to
|
||||
*
|
||||
* @param $query
|
||||
* @return mixed
|
||||
*/
|
||||
public function setQuery($query)
|
||||
{
|
||||
$this->query = $query;
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Protocol\Statusdat\Query;
|
||||
|
||||
/**
|
||||
* Class IQueryPart
|
||||
* @package Icinga\Protocol\Statusdat\Query
|
||||
*/
|
||||
interface IQueryPart
|
||||
{
|
||||
/**
|
||||
* Create a new query part with an optional expression to be parse
|
||||
*
|
||||
* @param string $expression An optional expression string to use
|
||||
* @param array $value The values fot the optional expression
|
||||
*/
|
||||
public function __construct($expression = null, &$value = array());
|
||||
|
||||
/**
|
||||
* Filter the given resultset
|
||||
*
|
||||
* @param array $base The resultset to use for filtering
|
||||
* @param array $idx An optional array containing prefiltered indices
|
||||
*/
|
||||
public function filter(array &$base, &$idx = null);
|
||||
|
||||
/**
|
||||
* Add additional information about the query this filter belongs to
|
||||
*
|
||||
* @param $query
|
||||
* @return mixed
|
||||
*/
|
||||
public function setQuery($query);
|
||||
}
|
|
@ -1,330 +0,0 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Protocol\Statusdat;
|
||||
|
||||
use Icinga\Util\File;
|
||||
use Icinga\Logger\Logger;
|
||||
use Icinga\Data\Selectable;
|
||||
use Icinga\Exception\ConfigurationError;
|
||||
|
||||
/**
|
||||
* Class Reader
|
||||
* @package Icinga\Protocol\Statusdat
|
||||
*/
|
||||
class Reader implements IReader, Selectable
|
||||
{
|
||||
/**
|
||||
* The default lifetime of the cache in milliseconds
|
||||
*/
|
||||
const DEFAULT_CACHE_LIFETIME = 30;
|
||||
|
||||
/**
|
||||
* The folder for the statusdat cache
|
||||
*/
|
||||
const STATUSDAT_DEFAULT_CACHE_PATH = '/tmp';
|
||||
|
||||
/**
|
||||
* The last state from the cache
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $lastState;
|
||||
|
||||
/**
|
||||
* True when this reader has already acquired the current runtime state (i.e. Status.dat)
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $hasRuntimeState = false;
|
||||
|
||||
/**
|
||||
* The representation of the object.cache file
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $objectCache ;
|
||||
|
||||
/**
|
||||
* The representation of the status.dat file
|
||||
* @var array
|
||||
*/
|
||||
private $statusCache;
|
||||
|
||||
/**
|
||||
* True when the icinga state differs from the cache
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $newState = false;
|
||||
|
||||
/**
|
||||
* The Parser object to use for parsing
|
||||
*
|
||||
* @var Parser
|
||||
*/
|
||||
private $parser;
|
||||
|
||||
/**
|
||||
* Whether to disable the cache
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $noCache;
|
||||
|
||||
/**
|
||||
* Create a new Reader from the given configuraion
|
||||
*
|
||||
* @param Zend_Config $config The configuration to read the status.dat information from
|
||||
* @param Parser $parser The parser to use (for testing)
|
||||
* @param bool $noCache Whether to disable the cache
|
||||
*/
|
||||
public function __construct($config = \Zend_Config, $parser = null, $noCache = false)
|
||||
{
|
||||
$this->noCache = $noCache;
|
||||
if (isset($config->no_cache)) {
|
||||
$this->noCache = $config->no_cache;
|
||||
}
|
||||
$this->config = $config;
|
||||
$this->parser = $parser;
|
||||
|
||||
if (!$this->noCache) {
|
||||
$this->cache = $this->initializeCaches($config);
|
||||
if ($this->fromCache()) {
|
||||
$this->createHostServiceConnections();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$this->lastState) {
|
||||
$this->parseObjectsCacheFile();
|
||||
}
|
||||
if (!$this->hasRuntimeState) {
|
||||
|
||||
}
|
||||
$this->parseStatusDatFile();
|
||||
if (!$noCache && $this->newState) {
|
||||
$this->statusCache->save($this->parser->getRuntimeState(), 'object' . md5($this->config->object_file));
|
||||
}
|
||||
$this->createHostServiceConnections();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the internal caches if enabled
|
||||
*
|
||||
* @throws ConfigurationError
|
||||
*/
|
||||
private function initializeCaches()
|
||||
{
|
||||
$defaultCachePath = self::STATUSDAT_DEFAULT_CACHE_PATH;
|
||||
$cachePath = $this->config->get('cache_path', $defaultCachePath);
|
||||
$maxCacheLifetime = intval($this->config->get('cache_path', self::DEFAULT_CACHE_LIFETIME));
|
||||
$cachingEnabled = true;
|
||||
if (!is_writeable($cachePath)) {
|
||||
Logger::warning(
|
||||
'Can\'t cache Status.dat backend; make sure cachepath %s is writable by the web user. '
|
||||
. 'Caching is now disabled',
|
||||
$cachePath
|
||||
);
|
||||
$cachePath = null;
|
||||
}
|
||||
$backendOptions = array(
|
||||
'cache_dir' => $cachePath
|
||||
);
|
||||
// the object cache might exist for months and is still valid
|
||||
$this->objectCache = $this->initCache($this->config->object_file, $backendOptions, null, $cachingEnabled);
|
||||
$this->statusCache = $this->initCache(
|
||||
$this->config->status_file,
|
||||
$backendOptions,
|
||||
$maxCacheLifetime,
|
||||
$cachingEnabled
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Init the Cache backend in Zend
|
||||
*
|
||||
* @param String $file The file to use as the cache master file
|
||||
* @param Zend_Config $backend The backend configuration to use
|
||||
* @param integer $lifetime The lifetime of the cache
|
||||
*
|
||||
* @return \Zend_Cache_Core|\Zend_Cache_Frontend
|
||||
*/
|
||||
private function initCache($file, $backendConfig, $lifetime)
|
||||
{
|
||||
$frontendOptions = array(
|
||||
'lifetime' => $lifetime,
|
||||
'automatic_serialization' => true,
|
||||
'master_files' => array($file)
|
||||
);
|
||||
return \Zend_Cache::factory('Core', 'File', $frontendOptions, $backendConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the current cache state
|
||||
*
|
||||
* @return bool True if the state is the same as the icinga state
|
||||
*/
|
||||
private function fromCache()
|
||||
{
|
||||
if (!$this->readObjectsCache()) {
|
||||
$this->newState = true;
|
||||
return false;
|
||||
}
|
||||
if (!$this->readStatusCache()) {
|
||||
$this->newState = true;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the object.cache file from the Zend_Cache backend
|
||||
*
|
||||
* @return bool True if the file could be loaded from cache
|
||||
*/
|
||||
private function readObjectsCache()
|
||||
{
|
||||
$this->lastState = $this->objectCache->load('object' . md5($this->config->object_file));
|
||||
if ($this->lastState == false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the status.dat file from the Zend_Cache backend
|
||||
*
|
||||
* @return bool True if the file could be loaded from cache
|
||||
*/
|
||||
private function readStatusCache()
|
||||
{
|
||||
if (!isset($this->stateCache)) {
|
||||
return true;
|
||||
}
|
||||
$statusInfo = $this->stateCache->load('state' . md5($this->config->status_file));
|
||||
if ($statusInfo == false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->hasRuntimeState = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Take the status.dat and objects.cache and connect all services to hosts
|
||||
*
|
||||
*/
|
||||
private function createHostServiceConnections()
|
||||
{
|
||||
if (!isset($this->lastState["service"])) {
|
||||
return;
|
||||
}
|
||||
foreach ($this->lastState["host"] as &$host) {
|
||||
$host->host = $host;
|
||||
}
|
||||
foreach ($this->lastState["service"] as &$service) {
|
||||
$service->service = &$service; // allow easier querying
|
||||
$host = &$this->lastState["host"][$service->host_name];
|
||||
if (!isset($host->services)) {
|
||||
$host->services = array();
|
||||
}
|
||||
$host->services[$service->service_description] = & $service;
|
||||
$service->host = & $host;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the object.cache file and update the current state
|
||||
*
|
||||
* @throws ConfigurationError If the object.cache couldn't be read
|
||||
*/
|
||||
private function parseObjectsCacheFile()
|
||||
{
|
||||
if (!is_readable($this->config->object_file)) {
|
||||
throw new ConfigurationError(
|
||||
'Can\'t read object-file "%s", check your configuration',
|
||||
$this->config->object_file
|
||||
);
|
||||
}
|
||||
if (!$this->parser) {
|
||||
$this->parser = new Parser(new File($this->config->object_file, 'r'));
|
||||
}
|
||||
$this->parser->parseObjectsFile();
|
||||
$this->lastState = $this->parser->getRuntimeState();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the status.dat file and update the current state
|
||||
*
|
||||
* @throws ConfigurationError If the status.dat couldn't be read
|
||||
*/
|
||||
private function parseStatusDatFile()
|
||||
{
|
||||
if (!is_readable($this->config->status_file)) {
|
||||
throw new ConfigurationError(
|
||||
'Can\'t read status-file %s, check your configuration',
|
||||
$this->config->status_file
|
||||
);
|
||||
}
|
||||
if (!$this->parser) {
|
||||
$this->parser = new Parser(new File($this->config->status_file, 'r'), $this->lastState);
|
||||
}
|
||||
$this->parser->parseRuntimeState(new File($this->config->status_file, 'r'));
|
||||
$this->lastState = $this->parser->getRuntimeState();
|
||||
if (!$this->noCache) {
|
||||
$this->statusCache->save(array("true" => true), "state" . md5($this->config->object_file));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new Query
|
||||
*
|
||||
* @return Query The query to operate on
|
||||
*/
|
||||
public function select()
|
||||
{
|
||||
return new Query($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the internal state of the status.dat
|
||||
*
|
||||
* @return mixed The internal status.dat representation
|
||||
*/
|
||||
public function getState()
|
||||
{
|
||||
return $this->lastState;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the object with the given name and type
|
||||
*
|
||||
* @param String $type The type of the object to return (service, host, servicegroup...)
|
||||
* @param String $name The name of the object
|
||||
*
|
||||
* @return ObjectContainer An object container wrapping the result or null if the object doesn't exist
|
||||
*/
|
||||
public function getObjectByName($type, $name)
|
||||
{
|
||||
if (isset($this->lastState[$type]) && isset($this->lastState[$type][$name])) {
|
||||
return new ObjectContainer($this->lastState[$type][$name], $this);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array containing all names of monitoring objects with the given type
|
||||
*
|
||||
* @param String $type The type of object to get the names for
|
||||
* @return array An array of names or null if the type does not exist
|
||||
*/
|
||||
public function getObjectNames($type)
|
||||
{
|
||||
return isset($this->lastState[$type]) ? array_keys($this->lastState[$type]) : null;
|
||||
}
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Protocol\Statusdat;
|
||||
|
||||
/**
|
||||
* Container class containing the runtime state of an object
|
||||
*
|
||||
* This class contains the state of the object as a string and parses it
|
||||
* on the fly as soon as values should be retrieved. This reduces memory usage,
|
||||
* as most runtime information is never received and only lives for a very short time.
|
||||
*
|
||||
*/
|
||||
class RuntimeStateContainer extends \stdClass
|
||||
{
|
||||
/**
|
||||
* The state string
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $runtimeState = "";
|
||||
|
||||
/**
|
||||
* Create a new runtime state container from the givven string
|
||||
*
|
||||
* @param string $str
|
||||
*/
|
||||
public function __construct($str = "")
|
||||
{
|
||||
$this->runtimeState = $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the argument exists
|
||||
*
|
||||
* @param String $attr The argument to retrieve
|
||||
* @return bool True if it exists, otherwise false
|
||||
*/
|
||||
public function __isset($attr)
|
||||
{
|
||||
try {
|
||||
$this->__get($attr);
|
||||
return true;
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the given attribute
|
||||
*
|
||||
* If the container string is not yet parsed, this will happen here
|
||||
*
|
||||
* @param String $attr The attribute to retrieve
|
||||
* @return mixed The value of the attribute
|
||||
* @throws \InvalidArgumentException When the attribute does not exist
|
||||
*/
|
||||
public function __get($attr)
|
||||
{
|
||||
$start = strpos($this->runtimeState, $attr . "=");
|
||||
if ($start === false) {
|
||||
throw new \InvalidArgumentException("Unknown property $attr");
|
||||
}
|
||||
|
||||
$start += strlen($attr . "=");
|
||||
$len = strpos($this->runtimeState, "\n", $start) - $start;
|
||||
$this->$attr = trim(substr($this->runtimeState, $start, $len));
|
||||
|
||||
return $this->$attr;
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Protocol\Statusdat\View;
|
||||
|
||||
/**
|
||||
* Interface for statusdat classes that provide a specific view on the dataset
|
||||
*
|
||||
* 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 AccessorStrategy
|
||||
{
|
||||
/**
|
||||
* 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 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);
|
||||
}
|
|
@ -1,143 +0,0 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Protocol\Statusdat\View;
|
||||
|
||||
use Iterator;
|
||||
use Countable;
|
||||
use ArrayAccess;
|
||||
use Exception;
|
||||
use Icinga\Exception\IcingaException;
|
||||
|
||||
/**
|
||||
* Wrapper around an array of monitoring objects that can be enhanced with an optional
|
||||
* object that extends AccessorStrategy. This will act as a dataview and provide
|
||||
* normalized access to the underlying data (mapping properties, retrieving additional data)
|
||||
*
|
||||
* If not Accessor is set, this class just behaves like a normal Iterator and returns
|
||||
* the underlying objects.
|
||||
*
|
||||
* If the dataset contains arrays instead of objects, they will be cast to objects.
|
||||
*
|
||||
*/
|
||||
class MonitoringObjectList implements Iterator, Countable, ArrayAccess
|
||||
{
|
||||
private $dataSet = array();
|
||||
private $position = 0;
|
||||
private $dataView = null;
|
||||
|
||||
public function __construct(array &$dataset, AccessorStrategy $dataView = null)
|
||||
{
|
||||
$this->dataSet = $dataset;
|
||||
$this->position = 0;
|
||||
$this->dataView = $dataView;
|
||||
}
|
||||
|
||||
public function count()
|
||||
{
|
||||
return count($this->dataSet);
|
||||
}
|
||||
|
||||
public function setPosition($pos)
|
||||
{
|
||||
$this->position = $pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* (PHP 5 >= 5.0.0)<br/>
|
||||
* Return the current element
|
||||
* @link http://php.net/manual/en/iterator.current.php
|
||||
* @return mixed Can return any type.
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
if ($this->dataView) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
return $this->dataSet[$this->position];
|
||||
}
|
||||
|
||||
/**
|
||||
* (PHP 5 >= 5.0.0)<br/>
|
||||
* Move forward to next element
|
||||
* @link http://php.net/manual/en/iterator.next.php
|
||||
* @return void Any returned value is ignored.
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
$this->position++;
|
||||
}
|
||||
|
||||
/**
|
||||
* (PHP 5 >= 5.0.0)<br/>
|
||||
* Return the key of the current element
|
||||
* @link http://php.net/manual/en/iterator.key.php
|
||||
* @return mixed scalar on success, or null on failure.
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
return $this->position;
|
||||
}
|
||||
|
||||
/**
|
||||
* (PHP 5 >= 5.0.0)<br/>
|
||||
* Checks if current position is valid
|
||||
* @link http://php.net/manual/en/iterator.valid.php
|
||||
* @return boolean The return value will be casted to boolean and then evaluated.
|
||||
* Returns true on success or false on failure.
|
||||
*/
|
||||
public function valid()
|
||||
{
|
||||
return $this->position < count($this->dataSet);
|
||||
}
|
||||
|
||||
/**
|
||||
* (PHP 5 >= 5.0.0)<br/>
|
||||
* Rewind the Iterator to the first element
|
||||
* @link http://php.net/manual/en/iterator.rewind.php
|
||||
* @return void Any returned value is ignored.
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
$this->position = 0;
|
||||
}
|
||||
|
||||
public function __isset($name)
|
||||
{
|
||||
return $this->dataView->exists($this->dataSet[$this->position], $name);
|
||||
}
|
||||
|
||||
public function __get($name)
|
||||
{
|
||||
return $this->dataView->get($this->dataSet[$this->position], $name);
|
||||
}
|
||||
|
||||
public function __set($name, $value)
|
||||
{
|
||||
throw new IcingaException('Setting is currently not available for objects');
|
||||
}
|
||||
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return count($this->dataSet) < $offset;
|
||||
}
|
||||
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
$res = new MonitoringObjectList($this->dataSet, $this->dataView);
|
||||
$res->position = $offset;
|
||||
return $res;
|
||||
}
|
||||
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
// non mutable
|
||||
}
|
||||
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
// non mutable
|
||||
}
|
||||
}
|
|
@ -45,8 +45,8 @@ class BackendConfigForm extends ConfigForm
|
|||
{
|
||||
$resources = array();
|
||||
foreach ($resourceConfig as $name => $resource) {
|
||||
if ($resource->type === 'db' || $resource->type === 'statusdat' || $resource->type === 'livestatus') {
|
||||
$resources[$resource->type === 'db' ? 'ido' : strtolower($resource->type)][$name] = $name;
|
||||
if ($resource->type === 'db' || $resource->type === 'livestatus') {
|
||||
$resources[$resource->type === 'db' ? 'ido' : 'livestatus'][$name] = $name;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -192,9 +192,6 @@ class BackendConfigForm extends ConfigForm
|
|||
if ($resourceType === 'ido' || array_key_exists('ido', $this->resources)) {
|
||||
$resourceTypes['ido'] = 'IDO Backend';
|
||||
}
|
||||
if ($resourceType === 'statusdat' || array_key_exists('statusdat', $this->resources)) {
|
||||
$resourceTypes['statusdat'] = 'Status.dat';
|
||||
}
|
||||
if ($resourceType === 'livestatus' || array_key_exists('livestatus', $this->resources)) {
|
||||
$resourceTypes['livestatus'] = 'Livestatus';
|
||||
}
|
||||
|
|
|
@ -1,83 +0,0 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Module\Monitoring\Backend\Statusdat\Query;
|
||||
|
||||
/**
|
||||
* Query map for comments
|
||||
*/
|
||||
class CommentQuery extends StatusdatQuery
|
||||
{
|
||||
public static $mappedParameters = array(
|
||||
'comment_id' => 'comment_id',
|
||||
'comment_internal_id' => 'comment_id',
|
||||
'comment_data' => 'comment_data',
|
||||
'comment_author' => 'author',
|
||||
'comment_timestamp' => 'entry_time',
|
||||
'comment_is_persistent' => 'persistent',
|
||||
'host_name' => 'host_name',
|
||||
'host' => 'host_name',
|
||||
);
|
||||
|
||||
public static $handlerParameters = array(
|
||||
'comment_objecttype_id' => 'getCommentObjectType',
|
||||
'comment_type' => 'getCommentType',
|
||||
'comment_expiration_timestamp' => 'getExpirationTime',
|
||||
'service' => 'getServiceDescription',
|
||||
'service_name' => 'getServiceDescription',
|
||||
'service_description' => 'getServiceDescription'
|
||||
);
|
||||
|
||||
public function getServiceDescription(&$obj)
|
||||
{
|
||||
if (isset($obj->service_description)) {
|
||||
return $obj->service_description;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
public function getExpirationTime(&$obj)
|
||||
{
|
||||
if ($obj->expires) {
|
||||
return $obj->expire_time;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function getCommentObjectType(&$obj)
|
||||
{
|
||||
if (isset($obj->service_description)) {
|
||||
return 2;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
public function getCommentType(&$obj)
|
||||
{
|
||||
switch ($obj->entry_type) {
|
||||
case 1:
|
||||
return 'comment';
|
||||
case 2:
|
||||
return 'downtime';
|
||||
case 3:
|
||||
return 'flapping';
|
||||
case 4:
|
||||
return 'ack';
|
||||
}
|
||||
return '';
|
||||
|
||||
}
|
||||
|
||||
public function getObjectType(&$obj)
|
||||
{
|
||||
return isset($obj->service_description) ? 'service ': 'host';
|
||||
}
|
||||
|
||||
public function selectBase()
|
||||
{
|
||||
$this->select()->from("comments", array());
|
||||
}
|
||||
}
|
|
@ -1,133 +0,0 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Module\Monitoring\Backend\Statusdat\Query;
|
||||
|
||||
class ContactQuery extends StatusdatQuery
|
||||
{
|
||||
public static $mappedParameters = array(
|
||||
'contact_name' => 'contact_name',
|
||||
'contact_alias' => 'alias',
|
||||
'contact_email' => 'email',
|
||||
'contact_pager' => 'pager',
|
||||
'contact_has_host_notfications' => 'host_notifications_enabled',
|
||||
'contact_has_service_notfications' => 'service_notifications_enabled',
|
||||
'contact_can_submit_commands' => 'can_submit_commands',
|
||||
'contact_notify_host_timeperiod' => 'host_notification_period',
|
||||
'contact_notify_service_timeperiod'=> 'service_notification_period',
|
||||
'contact_service_notification_options' => 'service_notification_options',
|
||||
'contact_host_notification_options' => 'host_notification_options',
|
||||
'contactgroup_name' => 'group.contactgroup_name',
|
||||
'contactgroup_alias' => 'group.alias'
|
||||
);
|
||||
|
||||
public static $handlerParameters = array(
|
||||
'contact_notify_service_recovery' => 'getServiceRecoveryFlag',
|
||||
'contact_notify_service_warning' => 'getServiceWarningFlag',
|
||||
'contact_notify_service_critical' => 'getServiceCriticalFlag',
|
||||
'contact_notify_service_unknown' => 'getServiceUnknownFlag',
|
||||
'contact_notify_service_flapping' => 'getServiceFlappingFlag',
|
||||
'contact_notify_service_downtime' => 'getServiceDowntimeFlag',
|
||||
'contact_notify_host_recovery' => 'getHostRecoveryFlag',
|
||||
'contact_notify_host_down' => 'getHostDownFlag',
|
||||
'contact_notify_host_unreachable' => 'getHostUnreachableFlag',
|
||||
'contact_notify_host_flapping' => 'getHostFlappingFlag',
|
||||
'contact_notify_host_downtime' => 'getHostDowntimeFlag',
|
||||
'host_name' => 'getHost',
|
||||
'host' => 'getHost',
|
||||
'service_host_name' => 'getHost',
|
||||
'service' => 'getService',
|
||||
'service_description' => 'getService'
|
||||
);
|
||||
|
||||
|
||||
public function getHost(&$obj)
|
||||
{
|
||||
$result = array();
|
||||
foreach ($this->state['host'] as $values) {
|
||||
if (!isset($values->contacts)) {
|
||||
continue;
|
||||
}
|
||||
if (stripos($values->contacts, $obj->contacts) !== false) {
|
||||
$result[] = $values;
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getService(&$obj)
|
||||
{
|
||||
$result = array();
|
||||
foreach ($this->state['service'] as $values) {
|
||||
if (!isset($values->contacts)) {
|
||||
continue;
|
||||
}
|
||||
if (stripos($values->contact_groups, $obj->contacts) !== false) {
|
||||
$result[] = $values;
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getServiceRecoveryFlag(&$obj)
|
||||
{
|
||||
return stripos($obj->service_notification_options, 'r') === false ? 0 : 1;
|
||||
}
|
||||
|
||||
public function getServiceWarningFlag(&$obj)
|
||||
{
|
||||
return stripos($obj->service_notification_options, 'w') === false ? 0 : 1;
|
||||
}
|
||||
|
||||
public function getServiceCriticalFlag(&$obj)
|
||||
{
|
||||
return stripos($obj->service_notification_options, 'c') === false ? 0 : 1;
|
||||
}
|
||||
|
||||
public function getServiceUnknownFlag(&$obj)
|
||||
{
|
||||
return stripos($obj->service_notification_options, 'u') === false ? 0 : 1;
|
||||
}
|
||||
|
||||
public function getServiceFlappingFlag(&$obj)
|
||||
{
|
||||
return stripos($obj->service_notification_options, 'f') === false ? 0 : 1;
|
||||
}
|
||||
|
||||
public function getServiceDowntimeFlag(&$obj)
|
||||
{
|
||||
return stripos($obj->service_notification_options, 's') === false ? 0 : 1;
|
||||
}
|
||||
|
||||
public function getHostRecoveryFlag(&$obj)
|
||||
{
|
||||
return stripos($obj->host_notification_options, 'r') === false ? 0 : 1;
|
||||
}
|
||||
|
||||
public function getHostDownFlag(&$obj)
|
||||
{
|
||||
return stripos($obj->host_notification_options, 'd') === false ? 0 : 1;
|
||||
}
|
||||
|
||||
public function getHostUnreachableFlag(&$obj)
|
||||
{
|
||||
return stripos($obj->host_notification_options, 'u') === false ? 0 : 1;
|
||||
}
|
||||
|
||||
public function getHostFlappingFlag(&$obj)
|
||||
{
|
||||
return stripos($obj->host_notification_options, 'f') === false ? 0 : 1;
|
||||
}
|
||||
|
||||
public function getHostDowntimeFlag(&$obj)
|
||||
{
|
||||
return strpos($obj->host_notification_options, 's') === false ? 0 : 1;
|
||||
}
|
||||
|
||||
public function selectBase()
|
||||
{
|
||||
$this->state = $this->ds->getState();
|
||||
$this->select()->from("contacts", array());
|
||||
}
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Module\Monitoring\Backend\Statusdat\Query;
|
||||
|
||||
class ContactgroupQuery extends StatusdatQuery
|
||||
{
|
||||
public static $mappedParameters = array(
|
||||
'contactgroup_name' => 'contactgroup_name',
|
||||
'contactgroup_alias' => 'alias',
|
||||
'contact_name' => 'contact.contact_name',
|
||||
'contact_alias' => 'contact.alias',
|
||||
'contact_email' => 'contact.email',
|
||||
'contact_pager' => 'contact.pager',
|
||||
'contact_has_host_notfications' => 'contact.host_notifications_enabled',
|
||||
'contact_has_service_notfications' => 'contact.service_notifications_enabled',
|
||||
'contact_can_submit_commands' => 'contact.can_submit_commands',
|
||||
'contact_notify_host_timeperiod' => 'contact.host_notification_period',
|
||||
'contact_notify_service_timeperiod' => 'contact.service_notification_period',
|
||||
'contact_service_notification_options' => 'contact.service_notification_options',
|
||||
'contact_host_notification_options' => 'contact.host_notification_options',
|
||||
);
|
||||
|
||||
public static $handlerParameters = array(
|
||||
'host_name' => 'getHosts',
|
||||
'host' => 'getHosts',
|
||||
'service_host_name' => 'getHosts',
|
||||
'service' => 'getService',
|
||||
'service_description' => 'getService'
|
||||
);
|
||||
|
||||
public function getHosts(&$obj)
|
||||
{
|
||||
$result = array();
|
||||
foreach ($this->state['host'] as $values) {
|
||||
if (stripos($values->contact_groups, $obj->contactgroup_name) !== false) {
|
||||
$result[] = $values;
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getService(&$obj)
|
||||
{
|
||||
$result = array();
|
||||
foreach ($this->state['service'] as $values) {
|
||||
if (stripos($values->contact_groups, $obj->contactgroup_name) !== false) {
|
||||
$result[] = $values;
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function selectBase()
|
||||
{
|
||||
$this->state = $this->ds->getState();
|
||||
return $this->select()->from("contactgroups", array());
|
||||
|
||||
}
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Module\Monitoring\Backend\Statusdat\Query;
|
||||
|
||||
/**
|
||||
* Handling downtime queries
|
||||
*/
|
||||
class DowntimeQuery extends StatusdatQuery
|
||||
{
|
||||
/**
|
||||
* Column map
|
||||
* @var array
|
||||
*/
|
||||
public static $mappedParameters = array(
|
||||
'downtime_author' => 'author',
|
||||
'downtime_comment' => 'comment',
|
||||
'downtime_duration' => 'duration',
|
||||
'downtime_end' => 'end_time',
|
||||
'downtime_was_started' => 'was_started',
|
||||
'downtime_is_fixed' => 'fixed',
|
||||
'downtime_is_in_effect' => 'is_in_effect',
|
||||
'downtime_trigger_time' => 'trigger_time',
|
||||
'downtime_triggered_by_id' => 'triggered_by_id',
|
||||
'downtime_internal_downtime_id' => 'downtime_id',
|
||||
'downtime_scheduled_start_time' => 'start_time',
|
||||
'host' => 'host_name',
|
||||
'host_name' => 'host_name',
|
||||
'service_host_name' => 'host_name'
|
||||
);
|
||||
|
||||
public static $handlerParameters = array(
|
||||
'object_type' => 'getObjectType',
|
||||
'downtime_start' => 'getDowntimeStart',
|
||||
'downtime_is_flexible' => 'getFlexibleFlag',
|
||||
'service_description' => 'getServiceDescription'
|
||||
);
|
||||
|
||||
public static $fieldTypes = array(
|
||||
'downtime_end' => self::TIMESTAMP,
|
||||
'downtime_trigger_time' => self::TIMESTAMP,
|
||||
'downtime_start' => self::TIMESTAMP
|
||||
);
|
||||
|
||||
public function getServiceDescription(&$obj)
|
||||
{
|
||||
if (isset ($obj->service_description)) {
|
||||
return $obj->service_description;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
public function getDowntimeStart(&$obj)
|
||||
{
|
||||
if ($obj->trigger_time != '0') {
|
||||
return $obj->trigger_time;
|
||||
} else {
|
||||
return $obj->start_time;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function getFlexibleFlag(&$obj)
|
||||
{
|
||||
return $obj->fixed ? 0 : 1;
|
||||
}
|
||||
|
||||
public function getObjectType(&$obj)
|
||||
{
|
||||
return isset($obj->service_description) ? 'service ': 'host';
|
||||
}
|
||||
|
||||
public function selectBase()
|
||||
{
|
||||
$this->select()->from("downtimes", array());
|
||||
}
|
||||
}
|
|
@ -1,248 +0,0 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Module\Monitoring\Backend\Statusdat\Query;
|
||||
|
||||
class GroupsummaryQuery extends StatusdatQuery
|
||||
{
|
||||
public static $mappedParameters = array(
|
||||
'hostgroup' => 'hostgroup_name',
|
||||
'servicegroup' => 'servicegroup_name'
|
||||
);
|
||||
|
||||
public static $handlerParameters = array(
|
||||
'hosts_up' => 'getHostUpSum',
|
||||
'hosts_unreachable_handled' => 'getHostUnreachableSum',
|
||||
'hosts_unreachable_unhandled' => 'getHostUnreachableUnhandledSum',
|
||||
'hosts_down_handled' => 'getHostDownSum',
|
||||
'hosts_down_unhandled' => 'getHostDownUnhandledSum',
|
||||
'hosts_pending' => 'getHostPendingSum',
|
||||
'services_ok' => 'getServiceOkSum',
|
||||
'services_unknown_handled' => 'getServiceUnknownSum',
|
||||
'services_unknown_unhandled' => 'getServiceUnknownUnhandledSum',
|
||||
'services_critical_handled' => 'getServiceCriticalSum',
|
||||
'services_critical_unhandled' => 'getServiceCriticalUnhandledSum',
|
||||
'services_warning_handled' => 'getServiceWarningSum',
|
||||
'services_warning_unhandled' => 'getServiceWarningUnhandledSum',
|
||||
'services_pending' => 'getServicePendingSum',
|
||||
|
||||
);
|
||||
|
||||
private function getMembers(&$obj, $hint = null)
|
||||
{
|
||||
if (!isset($obj->service) && !isset($obj->host)) {
|
||||
return null;
|
||||
}
|
||||
$memberList = isset($obj->service) ? $obj->service : $obj->host;
|
||||
|
||||
if (isset($obj->host) && $hint == 'service') {
|
||||
$result = array();
|
||||
foreach ($memberList as &$member) {
|
||||
if (isset($member->services)) {
|
||||
$result = $result + $member->services;
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
return $memberList;
|
||||
}
|
||||
|
||||
private function getMembersByCriteria(&$obj, $type, $namefield, $criteriaFn)
|
||||
{
|
||||
$memberList = $this->getMembers($obj, $type);
|
||||
if ($memberList === null) {
|
||||
return 0;
|
||||
}
|
||||
$ids = array();
|
||||
foreach ($memberList as $member) {
|
||||
$name = $member->$type->$namefield;
|
||||
if ($namefield === 'service_description') {
|
||||
$name .= ';' . $member->$type->host_name;
|
||||
}
|
||||
|
||||
if (isset($ids[$name])) {
|
||||
continue;
|
||||
} else {
|
||||
if ($criteriaFn($member->$type)) {
|
||||
$ids[$name] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return count(array_keys($ids));
|
||||
}
|
||||
|
||||
public function getHostUpSum(&$obj)
|
||||
{
|
||||
return $this->getMembersByCriteria($obj, 'host', 'host_name', function($member) {
|
||||
return ($member->status->current_state == 0
|
||||
&& $member->status->has_been_checked);
|
||||
});
|
||||
}
|
||||
|
||||
public function getHostUnreachableSum(&$obj)
|
||||
{
|
||||
return $this->getMembersByCriteria($obj, 'host', 'host_name', function($member) {
|
||||
return ($member->status->current_state == 2
|
||||
&& $member->status->has_been_checked
|
||||
&& (
|
||||
$member->status->problem_has_been_acknowledged
|
||||
|| $member->status->scheduled_downtime_depth
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public function getHostUnreachableUnhandledSum(&$obj)
|
||||
{
|
||||
return $this->getMembersByCriteria($obj, 'host', 'host_name', function($member) {
|
||||
return ($member->status->current_state == 2
|
||||
&& $member->status->has_been_checked
|
||||
&& !(
|
||||
$member->status->problem_has_been_acknowledged
|
||||
|| $member->status->scheduled_downtime_depth
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public function getHostDownSum(&$obj)
|
||||
{
|
||||
return $this->getMembersByCriteria($obj, 'host', 'host_name', function($member) {
|
||||
return ($member->status->current_state == 1
|
||||
&& $member->status->has_been_checked
|
||||
&& (
|
||||
$member->status->problem_has_been_acknowledged
|
||||
|| $member->status->scheduled_downtime_depth
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public function getHostDownUnhandledSum(&$obj)
|
||||
{
|
||||
return $this->getMembersByCriteria($obj, 'host', 'host_name', function($member) {
|
||||
return ($member->status->current_state == 1
|
||||
&& $member->status->has_been_checked
|
||||
&& !(
|
||||
$member->status->problem_has_been_acknowledged
|
||||
|| $member->status->scheduled_downtime_depth
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public function getHostPendingSum(&$obj)
|
||||
{
|
||||
return $this->getMembersByCriteria($obj, 'host', 'host_name', function($member) {
|
||||
return (!$member->status->has_been_checked);
|
||||
});
|
||||
}
|
||||
|
||||
public function getServiceOkSum(&$obj)
|
||||
{
|
||||
return $this->getMembersByCriteria($obj, 'service', 'service_description', function($member) {
|
||||
return ($member->status->current_state == 0
|
||||
&& $member->status->has_been_checked);
|
||||
});
|
||||
}
|
||||
|
||||
public function getServiceUnknownSum(&$obj)
|
||||
{
|
||||
return $this->getMembersByCriteria($obj, 'service', 'service_description', function($member) {
|
||||
|
||||
return ($member->status->current_state == 3
|
||||
&& $member->status->has_been_checked
|
||||
&& (
|
||||
$member->status->problem_has_been_acknowledged
|
||||
|| $member->status->scheduled_downtime_depth
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public function getServiceUnknownUnhandledSum(&$obj)
|
||||
{
|
||||
return $this->getMembersByCriteria($obj, 'service', 'service_description', function($member) {
|
||||
return ($member->status->current_state == 3
|
||||
&& $member->status->has_been_checked
|
||||
&& !(
|
||||
$member->status->problem_has_been_acknowledged
|
||||
|| $member->status->scheduled_downtime_depth
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public function getServiceCriticalSum(&$obj)
|
||||
{
|
||||
return $this->getMembersByCriteria($obj, 'service', 'service_description', function($member) {
|
||||
return ($member->status->current_state == 2
|
||||
&& $member->status->has_been_checked
|
||||
&& (
|
||||
$member->status->problem_has_been_acknowledged
|
||||
|| $member->status->scheduled_downtime_depth
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public function getServiceCriticalUnhandledSum(&$obj)
|
||||
{
|
||||
return $this->getMembersByCriteria($obj, 'service', 'service_description', function($member) {
|
||||
return ($member->status->current_state == 2
|
||||
&& $member->status->has_been_checked
|
||||
&& !(
|
||||
$member->status->problem_has_been_acknowledged
|
||||
|| $member->status->scheduled_downtime_depth
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public function getServiceWarningSum(&$obj)
|
||||
{
|
||||
return $this->getMembersByCriteria($obj, 'service', 'service_description', function($member) {
|
||||
return ($member->status->current_state == 1
|
||||
&& $member->status->has_been_checked
|
||||
&& !(
|
||||
$member->status->problem_has_been_acknowledged
|
||||
|| $member->status->scheduled_downtime_depth
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public function getServiceWarningUnhandledSum(&$obj)
|
||||
{
|
||||
return $this->getMembersByCriteria($obj, 'service', 'service_description', function($member) {
|
||||
return ($member->status->current_state == 1
|
||||
&& $member->status->has_been_checked
|
||||
&& (
|
||||
$member->status->problem_has_been_acknowledged
|
||||
|| $member->status->scheduled_downtime_depth
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public function getServicePendingSum(&$obj)
|
||||
{
|
||||
return $this->getMembersByCriteria($obj, 'service', 'service_description', function($member) {
|
||||
return (!$member->status->has_been_checked);
|
||||
});
|
||||
}
|
||||
|
||||
private function getTarget()
|
||||
{
|
||||
if (in_array('servicegroup', $this->getColumns())) {
|
||||
return 'servicegroups';
|
||||
}
|
||||
return 'hostgroups';
|
||||
}
|
||||
|
||||
public function selectBase()
|
||||
{
|
||||
$this->select()->from($this->getTarget(), array());
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Module\Monitoring\Backend\Statusdat\Query;
|
||||
|
||||
/**
|
||||
* Class HostgroupsummaryQuery
|
||||
* @package Icinga\Backend\Statusdat
|
||||
*/
|
||||
class HostgroupQuery extends StatusdatQuery
|
||||
{
|
||||
public static $mappedParameters = array(
|
||||
'hostgroups' => 'hostgroup_name',
|
||||
'hostgroup_name' => 'hostgroup_name',
|
||||
'hostgroup_alias' => 'alias',
|
||||
'host' => 'host.host_name',
|
||||
'host_name' => 'host.host_name'
|
||||
);
|
||||
|
||||
public function selectBase()
|
||||
{
|
||||
$this->select()->from("hostgroups", array());
|
||||
}
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Module\Monitoring\Backend\Statusdat\Query;
|
||||
|
||||
use Icinga\Protocol\Statusdat;
|
||||
use Icinga\Exception;
|
||||
|
||||
/**
|
||||
* Class HostListQuery
|
||||
* @package Icinga\Backend\Statusdat
|
||||
*/
|
||||
class HostListQuery extends StatusdatQuery
|
||||
{
|
||||
/**
|
||||
* @var \Icinga\Protocol\Statusdat\Query
|
||||
*/
|
||||
protected $query;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $view = 'Icinga\Backend\Statusdat\DataView\StatusdatHostView';
|
||||
|
||||
/**
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function selectBase()
|
||||
{
|
||||
$this->select()->from("hosts", array());
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Module\Monitoring\Backend\Statusdat\Query;
|
||||
|
||||
/**
|
||||
* Class HostgroupsummaryQuery
|
||||
* @package Icinga\Backend\Statusdat
|
||||
*/
|
||||
class ServicegroupQuery extends StatusdatQuery
|
||||
{
|
||||
public static $mappedParameters = array(
|
||||
'servicegroups' => 'servicegroup_name',
|
||||
'servicegroup_name' => 'servicegroup_name',
|
||||
'servicegroup_alias' => 'alias',
|
||||
'host' => 'service.host_name',
|
||||
'host_name' => 'service.host_name',
|
||||
'service' => 'service.service_description',
|
||||
'service_description'=> 'service.service_description'
|
||||
|
||||
);
|
||||
|
||||
public function selectBase()
|
||||
{
|
||||
$this->select()->from("servicegroups", array());
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Module\Monitoring\Backend\Statusdat\Query;
|
||||
|
||||
/**
|
||||
* Class ServicegroupsummaryQuery
|
||||
* @package Icinga\Backend\Statusdat
|
||||
*/
|
||||
class ServicegroupsummaryQuery extends GroupsummaryQuery
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $groupType = "servicegroup";
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $base = "services";
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Module\Monitoring\Backend\Statusdat\Query;
|
||||
|
||||
use Icinga\Protocol\Statusdat;
|
||||
use Icinga\Exception;
|
||||
|
||||
/**
|
||||
* Class ServicelistQuery
|
||||
* @package Icinga\Backend\Statusdat
|
||||
*/
|
||||
class ServicelistQuery extends StatusdatQuery
|
||||
{
|
||||
/**
|
||||
* @var \Icinga\Protocol\Statusdat\Query
|
||||
*/
|
||||
protected $query;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $view = 'Icinga\Backend\Statusdat\DataView\StatusdatServiceView';
|
||||
|
||||
public function selectBase()
|
||||
{
|
||||
$this->select()->from("services", array());
|
||||
}
|
||||
}
|
|
@ -1,361 +0,0 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Module\Monitoring\Backend\Statusdat\Query;
|
||||
|
||||
use Icinga\Protocol\Statusdat;
|
||||
use Icinga\Protocol\Statusdat\IReader;
|
||||
use Icinga\Exception;
|
||||
|
||||
class StatusQuery extends StatusdatQuery
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public static $mappedParameters = array(
|
||||
'host' => 'host.host_name',
|
||||
'host_name' => 'host.host_name',
|
||||
'host_display_name' => 'host.host_name',
|
||||
'host_alias' => 'host.alias',
|
||||
'host_address' => 'host.address',
|
||||
'host_icon_image' => 'host.icon_image',
|
||||
'host_action_url' => 'host.action_url',
|
||||
'host_notes_url' => 'host.notes_url',
|
||||
'host_output' => 'host.status.plugin_output',
|
||||
'host_long_output' => 'host.status.long_plugin_output',
|
||||
'host_perfdata' => 'host.status.performance_data',
|
||||
'host_check_source' => 'host.status.check_source',
|
||||
'host_acknowledged' => 'host.status.problem_has_been_acknowledged',
|
||||
'host_last_state_change' => 'host.status.last_state_change',
|
||||
'host_last_hard_state' => 'host.status.last_hard_state',
|
||||
'host_last_hard_state_change' => 'host.status.last_hard_state_change',
|
||||
'host_check_command' => 'host.status.check_command',
|
||||
'host_last_check' => 'host.status.last_check',
|
||||
'host_next_check' => 'host.status.next_check',
|
||||
'host_check_execution_time' => 'host.status.check_execution_time',
|
||||
'host_check_latency' => 'host.status.check_latency',
|
||||
'host_notifications_enabled' => 'host.status.notifications_enabled',
|
||||
'host_last_time_up' => 'host.status.last_time_up',
|
||||
'host_last_time_down' => 'host.status.last_time_down',
|
||||
'host_last_time_unreachable' => 'host.status.last_time_unreachable',
|
||||
'host_current_check_attempt' => 'host.status.current_attempt',
|
||||
'host_max_check_attempts' => 'host.status.max_attempts',
|
||||
'host_check_type' => 'host.status.check_type',
|
||||
'host_state_type' => 'host.status.state_type',
|
||||
'host_last_notification' => 'host.status.last_notification',
|
||||
'host_next_notification' => 'host.status.next_notification',
|
||||
'host_no_more_notifications' => 'host.status.no_more_notifications',
|
||||
'host_problem_has_been_acknowledged' => 'host.status.problem_has_been_acknowledged',
|
||||
'host_acknowledgement_type' => 'host.status.acknowledgement_type',
|
||||
'host_current_notification_number' => 'host.status.current_notification_number',
|
||||
'host_passive_checks_enabled' => 'host.status.passive_checks_enabled',
|
||||
'host_active_checks_enabled' => 'host.status.active_checks_enabled',
|
||||
'host_event_handler_enabled' => 'host.status.event_handler_enabled',
|
||||
'host_flap_detection_enabled' => 'host.status.flap_detection_enabled',
|
||||
'host_is_flapping' => 'host.status.is_flapping',
|
||||
'host_percent_state_change' => 'host.status.percent_state_change',
|
||||
'host_scheduled_downtime_depth' => 'host.status.scheduled_downtime_depth',
|
||||
'host_failure_prediction_enabled' => 'host.status.failure_prediction_enabled',
|
||||
'host_process_performance_data' => 'host.status.process_performance_data',
|
||||
'host_obsessing' => 'host.status.obsess_over_host',
|
||||
'host_modified_host_attributes' => 'host.status.modified_host_attributes',
|
||||
'host_event_handler' => 'host.status.event_handler',
|
||||
'host_check_command' => 'host.status.check_command',
|
||||
'host_normal_check_interval' => 'host.status.normal_check_interval',
|
||||
'host_retry_check_interval' => 'host.status.retry_check_interval',
|
||||
'host_check_timeperiod_object_id' => 'host.status.check_timeperiod_object_id',
|
||||
'host_status_update_time' => 'host.status.status_update_time',
|
||||
|
||||
'service_host_name' => 'service.host_name',
|
||||
'service' => 'service.service_description',
|
||||
'service_description' => 'service.service_description',
|
||||
'service_display_name' => 'service.service_description',
|
||||
'service_icon_image' => 'service.icon_image',
|
||||
'service_action_url' => 'service.action_url',
|
||||
'service_notes_url' => 'service.notes_url',
|
||||
'service_state_type' => 'service.status.state_type',
|
||||
'service_output' => 'service.status.output',
|
||||
'service_long_output' => 'service.status.long_output',
|
||||
'service_perfdata' => 'service.status.perfdata',
|
||||
'service_check_source' => 'service.status.check_source',
|
||||
'service_acknowledged' => 'service.status.problem_has_been_acknowledged',
|
||||
'service_last_state_change' => 'service.status.last_state_change',
|
||||
'service_check_command' => 'service.status.check_command',
|
||||
'service_last_time_ok' => 'service.status.last_time_ok',
|
||||
'service_last_time_warning' => 'service.status.last_time_warning',
|
||||
'service_last_time_critical' => 'service.status.last_time_critical',
|
||||
'service_last_time_unknown' => 'service.status.last_time_unknown',
|
||||
'service_current_check_attempt' => 'service.status.current_check_attempt',
|
||||
'service_max_check_attempts' => 'service.status.max_check_attempts',
|
||||
'service_last_check' => 'service.status.last_check',
|
||||
'service_next_check' => 'service.status.next_check',
|
||||
'service_check_type' => 'service.status.check_type',
|
||||
'service_last_hard_state_change' => 'service.status.last_hard_state_change',
|
||||
'service_last_hard_state' => 'service.status.last_hard_state',
|
||||
'service_last_notification' => 'service.status.last_notification',
|
||||
'service_next_notification' => 'service.status.next_notification',
|
||||
'service_no_more_notifications' => 'service.status.no_more_notifications',
|
||||
'service_notifications_enabled' => 'service.status.notifications_enabled',
|
||||
'service_problem_has_been_acknowledged' => 'service.status.problem_has_been_acknowledged',
|
||||
'service_acknowledgement_type' => 'service.status.acknowledgement_type',
|
||||
'service_current_notification_number' => 'service.status.current_notification_number',
|
||||
'service_passive_checks_enabled' => 'service.status.passive_checks_enabled',
|
||||
'service_active_checks_enabled' => 'service.status.active_checks_enabled',
|
||||
'service_event_handler_enabled' => 'service.status.event_handler_enabled',
|
||||
'service_flap_detection_enabled' => 'service.status.flap_detection_enabled',
|
||||
'service_is_flapping' => 'service.status.is_flapping',
|
||||
'service_percent_state_change' => 'service.status.percent_state_change',
|
||||
'service_check_latency' => 'service.status.latency',
|
||||
'service_check_execution_time' => 'service.status.execution_time',
|
||||
'service_scheduled_downtime_depth' => 'service.status.scheduled_downtime_depth',
|
||||
'service_failure_prediction_enabled' => 'service.status.failure_prediction_enabled',
|
||||
'service_process_performance_data' => 'service.status.process_performance_data',
|
||||
'service_obsessing' => 'service.status.obsess_over_service',
|
||||
'service_modified_service_attributes' => 'service.status.modified_service_attributes',
|
||||
'service_event_handler' => 'service.status.event_handler',
|
||||
'service_check_command' => 'service.status.check_command',
|
||||
'service_normal_check_interval' => 'service.status.normal_check_interval',
|
||||
'service_retry_check_interval' => 'service.status.retry_check_interval',
|
||||
'service_check_timeperiod_object_id' => 'service.status.check_timeperiod_object_id',
|
||||
'service_status_update_time' => 'service.status.status_update_time',
|
||||
'hostgroup' => 'host.group',
|
||||
'servicegroup' => 'service.group'
|
||||
);
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
private $state;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public static $handlerParameters = array(
|
||||
'host_ipv4' => 'getAddress',
|
||||
'host_unhandled_service_count' => 'getNrOfUnhandledServices',
|
||||
'host_last_comment' => 'getLastComment',
|
||||
'service_last_comment' => 'getLastComment',
|
||||
'host_state' => 'getStateForHost',
|
||||
'host_hard_state' => 'getHardStateForHost',
|
||||
'host_handled' => 'isHandledForHost',
|
||||
'host_unhandled' => 'isHostUnhandled',
|
||||
'host_severity' => 'getSeverityForHost',
|
||||
'host_in_downtime' => 'isInDowntimeForHost',
|
||||
'host_problem' => 'isProblemForHost',
|
||||
'host_attempt' => 'getAttemptStringForHost',
|
||||
'service_state' => 'getState',
|
||||
'service_hard_state' => 'getHardState',
|
||||
'service_handled' => 'isHandled',
|
||||
'service_unhandled' => 'isUnhandled',
|
||||
'service_severity' => 'getSeverity',
|
||||
'service_in_downtime' => 'isInDowntime',
|
||||
'service_problem' => 'isProblem',
|
||||
'service_attempt' => 'getAttemptString',
|
||||
);
|
||||
|
||||
public static $fieldTypes = array(
|
||||
'host_last_state_change' => self::TIMESTAMP,
|
||||
'host_last_hard_state_change' => self::TIMESTAMP,
|
||||
'host_last_check' => self::TIMESTAMP,
|
||||
'host_next_check' => self::TIMESTAMP,
|
||||
'host_last_time_up' => self::TIMESTAMP,
|
||||
'host_last_time_down' => self::TIMESTAMP,
|
||||
'host_last_time_unreachable' => self::TIMESTAMP,
|
||||
'host_status_update_time' => self::TIMESTAMP,
|
||||
'service_last_state_change' => self::TIMESTAMP,
|
||||
'service_last_hard_state_change' => self::TIMESTAMP,
|
||||
'service_last_check' => self::TIMESTAMP,
|
||||
'service_next_check' => self::TIMESTAMP,
|
||||
'service_last_time_ok' => self::TIMESTAMP,
|
||||
'service_last_time_warning' => self::TIMESTAMP,
|
||||
'service_last_time_critical' => self::TIMESTAMP,
|
||||
'service_last_time_unknown' => self::TIMESTAMP,
|
||||
'service_status_update_time' => self::TIMESTAMP
|
||||
);
|
||||
|
||||
public function selectBase()
|
||||
{
|
||||
$target = $this->getTarget();
|
||||
$this->select()->from($target."s", array());
|
||||
}
|
||||
|
||||
public function getAttemptString(&$obj)
|
||||
{
|
||||
return $obj->status->current_attempt . '/' . $obj->status->max_attempts;
|
||||
}
|
||||
|
||||
public function isProblem(&$obj)
|
||||
{
|
||||
return $obj->status->current_state > 0 ? 1 : 0;
|
||||
}
|
||||
|
||||
public function isInDowntime(&$obj)
|
||||
{
|
||||
return $obj->status->scheduled_downtime_depth > 0 ? 1 : 0;
|
||||
}
|
||||
|
||||
public function getAddress(&$obj)
|
||||
{
|
||||
return inet_pton($obj->host->address);
|
||||
}
|
||||
|
||||
public function getState(&$obj)
|
||||
{
|
||||
if (!$obj->status->has_been_checked) {
|
||||
return 99;
|
||||
}
|
||||
return $obj->status->current_state;
|
||||
}
|
||||
|
||||
public function getHardState(&$obj)
|
||||
{
|
||||
if (!$obj->status->has_been_checked) {
|
||||
return 99;
|
||||
} else {
|
||||
if ($obj->status->state_type == 1) {
|
||||
return $this->status->current_state;
|
||||
} else {
|
||||
return $this->status->last_hard_state;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function getSeverity(&$host)
|
||||
{
|
||||
$status = $host->status;
|
||||
$severity = 0;
|
||||
|
||||
if (!$status->has_been_checked) {
|
||||
$severity += 16;
|
||||
} elseif($status->current_state == 0) {
|
||||
return $severity;
|
||||
} elseif ($status->current_state == 1) {
|
||||
$severity += 32;
|
||||
} elseif ($status->current_state == 2) {
|
||||
$severity += 64;
|
||||
} else {
|
||||
$severity += 256;
|
||||
}
|
||||
|
||||
if ($status->problem_has_been_acknowledged == 1) {
|
||||
$severity += 2;
|
||||
} elseif ($status->scheduled_downtime_depth > 0) {
|
||||
$severity += 1;
|
||||
} else {
|
||||
$severity += 4;
|
||||
}
|
||||
|
||||
return $severity;
|
||||
}
|
||||
|
||||
public function isHandled(&$host)
|
||||
{
|
||||
return ($host->status->current_state == 0 ||
|
||||
$host->status->problem_has_been_acknowledged == 1 ||
|
||||
$host->status->scheduled_downtime_depth > 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
public function isUnhandled(&$hostOrService)
|
||||
{
|
||||
return +!$this->isHandled($hostOrService);
|
||||
}
|
||||
|
||||
public function getNrOfUnhandledServices(&$obj)
|
||||
{
|
||||
$host = &$obj->host;
|
||||
$ct = 0;
|
||||
if (!isset($host->services)) {
|
||||
return $ct;
|
||||
}
|
||||
foreach ($host->services as &$service) {
|
||||
if ($service->status->current_state > 0
|
||||
&& $service->status->problem_has_been_acknowledged == 0
|
||||
&& $service->status->scheduled_downtime_depth == 0) {
|
||||
$ct++;
|
||||
}
|
||||
}
|
||||
return $ct;
|
||||
}
|
||||
|
||||
public function getLastComment(&$host)
|
||||
{
|
||||
if (!isset($host->comment) || empty($host->comment)) {
|
||||
return null;
|
||||
}
|
||||
$comment = end($host->comment);
|
||||
return $comment->comment_id;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $item
|
||||
* @return null
|
||||
*/
|
||||
public function getHost(&$item)
|
||||
{
|
||||
if (!isset($this->state['service'][$item->host_name])) {
|
||||
return null;
|
||||
}
|
||||
if (!isset($this->state['host'][$item->host_name])) {
|
||||
return null;
|
||||
}
|
||||
return $this->state['host'][$item->host_name];
|
||||
}
|
||||
|
||||
|
||||
private function getTarget()
|
||||
{
|
||||
foreach ($this->getColumns() as $column) {
|
||||
if (preg_match("/^service/",$column)) {
|
||||
return "service";
|
||||
}
|
||||
}
|
||||
|
||||
return "host";
|
||||
}
|
||||
|
||||
|
||||
public function getStateForHost(&$obj)
|
||||
{
|
||||
return $this->getState($obj->host);
|
||||
}
|
||||
|
||||
public function getHardStateForHost(&$obj)
|
||||
{
|
||||
return $this->getHardState($obj->host);
|
||||
}
|
||||
|
||||
public function isHandledForHost(&$obj)
|
||||
{
|
||||
return $this->isHandled($obj->host);
|
||||
}
|
||||
|
||||
public function isHostUnhandled(&$obj)
|
||||
{
|
||||
return $this->isUnhandled($obj->host);
|
||||
}
|
||||
|
||||
public function getSeverityForHost(&$obj)
|
||||
{
|
||||
return $this->getSeverity($obj->host);
|
||||
}
|
||||
|
||||
public function isInDowntimeForHost(&$obj)
|
||||
{
|
||||
return $this->isInDowntime($obj->host);
|
||||
}
|
||||
|
||||
public function isProblemForHost(&$obj)
|
||||
{
|
||||
return $this->isProblem($obj->host);
|
||||
}
|
||||
|
||||
public function getAttemptStringForHost(&$obj)
|
||||
{
|
||||
return $this->getAttemptStringForHost($obj->host);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,115 +0,0 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Module\Monitoring\Backend\Statusdat\Query;
|
||||
|
||||
class StatusSummaryQuery extends StatusdatQuery
|
||||
{
|
||||
public function selectBase()
|
||||
{
|
||||
$this->select()->from('hosts', array())->groupByFunction(
|
||||
'groupByStatus',
|
||||
$this
|
||||
);
|
||||
}
|
||||
|
||||
public function groupByStatus(&$indices)
|
||||
{
|
||||
$hostsPending = 0;
|
||||
$hostsUp = 0;
|
||||
$hostsDownHandled = 0;
|
||||
$hostsDownUnhandled = 0;
|
||||
$hostsUnreachableHandled = 0;
|
||||
$hostsUnreachableUnhandled = 0;
|
||||
$servicesPending = 0;
|
||||
$servicesOk = 0;
|
||||
$servicesCriticalHandled = 0;
|
||||
$servicesCriticalUnhandled = 0;
|
||||
$servicesWarningHandled = 0;
|
||||
$servicesWarningUnhandled = 0;
|
||||
$servicesUnknownHandled = 0;
|
||||
$servicesUnknownUnhandled = 0;
|
||||
foreach ($indices['host'] as $hostName) {
|
||||
$host = $this->ds->getObjectByName('host', $hostName);
|
||||
$hostStatus = $host->status;
|
||||
if ($hostStatus->has_been_checked !== '1') {
|
||||
++$hostsPending;
|
||||
} elseif ($hostStatus->current_state === '0') {
|
||||
++$hostsUp;
|
||||
} elseif ($hostStatus->current_state === '2') {
|
||||
if ($hostStatus->problem_has_been_acknowledged === '1'
|
||||
|| $hostStatus->scheduled_downtime_depth === '1'
|
||||
) {
|
||||
++$hostsDownHandled;
|
||||
} else {
|
||||
++$hostsDownUnhandled;
|
||||
}
|
||||
} elseif ($hostStatus->current_state === '1') {
|
||||
if ($hostStatus->problem_has_been_acknowledged === '1'
|
||||
|| $hostStatus->scheduled_downtime_depth === '1'
|
||||
) {
|
||||
++$hostsUnreachableHandled;
|
||||
} else {
|
||||
++$hostsUnreachableUnhandled;
|
||||
}
|
||||
}
|
||||
if ($host->services === null) {
|
||||
// Host does not have any service associated
|
||||
continue;
|
||||
}
|
||||
foreach ($host->services as $service) {
|
||||
$serviceStatus = $service->status;
|
||||
if ($serviceStatus->has_been_checked !== '1') {
|
||||
++$servicesPending;
|
||||
} elseif ($serviceStatus->current_state === '0') {
|
||||
++$servicesOk;
|
||||
} elseif ($serviceStatus->current_state === '2') {
|
||||
if ($serviceStatus->problem_has_been_acknowledged === '1'
|
||||
|| $serviceStatus->scheduled_downtime_depth === '1'
|
||||
|| $hostStatus->current_state !== '0'
|
||||
) {
|
||||
++$servicesCriticalHandled;
|
||||
} else {
|
||||
++$servicesCriticalUnhandled;
|
||||
}
|
||||
} elseif ($serviceStatus->current_state === '1') {
|
||||
if ($serviceStatus->problem_has_been_acknowledged === '1'
|
||||
|| $serviceStatus->scheduled_downtime_depth === '1'
|
||||
|| $hostStatus->current_state !== '0'
|
||||
) {
|
||||
++$servicesWarningHandled;
|
||||
} else {
|
||||
++$servicesWarningUnhandled;
|
||||
}
|
||||
} elseif ($serviceStatus->current_state === '3') {
|
||||
if ($serviceStatus->problem_has_been_acknowledged === '1'
|
||||
|| $serviceStatus->scheduled_downtime_depth === '1'
|
||||
|| $hostStatus->current_state !== '0'
|
||||
) {
|
||||
++$servicesUnknownHandled;
|
||||
} else {
|
||||
++$servicesUnknownUnhandled;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$rs = array(
|
||||
'hosts_up' => $hostsUp,
|
||||
'hosts_unreachable_handled' => $hostsUnreachableHandled,
|
||||
'hosts_unreachable_unhandled' => $hostsUnreachableUnhandled,
|
||||
'hosts_down_handled' => $hostsDownHandled,
|
||||
'hosts_down_unhandled' => $hostsDownUnhandled,
|
||||
'hosts_pending' => $hostsPending,
|
||||
'services_ok' => $servicesOk,
|
||||
'services_unknown_handled' => $servicesUnknownHandled,
|
||||
'services_unknown_unhandled' => $servicesUnknownUnhandled,
|
||||
'services_critical_handled' => $servicesCriticalHandled,
|
||||
'services_critical_unhandled' => $servicesCriticalUnhandled,
|
||||
'services_warning_handled' => $servicesWarningHandled,
|
||||
'services_warning_unhandled' => $servicesWarningUnhandled,
|
||||
'services_pending' => $servicesPending
|
||||
);
|
||||
return array((object) array_intersect_key($rs, array_flip($this->getColumns())));
|
||||
}
|
||||
}
|
|
@ -1,218 +0,0 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Module\Monitoring\Backend\Statusdat\Query;
|
||||
|
||||
use Icinga\Logger\Logger;
|
||||
use Icinga\Data\Optional;
|
||||
use Icinga\Data\The;
|
||||
use Icinga\Filter\Query\Node;
|
||||
use Icinga\Filter\Query\Tree;
|
||||
use Icinga\Protocol\Statusdat;
|
||||
use Icinga\Exception;
|
||||
use Icinga\Data\SimpleQuery;
|
||||
use Icinga\Protocol\Statusdat\Query as Query;
|
||||
use Icinga\Protocol\Statusdat\View\AccessorStrategy;
|
||||
use Icinga\Filter\Filterable;
|
||||
|
||||
/**
|
||||
* Class Query
|
||||
* @package Icinga\Backend\Statusdat
|
||||
*/
|
||||
abstract class StatusdatQuery extends Query implements Filterable, AccessorStrategy
|
||||
{
|
||||
const TIMESTAMP = 'timestamp';
|
||||
|
||||
/**
|
||||
* An array containing the mappi
|
||||
*
|
||||
* When implementing your own Mapper, this contains the static mapping rules.
|
||||
*
|
||||
* @see Icinga\Module\Monitoring\Backend\Statusdat\DataView\StatusdatServiceView for an example
|
||||
* @var array
|
||||
*/
|
||||
public static $mappedParameters = array();
|
||||
|
||||
/**
|
||||
* An array containing all properties that are retrieved by a function
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* @var array
|
||||
* @see Icinga\Backend\Statusdat\DataView\StatusdatServiceView for an example
|
||||
*/
|
||||
public static $handlerParameters = array();
|
||||
|
||||
public static $fieldTypes = array();
|
||||
|
||||
/**
|
||||
* @var null
|
||||
*/
|
||||
private $cursor = null;
|
||||
|
||||
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
$this->selectBase();
|
||||
}
|
||||
|
||||
abstract public function selectBase();
|
||||
|
||||
/**
|
||||
* 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, $isFunction = false)
|
||||
{
|
||||
|
||||
if ($column) {
|
||||
$column = strval($column);
|
||||
if (isset(static::$mappedParameters[$column])) {
|
||||
parent::order(static::$mappedParameters[$column], strtolower($dir));
|
||||
} elseif (isset(static::$handlerParameters[$column])) {
|
||||
parent::orderByFn(array($this, static::$handlerParameters[$column]), strtolower($dir));
|
||||
} else {
|
||||
Logger::info("Tried to sort by unknown column %s", $column);
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private $functionMap = array(
|
||||
"TO_DATE" => "toDateFormat"
|
||||
);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @see Icinga\Backend\DataView\AccessorStrategy
|
||||
*
|
||||
* @param The $item
|
||||
* @param The $field
|
||||
* @return The|string
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function get(&$item, $field)
|
||||
{
|
||||
$result = null;
|
||||
if (isset($item->$field)) {
|
||||
$result = $item->$field;
|
||||
} elseif (isset(static::$mappedParameters[$field])) {
|
||||
$result = $this->getMappedParameter($item, $field);
|
||||
} elseif (isset(static::$handlerParameters[$field])) {
|
||||
$hdl = static::$handlerParameters[$field];
|
||||
$result = $this->$hdl($item);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function applyPropertyFunction($function, $value)
|
||||
{
|
||||
if (!isset($this->functionMap[$function])) {
|
||||
return $value;
|
||||
}
|
||||
$fn = $this->functionMap[$function];
|
||||
|
||||
return $this->$fn($value);
|
||||
}
|
||||
|
||||
private function toDateFormat($value)
|
||||
{
|
||||
if (is_numeric($value)) {
|
||||
return date("Y-m-d H:i:s", intval($value));
|
||||
} else {
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
||||
private function getMappedParameter(&$item, $field)
|
||||
{
|
||||
$matches = array();
|
||||
$fieldDef = static::$mappedParameters[$field];
|
||||
|
||||
$function = false;
|
||||
if (preg_match_all('/(?P<FUNCTION>\w+)\((?P<PARAMETER>.*)\)/', $fieldDef, $matches)) {
|
||||
$function = $matches["FUNCTION"][0];
|
||||
$fieldDef = $matches["PARAMETER"][0];
|
||||
}
|
||||
$mapped = explode(".", $fieldDef);
|
||||
$res = $item;
|
||||
|
||||
foreach ($mapped as $map) {
|
||||
if (is_array($res)) {
|
||||
$subResult = array();
|
||||
foreach ($res as $subitem) {
|
||||
if (!isset($subitem->$map)) {
|
||||
continue;
|
||||
}
|
||||
$subResult[] = $subitem->$map;
|
||||
}
|
||||
$res = join(',', $subResult);
|
||||
} else {
|
||||
if (!isset($res->$map)) {
|
||||
return "";
|
||||
}
|
||||
$res = $res->$map;
|
||||
}
|
||||
}
|
||||
|
||||
if ($function) {
|
||||
return $this->applyPropertyFunction($function, $res);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @see Icinga\Backend\DataView\AccessorStrategy
|
||||
*
|
||||
* @param The $field
|
||||
* @return The|string
|
||||
*/
|
||||
public function getMappedField($field)
|
||||
{
|
||||
if (isset(static::$mappedParameters[$field])) {
|
||||
return static::$mappedParameters[$field];
|
||||
}
|
||||
return $field;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @see Icinga\Backend\DataView\AccessorStrategy
|
||||
*
|
||||
* @param The $item
|
||||
* @param The $field
|
||||
* @return bool
|
||||
*/
|
||||
public function exists(&$item, $field)
|
||||
{
|
||||
return (isset($item->$field)
|
||||
|| isset(static::$mappedParameters[$field])
|
||||
|| isset(static::$handlerParameters[$field])
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public function isValidFilterTarget($field)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function isTimestamp($field)
|
||||
{
|
||||
return isset(static::$fieldTypes[$field]) && static::$fieldTypes[$field] === self::TIMESTAMP;
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue