commit
1b600a8dd3
|
@ -1,19 +1,33 @@
|
|||
<?php
|
||||
// @codingStandardsIgnoreStart
|
||||
|
||||
// TODO: Search for the best and safest quoting
|
||||
// TODO: Check whether attributes are safe. Script, title in combination with
|
||||
// Hover-Tips etc. Eventually create a whitelist for a few options only.
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
/**
|
||||
* Class Zend_View_Helper_Qlink
|
||||
* @package Application\Views
|
||||
*/
|
||||
class Zend_View_Helper_Qlink extends Zend_View_Helper_Abstract
|
||||
{
|
||||
|
||||
public function qlink($htmlContent, $urlFormat, array $uriParams = array(),
|
||||
array $properties = array())
|
||||
{
|
||||
/**
|
||||
* @param $htmlContent
|
||||
* @param $urlFormat
|
||||
* @param array $uriParams
|
||||
* @param array $properties
|
||||
* @return string
|
||||
*/
|
||||
public function qlink(
|
||||
$htmlContent,
|
||||
$urlFormat,
|
||||
array $uriParams = array(),
|
||||
array $properties = array()
|
||||
) {
|
||||
$quote = true;
|
||||
$attributes = array();
|
||||
$baseUrl = null;
|
||||
foreach ($properties as $key => $val) {
|
||||
if ($key === 'baseUrl' ) {
|
||||
if ($key === 'baseUrl') {
|
||||
// $baseUrl = filter_var($val, FILTER_SANITIZE_URL) . '/';
|
||||
$baseUrl = rawurlencode($val) . '/';
|
||||
continue;
|
||||
|
@ -47,17 +61,20 @@ class Zend_View_Helper_Qlink extends Zend_View_Helper_Abstract
|
|||
'<a href="%s"%s>%s</a>',
|
||||
$this->getFormattedUrl($urlFormat, $uriParams, $baseUrl),
|
||||
!empty($attributes) ? ' ' . implode(' ', $attributes) : '',
|
||||
$quote
|
||||
? filter_var(
|
||||
$quote ? filter_var(
|
||||
$htmlContent,
|
||||
FILTER_SANITIZE_FULL_SPECIAL_CHARS,
|
||||
FILTER_FLAG_NO_ENCODE_QUOTES
|
||||
)
|
||||
// Alternativ: htmlentities($htmlContent)
|
||||
: $htmlContent
|
||||
) : $htmlContent // Alternative: htmlentities($htmlContent)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $urlFormat
|
||||
* @param $uriParams
|
||||
* @param null $baseUrl
|
||||
* @return string
|
||||
*/
|
||||
public function getFormattedUrl($urlFormat, $uriParams, $baseUrl = null)
|
||||
{
|
||||
$params = $args = array();
|
||||
|
@ -70,10 +87,10 @@ class Zend_View_Helper_Qlink extends Zend_View_Helper_Abstract
|
|||
}
|
||||
$url = $urlFormat;
|
||||
$url = vsprintf($url, $params);
|
||||
if (! empty($args)) {
|
||||
if (!empty($args)) {
|
||||
$url .= '?' . implode('&', $args);
|
||||
}
|
||||
return is_null($baseUrl) ? $this->view->baseUrl($url) : $baseUrl.$url;
|
||||
return is_null($baseUrl) ? $this->view->baseUrl($url) : $baseUrl . $url;
|
||||
}
|
||||
}
|
||||
|
||||
// @codingStandardsIgnoreEnd
|
|
@ -1,9 +1,13 @@
|
|||
#!/usr/bin/php
|
||||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
require_once dirname(__FILE__) . '/../library/Icinga/Application/Cli.php';
|
||||
use Icinga\Application\Cli,
|
||||
Icinga\Application\TranslationHelper;
|
||||
|
||||
use Icinga\Application\Cli;
|
||||
use Icinga\Application\TranslationHelper;
|
||||
|
||||
$bootstrap = Cli::start();
|
||||
|
||||
if (count($argv) < 2) {
|
||||
|
|
|
@ -1,15 +1,19 @@
|
|||
#!/usr/bin/php
|
||||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
set_include_path(
|
||||
realpath(dirname(__FILE__) . '/../library/')
|
||||
. ':' . get_include_path()
|
||||
. ':'
|
||||
. get_include_path()
|
||||
);
|
||||
|
||||
require_once 'Icinga/Application/Cli.php';
|
||||
use Icinga\Application\Cli,
|
||||
Icinga\Util\Format;
|
||||
|
||||
use Icinga\Application\Cli;
|
||||
use Icinga\Util\Format;
|
||||
|
||||
$app = Cli::start();
|
||||
|
||||
echo Format::bytes(10930423) . "\n";
|
||||
|
||||
|
|
|
@ -1,68 +1,130 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Application;
|
||||
|
||||
use Icinga\Exception\ConfigurationError;
|
||||
|
||||
/**
|
||||
* Class Logger
|
||||
* @package Icinga\Application
|
||||
*/
|
||||
class Logger
|
||||
{
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const DEFAULT_LOG_TYPE = "stream";
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const DEFAULT_LOG_TARGET = "./var/log/icinga.log";
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const DEFAULT_DEBUG_TARGET = "./var/log/icinga.debug.log";
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $writers = array();
|
||||
|
||||
/**
|
||||
* @var null
|
||||
*/
|
||||
private $logger = null;
|
||||
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
private static $instance;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private static $queue = array();
|
||||
|
||||
/**
|
||||
* @param \Zend_Config $config
|
||||
*/
|
||||
public function __construct(\Zend_Config $config)
|
||||
{
|
||||
$this->overwrite($config);
|
||||
}
|
||||
|
||||
public function getWriters() {
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getWriters()
|
||||
{
|
||||
return $this->writers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Zend_Config $config
|
||||
*/
|
||||
public function overwrite(\Zend_Config $config)
|
||||
{
|
||||
$this->clearLog();
|
||||
try {
|
||||
if ($config->debug && $config->debug->enable == 1)
|
||||
if ($config->debug && $config->debug->enable == 1) {
|
||||
$this->setupDebugLog($config);
|
||||
} catch (\Icinga\Exception\ConfigurationError $e) {
|
||||
$this->warn("Could not create debug log: {$e->getMessage()}");
|
||||
}
|
||||
} catch (ConfigurationError $e) {
|
||||
$this->warn("Could not create debug log: {$e->getMessage()}");
|
||||
}
|
||||
|
||||
$this->setupLog($config);
|
||||
$this->flushQueue();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Zend_Config $config
|
||||
*/
|
||||
private function setupDebugLog(\Zend_Config $config)
|
||||
{
|
||||
$type = $config->debug->get("type", self::DEFAULT_LOG_TYPE);
|
||||
$target = $config->debug->get("target", self::DEFAULT_LOG_TARGET);
|
||||
if ($target == self::DEFAULT_LOG_TARGET)
|
||||
$type == self::DEFAULT_LOG_TYPE;
|
||||
if ($target == self::DEFAULT_LOG_TARGET) {
|
||||
$type == self::DEFAULT_LOG_TYPE;
|
||||
}
|
||||
|
||||
$this->addWriter($type, $target, \Zend_Log::DEBUG);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Zend_Config $config
|
||||
*/
|
||||
private function setupLog(\Zend_Config $config)
|
||||
{
|
||||
$type = $config->get("type", self::DEFAULT_LOG_TYPE);
|
||||
$target = $config->get("target", self::DEFAULT_DEBUG_TARGET);
|
||||
if ($target == self::DEFAULT_DEBUG_TARGET)
|
||||
if ($target == self::DEFAULT_DEBUG_TARGET) {
|
||||
$type == self::DEFAULT_LOG_TYPE;
|
||||
}
|
||||
$level = \Zend_Log::WARN;
|
||||
if ($config->get("verbose", 0) == 1)
|
||||
if ($config->get("verbose", 0) == 1) {
|
||||
$level = \Zend_Log::INFO;
|
||||
}
|
||||
$this->addWriter($type, $target, $level);
|
||||
}
|
||||
|
||||
private function addWriter($type, $target , $priority)
|
||||
/**
|
||||
* @param $type
|
||||
* @param $target
|
||||
* @param $priority
|
||||
* @throws ConfigurationError
|
||||
*/
|
||||
private function addWriter($type, $target, $priority)
|
||||
{
|
||||
$type[0] = strtoupper($type[0]);
|
||||
$writerClass = "\Zend_Log_Writer_" . $type;
|
||||
if (!class_exists($writerClass))
|
||||
throw new \Icinga\Exception\ConfigurationError("Could not create log: Unknown type " . $type);
|
||||
if (!class_exists($writerClass)) {
|
||||
throw new ConfigurationError("Could not create log: Unknown type " . $type);
|
||||
}
|
||||
|
||||
$writer = new $writerClass($target);
|
||||
|
||||
|
@ -71,13 +133,20 @@ class Logger
|
|||
$this->writers[] = $writer;
|
||||
}
|
||||
|
||||
/**
|
||||
* flushQueue
|
||||
*/
|
||||
public function flushQueue()
|
||||
{
|
||||
foreach(self::$queue as $msgTypePair) {
|
||||
$this->logger->log($msgTypePair[0],$msgTypePair[1]);
|
||||
foreach (self::$queue as $msgTypePair) {
|
||||
$this->logger->log($msgTypePair[0], $msgTypePair[1]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $argv
|
||||
* @return string
|
||||
*/
|
||||
public static function formatMessage(array $argv)
|
||||
{
|
||||
|
||||
|
@ -90,14 +159,17 @@ class Logger
|
|||
$format = json_encode($format);
|
||||
}
|
||||
foreach ($argv as &$arg) {
|
||||
if (!is_string($arg))
|
||||
if (!is_string($arg)) {
|
||||
$arg = json_encode($arg);
|
||||
}
|
||||
}
|
||||
|
||||
return @vsprintf($format, $argv);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* clearLog
|
||||
*/
|
||||
public function clearLog()
|
||||
{
|
||||
$this->logger = null;
|
||||
|
@ -105,47 +177,79 @@ class Logger
|
|||
$this->logger = new \Zend_Log();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Zend_Config $config
|
||||
* @return Logger
|
||||
*/
|
||||
public static function create(\Zend_Config $config)
|
||||
{
|
||||
if (self::$instance)
|
||||
if (self::$instance) {
|
||||
return self::$instance->overwrite($config);
|
||||
}
|
||||
return self::$instance = new Logger($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* debug
|
||||
*/
|
||||
public static function debug()
|
||||
{
|
||||
self::log(self::formatMessage(func_get_args()),\Zend_Log::DEBUG);
|
||||
self::log(self::formatMessage(func_get_args()), \Zend_Log::DEBUG);
|
||||
}
|
||||
|
||||
public static function warn() {
|
||||
self::log(self::formatMessage(func_get_args()),\Zend_Log::WARN);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static function warn()
|
||||
{
|
||||
self::log(self::formatMessage(func_get_args()), \Zend_Log::WARN);
|
||||
}
|
||||
|
||||
public static function info() {
|
||||
self::log(self::formatMessage(func_get_args()),\Zend_Log::INFO);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static function info()
|
||||
{
|
||||
self::log(self::formatMessage(func_get_args()), \Zend_Log::INFO);
|
||||
}
|
||||
|
||||
public static function error() {
|
||||
self::log(self::formatMessage(func_get_args()),\Zend_Log::ERR);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static function error()
|
||||
{
|
||||
self::log(self::formatMessage(func_get_args()), \Zend_Log::ERR);
|
||||
}
|
||||
|
||||
public static function fatal() {
|
||||
self::log(self::formatMessage(func_get_args()),\Zend_Log::EMERG);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static function fatal()
|
||||
{
|
||||
self::log(self::formatMessage(func_get_args()), \Zend_Log::EMERG);
|
||||
}
|
||||
|
||||
private static function log($msg,$level = \Zend_Log::INFO) {
|
||||
/**
|
||||
* @param $msg
|
||||
* @param int $level
|
||||
*/
|
||||
private static function log($msg, $level = \Zend_Log::INFO)
|
||||
{
|
||||
$logger = self::$instance;
|
||||
|
||||
if(!$logger) {
|
||||
array_push(self::$queue, array($msg,$level));
|
||||
if (!$logger) {
|
||||
array_push(self::$queue, array($msg, $level));
|
||||
return;
|
||||
}
|
||||
|
||||
$logger->logger->log($msg,$level);
|
||||
$logger->logger->log($msg, $level);
|
||||
}
|
||||
|
||||
|
||||
public static function reset() {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static function reset()
|
||||
{
|
||||
self::$queue = array();
|
||||
self::$instance = null;
|
||||
}
|
||||
|
|
|
@ -1,16 +1,26 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Backend;
|
||||
|
||||
use Icinga\Application\Config;
|
||||
|
||||
/**
|
||||
* Icinga Backend Abstract
|
||||
*
|
||||
* @package Icinga\Backend
|
||||
*/
|
||||
namespace Icinga\Backend;
|
||||
use Icinga\Application\Config;
|
||||
|
||||
abstract class AbstractBackend
|
||||
{
|
||||
/**
|
||||
* @var \Zend_Config
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $extensions = array();
|
||||
|
||||
/**
|
||||
|
@ -23,8 +33,9 @@ abstract class AbstractBackend
|
|||
*/
|
||||
final public function __construct(\Zend_Config $config = null)
|
||||
{
|
||||
if ($config == null)
|
||||
if ($config == null) {
|
||||
$config = new \Zend_Config(array());
|
||||
}
|
||||
$this->config = $config;
|
||||
$this->init();
|
||||
}
|
||||
|
@ -34,7 +45,9 @@ abstract class AbstractBackend
|
|||
*
|
||||
* return void
|
||||
*/
|
||||
protected function init() {}
|
||||
protected function init()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Dummy function for fluent code
|
||||
|
@ -52,44 +65,58 @@ abstract class AbstractBackend
|
|||
* Leave fields empty to get all available properties
|
||||
*
|
||||
* @param string Virtual table name
|
||||
* @param array Fields
|
||||
* return \Icinga\Backend\Ido\Query
|
||||
* @param array $fields
|
||||
* @throws \Exception
|
||||
* @return
|
||||
* @internal param \Icinga\Backend\Fields $array return \Icinga\Backend\Ido\Query* return \Icinga\Backend\Ido\Query
|
||||
*/
|
||||
public function from($virtual_table, $fields = array())
|
||||
{
|
||||
$classname = $this->tableToClassName($virtual_table);
|
||||
if (! class_exists($classname)) {
|
||||
if (!class_exists($classname)) {
|
||||
throw new \Exception(sprintf('Asking for invalid virtual table %s', $classname));
|
||||
}
|
||||
$query = new $classname($this, $fields);
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $virtual_table
|
||||
* @return bool
|
||||
*/
|
||||
public function hasView($virtual_table)
|
||||
{
|
||||
return class_exists($this->tableToClassName($virtual_table));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $virtual_table
|
||||
* @return string
|
||||
*/
|
||||
protected function tableToClassName($virtual_table)
|
||||
{
|
||||
if (strpos($virtual_table,"/") !== false) {
|
||||
list($module, $classname) = explode("/",$virtual_table,2);
|
||||
$class = array_pop(explode("\\",get_class($this)));
|
||||
return 'Icinga\\'.ucfirst($module).'\\Backend\\'.$class.'\\'.ucfirst($classname).'Query';
|
||||
if (strpos($virtual_table, "/") !== false) {
|
||||
list($module, $classname) = explode("/", $virtual_table, 2);
|
||||
$class = array_pop(explode("\\", get_class($this)));
|
||||
return 'Icinga\\' . ucfirst($module) . '\\Backend\\' . $class . '\\' . ucfirst($classname) . 'Query';
|
||||
} else {
|
||||
return get_class($this) . '\\' . ucfirst($virtual_table . 'Query');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return preg_replace('~^.+\\\(.+?)$~', '$1', get_class($this));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->getName();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,35 +1,53 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Backend\Criteria;
|
||||
|
||||
/**
|
||||
* Class Order
|
||||
*
|
||||
* Constants for order definitions.
|
||||
* These only describe logical orders without going into storage specific
|
||||
* details, like which fields are used for ordering. It's completely up to the query to determine what to do with these
|
||||
* constants (although the result should be consistent among the different storage apis).
|
||||
*
|
||||
* @package Icinga\Backend\Criteria
|
||||
*/
|
||||
class Order
|
||||
{
|
||||
/**
|
||||
* Order by the newest events. What this means has to be determined in the context.
|
||||
* Mostly this affects last_state_change
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const STATE_CHANGE = "state_change";
|
||||
|
||||
/**
|
||||
* Order by the state of service objects. Mostly this is critical->unknown->warning->ok,
|
||||
* but also might take acknowledgments and downtimes in account
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const SERVICE_STATE = "service_state";
|
||||
|
||||
/**
|
||||
* Order by the state of host objects. Mostly this is critical->unknown->warning->ok,
|
||||
* but also might take acknowledgments and downtimes in account
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const HOST_STATE = "host_state";
|
||||
const HOST_STATE = "host_state";
|
||||
|
||||
const HOST_NAME = "host_name";
|
||||
const SERVICE_NAME = "service_description";
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
const HOST_NAME = "host_name";
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const SERVICE_NAME = "service_description";
|
||||
}
|
||||
|
||||
|
|
|
@ -1,21 +1,26 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Backend\DataView;
|
||||
|
||||
/**
|
||||
* Class AbstractAccessorStrategy
|
||||
* Basic interface for views.
|
||||
* The name sound weirder than it is: Views define special get and exists operations for fields that are not
|
||||
* directly available in a resultset, but exist under another name or can be accessed by loading an additional object
|
||||
* during runtime.
|
||||
* The name sound weirder than it is: Views define special get and exists operations for fields
|
||||
* that are not directly available in a resultset, but exist under another name or can be
|
||||
* accessed by loading an additional object during runtime.
|
||||
*
|
||||
* @see Icinga\Backend\DataView\ObjectRemappingView For an implementation of mapping field names
|
||||
* to storage specific names, e.g. service_state being status.current_state in status.dat views.
|
||||
*
|
||||
* @see Icinga\Backend\MonitoringObjectList For the typical usage of this class. It is not wrapped
|
||||
* around the monitoring object, so we don't use __get() or __set() and always have to give the item we'd like to access.
|
||||
*
|
||||
* around the monitoring object, so we don't use __get() or __set() and always have to give the
|
||||
* item we'd like to access.
|
||||
* @package Icinga\Backend\DataView
|
||||
*/
|
||||
interface AbstractAccessorStrategy {
|
||||
interface AbstractAccessorStrategy
|
||||
{
|
||||
/**
|
||||
* Returns a field for the item, or throws an Exception if the field doesn't exist
|
||||
*
|
||||
|
@ -25,7 +30,7 @@ interface AbstractAccessorStrategy {
|
|||
*
|
||||
* @throws \InvalidArgumentException when the field does not exist
|
||||
*/
|
||||
public function get(&$item,$field);
|
||||
public function get(&$item, $field);
|
||||
|
||||
/**
|
||||
* Returns the name that the field has in the specific backend. Might not be available for every field/view
|
||||
|
@ -41,5 +46,5 @@ interface AbstractAccessorStrategy {
|
|||
* @param $field The field to check on the $item
|
||||
* @return bool True when the field exists, otherwise false
|
||||
*/
|
||||
public function exists(&$item,$field);
|
||||
public function exists(&$item, $field);
|
||||
}
|
||||
|
|
|
@ -1,17 +1,25 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Backend\DataView;
|
||||
|
||||
/**
|
||||
* Class ObjectRemappingView
|
||||
*
|
||||
* Dataview that maps generic field names to storage specific fields or requests them via handlers.
|
||||
*
|
||||
* When accessing objects, every storage api returns them with other names. You can't simply say $object->service_state,
|
||||
* because this field is, e.g. under status.current_state in the status.dat view, while IDO uses servicestate->current_state.
|
||||
* When accessing objects, every storage api returns them with other names. You can't simply say
|
||||
* $object->service_state, because this field is, e.g. under status.current_state in the status.dat
|
||||
* view, while IDO uses servicestate->current_state.
|
||||
*
|
||||
* This view is intended for normalizing these changes, so a request of service_state returns the right field for the backend.
|
||||
* When implementing it, you have to fill the mappedParameters and/or the handlerParameters array. While mappedParameters
|
||||
* simply translate logic field names to storage specific ones, handlerParameters determins functions that handle data
|
||||
* retrieval for the specific fields.
|
||||
* This view is intended for normalizing these changes, so a request of service_state returns the
|
||||
* right field for the backend. When implementing it, you have to fill the mappedParameters and/or
|
||||
* the handlerParameters array. While mappedParameters simply translate logic field names to
|
||||
* storage specific ones, handlerParameters determins functions that handle data retrieval for
|
||||
* the specific fields.
|
||||
*
|
||||
* @package Icinga\Backend\DataView
|
||||
*/
|
||||
class ObjectRemappingView implements AbstractAccessorStrategy
|
||||
{
|
||||
|
@ -46,15 +54,17 @@ class ObjectRemappingView implements AbstractAccessorStrategy
|
|||
public function get(&$item, $field)
|
||||
{
|
||||
|
||||
if (isset($item->$field))
|
||||
if (isset($item->$field)) {
|
||||
return $item->$field;
|
||||
}
|
||||
if (isset($this->mappedParameters[$field])) {
|
||||
$mapped = explode(".",$this->mappedParameters[$field]);
|
||||
$mapped = explode(".", $this->mappedParameters[$field]);
|
||||
$res = $item;
|
||||
|
||||
foreach($mapped as $map) {
|
||||
if(!isset($res->$map))
|
||||
foreach ($mapped as $map) {
|
||||
if (!isset($res->$map)) {
|
||||
return "";
|
||||
}
|
||||
$res = $res->$map;
|
||||
}
|
||||
return $res;
|
||||
|
@ -76,8 +86,9 @@ class ObjectRemappingView implements AbstractAccessorStrategy
|
|||
*/
|
||||
public function getNormalizedFieldName($field)
|
||||
{
|
||||
if(isset($this->mappedParameters[$field]))
|
||||
if (isset($this->mappedParameters[$field])) {
|
||||
return $this->mappedParameters[$field];
|
||||
}
|
||||
return $field;
|
||||
}
|
||||
|
||||
|
@ -96,5 +107,4 @@ class ObjectRemappingView implements AbstractAccessorStrategy
|
|||
|| isset($this->handlerParameters[$field])
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,23 +1,85 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Backend;
|
||||
|
||||
use Icinga\Web\Paginator\Adapter\QueryAdapter;
|
||||
|
||||
/**
|
||||
* Class Query
|
||||
* @package Icinga\Backend
|
||||
*/
|
||||
abstract class Query
|
||||
{
|
||||
|
||||
/**
|
||||
* @var AbstractBackend
|
||||
*/
|
||||
protected $backend;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $columns = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $available_columns = array();
|
||||
|
||||
/**
|
||||
* @param null $count
|
||||
* @param null $offset
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function limit($count = null, $offset = null);
|
||||
|
||||
/**
|
||||
* @param $column
|
||||
* @param null $value
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function where($column, $value = null);
|
||||
|
||||
/**
|
||||
* @param string $column
|
||||
* @param null $dir
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function order($column = '', $dir = null);
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function fetchAll();
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function fetchRow();
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function fetchPairs();
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function fetchOne();
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function count();
|
||||
|
||||
public function __construct(\Icinga\Backend\AbstractBackend $backend, $columns = array())
|
||||
/**
|
||||
* @param AbstractBackend $backend
|
||||
* @param array $columns
|
||||
* @return \Icinga\Backend\Query
|
||||
*/
|
||||
public function __construct(AbstractBackend $backend, $columns = array())
|
||||
{
|
||||
$this->backend = $backend;
|
||||
if (empty($columns) || $columns === '*') {
|
||||
|
@ -28,6 +90,10 @@ abstract class Query
|
|||
$this->init();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $filters
|
||||
* @return $this
|
||||
*/
|
||||
public function applyFilters($filters = array())
|
||||
{
|
||||
foreach ($filters as $key => $val) {
|
||||
|
@ -36,13 +102,23 @@ abstract class Query
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
abstract protected function init();
|
||||
|
||||
protected function finalize() {}
|
||||
/*
|
||||
*
|
||||
*/
|
||||
protected function finalize()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a pagination adapter for the current query
|
||||
*
|
||||
* @param null $limit
|
||||
* @param null $page
|
||||
* @return \Zend_Paginator
|
||||
*/
|
||||
public function paginate($limit = null, $page = null)
|
||||
|
@ -56,11 +132,10 @@ abstract class Query
|
|||
$limit = $request->getParam('limit', 20);
|
||||
}
|
||||
$paginator = new \Zend_Paginator(
|
||||
new \Icinga\Web\Paginator\Adapter\QueryAdapter($this)
|
||||
new QueryAdapter($this)
|
||||
);
|
||||
$paginator->setItemCountPerPage($limit);
|
||||
$paginator->setCurrentPageNumber($page);
|
||||
return $paginator;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,58 +1,87 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Backend;
|
||||
|
||||
use Icinga\Backend\Statusdat\DataView\StatusdatHostView;
|
||||
use Icinga\Backend\Statusdat\DataView\StatusdatServiceView;
|
||||
use Icinga\Protocol\Statusdat as StatusdatProtocol;
|
||||
|
||||
|
||||
/**
|
||||
* Class Statusdat
|
||||
* @package Icinga\Backend
|
||||
*/
|
||||
class Statusdat extends AbstractBackend
|
||||
{
|
||||
/**
|
||||
* @var null
|
||||
*/
|
||||
private $reader = null;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
$this->reader = new StatusdatProtocol\Reader($this->config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null
|
||||
*/
|
||||
public function getReader()
|
||||
{
|
||||
return $this->reader;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $filter
|
||||
* @param array $flags
|
||||
* @return mixed
|
||||
*/
|
||||
public function listServices($filter = array(), $flags = array())
|
||||
{
|
||||
$query = $this->select()->from("servicelist");
|
||||
return $query->fetchAll();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $host
|
||||
* @return MonitoringObjectList|null
|
||||
*/
|
||||
public function fetchHost($host)
|
||||
{
|
||||
$objs = & $this->reader->getObjects();
|
||||
|
||||
if (!isset($objs["host"][$host]))
|
||||
if (!isset($objs["host"][$host])) {
|
||||
return null;
|
||||
}
|
||||
$result = array($objs["host"][$host]);
|
||||
return new MonitoringObjectList(
|
||||
$result,
|
||||
new \Icinga\Backend\Statusdat\DataView\StatusdatHostView($this->reader)
|
||||
new StatusdatHostView($this->reader)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $host
|
||||
* @param $service
|
||||
* @return MonitoringObjectList|null
|
||||
*/
|
||||
public function fetchService($host, $service)
|
||||
{
|
||||
$idxName = $host . ";" . $service;
|
||||
$objs = & $this->reader->getObjects();
|
||||
|
||||
if (!isset($objs["service"][$idxName]))
|
||||
if (!isset($objs["service"][$idxName])) {
|
||||
return null;
|
||||
}
|
||||
$result = array($objs["service"][$idxName]);
|
||||
return new MonitoringObjectList(
|
||||
$result,
|
||||
new \Icinga\Backend\Statusdat\DataView\StatusdatServiceView($this->reader)
|
||||
new StatusdatServiceView($this->reader)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,48 +1,73 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Backend\Statusdat\DataView;
|
||||
|
||||
use Icinga\Backend\DataView\ObjectRemappingView;
|
||||
use \Icinga\Protocol\Statusdat\IReader;
|
||||
class StatusdatHostView extends \Icinga\Backend\DataView\ObjectRemappingView
|
||||
|
||||
/**
|
||||
* Class StatusdatHostView
|
||||
* @package Icinga\Backend\Statusdat\DataView
|
||||
*/
|
||||
class StatusdatHostView extends ObjectRemappingView
|
||||
{
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
private $state;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $handlerParameters = array(
|
||||
"host" => "getHost",
|
||||
"downtimes_with_info" => "getDowntimes",
|
||||
"comments_with_info" => "getComments"
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $mappedParameters = array(
|
||||
"host_address" => "host_name",
|
||||
"host_name" => "host_name",
|
||||
"host_state" => "status.current_state",
|
||||
"host_output" => "status.plugin_output",
|
||||
"host_perfdata" => "status.long_plugin_output",
|
||||
"host_state" => "status.current_state",
|
||||
"host_perfdata" => "status.long_plugin_output",
|
||||
"host_last_state_change" => "status.last_state_change",
|
||||
"host_output" => "status.plugin_output",
|
||||
"host_check_command" => "check_command",
|
||||
"host_last_check" => "status.last_check",
|
||||
"host_next_check" => "status.next_check",
|
||||
"host_check_latency" => "status.check_latency",
|
||||
"host_check_execution_time" => "status.check_execution_time",
|
||||
"active_checks_enabled" => "status.active_checks_enabled",
|
||||
|
||||
"acknowledged" => "status.problem_has_been_acknowledged",
|
||||
"host_acknowledged" => "status.problem_has_been_acknowledged",
|
||||
// "state" => "current_state"
|
||||
);
|
||||
|
||||
|
||||
public function getHost(&$item) {
|
||||
if(!isset($this->state["host"][$item->host_name]))
|
||||
/**
|
||||
* @param $item
|
||||
* @return null
|
||||
*/
|
||||
public function getHost(&$item)
|
||||
{
|
||||
if (!isset($this->state["host"][$item->host_name])) {
|
||||
return null;
|
||||
if(!isset($this->state["host"][$item->host_name]))
|
||||
}
|
||||
if (!isset($this->state["host"][$item->host_name])) {
|
||||
return null;
|
||||
}
|
||||
return $this->state["host"][$item->host_name];
|
||||
}
|
||||
|
||||
public function __construct(IReader $reader) {
|
||||
$this->state = &$reader->getState();
|
||||
/**
|
||||
* @param IReader $reader
|
||||
*/
|
||||
public function __construct(IReader $reader)
|
||||
{
|
||||
$this->state = & $reader->getState();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,30 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Backend\Statusdat\DataView;
|
||||
|
||||
use Icinga\Backend\DataView\ObjectRemappingView;
|
||||
use \Icinga\Protocol\Statusdat\IReader;
|
||||
|
||||
class StatusdatServiceView extends \Icinga\Backend\DataView\ObjectRemappingView
|
||||
class StatusdatServiceView extends ObjectRemappingView
|
||||
{
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
private $state;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $handlerParameters = array(
|
||||
"host" => "getHost",
|
||||
"downtimes_with_info" => "getDowntimes"
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $mappedParameters = array(
|
||||
"host_address" => "parenthost.address",
|
||||
"host_name" => "host_name",
|
||||
|
@ -26,35 +40,57 @@ class StatusdatServiceView extends \Icinga\Backend\DataView\ObjectRemappingView
|
|||
"service_next_check" => "status.next_check",
|
||||
"service_check_latency" => "status.check_latency",
|
||||
"service_check_execution_time" => "status.check_execution_time",
|
||||
"service_acknowledged" => "status.problem_has_been_acknowledged",
|
||||
"service_comments" => "comment"
|
||||
"service_acknowledged" => "status.problem_has_been_acknowledged",
|
||||
"service_comments" => "comment"
|
||||
|
||||
);
|
||||
|
||||
/**
|
||||
* @param \Icinga\Backend\DataView\The $item
|
||||
* @param \Icinga\Backend\DataView\The $field
|
||||
* @return \Icinga\Backend\DataView\The|string
|
||||
*/
|
||||
public function get(&$item, $field)
|
||||
{
|
||||
if(!isset($item->parenthost) && isset($this->state["host"]))
|
||||
if (!isset($item->parenthost) && isset($this->state["host"])) {
|
||||
$item->parenthost = $this->state["host"];
|
||||
}
|
||||
|
||||
return parent::get($item,$field);
|
||||
return parent::get($item, $field);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Icinga\Backend\DataView\The $item
|
||||
* @param \Icinga\Backend\DataView\The $field
|
||||
* @return bool
|
||||
*/
|
||||
public function exists(&$item, $field)
|
||||
{
|
||||
if(!isset($item->parenthost))
|
||||
if (!isset($item->parenthost)) {
|
||||
$item->parenthost = $this->state["host"];
|
||||
}
|
||||
|
||||
return parent::exists($item,$field);
|
||||
return parent::exists($item, $field);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $item
|
||||
* @return null
|
||||
*/
|
||||
public function getHost(&$item)
|
||||
{
|
||||
if (!isset($this->state["host"][$item->host_name]))
|
||||
if (!isset($this->state["host"][$item->host_name])) {
|
||||
return null;
|
||||
if (!isset($this->state["host"][$item->host_name]))
|
||||
}
|
||||
if (!isset($this->state["host"][$item->host_name])) {
|
||||
return null;
|
||||
}
|
||||
return $this->state["host"][$item->host_name];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param IReader $reader
|
||||
*/
|
||||
public function __construct(IReader $reader)
|
||||
{
|
||||
$this->state = & $reader->getState();
|
||||
|
|
|
@ -1,25 +1,45 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Backend\Statusdat;
|
||||
|
||||
abstract class GroupsummaryQuery extends Query
|
||||
{
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
protected $reader;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $groupType = "servicegroup";
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $base = "services";
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $available_columns = array(
|
||||
'ok' => 'SUM(CASE WHEN state = 0 THEN 1 ELSE 0 END)',
|
||||
'critical' => 'SUM(CASE WHEN state = 2 AND downtime = 0 AND ack = 0 THEN 1 ELSE 0 END)',
|
||||
'critical_dt' => 'SUM(CASE WHEN state = 2 AND downtime = 1 THEN 1 ELSE 0 END)',
|
||||
'ok' => 'SUM(CASE WHEN state = 0 THEN 1 ELSE 0 END)',
|
||||
'critical' => 'SUM(CASE WHEN state = 2 AND downtime = 0 AND ack = 0 THEN 1 ELSE 0 END)',
|
||||
'critical_dt' => 'SUM(CASE WHEN state = 2 AND downtime = 1 THEN 1 ELSE 0 END)',
|
||||
'critical_ack' => 'SUM(CASE WHEN state = 2 AND downtime = 0 AND ack = 1 THEN 1 ELSE 0 END)',
|
||||
'unknown' => 'SUM(CASE WHEN state = 3 AND downtime = 0 AND ack = 0 THEN 1 ELSE 0 END)',
|
||||
'unknown_dt' => 'SUM(CASE WHEN state = 3 AND downtime = 1 THEN 1 ELSE 0 END)',
|
||||
'unknown_ack' => 'SUM(CASE WHEN state = 3 AND downtime = 0 AND ack = 1 THEN 1 ELSE 0 END)',
|
||||
'warning' => 'SUM(CASE WHEN state = 1 AND downtime = 0 AND ack = 0 THEN 1 ELSE 0 END)',
|
||||
'warning_dt' => 'SUM(CASE WHEN state = 1 AND downtime = 1 THEN 1 ELSE 0 END)',
|
||||
'warning_ack' => 'SUM(CASE WHEN state = 1 AND downtime = 0 AND ack = 1 THEN 1 ELSE 0 END)',
|
||||
'unknown' => 'SUM(CASE WHEN state = 3 AND downtime = 0 AND ack = 0 THEN 1 ELSE 0 END)',
|
||||
'unknown_dt' => 'SUM(CASE WHEN state = 3 AND downtime = 1 THEN 1 ELSE 0 END)',
|
||||
'unknown_ack' => 'SUM(CASE WHEN state = 3 AND downtime = 0 AND ack = 1 THEN 1 ELSE 0 END)',
|
||||
'warning' => 'SUM(CASE WHEN state = 1 AND downtime = 0 AND ack = 0 THEN 1 ELSE 0 END)',
|
||||
'warning_dt' => 'SUM(CASE WHEN state = 1 AND downtime = 1 THEN 1 ELSE 0 END)',
|
||||
'warning_ack' => 'SUM(CASE WHEN state = 1 AND downtime = 0 AND ack = 1 THEN 1 ELSE 0 END)',
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $order_columns = array(
|
||||
'state' => array(
|
||||
'ASC' => array(
|
||||
|
@ -50,54 +70,66 @@ abstract class GroupsummaryQuery extends Query
|
|||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* @param $obj
|
||||
* @return string
|
||||
*/
|
||||
private function getStateType(&$obj)
|
||||
{
|
||||
|
||||
if ($obj->status->current_state == 0)
|
||||
if ($obj->status->current_state == 0) {
|
||||
return "ok";
|
||||
}
|
||||
$typeBase = "";
|
||||
if ($obj->status->current_state == 1) {
|
||||
$typeBase = 'warning';
|
||||
} else if ($obj->status->current_state == 2) {
|
||||
$typeBase = 'critical';
|
||||
} else if ($obj->status->current_state == 3) {
|
||||
$typeBase = 'unknown';
|
||||
} else {
|
||||
if ($obj->status->current_state == 2) {
|
||||
$typeBase = 'critical';
|
||||
} else {
|
||||
if ($obj->status->current_state == 3) {
|
||||
$typeBase = 'unknown';
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($obj->status->problem_has_been_acknowledged) {
|
||||
return $typeBase . "_ack";
|
||||
|
||||
} else if (isset($obj->status->downtime)) {
|
||||
return $typeBase . "_dt";
|
||||
} else {
|
||||
if (isset($obj->status->downtime)) {
|
||||
return $typeBase . "_dt";
|
||||
}
|
||||
}
|
||||
return $typeBase;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $indices
|
||||
* @return array
|
||||
*/
|
||||
public function groupByProblemType(&$indices)
|
||||
{
|
||||
|
||||
|
||||
$typename = $this->groupType."_name";
|
||||
$typename = $this->groupType . "_name";
|
||||
$result = array();
|
||||
foreach ($indices as $type=>$subIndices) {
|
||||
foreach ($indices as $type => $subIndices) {
|
||||
|
||||
foreach ($subIndices as $objName) {
|
||||
|
||||
$obj = &$this->reader->getObjectByName($type,$objName);
|
||||
$obj = & $this->reader->getObjectByName($type, $objName);
|
||||
$statetype = $this->getStateType($obj);
|
||||
foreach($obj->group as $group) {
|
||||
if(!isset($result[$group])) {
|
||||
$result[$group] = (object) array(
|
||||
$typename => $group,
|
||||
'ok' => 0,
|
||||
'critical' => 0,
|
||||
'critical_dt' => 0,
|
||||
foreach ($obj->group as $group) {
|
||||
if (!isset($result[$group])) {
|
||||
$result[$group] = (object)array(
|
||||
$typename => $group,
|
||||
'ok' => 0,
|
||||
'critical' => 0,
|
||||
'critical_dt' => 0,
|
||||
'critical_ack' => 0,
|
||||
'unknown' => 0,
|
||||
'unknown_dt' => 0,
|
||||
'unknown_ack' => 0,
|
||||
'warning' => 0,
|
||||
'warning_dt' => 0,
|
||||
'warning_ack' => 0
|
||||
'unknown' => 0,
|
||||
'unknown_dt' => 0,
|
||||
'unknown_ack' => 0,
|
||||
'warning' => 0,
|
||||
'warning_dt' => 0,
|
||||
'warning_ack' => 0
|
||||
);
|
||||
}
|
||||
$result[$group]->$statetype++;
|
||||
|
@ -110,21 +142,30 @@ abstract class GroupsummaryQuery extends Query
|
|||
|
||||
/**
|
||||
* @var \Icinga\Protocol\Statusdat\Query
|
||||
* @return mixed|void
|
||||
*/
|
||||
|
||||
|
||||
public function init() {
|
||||
public function init()
|
||||
{
|
||||
$this->reader = $this->backend->getReader();
|
||||
$this->query = $this->reader->select()->from($this->base,array())->groupByFunction("groupByProblemType",$this)->where("COUNT{group} > 0");
|
||||
$this->query = $this->reader->select()->from($this->base, array())->groupByFunction(
|
||||
"groupByProblemType",
|
||||
$this
|
||||
)->where("COUNT{group} > 0");
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param The $column
|
||||
* @param null $value
|
||||
* @return $this|Query
|
||||
*/
|
||||
public function where($column, $value = null)
|
||||
{
|
||||
if ($column === 'problems') {
|
||||
if ($value === 'true') {
|
||||
//$this->where("COUNT{downtime} == 0 AND status.problem_has_been_acknowledged == 0 AND status.current_state > 0");
|
||||
//$this->where(
|
||||
// "COUNT{downtime} == 0 AND status.problem_has_been_acknowledged == 0 AND status.current_state > 0"
|
||||
// );
|
||||
}
|
||||
} elseif ($column === 'search') {
|
||||
if ($value) {
|
||||
|
@ -136,4 +177,3 @@ abstract class GroupsummaryQuery extends Query
|
|||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,22 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Backend\Statusdat;
|
||||
|
||||
/**
|
||||
* Class HostgroupsummaryQuery
|
||||
* @package Icinga\Backend\Statusdat
|
||||
*/
|
||||
class HostgroupsummaryQuery extends GroupsummaryQuery
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $groupType = "hostgroup";
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $base = "hosts";
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,29 +1,34 @@
|
|||
<?php
|
||||
/**
|
||||
* Created by JetBrains PhpStorm.
|
||||
* User: moja
|
||||
* Date: 1/29/13
|
||||
* Time: 11:36 AM
|
||||
* To change this template use File | Settings | File Templates.
|
||||
*/
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Backend\Statusdat;
|
||||
|
||||
use Icinga\Protocol\Statusdat;
|
||||
use Icinga\Exception;
|
||||
|
||||
|
||||
/**
|
||||
* Class HostListQuery
|
||||
* @package Icinga\Backend\Statusdat
|
||||
*/
|
||||
class HostListQuery extends Query
|
||||
{
|
||||
/**
|
||||
* @var \Icinga\Protocol\Statusdat\Query
|
||||
*/
|
||||
protected $query;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $view = 'Icinga\Backend\Statusdat\DataView\StatusdatHostView';
|
||||
|
||||
public function init() {
|
||||
/**
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
$this->reader = $this->backend->getReader();
|
||||
$this->query = $this->reader->select()->from("hosts",array());
|
||||
$this->query = $this->reader->select()->from("hosts", array());
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,28 +1,41 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Backend\Statusdat;
|
||||
|
||||
use Icinga\Backend\Criteria\Order;
|
||||
use Icinga\Backend\MonitoringObjectList as MList;
|
||||
use Icinga\Protocol\Statusdat;
|
||||
use Icinga\Exception;
|
||||
|
||||
use Icinga\Backend\Query as BaseQuery;
|
||||
|
||||
/**
|
||||
* Base class for statusdat queries, contains most of the filter/order logic
|
||||
*
|
||||
* Class Query
|
||||
* @package Icinga\Backend\Statusdat
|
||||
*/
|
||||
abstract class Query extends \Icinga\Backend\Query
|
||||
abstract class Query extends BaseQuery
|
||||
{
|
||||
/**
|
||||
* @var null
|
||||
*/
|
||||
protected $cursor = null;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $view = 'Icinga\Backend\Statusdat\DataView\StatusdatServiceView';
|
||||
|
||||
/**
|
||||
* @var array Mapping of order to field names
|
||||
* @todo Is not complete right now
|
||||
*/
|
||||
protected $orderColumns = array(
|
||||
\Icinga\Backend\Criteria\Order::SERVICE_STATE => "status.current_state",
|
||||
\Icinga\Backend\Criteria\Order::STATE_CHANGE => "status.last_state_change",
|
||||
\Icinga\Backend\Criteria\Order::HOST_STATE => "status.current_state",
|
||||
\Icinga\Backend\Criteria\Order::HOST_NAME => "host_name",
|
||||
\Icinga\Backend\Criteria\Order::SERVICE_NAME => "service_description"
|
||||
Order::SERVICE_STATE => "status.current_state",
|
||||
Order::STATE_CHANGE => "status.last_state_change",
|
||||
Order::HOST_STATE => "status.current_state",
|
||||
Order::HOST_NAME => "host_name",
|
||||
Order::SERVICE_NAME => "service_description"
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -40,10 +53,11 @@ abstract class Query extends \Icinga\Backend\Query
|
|||
foreach ($filters as $filter => $value) {
|
||||
$filter[0] = strtoupper($filter[0]);
|
||||
$filterMethod = "apply" . $filter . "Filter";
|
||||
if (method_exists($this, $filterMethod))
|
||||
if (method_exists($this, $filterMethod)) {
|
||||
$this->$filterMethod($filter, $value);
|
||||
else
|
||||
} else {
|
||||
$this->where($filter, $value);
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
@ -117,27 +131,45 @@ abstract class Query extends \Icinga\Backend\Query
|
|||
$this->query->where("(status.problem_has_been_acknowledged = ? )", $val);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $type
|
||||
* @param $value
|
||||
*/
|
||||
public function applyHostnameFilter($type, $value)
|
||||
{
|
||||
if (!is_array($value))
|
||||
if (!is_array($value)) {
|
||||
$value = array($value);
|
||||
}
|
||||
$this->query->where("host_name LIKE ?", $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $type
|
||||
* @param $value
|
||||
*/
|
||||
public function applyStateFilter($type, $value)
|
||||
{
|
||||
$this->query->where("status.current_state = $value");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $type
|
||||
* @param $value
|
||||
*/
|
||||
public function applyHoststateFilter($type, $value)
|
||||
{
|
||||
$this->query->where("host.status.current_state = $value");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $type
|
||||
* @param $value
|
||||
*/
|
||||
public function applyServiceDescriptionFilter($type, $value)
|
||||
{
|
||||
if (!is_array($value))
|
||||
if (!is_array($value)) {
|
||||
$value = array($value);
|
||||
}
|
||||
$this->query->where("service_description LIKE ?", $value);
|
||||
}
|
||||
|
||||
|
@ -163,52 +195,70 @@ abstract class Query extends \Icinga\Backend\Query
|
|||
public function order($column = '', $dir = null)
|
||||
{
|
||||
|
||||
if ($column)
|
||||
if ($column) {
|
||||
$this->query->order($this->orderColumns[$column], strtolower($dir));
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a filter on this query by calling the statusdat where() function
|
||||
*
|
||||
* @param $column The (statusdat!) column to filter in "field operator ?" format. (@example status.current_state > ?)
|
||||
* @param $column The (statusdat!) column to filter in "field operator ?"
|
||||
* format. (@example status.current_state > ?)
|
||||
* @param mixed $value The value to filter for
|
||||
* @return Query Returns this query,for fluent interface
|
||||
*/
|
||||
public function where($column, $value = null)
|
||||
{
|
||||
if (!is_array($value))
|
||||
if (!is_array($value)) {
|
||||
$value = array($value);
|
||||
}
|
||||
$this->query->where($column, $value);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MList|mixed|null
|
||||
*/
|
||||
public function fetchAll()
|
||||
{
|
||||
$view = $this->view;
|
||||
if (!$this->cursor)
|
||||
if (!$this->cursor) {
|
||||
$this->cursor = new MList($this->query->getResult(), new $view($this->reader));
|
||||
}
|
||||
return $this->cursor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function fetchRow()
|
||||
{
|
||||
return next($this->fetchAll());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function fetchPairs()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function fetchOne()
|
||||
{
|
||||
return next($this->fetchAll());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|mixed
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return count($this->query->getResult());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,22 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Backend\Statusdat;
|
||||
|
||||
/**
|
||||
* Class ServicegroupsummaryQuery
|
||||
* @package Icinga\Backend\Statusdat
|
||||
*/
|
||||
class ServicegroupsummaryQuery extends GroupsummaryQuery
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $groupType = "servicegroup";
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $base = "services";
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,32 +1,34 @@
|
|||
<?php
|
||||
/**
|
||||
* Created by JetBrains PhpStorm.
|
||||
* User: moja
|
||||
* Date: 1/29/13
|
||||
* Time: 11:36 AM
|
||||
* To change this template use File | Settings | File Templates.
|
||||
*/
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Backend\Statusdat;
|
||||
|
||||
use Icinga\Backend\MonitoringObjectList as MList;
|
||||
use Icinga\Protocol\Statusdat;
|
||||
use Icinga\Backend\Statusdat\DataView\StatusdatServiceView as StatusdatServiceView;
|
||||
use Icinga\Exception;
|
||||
|
||||
|
||||
/**
|
||||
* Class ServicelistQuery
|
||||
* @package Icinga\Backend\Statusdat
|
||||
*/
|
||||
class ServicelistQuery extends Query
|
||||
{
|
||||
/**
|
||||
* @var \Icinga\Protocol\Statusdat\Query
|
||||
*/
|
||||
protected $query;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $view = 'Icinga\Backend\Statusdat\DataView\StatusdatServiceView';
|
||||
|
||||
|
||||
public function init() {
|
||||
public function init()
|
||||
{
|
||||
$this->reader = $this->backend->getReader();
|
||||
$this->query = $this->reader->select()->from("services",array());
|
||||
$this->query = $this->reader->select()->from("services", array());
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Exception;
|
||||
|
||||
/**
|
||||
* Class ConfigurationError
|
||||
* @package Icinga\Exception
|
||||
*/
|
||||
class ConfigurationError extends \RuntimeException
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Exception;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* Class MissingParameterException
|
||||
* @package Icinga\Exception
|
||||
*/
|
||||
class MissingParameterException extends RuntimeException
|
||||
{
|
||||
}
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Exception;
|
||||
|
||||
/**
|
||||
* Class NotImplementedError
|
||||
* @package Icinga\Exception
|
||||
*/
|
||||
class NotImplementedError extends \Exception
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Exception;
|
||||
|
||||
/**
|
||||
* Class ProgrammingError
|
||||
* @package Icinga\Exception
|
||||
*/
|
||||
class ProgrammingError extends \Exception
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -1,50 +1,105 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Protocol;
|
||||
|
||||
/**
|
||||
* Class AbstractQuery
|
||||
* @package Icinga\Protocol
|
||||
*/
|
||||
abstract class AbstractQuery
|
||||
{
|
||||
const SORT_ASC = 1;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const SORT_ASC = 1;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const SORT_DESC = -1;
|
||||
|
||||
/**
|
||||
* @param $key
|
||||
* @param null $val
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function where($key, $val = null);
|
||||
|
||||
/**
|
||||
* @param $col
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function order($col);
|
||||
|
||||
/**
|
||||
* @param null $count
|
||||
* @param null $offset
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function limit($count = null, $offset = null);
|
||||
|
||||
/**
|
||||
* @param $table
|
||||
* @param null $columns
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function from($table, $columns = null);
|
||||
|
||||
public function hasOrder()
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasOrder()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function hasColumns()
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasColumns()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getColumns()
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getColumns()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
public function hasLimit()
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasLimit()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function hasOffset()
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasOffset()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return null
|
||||
*/
|
||||
public function getLimit()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return null
|
||||
*/
|
||||
public function getOffset()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,27 +1,61 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Protocol\Commandpipe;
|
||||
|
||||
use \Icinga\Protocol\Commandpipe\Exception\InvalidCommandException;
|
||||
use \Icinga\Protocol\Commandpipe\Comment;
|
||||
|
||||
|
||||
/**
|
||||
* Class Acknowledgement
|
||||
* @package Icinga\Protocol\Commandpipe
|
||||
*/
|
||||
class Acknowledgement implements IComment
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
public $expireTime = -1;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $notify = false;
|
||||
|
||||
/**
|
||||
* @var Comment|null
|
||||
*/
|
||||
public $comment = null;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $sticky;
|
||||
|
||||
/**
|
||||
* @param int $time
|
||||
*/
|
||||
public function setExpireTime($time)
|
||||
{
|
||||
$this->expireTime = intval($time);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param boolean $bool
|
||||
*/
|
||||
public function setNotify($bool)
|
||||
{
|
||||
$this->notify = (bool) $bool;
|
||||
$this->notify = (bool)$bool;
|
||||
}
|
||||
|
||||
public function __construct(Comment $comment, $notify = false, $expire = -1, $sticky=false)
|
||||
/**
|
||||
* @param Comment $comment
|
||||
* @param bool $notify
|
||||
* @param $expire
|
||||
* @param bool $sticky
|
||||
*/
|
||||
public function __construct(Comment $comment, $notify = false, $expire = -1, $sticky = false)
|
||||
{
|
||||
$this->comment = $comment;
|
||||
$this->setNotify($notify);
|
||||
|
@ -29,30 +63,35 @@ class Acknowledgement implements IComment
|
|||
$this->sticky = $sticky;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $type
|
||||
* @return string
|
||||
* @throws Exception\InvalidCommandException
|
||||
*/
|
||||
public function getFormatString($type)
|
||||
{
|
||||
$params = ';'.($this->sticky ? '2' : '0').';'.($this->notify ? '1 ': '0').';'.($this->comment->persistent ? '1' : '0');
|
||||
$params .= ($this->expireTime > -1 ? ';'.$this->expireTime.';' : ';').$this->comment->author.';'.$this->comment->comment;
|
||||
$params = ';'
|
||||
. ($this->sticky ? '2' : '0')
|
||||
. ';' . ($this->notify ? '1 ' : '0')
|
||||
. ';' . ($this->comment->persistent ? '1' : '0');
|
||||
|
||||
switch($type) {
|
||||
$params .= ($this->expireTime > -1 ? ';'. $this->expireTime . ';' : ';')
|
||||
. $this->comment->author . ';' . $this->comment->comment;
|
||||
|
||||
switch ($type) {
|
||||
case CommandPipe::TYPE_HOST:
|
||||
$typeVar = "HOST";
|
||||
$params = ";%s".$params;
|
||||
$params = ";%s" . $params;
|
||||
break;
|
||||
case CommandPipe::TYPE_SERVICE:
|
||||
$typeVar = "SVC";
|
||||
$params = ";%s;%s".$params;
|
||||
$params = ";%s;%s" . $params;
|
||||
break;
|
||||
default:
|
||||
throw new InvalidCommandException("Acknowledgements can only apply on hosts and services ");
|
||||
}
|
||||
|
||||
$base = "ACKNOWLEDGE_{$typeVar}_PROBLEM".($this->expireTime > -1 ? '_EXPIRE' : '' );
|
||||
return $base.$params;
|
||||
|
||||
|
||||
|
||||
$base = "ACKNOWLEDGE_{$typeVar}_PROBLEM" . ($this->expireTime > -1 ? '_EXPIRE' : '');
|
||||
return $base . $params;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,77 +1,167 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Protocol\Commandpipe;
|
||||
|
||||
use Icinga\Application\Logger as IcingaLogger;
|
||||
|
||||
/**
|
||||
* Class CommandPipe
|
||||
* @package Icinga\Protocol\Commandpipe
|
||||
*/
|
||||
class CommandPipe
|
||||
{
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
private $path;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
private $name;
|
||||
private $user = falsE;
|
||||
|
||||
/**
|
||||
* @var bool|mixed
|
||||
*/
|
||||
private $user = false;
|
||||
|
||||
/**
|
||||
* @var bool|mixed
|
||||
*/
|
||||
private $host = false;
|
||||
|
||||
/**
|
||||
* @var int|mixed
|
||||
*/
|
||||
private $port = 22;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $fopen_mode = "w";
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const TYPE_HOST = "HOST";
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const TYPE_SERVICE = "SVC";
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const TYPE_HOSTGROUP = "HOSTGROUP";
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const TYPE_SERVICEGROUP = "SERVICEGROUP";
|
||||
|
||||
|
||||
/**
|
||||
* @param \Zend_Config $config
|
||||
*/
|
||||
public function __construct(\Zend_Config $config)
|
||||
{
|
||||
$this->path = $config->path;
|
||||
$this->name = $config->name;
|
||||
if(isset($config->host)) {
|
||||
if (isset($config->host)) {
|
||||
$this->host = $config->host;
|
||||
}
|
||||
if(isset($config->port)) {
|
||||
if (isset($config->port)) {
|
||||
$this->port = $config->port;
|
||||
}
|
||||
if(isset($config->user)) {
|
||||
if (isset($config->user)) {
|
||||
$this->user = $config->user;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $command
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function send($command)
|
||||
{
|
||||
if(!$this->host) {
|
||||
IcingaLogger::debug("Attempting to send external icinga command $command to local command file {$this->path}");
|
||||
if (!$this->host) {
|
||||
IcingaLogger::debug(
|
||||
"Attempting to send external icinga command $command to local command file {$this->path}"
|
||||
);
|
||||
$file = @fopen($this->path, $this->fopen_mode);
|
||||
if (!$file)
|
||||
throw new \RuntimeException("Could not open icinga pipe at $file : ".print_r(error_get_last(), true));
|
||||
fwrite($file,"[".time()."] ".$command.PHP_EOL);
|
||||
IcingaLogger::debug('Writing ['.time().'] '.$command.PHP_EOL);
|
||||
if (!$file) {
|
||||
throw new \RuntimeException("Could not open icinga pipe at $file : " . print_r(error_get_last(), true));
|
||||
}
|
||||
fwrite($file, "[" . time() . "] " . $command . PHP_EOL);
|
||||
IcingaLogger::debug('Writing [' . time() . '] ' . $command . PHP_EOL);
|
||||
fclose($file);
|
||||
} else {
|
||||
// send over ssh
|
||||
$retCode = 0;
|
||||
$output = array();
|
||||
IcingaLogger::debug('Icinga instance is on different host, attempting to send command %s via ssh to %s:%s/%s', $command, $this->host, $this->port, $this->path);
|
||||
$hostConnector = $this->user ? $this->user."@".$this->host : $this->host;
|
||||
exec("ssh $hostConnector -p{$this->port} \"echo '[".time()."] ".escapeshellcmd($command)."' > {$this->path}\"", $output, $retCode);
|
||||
IcingaLogger::debug("$:ssh $hostConnector -p{$this->port} \"echo '[".time()."] ".escapeshellcmd($command)."' > {$this->path}\"");
|
||||
IcingaLogger::debug(
|
||||
'Icinga instance is on different host, attempting to send command %s via ssh to %s:%s/%s',
|
||||
$command,
|
||||
$this->host,
|
||||
$this->port,
|
||||
$this->path
|
||||
);
|
||||
$hostConnector = $this->user ? $this->user . "@" . $this->host : $this->host;
|
||||
exec(
|
||||
"ssh $hostConnector -p{$this->port} \"echo '[" . time() . "] "
|
||||
. escapeshellcmd(
|
||||
$command
|
||||
)
|
||||
. "' > {$this->path}\"",
|
||||
$output,
|
||||
$retCode
|
||||
);
|
||||
IcingaLogger::debug(
|
||||
"$:ssh $hostConnector -p{$this->port} \"echo '[" . time() . "] " . escapeshellcmd(
|
||||
$command
|
||||
) . "' > {$this->path}\""
|
||||
);
|
||||
IcingaLogger::debug("Code code %s: %s ", $retCode, $output);
|
||||
|
||||
if($retCode != 0) {
|
||||
throw new \RuntimeException('Could not send command to remote icinga host: '.implode("\n", $output)." (returncode $retCode)");
|
||||
if ($retCode != 0) {
|
||||
throw new \RuntimeException(
|
||||
'Could not send command to remote icinga host: '
|
||||
. implode(
|
||||
"\n",
|
||||
$output
|
||||
)
|
||||
. " (returncode $retCode)"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function acknowledge($objects,IComment $acknowledgementOrComment) {
|
||||
if (is_a($acknowledgementOrComment,'Icinga\Protocol\Commandpipe\Comment'))
|
||||
/**
|
||||
* @param $objects
|
||||
* @param IComment $acknowledgementOrComment
|
||||
*/
|
||||
public function acknowledge($objects, IComment $acknowledgementOrComment)
|
||||
{
|
||||
if (is_a($acknowledgementOrComment, 'Icinga\Protocol\Commandpipe\Comment')) {
|
||||
$acknowledgementOrComment = new Acknowledgement($acknowledgementOrComment);
|
||||
}
|
||||
|
||||
foreach ($objects as $object) {
|
||||
if (isset($object->service_description)) {
|
||||
$format = $acknowledgementOrComment->getFormatString(self::TYPE_SERVICE);
|
||||
$this->send(sprintf($format,$object->host_name,$object->service_description));
|
||||
$this->send(sprintf($format, $object->host_name, $object->service_description));
|
||||
} else {
|
||||
$format = $acknowledgementOrComment->getFormatString(self::TYPE_HOST);
|
||||
$this->send(sprintf($format,$object->host_name));
|
||||
$this->send(sprintf($format, $object->host_name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $objects
|
||||
*/
|
||||
public function removeAcknowledge($objects)
|
||||
{
|
||||
foreach ($objects as $object) {
|
||||
|
@ -83,6 +173,11 @@ class CommandPipe
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $objects
|
||||
* @param $state
|
||||
* @param $output
|
||||
*/
|
||||
public function submitCheckResult($objects, $state, $output)
|
||||
{
|
||||
foreach ($objects as $object) {
|
||||
|
@ -94,46 +189,67 @@ class CommandPipe
|
|||
}
|
||||
}
|
||||
|
||||
public function scheduleForcedCheck($objects,$time=false,$withChilds=false) {
|
||||
if (!$time)
|
||||
/**
|
||||
* @param $objects
|
||||
* @param bool $time
|
||||
* @param bool $withChilds
|
||||
*/
|
||||
public function scheduleForcedCheck($objects, $time = false, $withChilds = false)
|
||||
{
|
||||
if (!$time) {
|
||||
$time = time();
|
||||
}
|
||||
$base = "SCHEDULE_FORCED_";
|
||||
foreach ($objects as $object) {
|
||||
if (isset($object->service_description)) {
|
||||
$this->send($base."SVC_CHECK;$object->host_name;$object->service_description;$time");
|
||||
$this->send($base . "SVC_CHECK;$object->host_name;$object->service_description;$time");
|
||||
} else {
|
||||
$this->send($base.'HOST_'.($withChilds ? 'SVC_CHECKS' : 'CHECK' ).";$object->host_name;$time");
|
||||
$this->send($base . 'HOST_' . ($withChilds ? 'SVC_CHECKS' : 'CHECK') . ";$object->host_name;$time");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function scheduleCheck($objects,$time=false,$withChilds=false) {
|
||||
if (!$time)
|
||||
/**
|
||||
* @param $objects
|
||||
* @param bool $time
|
||||
* @param bool $withChilds
|
||||
*/
|
||||
public function scheduleCheck($objects, $time = false, $withChilds = false)
|
||||
{
|
||||
if (!$time) {
|
||||
$time = time();
|
||||
}
|
||||
$base = "SCHEDULE_";
|
||||
foreach ($objects as $object) {
|
||||
if (isset($object->service_description)) {
|
||||
$this->send($base."SVC_CHECK;$object->host_name;$object->service_description;$time");
|
||||
$this->send($base . "SVC_CHECK;$object->host_name;$object->service_description;$time");
|
||||
} else {
|
||||
$this->send($base.'HOST_'.($withChilds ? 'SVC_CHECKS' : 'CHECK' ).";$object->host_name;$time");
|
||||
$this->send($base . 'HOST_' . ($withChilds ? 'SVC_CHECKS' : 'CHECK') . ";$object->host_name;$time");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $objects
|
||||
* @param Comment $comment
|
||||
*/
|
||||
public function addComment(array $objects, Comment $comment)
|
||||
{
|
||||
foreach ($objects as $object) {
|
||||
if (isset($object->service_description)) {
|
||||
$format = $comment->getFormatString(self::TYPE_SERVICE);
|
||||
$this->send(sprintf($format,$object->host_name,$object->service_description));
|
||||
$this->send(sprintf($format, $object->host_name, $object->service_description));
|
||||
} else {
|
||||
$format = $comment->getFormatString(self::TYPE_HOST);
|
||||
$this->send(sprintf($format,$object->host_name));
|
||||
$this->send(sprintf($format, $object->host_name));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $objectsOrComments
|
||||
*/
|
||||
public function removeComment($objectsOrComments)
|
||||
{
|
||||
foreach ($objectsOrComments as $object) {
|
||||
|
@ -143,178 +259,322 @@ class CommandPipe
|
|||
} else {
|
||||
$type = "HOST_COMMENT";
|
||||
}
|
||||
$this->send("DEL_{$type};".intval($object->comment_id));
|
||||
$this->send("DEL_{$type};" . intval($object->comment_id));
|
||||
} else {
|
||||
if (isset($object->service_description)) {
|
||||
$type = "SERVICE_COMMENT";
|
||||
} else {
|
||||
$type = "HOST_COMMENT";
|
||||
}
|
||||
$cmd = "DEL_ALL_{$type}S;".$object->host_name;
|
||||
if ($type == "SERVICE_COMMENT")
|
||||
$cmd .= ";".$object->service_description;
|
||||
$cmd = "DEL_ALL_{$type}S;" . $object->host_name;
|
||||
if ($type == "SERVICE_COMMENT") {
|
||||
$cmd .= ";" . $object->service_description;
|
||||
}
|
||||
$this->send($cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function enableGlobalNotifications()
|
||||
{
|
||||
$this->send("ENABLE_NOTIFICATIONS");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function disableGlobalNotifications()
|
||||
{
|
||||
$this->send("DISABLE_NOTIFICATIONS");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $object
|
||||
* @return string
|
||||
*/
|
||||
private function getObjectType($object)
|
||||
{
|
||||
//@TODO: This must be refactored once more commands are supported
|
||||
if (isset($object->service_description))
|
||||
if (isset($object->service_description)) {
|
||||
return self::TYPE_SERVICE;
|
||||
}
|
||||
return self::TYPE_HOST;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $objects
|
||||
* @param Downtime $downtime
|
||||
*/
|
||||
public function scheduleDowntime($objects, Downtime $downtime)
|
||||
{
|
||||
foreach ($objects as $object) {
|
||||
$type = $this->getObjectType($object);
|
||||
if($type == self::TYPE_SERVICE)
|
||||
$this->send(sprintf($downtime->getFormatString($type),$object->host_name,$object->service_description));
|
||||
else
|
||||
$this->send(sprintf($downtime->getFormatString($type),$object->host_name));
|
||||
if ($type == self::TYPE_SERVICE) {
|
||||
$this->send(
|
||||
sprintf($downtime->getFormatString($type), $object->host_name, $object->service_description)
|
||||
);
|
||||
} else {
|
||||
$this->send(sprintf($downtime->getFormatString($type), $object->host_name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function removeDowntime($objects,$starttime = 0)
|
||||
/**
|
||||
* @param $objects
|
||||
* @param int $starttime
|
||||
*/
|
||||
public function removeDowntime($objects, $starttime = 0)
|
||||
{
|
||||
foreach ($objects as $object) {
|
||||
$type = $this->getObjectType($object);
|
||||
if (isset($object->downtime_id)) {
|
||||
$this->send("DEL_".$type."_DOWNTIME;".$object->downtime_id);
|
||||
$this->send("DEL_" . $type . "_DOWNTIME;" . $object->downtime_id);
|
||||
continue;
|
||||
}
|
||||
$cmd = "DEL_DOWNTIME_BY_HOST_NAME;".$object->host_name;
|
||||
if($type == self::TYPE_SERVICE)
|
||||
$cmd .= ";".$object->service_description;
|
||||
if($starttime != 0)
|
||||
$cmd .= ";".$starttime;
|
||||
$cmd = "DEL_DOWNTIME_BY_HOST_NAME;" . $object->host_name;
|
||||
if ($type == self::TYPE_SERVICE) {
|
||||
$cmd .= ";" . $object->service_description;
|
||||
}
|
||||
if ($starttime != 0) {
|
||||
$cmd .= ";" . $starttime;
|
||||
}
|
||||
$this->send($cmd);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function restartIcinga()
|
||||
{
|
||||
$this->send("RESTART_PROCESS");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $objects
|
||||
* @param PropertyModifier $flags
|
||||
*/
|
||||
public function setMonitoringProperties($objects, PropertyModifier $flags)
|
||||
{
|
||||
foreach ($objects as $object) {
|
||||
$type = $this->getObjectType($object);
|
||||
$formatArray = $flags->getFormatString($type);
|
||||
foreach ($formatArray as $format) {
|
||||
$format .= ";".$object->host_name.($type == self::TYPE_SERVICE ? ";".$object->service_description : "");
|
||||
$format .= ";"
|
||||
. $object->host_name
|
||||
. ($type == self::TYPE_SERVICE ? ";" . $object->service_description : "");
|
||||
$this->send($format);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $objects
|
||||
*/
|
||||
public function enableActiveChecks($objects)
|
||||
{
|
||||
$this->setMonitoringProperties($objects,new PropertyModifier(array(
|
||||
PropertyModifier::ACTIVE => PropertyModifier::STATE_ENABLE
|
||||
)));
|
||||
$this->setMonitoringProperties(
|
||||
$objects,
|
||||
new PropertyModifier(
|
||||
array(
|
||||
PropertyModifier::ACTIVE => PropertyModifier::STATE_ENABLE
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $objects
|
||||
*/
|
||||
public function disableActiveChecks($objects)
|
||||
{
|
||||
$this->modifyMonitoringProperties($objects,new PropertyModifier(array(
|
||||
PropertyModifier::ACTIVE => PropertyModifier::STATE_DISABLE
|
||||
)));
|
||||
$this->modifyMonitoringProperties(
|
||||
$objects,
|
||||
new PropertyModifier(
|
||||
array(
|
||||
PropertyModifier::ACTIVE => PropertyModifier::STATE_DISABLE
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $objects
|
||||
*/
|
||||
public function enablePassiveChecks($objects)
|
||||
{
|
||||
$this->setMonitoringProperties($objects,new PropertyModifier(array(
|
||||
PropertyModifier::PASSIVE => PropertyModifier::STATE_ENABLE
|
||||
)));
|
||||
$this->setMonitoringProperties(
|
||||
$objects,
|
||||
new PropertyModifier(
|
||||
array(
|
||||
PropertyModifier::PASSIVE => PropertyModifier::STATE_ENABLE
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $objects
|
||||
*/
|
||||
public function disablePassiveChecks($objects)
|
||||
{
|
||||
$this->modifyMonitoringProperties($objects,new PropertyModifier(array(
|
||||
PropertyModifier::PASSIVE => PropertyModifier::STATE_DISABLE
|
||||
)));
|
||||
$this->modifyMonitoringProperties(
|
||||
$objects,
|
||||
new PropertyModifier(
|
||||
array(
|
||||
PropertyModifier::PASSIVE => PropertyModifier::STATE_DISABLE
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $objects
|
||||
*/
|
||||
public function enableFlappingDetection($objects)
|
||||
{
|
||||
$this->setMonitoringProperties($objects,new PropertyModifier(array(
|
||||
PropertyModifier::FLAPPING => PropertyModifier::STATE_ENABLE
|
||||
)));
|
||||
$this->setMonitoringProperties(
|
||||
$objects,
|
||||
new PropertyModifier(
|
||||
array(
|
||||
PropertyModifier::FLAPPING => PropertyModifier::STATE_ENABLE
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $objects
|
||||
*/
|
||||
public function disableFlappingDetection($objects)
|
||||
{
|
||||
$this->setMonitoringProperties($objects,new PropertyModifier(array(
|
||||
PropertyModifier::FLAPPING => PropertyModifier::STATE_DISABLE
|
||||
)));
|
||||
$this->setMonitoringProperties(
|
||||
$objects,
|
||||
new PropertyModifier(
|
||||
array(
|
||||
PropertyModifier::FLAPPING => PropertyModifier::STATE_DISABLE
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $objects
|
||||
*/
|
||||
public function enableNotifications($objects)
|
||||
{
|
||||
$this->setMonitoringProperties($objects,new PropertyModifier(array(
|
||||
PropertyModifier::NOTIFICATIONS => PropertyModifier::STATE_ENABLE
|
||||
)));
|
||||
$this->setMonitoringProperties(
|
||||
$objects,
|
||||
new PropertyModifier(
|
||||
array(
|
||||
PropertyModifier::NOTIFICATIONS => PropertyModifier::STATE_ENABLE
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $objects
|
||||
*/
|
||||
public function disableNotifications($objects)
|
||||
{
|
||||
$this->setMonitoringProperties($objects,new PropertyModifier(array(
|
||||
PropertyModifier::NOTIFICATIONS => PropertyModifier::STATE_DISABLE
|
||||
)));
|
||||
$this->setMonitoringProperties(
|
||||
$objects,
|
||||
new PropertyModifier(
|
||||
array(
|
||||
PropertyModifier::NOTIFICATIONS => PropertyModifier::STATE_DISABLE
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $objects
|
||||
*/
|
||||
public function enableFreshnessChecks($objects)
|
||||
{
|
||||
$this->setMonitoringProperties($objects,new PropertyModifier(array(
|
||||
PropertyModifier::FRESHNESS => PropertyModifier::STATE_ENABLE
|
||||
)));
|
||||
$this->setMonitoringProperties(
|
||||
$objects,
|
||||
new PropertyModifier(
|
||||
array(
|
||||
PropertyModifier::FRESHNESS => PropertyModifier::STATE_ENABLE
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $objects
|
||||
*/
|
||||
public function disableFreshnessChecks($objects)
|
||||
{
|
||||
$this->setMonitoringProperties($objects,new PropertyModifier(array(
|
||||
PropertyModifier::FRESHNESS => PropertyModifier::STATE_DISABLE
|
||||
)));
|
||||
$this->setMonitoringProperties(
|
||||
$objects,
|
||||
new PropertyModifier(
|
||||
array(
|
||||
PropertyModifier::FRESHNESS => PropertyModifier::STATE_DISABLE
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $objects
|
||||
*/
|
||||
public function enableEventHandler($objects)
|
||||
{
|
||||
$this->setMonitoringProperties($objects,new PropertyModifier(array(
|
||||
PropertyModifier::EVENTHANDLER => PropertyModifier::STATE_ENABLE
|
||||
)));
|
||||
$this->setMonitoringProperties(
|
||||
$objects,
|
||||
new PropertyModifier(
|
||||
array(
|
||||
PropertyModifier::EVENTHANDLER => PropertyModifier::STATE_ENABLE
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $objects
|
||||
*/
|
||||
public function disableEventHandler($objects)
|
||||
{
|
||||
$this->setMonitoringProperties($objects,new PropertyModifier(array(
|
||||
PropertyModifier::EVENTHANDLER => PropertyModifier::STATE_DISABLE
|
||||
)));
|
||||
$this->setMonitoringProperties(
|
||||
$objects,
|
||||
new PropertyModifier(
|
||||
array(
|
||||
PropertyModifier::EVENTHANDLER => PropertyModifier::STATE_DISABLE
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $objects
|
||||
*/
|
||||
public function enablePerfdata($objects)
|
||||
{
|
||||
$this->setMonitoringProperties($objects,new PropertyModifier(array(
|
||||
PropertyModifier::PERFDATA => PropertyModifier::STATE_ENABLE
|
||||
)));
|
||||
$this->setMonitoringProperties(
|
||||
$objects,
|
||||
new PropertyModifier(
|
||||
array(
|
||||
PropertyModifier::PERFDATA => PropertyModifier::STATE_ENABLE
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function disablePerfdata($objects)
|
||||
{
|
||||
$this->setMonitoringProperties($objects,new PropertyModifier(array(
|
||||
PropertyModifier::PERFDATA => PropertyModifier::STATE_DISABLE
|
||||
)));
|
||||
$this->setMonitoringProperties(
|
||||
$objects,
|
||||
new PropertyModifier(
|
||||
array(
|
||||
PropertyModifier::PERFDATA => PropertyModifier::STATE_DISABLE
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,37 +1,63 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Protocol\Commandpipe;
|
||||
|
||||
/**
|
||||
* Class Comment
|
||||
* @package Icinga\Protocol\Commandpipe
|
||||
*/
|
||||
class Comment implements IComment
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $persistent = false;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $author = "";
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $comment = "";
|
||||
|
||||
public function __construct($author,$comment,$persistent=false)
|
||||
/**
|
||||
* @param $author
|
||||
* @param $comment
|
||||
* @param bool $persistent
|
||||
*/
|
||||
public function __construct($author, $comment, $persistent = false)
|
||||
{
|
||||
$this->author = $author;
|
||||
$this->comment = $comment;
|
||||
$this->persistent = $persistent;
|
||||
}
|
||||
|
||||
public function getFormatString($type) {
|
||||
$params = ';'.($this->persistent ? '1' : '0').';'.$this->author.';'.$this->comment;
|
||||
/**
|
||||
* @param $type
|
||||
* @return string
|
||||
* @throws InvalidCommandException
|
||||
*/
|
||||
public function getFormatString($type)
|
||||
{
|
||||
$params = ';' . ($this->persistent ? '1' : '0') . ';' . $this->author . ';' . $this->comment;
|
||||
|
||||
switch($type) {
|
||||
switch ($type) {
|
||||
case CommandPipe::TYPE_HOST:
|
||||
$typeVar = "HOST";
|
||||
$params = ";%s".$params;
|
||||
$params = ";%s" . $params;
|
||||
break;
|
||||
case CommandPipe::TYPE_SERVICE:
|
||||
$typeVar = "SVC";
|
||||
$params = ";%s;%s".$params;
|
||||
$params = ";%s;%s" . $params;
|
||||
break;
|
||||
default:
|
||||
throw new InvalidCommandException("Acknowledgements can only apply on hosts and services ");
|
||||
}
|
||||
return "ADD_{$typeVar}_COMMENT$params";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,29 +1,67 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Protocol\Commandpipe;
|
||||
|
||||
/**
|
||||
* Class Downtime
|
||||
* @package Icinga\Protocol\Commandpipe
|
||||
*/
|
||||
class Downtime
|
||||
{
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
public $startTime;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
public $endTime;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
private $fixed = false;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
public $duration;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
public $comment;
|
||||
|
||||
public function __construct($start,$end,Comment $comment,$duration=0)
|
||||
/**
|
||||
* @param $start
|
||||
* @param $end
|
||||
* @param Comment $comment
|
||||
* @param int $duration
|
||||
*/
|
||||
public function __construct($start, $end, Comment $comment, $duration = 0)
|
||||
{
|
||||
$this->startTime = $start;
|
||||
$this->endTime = $end;
|
||||
$this->comment = $comment;
|
||||
if($duration != 0)
|
||||
if ($duration != 0) {
|
||||
$this->fixed = true;
|
||||
}
|
||||
$this->duration = intval($duration);
|
||||
}
|
||||
|
||||
public function getFormatString($type) {
|
||||
return 'SCHEDULE_'.$type.'_DOWNTIME;%s'
|
||||
.($type == CommandPipe::TYPE_SERVICE ? ';%s;' : ';')
|
||||
.$this->startTime.';'.$this->endTime
|
||||
.';'.($this->fixed ? '1' : '0').';'.$this->duration.';0;'
|
||||
.$this->comment->author.';'.$this->comment->comment;
|
||||
/**
|
||||
* @param $type
|
||||
* @return string
|
||||
*/
|
||||
public function getFormatString($type)
|
||||
{
|
||||
return 'SCHEDULE_' . $type . '_DOWNTIME;%s'
|
||||
. ($type == CommandPipe::TYPE_SERVICE ? ';%s;' : ';')
|
||||
. $this->startTime . ';' . $this->endTime
|
||||
. ';' . ($this->fixed ? '1' : '0') . ';' . $this->duration . ';0;'
|
||||
. $this->comment->author . ';' . $this->comment->comment;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Protocol\Commandpipe\Exception;
|
||||
|
||||
class InvalidCommandException extends \Exception
|
||||
/**
|
||||
* Class InvalidCommandException
|
||||
* @package Icinga\Protocol\Commandpipe\Exception
|
||||
*/
|
||||
class InvalidCommandException extends \Exception
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Protocol\Commandpipe;
|
||||
|
||||
/**
|
||||
* Class IComment
|
||||
* @package Icinga\Protocol\Commandpipe
|
||||
*/
|
||||
interface IComment
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -1,52 +1,104 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Protocol\Commandpipe;
|
||||
|
||||
class PropertyModifier {
|
||||
/**
|
||||
* Class PropertyModifier
|
||||
* @package Icinga\Protocol\Commandpipe
|
||||
*/
|
||||
class PropertyModifier
|
||||
{
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const STATE_ENABLE = 1;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const STATE_DISABLE = 0;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const STATE_KEEP = -1;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const FLAPPING = "%s_FLAP_DETECTION";
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const ACTIVE = "%s_CHECK";
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const PASSIVE = "PASSIVE_%s_CHECKS";
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const NOTIFICATIONS = "%s_NOTIFICATIONS";
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const FRESHNESS = "%s_FRESHNESS_CHECKS";
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const EVENTHANDLER = "%s_EVENT_HANDLER";
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $flags = array(
|
||||
self::FLAPPING => self::STATE_KEEP,
|
||||
self::ACTIVE => self::STATE_KEEP,
|
||||
self::PASSIVE => self::STATE_KEEP,
|
||||
self::NOTIFICATIONS => self::STATE_KEEP,
|
||||
self::FLAPPING => self::STATE_KEEP,
|
||||
self::ACTIVE => self::STATE_KEEP,
|
||||
self::PASSIVE => self::STATE_KEEP,
|
||||
self::NOTIFICATIONS => self::STATE_KEEP,
|
||||
self::FRESHNESS => self::STATE_KEEP,
|
||||
self::EVENTHANDLER => self::STATE_KEEP
|
||||
);
|
||||
|
||||
/**
|
||||
* @param array $flags
|
||||
*/
|
||||
public function __construct(array $flags)
|
||||
{
|
||||
foreach ($flags as $type=>$value) {
|
||||
foreach ($flags as $type => $value) {
|
||||
if (isset($this->flags[$type])) {
|
||||
$this->flags[$type] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getFormatString($type) {
|
||||
/**
|
||||
* @param $type
|
||||
* @return array
|
||||
*/
|
||||
public function getFormatString($type)
|
||||
{
|
||||
$cmd = array();
|
||||
foreach($this->flags as $cmdTemplate=>$setting) {
|
||||
if($setting == self::STATE_KEEP)
|
||||
foreach ($this->flags as $cmdTemplate => $setting) {
|
||||
if ($setting == self::STATE_KEEP) {
|
||||
continue;
|
||||
}
|
||||
$commandString = ($setting == self::STATE_ENABLE ? "ENABLE_" : "DISABLE_");
|
||||
$targetString = $type;
|
||||
if($type == CommandPipe::TYPE_SERVICE && $cmdTemplate == self::FRESHNESS) {
|
||||
if ($type == CommandPipe::TYPE_SERVICE && $cmdTemplate == self::FRESHNESS) {
|
||||
// the external command definition is inconsistent here..
|
||||
$targetString = "SERVICE";
|
||||
}
|
||||
$commandString .= sprintf($cmdTemplate,$targetString);
|
||||
$commandString .= sprintf($cmdTemplate, $targetString);
|
||||
$cmd[] = $commandString;
|
||||
}
|
||||
return $cmd;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Protocol\Ldap;
|
||||
|
||||
use Icinga\Application\Platform;
|
||||
use Icinga\Application\Config;
|
||||
use Icinga\Application\Logger as Log;
|
||||
|
||||
/**
|
||||
* Connection class
|
||||
*
|
||||
* @package Icinga\Protocol\Ldap
|
||||
*/
|
||||
/**
|
||||
* Backend class managing all the LDAP stuff for you.
|
||||
*
|
||||
|
@ -31,12 +29,39 @@ use Icinga\Application\Logger as Log;
|
|||
*/
|
||||
class Connection
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $ds;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $hostname;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $bind_dn;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $bind_pw;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $root_dn;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $count;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $ldap_extension = array(
|
||||
'1.3.6.1.4.1.1466.20037' => 'STARTTLS', // notes?
|
||||
// '1.3.6.1.4.1.4203.1.11.1' => '11.1', // PASSWORD_MODIFY
|
||||
|
@ -44,40 +69,38 @@ class Connection
|
|||
// '1.3.6.1.1.8' => '8', // Cancel Extended Request
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $ms_capability = array(
|
||||
// Prefix LDAP_CAP_
|
||||
// Source: http://msdn.microsoft.com/en-us/library/cc223359.aspx
|
||||
|
||||
// Running Active Directory as AD DS:
|
||||
'1.2.840.113556.1.4.800' => 'ACTIVE_DIRECTORY_OID',
|
||||
|
||||
'1.2.840.113556.1.4.800' => 'ACTIVE_DIRECTORY_OID',
|
||||
// Capable of signing and sealing on an NTLM authenticated connection
|
||||
// and of performing subsequent binds on a signed or sealed connection.
|
||||
'1.2.840.113556.1.4.1791' => 'ACTIVE_DIRECTORY_LDAP_INTEG_OID',
|
||||
|
||||
// If AD DS: running at least W2K3, if AD LDS running at least W2K8
|
||||
'1.2.840.113556.1.4.1670' => 'ACTIVE_DIRECTORY_V51_OID',
|
||||
|
||||
// If AD LDS: accepts DIGEST-MD5 binds for AD LDSsecurity principals
|
||||
'1.2.840.113556.1.4.1880' => 'ACTIVE_DIRECTORY_ADAM_DIGEST',
|
||||
|
||||
// Running Active Directory as AD LDS
|
||||
'1.2.840.113556.1.4.1851' => 'ACTIVE_DIRECTORY_ADAM_OID',
|
||||
|
||||
// If AD DS: it's a Read Only DC (RODC)
|
||||
'1.2.840.113556.1.4.1920' => 'ACTIVE_DIRECTORY_PARTIAL_SECRETS_OID',
|
||||
|
||||
// Running at least W2K8
|
||||
'1.2.840.113556.1.4.1935' => 'ACTIVE_DIRECTORY_V60_OID',
|
||||
|
||||
// Running at least W2K8r2
|
||||
'1.2.840.113556.1.4.2080' => 'ACTIVE_DIRECTORY_V61_R2_OID',
|
||||
|
||||
// Running at least W2K12
|
||||
'1.2.840.113556.1.4.2237' => 'ACTIVE_DIRECTORY_W8_OID',
|
||||
|
||||
);
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $root;
|
||||
|
||||
/**
|
||||
|
@ -90,17 +113,23 @@ class Connection
|
|||
public function __construct($config)
|
||||
{
|
||||
$this->hostname = $config->hostname;
|
||||
$this->bind_dn = $config->bind_dn;
|
||||
$this->bind_pw = $config->bind_pw;
|
||||
$this->root_dn = $config->root_dn;
|
||||
$this->bind_dn = $config->bind_dn;
|
||||
$this->bind_pw = $config->bind_pw;
|
||||
$this->root_dn = $config->root_dn;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDN()
|
||||
{
|
||||
return $this->root_dn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Root|string
|
||||
*/
|
||||
public function root()
|
||||
{
|
||||
if ($this->root === null) {
|
||||
|
@ -109,30 +138,50 @@ class Connection
|
|||
return $this->root;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Query
|
||||
*/
|
||||
public function select()
|
||||
{
|
||||
return new Query($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $query
|
||||
* @param array $fields
|
||||
* @return mixed
|
||||
*/
|
||||
public function fetchOne($query, $fields = array())
|
||||
{
|
||||
$row = (array) $this->fetchRow($query, $fields);
|
||||
$row = (array)$this->fetchRow($query, $fields);
|
||||
return array_shift($row);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $query
|
||||
* @param array $fields
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function fetchDN($query, $fields = array())
|
||||
{
|
||||
$rows = $this->fetchAll($query, $fields);
|
||||
if (count($rows) !== 1) {
|
||||
throw new Exception(sprintf(
|
||||
'Cannot fetch single DN for %s',
|
||||
$query
|
||||
));
|
||||
throw new Exception(
|
||||
sprintf(
|
||||
'Cannot fetch single DN for %s',
|
||||
$query
|
||||
)
|
||||
);
|
||||
}
|
||||
return key($rows);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $query
|
||||
* @param array $fields
|
||||
* @return mixed
|
||||
*/
|
||||
public function fetchRow($query, $fields = array())
|
||||
{
|
||||
// TODO: This is ugly, make it better!
|
||||
|
@ -140,19 +189,28 @@ class Connection
|
|||
return array_shift($results);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Query $query
|
||||
* @return int
|
||||
*/
|
||||
public function count(Query $query)
|
||||
{
|
||||
$results = $this->runQuery($query, '+');
|
||||
return ldap_count_entries($this->ds, $results);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $query
|
||||
* @param array $fields
|
||||
* @return array
|
||||
*/
|
||||
public function fetchAll($query, $fields = array())
|
||||
{
|
||||
$offset = null;
|
||||
$limit = null;
|
||||
if ($query->hasLimit()) {
|
||||
$offset = $query->getOffset();
|
||||
$limit = $query->getLimit();
|
||||
$limit = $query->getLimit();
|
||||
}
|
||||
$entries = array();
|
||||
$results = $this->runQuery($query, $fields);
|
||||
|
@ -172,9 +230,13 @@ class Connection
|
|||
return $entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $attrs
|
||||
* @return object
|
||||
*/
|
||||
public function cleanupAttributes(& $attrs)
|
||||
{
|
||||
$clean = (object) array();
|
||||
$clean = (object)array();
|
||||
for ($i = 0; $i < $attrs['count']; $i++) {
|
||||
$attr_name = $attrs[$i];
|
||||
if ($attrs[$attr_name]['count'] === 1) {
|
||||
|
@ -188,6 +250,12 @@ class Connection
|
|||
return $clean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $query
|
||||
* @param $fields
|
||||
* @return resource
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function runQuery($query, $fields)
|
||||
{
|
||||
$this->connect();
|
||||
|
@ -201,29 +269,37 @@ class Connection
|
|||
$results = ldap_search(
|
||||
$this->ds,
|
||||
$this->root_dn,
|
||||
(string) $query,
|
||||
(string)$query,
|
||||
$fields,
|
||||
0, // Attributes and values
|
||||
0 // No limit - at least where possible
|
||||
0 // No limit - at least where possible
|
||||
);
|
||||
if (! $results) {
|
||||
throw new Exception(sprintf(
|
||||
'LDAP query "%s" (root %s) failed: %s',
|
||||
$query,
|
||||
$this->root_dn,
|
||||
ldap_error($this->ds)
|
||||
));
|
||||
if (!$results) {
|
||||
throw new Exception(
|
||||
sprintf(
|
||||
'LDAP query "%s" (root %s) failed: %s',
|
||||
$query,
|
||||
$this->root_dn,
|
||||
ldap_error($this->ds)
|
||||
)
|
||||
);
|
||||
|
||||
die('Query failed');
|
||||
}
|
||||
$list = array();
|
||||
if ($query instanceof Query) {
|
||||
foreach ($query->getSortColumns() as $col) {
|
||||
ldap_sort($this->ds, $results, $col[0]) ;
|
||||
ldap_sort($this->ds, $results, $col[0]);
|
||||
}
|
||||
}
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $username
|
||||
* @param $password
|
||||
* @return bool
|
||||
*/
|
||||
public function testCredentials($username, $password)
|
||||
{
|
||||
Log::debug("Trying to connect to %s", $this->hostname);
|
||||
|
@ -233,10 +309,12 @@ class Connection
|
|||
if ($r) {
|
||||
return true;
|
||||
} else {
|
||||
log::fatal('LDAP connection (%s / %s) failed: %s',
|
||||
log::fatal(
|
||||
'LDAP connection (%s / %s) failed: %s',
|
||||
$username,
|
||||
'***',
|
||||
ldap_error($ds));
|
||||
ldap_error($ds)
|
||||
);
|
||||
return false;
|
||||
/* TODO: Log failure
|
||||
throw new Exception(sprintf(
|
||||
|
@ -249,17 +327,26 @@ class Connection
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getConfigDir()
|
||||
{
|
||||
return Config::getInstance()->getConfigDir() . '/ldap';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $domain
|
||||
*/
|
||||
protected function discoverServerlistForDomain($domain)
|
||||
{
|
||||
$ldaps_records = dns_get_record('_ldaps._tcp.' . $domain, DNS_SRV);
|
||||
$ldap_records = dns_get_record('_ldap._tcp.' . $domain, DNS_SRV);
|
||||
$ldap_records = dns_get_record('_ldap._tcp.' . $domain, DNS_SRV);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected function prepareTlsEnvironment()
|
||||
{
|
||||
$strict_tls = true;
|
||||
|
@ -276,9 +363,13 @@ class Connection
|
|||
// file_put_contents('/tmp/tom_LDAP.conf', "TLS_REQCERT never\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return object
|
||||
*/
|
||||
protected function fetchRootDseDetails()
|
||||
{
|
||||
$query = $this->select()->from('*', array('+'))
|
||||
$query = $this->select()->from('*', array('+'));
|
||||
|
||||
/*, array(
|
||||
'defaultNamingContext',
|
||||
'namingContexts',
|
||||
|
@ -288,13 +379,13 @@ class Connection
|
|||
'supportedLDAPVersion', // => array(3, 2)
|
||||
'supportedCapabilities'
|
||||
))*/
|
||||
;
|
||||
|
||||
$fields = $query->listFields();
|
||||
|
||||
$result = ldap_read(
|
||||
$this->ds,
|
||||
'',
|
||||
(string) $query,
|
||||
(string)$query,
|
||||
$query->listFields(),
|
||||
0,
|
||||
0
|
||||
|
@ -302,8 +393,8 @@ class Connection
|
|||
|
||||
$entry = ldap_first_entry($this->ds, $result);
|
||||
$result = $this->cleanupAttributes(ldap_get_attributes($this->ds, $entry));
|
||||
|
||||
|
||||
|
||||
|
||||
if (isset($result->supportedCapabilities)) {
|
||||
foreach ($result->supportedCapabilities as $oid) {
|
||||
if (array_key_exists($oid, $this->ms_capability)) {
|
||||
|
@ -322,14 +413,22 @@ class Connection
|
|||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function discoverCapabilities()
|
||||
{
|
||||
$this->fetchRootDseDetails();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function connect()
|
||||
{
|
||||
if ($this->ds !== null) return;
|
||||
if ($this->ds !== null) {
|
||||
return;
|
||||
}
|
||||
$use_tls = true;
|
||||
$force_tls = true;
|
||||
|
||||
|
@ -343,34 +442,42 @@ class Connection
|
|||
if (ldap_start_tls($this->ds)) {
|
||||
Log::debug("Trying ldap_start_tls() succeeded");
|
||||
} else {
|
||||
Log::warn("ldap_start_tls() failed: %s. Does your ldap_ca.conf point to the certificate? ",ldap_error($this->ds));
|
||||
Log::warn(
|
||||
"ldap_start_tls() failed: %s. Does your ldap_ca.conf point to the certificate? ",
|
||||
ldap_error($this->ds)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// ldap_rename requires LDAPv3:
|
||||
if (! ldap_set_option($this->ds, LDAP_OPT_PROTOCOL_VERSION, 3)) {
|
||||
if (!ldap_set_option($this->ds, LDAP_OPT_PROTOCOL_VERSION, 3)) {
|
||||
throw new Exception('LDAPv3 is required');
|
||||
}
|
||||
//
|
||||
// Not setting this results in "Operations error" on AD when using the
|
||||
|
||||
// Not setting this results in "Operations error" on AD when using the
|
||||
// whole domain as search base:
|
||||
ldap_set_option($this->ds, LDAP_OPT_REFERRALS, 0);
|
||||
|
||||
// ldap_set_option($this->ds, LDAP_OPT_DEREF, LDAP_DEREF_NEVER);
|
||||
Log::debug("Trying ldap_bind(%s)",$this->bind_dn);
|
||||
Log::debug("Trying ldap_bind(%s)", $this->bind_dn);
|
||||
|
||||
$r = @ldap_bind($this->ds, $this->bind_dn, $this->bind_pw);
|
||||
|
||||
if (! $r) {
|
||||
log::fatal('LDAP connection (%s / %s) failed: %s',
|
||||
$this->bind_dn,
|
||||
'***',
|
||||
ldap_error($this->ds));
|
||||
throw new Exception(sprintf(
|
||||
if (!$r) {
|
||||
log::fatal(
|
||||
'LDAP connection (%s / %s) failed: %s',
|
||||
$this->bind_dn,
|
||||
'***' /* $this->bind_pw */,
|
||||
'***',
|
||||
ldap_error($this->ds)
|
||||
));
|
||||
);
|
||||
throw new Exception(
|
||||
sprintf(
|
||||
'LDAP connection (%s / %s) failed: %s',
|
||||
$this->bind_dn,
|
||||
'***' /* $this->bind_pw */,
|
||||
ldap_error($this->ds)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Protocol\Ldap;
|
||||
|
||||
/**
|
||||
* Class Exception
|
||||
* @package Icinga\Protocol\Ldap
|
||||
*/
|
||||
class Exception extends \Exception
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Protocol\Ldap;
|
||||
/**
|
||||
* LdapUtils class
|
||||
*
|
||||
* @package Icinga\Protocol\Ldap
|
||||
*/
|
||||
|
||||
/**
|
||||
* This class provides useful LDAP-related functions
|
||||
*
|
||||
|
@ -52,7 +50,9 @@ class LdapUtils
|
|||
{
|
||||
$str = '';
|
||||
foreach ($parts as $part) {
|
||||
if ($str !== '') { $str .= ','; }
|
||||
if ($str !== '') {
|
||||
$str .= ',';
|
||||
}
|
||||
list($key, $val) = preg_split('~=~', $part, 2);
|
||||
$str .= $key . '=' . self::quoteForDN($val);
|
||||
}
|
||||
|
@ -69,9 +69,20 @@ class LdapUtils
|
|||
*/
|
||||
public static function quoteForDN($str)
|
||||
{
|
||||
return self::quoteChars($str, array(
|
||||
',', '=', '+', '<', '>', ';', '\\', '"', '#'
|
||||
));
|
||||
return self::quoteChars(
|
||||
$str,
|
||||
array(
|
||||
',',
|
||||
'=',
|
||||
'+',
|
||||
'<',
|
||||
'>',
|
||||
';',
|
||||
'\\',
|
||||
'"',
|
||||
'#'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -80,6 +91,7 @@ class LdapUtils
|
|||
* Special characters will be escaped
|
||||
*
|
||||
* @param string String to be escaped
|
||||
* @param bool $allow_wildcard
|
||||
* @return string
|
||||
*/
|
||||
public static function quoteForSearch($str, $allow_wildcard = false)
|
||||
|
@ -95,14 +107,16 @@ class LdapUtils
|
|||
*
|
||||
* Special characters will be escaped
|
||||
*
|
||||
* @param string String to be escaped
|
||||
* @param $str
|
||||
* @param $chars
|
||||
* @internal param String $string to be escaped
|
||||
* @return string
|
||||
*/
|
||||
protected static function quoteChars($str, $chars)
|
||||
{
|
||||
$quotedChars = array();
|
||||
foreach ($chars as $k => $v) {
|
||||
// Temporarily prefixing with illegal '('
|
||||
// Temporarily prefixing with illegal '('
|
||||
$quotedChars[$k] = '(' . str_pad(dechex(ord($v)), 2, '0');
|
||||
}
|
||||
$str = str_replace($chars, $quotedChars, $str);
|
||||
|
@ -112,4 +126,3 @@ class LdapUtils
|
|||
return $str;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,31 +1,49 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Protocol\Ldap;
|
||||
/**
|
||||
* Node class
|
||||
*
|
||||
* @package Icinga\Protocol\Ldap
|
||||
*/
|
||||
|
||||
/**
|
||||
* This class represents an LDAP node object
|
||||
*
|
||||
* @copyright Copyright (c) 2013 Icinga-Web Team <info@icinga.org>
|
||||
* @author Icinga-Web Team <info@icinga.org>
|
||||
* @package Icinga\Protocol\Ldap
|
||||
* @package Icinga\Protocol\Ldap
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
|
||||
*/
|
||||
class Node extends Root
|
||||
{
|
||||
/**
|
||||
* @var Connection
|
||||
*/
|
||||
protected $connection;
|
||||
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
protected $rdn;
|
||||
|
||||
/**
|
||||
* @var Root
|
||||
*/
|
||||
protected $parent;
|
||||
|
||||
/**
|
||||
* @param Root $parent
|
||||
*/
|
||||
protected function __construct(Root $parent)
|
||||
{
|
||||
$this->connection = $parent->getConnection();
|
||||
$this->parent = $parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $parent
|
||||
* @param $rdn
|
||||
* @param array $props
|
||||
* @return Node
|
||||
*/
|
||||
public static function createWithRDN($parent, $rdn, $props = array())
|
||||
{
|
||||
$node = new Node($parent);
|
||||
|
@ -34,14 +52,19 @@ class Node extends Root
|
|||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getRDN()
|
||||
{
|
||||
return $this->rdn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed|string
|
||||
*/
|
||||
public function getDN()
|
||||
{
|
||||
return $this->parent->getDN() . '.' . $this->getRDN();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Protocol\Ldap;
|
||||
/**
|
||||
* Search class
|
||||
*
|
||||
* @package Icinga\Protocol\Ldap
|
||||
*/
|
||||
|
||||
use Icinga\Web\Paginator\Adapter\QueryAdapter;
|
||||
|
||||
/**
|
||||
* Search abstraction class
|
||||
*
|
||||
|
@ -19,22 +19,50 @@ namespace Icinga\Protocol\Ldap;
|
|||
* @author Icinga-Web Team <info@icinga.org>
|
||||
* @package Icinga\Protocol\Ldap
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
|
||||
* @package Icinga\Protocol\Ldap
|
||||
*/
|
||||
class Query
|
||||
{
|
||||
/**
|
||||
* @var Connection
|
||||
*/
|
||||
protected $connection;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $filters = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $fields = array();
|
||||
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
protected $limit_count;
|
||||
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
protected $limit_offset;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $sort_columns = array();
|
||||
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
protected $count;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param Connection LDAP Connection object
|
||||
* @return void
|
||||
* @param \Icinga\Protocol\Ldap\Connection $connection LDAP Connection object
|
||||
* @return \Icinga\Protocol\Ldap\Query
|
||||
*/
|
||||
public function __construct(Connection $connection)
|
||||
{
|
||||
|
@ -57,19 +85,24 @@ class Query
|
|||
/**
|
||||
* Count result set, ignoring limits
|
||||
*
|
||||
* @param null $count
|
||||
* @param null $offset
|
||||
* @throws Exception
|
||||
* @return int
|
||||
*/
|
||||
public function limit($count = null, $offset = null)
|
||||
{
|
||||
if (! preg_match('~^\d+~', $count . $offset)) {
|
||||
throw new Exception(sprintf(
|
||||
'Got invalid limit: %s, %s',
|
||||
$count,
|
||||
$offset
|
||||
));
|
||||
if (!preg_match('~^\d+~', $count . $offset)) {
|
||||
throw new Exception(
|
||||
sprintf(
|
||||
'Got invalid limit: %s, %s',
|
||||
$count,
|
||||
$offset
|
||||
)
|
||||
);
|
||||
}
|
||||
$this->limit_count = (int) $count;
|
||||
$this->limit_offset = (int) $offset;
|
||||
$this->limit_count = (int)$count;
|
||||
$this->limit_offset = (int)$offset;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -122,15 +155,18 @@ class Query
|
|||
{
|
||||
$result = $this->fetchAll();
|
||||
$sorted = array();
|
||||
foreach ($result as $key => & $item)
|
||||
{
|
||||
$new_key = LdapUtils::implodeDN(array_reverse(LdapUtils::explodeDN(
|
||||
preg_replace(
|
||||
'/,' . preg_quote($this->connection->getDN(), '/') . '$/',
|
||||
'',
|
||||
$key
|
||||
foreach ($result as $key => & $item) {
|
||||
$new_key = LdapUtils::implodeDN(
|
||||
array_reverse(
|
||||
LdapUtils::explodeDN(
|
||||
preg_replace(
|
||||
'/,' . preg_quote($this->connection->getDN(), '/') . '$/',
|
||||
'',
|
||||
$key
|
||||
)
|
||||
)
|
||||
)
|
||||
)));
|
||||
);
|
||||
$sorted[$new_key] = $key;
|
||||
}
|
||||
unset($groups);
|
||||
|
@ -189,6 +225,8 @@ class Query
|
|||
*
|
||||
* This creates an objectClass filter
|
||||
*
|
||||
* @param $objectClass
|
||||
* @param array $fields
|
||||
* @return Query
|
||||
*/
|
||||
public function from($objectClass, $fields = array())
|
||||
|
@ -249,6 +287,8 @@ class Query
|
|||
/**
|
||||
* Return a pagination adapter for the current query
|
||||
*
|
||||
* @param null $limit
|
||||
* @param null $page
|
||||
* @return \Zend_Paginator
|
||||
*/
|
||||
public function paginate($limit = null, $page = null)
|
||||
|
@ -264,7 +304,7 @@ class Query
|
|||
}
|
||||
$paginator = new \Zend_Paginator(
|
||||
// TODO: Adapter doesn't fit yet:
|
||||
new \Icinga\Web\Paginator\Adapter\QueryAdapter($this)
|
||||
new QueryAdapter($this)
|
||||
);
|
||||
$paginator->setItemCountPerPage($limit);
|
||||
$paginator->setCurrentPageNumber($page);
|
||||
|
@ -303,7 +343,7 @@ class Query
|
|||
}
|
||||
|
||||
/**
|
||||
* Descructor
|
||||
* Destructor
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
|
@ -311,4 +351,3 @@ class Query
|
|||
unset($this->connection);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Protocol\Ldap;
|
||||
/**
|
||||
* Root class
|
||||
*
|
||||
* @package Icinga\Protocol\Ldap
|
||||
*/
|
||||
|
||||
/**
|
||||
* This class is a special node object, representing your connections root node
|
||||
*
|
||||
|
@ -13,40 +11,71 @@ namespace Icinga\Protocol\Ldap;
|
|||
* @author Icinga-Web Team <info@icinga.org>
|
||||
* @package Icinga\Protocol\Ldap
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
|
||||
* @package Icinga\Protocol\Ldap
|
||||
*/
|
||||
class Root
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $rdn;
|
||||
|
||||
/**
|
||||
* @var Connection
|
||||
*/
|
||||
protected $connection;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $children = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $props = array();
|
||||
|
||||
/**
|
||||
* @param Connection $connection
|
||||
*/
|
||||
protected function __construct(Connection $connection)
|
||||
{
|
||||
$this->connection = $connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasParent()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Connection $connection
|
||||
* @return Root
|
||||
*/
|
||||
public static function forConnection(Connection $connection)
|
||||
{
|
||||
$root = new Root($connection);
|
||||
return $root;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $dn
|
||||
* @param array $props
|
||||
* @return Node
|
||||
*/
|
||||
public function createChildByDN($dn, $props = array())
|
||||
{
|
||||
$dn = $this->stripMyDN($dn);
|
||||
$parts = array_reverse(LdapUtils::explodeDN($dn));
|
||||
$parent = $this;
|
||||
while($rdn = array_shift($parts)) {
|
||||
while ($rdn = array_shift($parts)) {
|
||||
if ($parent->hasChildRDN($rdn)) {
|
||||
$child = $parent->getChildByRDN($rdn);
|
||||
} else {
|
||||
$child = Node::createWithRDN($parent, $rdn, (array) $props);
|
||||
$child = Node::createWithRDN($parent, $rdn, (array)$props);
|
||||
$parent->addChild($child);
|
||||
}
|
||||
$parent = $child;
|
||||
|
@ -54,102 +83,159 @@ class Root
|
|||
return $child;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $rdn
|
||||
* @return bool
|
||||
*/
|
||||
public function hasChildRDN($rdn)
|
||||
{
|
||||
return array_key_exists(strtolower($rdn), $this->children);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $rdn
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getChildByRDN($rdn)
|
||||
{
|
||||
if (! $this->hasChildRDN($rdn)) {
|
||||
throw new Exception(sprintf(
|
||||
'The child RDN "%s" is not available',
|
||||
$rdn
|
||||
));
|
||||
if (!$this->hasChildRDN($rdn)) {
|
||||
throw new Exception(
|
||||
sprintf(
|
||||
'The child RDN "%s" is not available',
|
||||
$rdn
|
||||
)
|
||||
);
|
||||
}
|
||||
return $this->children[strtolower($rdn)];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function children()
|
||||
{
|
||||
return $this->children;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasChildren()
|
||||
{
|
||||
return ! empty($this->children);
|
||||
return !empty($this->children);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Node $child
|
||||
* @return $this
|
||||
*/
|
||||
public function addChild(Node $child)
|
||||
{
|
||||
$this->children[strtolower($child->getRDN())] = $child;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $dn
|
||||
* @return string
|
||||
*/
|
||||
protected function stripMyDN($dn)
|
||||
{
|
||||
$this->assertSubDN($dn);
|
||||
return substr($dn, 0, strlen($dn) - strlen($this->getDN()) - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $dn
|
||||
* @return $this
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function assertSubDN($dn)
|
||||
{
|
||||
$mydn = $this->getDN();
|
||||
$end = substr($dn, -1 * strlen($mydn));
|
||||
if (strtolower($end) !== strtolower($mydn)) {
|
||||
throw new Exception(sprintf(
|
||||
'"%s" is not a child of "%s"',
|
||||
$dn,
|
||||
$mydn
|
||||
));
|
||||
throw new Exception(
|
||||
sprintf(
|
||||
'"%s" is not a child of "%s"',
|
||||
$dn,
|
||||
$mydn
|
||||
)
|
||||
);
|
||||
}
|
||||
if (strlen($dn) === strlen($mydn)) {
|
||||
throw new Exception(sprintf(
|
||||
'"%s" is not a child of "%s", they are equal',
|
||||
$dn,
|
||||
$mydn
|
||||
));
|
||||
throw new Exception(
|
||||
sprintf(
|
||||
'"%s" is not a child of "%s", they are equal',
|
||||
$dn,
|
||||
$mydn
|
||||
)
|
||||
);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Connection $connection
|
||||
* @return $this
|
||||
*/
|
||||
public function setConnection(Connection $connection)
|
||||
{
|
||||
$this->connection = $connection;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Connection
|
||||
*/
|
||||
public function getConnection()
|
||||
{
|
||||
return $this->connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasBeenChanged()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getRDN()
|
||||
{
|
||||
return $this->getDN();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getDN()
|
||||
{
|
||||
return $this->connection->getDN();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $key
|
||||
* @return null
|
||||
*/
|
||||
public function __get($key)
|
||||
{
|
||||
if (! array_key_exists($key, $this->props)) {
|
||||
if (!array_key_exists($key, $this->props)) {
|
||||
return null;
|
||||
}
|
||||
return $this->props[$key];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $key
|
||||
* @return bool
|
||||
*/
|
||||
public function __isset($key)
|
||||
{
|
||||
return array_key_exists($key, $this->props);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Protocol\Statusdat\Exception;
|
||||
|
||||
/**
|
||||
* Class ParsingException
|
||||
* @package Icinga\Protocol\Statusdat\Exception
|
||||
*/
|
||||
class ParsingException extends \RuntimeException
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -1,18 +1,25 @@
|
|||
<?php
|
||||
/**
|
||||
* Created by JetBrains PhpStorm.
|
||||
* User: moja
|
||||
* Date: 1/17/13
|
||||
* Time: 10:21 AM
|
||||
* To change this template use File | Settings | File Templates.
|
||||
*/
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Protocol\Statusdat;
|
||||
|
||||
interface IReader
|
||||
{
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getState();
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getObjects();
|
||||
|
||||
public function getObjectByName($type,$name);
|
||||
|
||||
/**
|
||||
* @param $type
|
||||
* @param $name
|
||||
* @return mixed
|
||||
*/
|
||||
public function getObjectByName($type, $name);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
<?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(\stdClass &$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) {
|
||||
|
||||
$result = $result->$elem;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
|
@ -1,30 +1,72 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Protocol\Statusdat;
|
||||
|
||||
use Icinga\Application\Logger;
|
||||
use Icinga\Exception\ConfigurationError;
|
||||
use Icinga\Exception\ProgrammingError;
|
||||
use Icinga\Protocol\Statusdat\Exception\ParsingException as ParsingException;
|
||||
|
||||
class Parser
|
||||
/**
|
||||
* Class Parser
|
||||
* @package Icinga\Protocol\Statusdat
|
||||
*/
|
||||
class Parser
|
||||
{
|
||||
private $deferred = array();
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $deferred = array();
|
||||
|
||||
/**
|
||||
* @var null|resource
|
||||
*/
|
||||
private $filehandle = null;
|
||||
|
||||
/**
|
||||
* @var null
|
||||
*/
|
||||
private $currentObjectType = null;
|
||||
|
||||
/**
|
||||
* @var null
|
||||
*/
|
||||
private $currentStateType = null;
|
||||
|
||||
/**
|
||||
* @var null
|
||||
*/
|
||||
private $icingaState = null;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $lineCtr = 0;
|
||||
|
||||
|
||||
/**
|
||||
* @param null $filehandle
|
||||
* @param null $baseState
|
||||
* @throws \Icinga\Exception\ConfigurationError
|
||||
*/
|
||||
public function __construct($filehandle = null, $baseState = null)
|
||||
{
|
||||
if (!is_resource($filehandle))
|
||||
throw new \Icinga\Exception\ConfigurationError("Statusdat parser can't find $filehandle");
|
||||
if (!is_resource($filehandle)) {
|
||||
throw new ConfigurationError("Statusdat parser can't find $filehandle");
|
||||
}
|
||||
|
||||
$this->filehandle = $filehandle;
|
||||
$this->icingaState = $baseState;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function parseObjectsFile()
|
||||
{
|
||||
\Icinga\Application\Logger::debug("Reading new objects file");
|
||||
Logger::debug("Reading new objects file");
|
||||
$DEFINE = strlen("define ");
|
||||
$filehandle = $this->filehandle;
|
||||
$this->icingaState = array();
|
||||
|
@ -33,9 +75,10 @@ class Parser
|
|||
$line = trim(fgets($filehandle));
|
||||
|
||||
$this->lineCtr++;
|
||||
if ($line === "" || $line[0] === "#")
|
||||
if ($line === "" || $line[0] === "#") {
|
||||
continue;
|
||||
$this->currentObjectType = trim(substr($line,$DEFINE,-1));
|
||||
}
|
||||
$this->currentObjectType = trim(substr($line, $DEFINE, -1));
|
||||
if (!isset($this->icingaState[$this->currentObjectType])) {
|
||||
$this->icingaState[$this->currentObjectType] = array();
|
||||
}
|
||||
|
@ -44,50 +87,62 @@ class Parser
|
|||
$this->processDeferred();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null $filehandle
|
||||
* @throws ProgrammingError
|
||||
*/
|
||||
public function parseRuntimeState($filehandle = null)
|
||||
{
|
||||
if($filehandle != null)
|
||||
if ($filehandle != null) {
|
||||
$this->filehandle = $filehandle;
|
||||
else
|
||||
} else {
|
||||
$filehandle = $this->filehandle;
|
||||
}
|
||||
|
||||
if(!$this->icingaState)
|
||||
throw new \Icinga\Exception\ProgrammingError("Tried to read runtime state without existing objects data");
|
||||
if (!$this->icingaState) {
|
||||
throw new ProgrammingError("Tried to read runtime state without existing objects data");
|
||||
}
|
||||
$this->overwrites = array();
|
||||
while (!feof($filehandle)) {
|
||||
|
||||
$line = trim(fgets($filehandle));
|
||||
|
||||
$this->lineCtr++;
|
||||
if ($line === "" || $line[0] === "#")
|
||||
if ($line === "" || $line[0] === "#") {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->currentStateType = trim(substr($line,0,-1));
|
||||
$this->currentStateType = trim(substr($line, 0, -1));
|
||||
$this->readCurrentState();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @throws Exception\ParsingException
|
||||
*/
|
||||
private function readCurrentObject()
|
||||
{
|
||||
$filehandle = $this->filehandle;
|
||||
$monitoringObject = new \stdClass();
|
||||
while (!feof($filehandle)) {
|
||||
$line = explode("\t",trim(fgets($filehandle)),2);
|
||||
$line = explode("\t", trim(fgets($filehandle)), 2);
|
||||
$this->lineCtr++;
|
||||
if (!$line)
|
||||
if (!$line) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// End of object
|
||||
if ($line[0] === "}") {
|
||||
$this->registerObject($monitoringObject);
|
||||
return;
|
||||
}
|
||||
if(!isset($line[1]))
|
||||
if (!isset($line[1])) {
|
||||
$line[1] = "";
|
||||
}
|
||||
$monitoringObject->{$line[0]} = trim($line[1]);
|
||||
}
|
||||
throw new ParsingException("Unexpected EOF in objects.cache, line ".$this->lineCtr);
|
||||
throw new ParsingException("Unexpected EOF in objects.cache, line " . $this->lineCtr);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -101,48 +156,60 @@ class Parser
|
|||
|
||||
$objectType = $this->getObjectTypeForState();
|
||||
|
||||
if($objectType != "host" && $objectType != "service") {
|
||||
if ($objectType != "host" && $objectType != "service") {
|
||||
$this->skipObject(); // ignore unknown objects
|
||||
return;
|
||||
}
|
||||
if(!isset($this->icingaState[$this->currentObjectType]))
|
||||
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;
|
||||
}
|
||||
$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 (!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") {
|
||||
$base[$name]->status = &$statusdatObject;
|
||||
if ($type == "status") {
|
||||
$base[$name]->status = & $statusdatObject;
|
||||
} else {
|
||||
if(!isset($base[$name]->$type) || !in_array($base[$name]->$type,$this->overwrites)) {
|
||||
if (!isset($base[$name]->$type) || !in_array($base[$name]->$type, $this->overwrites)) {
|
||||
$base[$name]->$type = array();
|
||||
$this->overwrites[] = &$base[$name]->$type;
|
||||
$this->overwrites[] = & $base[$name]->$type;
|
||||
}
|
||||
array_push($base[$name]->$type,$statusdatObject);
|
||||
array_push($base[$name]->$type, $statusdatObject);
|
||||
}
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|string
|
||||
*/
|
||||
private function getObjectTypeForState()
|
||||
{
|
||||
$pos = strpos($this->currentStateType,"service");
|
||||
$pos = strpos($this->currentStateType, "service");
|
||||
|
||||
if($pos === False) {
|
||||
$pos = strpos($this->currentStateType,"host");
|
||||
if ($pos === false) {
|
||||
$pos = strpos($this->currentStateType, "host");
|
||||
} else {
|
||||
$this->currentObjectType = "service";
|
||||
return "service";
|
||||
}
|
||||
|
||||
if($pos === False)
|
||||
if ($pos === false) {
|
||||
return $this->currentStateType;
|
||||
else {
|
||||
} else {
|
||||
$this->currentObjectType = "host";
|
||||
return "host";
|
||||
}
|
||||
|
@ -150,89 +217,118 @@ class Parser
|
|||
return $this->currentObjectType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $returnString
|
||||
* @return string
|
||||
*/
|
||||
protected function skipObject($returnString = false)
|
||||
{
|
||||
if(!$returnString) {
|
||||
while(trim(fgets($this->filehandle)) !== "}") {
|
||||
if (!$returnString) {
|
||||
while (trim(fgets($this->filehandle)) !== "}") {
|
||||
}
|
||||
return;
|
||||
return null;
|
||||
} else {
|
||||
$str = "";
|
||||
while(($val = trim(fgets($this->filehandle))) !== "}") {
|
||||
$str .= $val."\n";
|
||||
while (($val = trim(fgets($this->filehandle))) !== "}") {
|
||||
$str .= $val . "\n";
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
|
||||
protected function registerObject(&$object) {
|
||||
/**
|
||||
* @param $object
|
||||
*/
|
||||
protected function registerObject(&$object)
|
||||
{
|
||||
|
||||
$name = $this->getObjectIdentifier($object);
|
||||
|
||||
if($name !== false) {
|
||||
$this->icingaState[$this->currentObjectType][$name] = &$object;
|
||||
if ($name !== false) {
|
||||
$this->icingaState[$this->currentObjectType][$name] = & $object;
|
||||
}
|
||||
$this->registerObjectAsProperty($object);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $object
|
||||
*/
|
||||
protected function registerObjectAsProperty(&$object)
|
||||
{
|
||||
if($this->currentObjectType == "service" || $this->currentObjectType == "host") {
|
||||
return;
|
||||
if ($this->currentObjectType == "service" || $this->currentObjectType == "host") {
|
||||
return null;
|
||||
}
|
||||
$isService = strpos($this->currentObjectType,"service") !== False;
|
||||
$isHost = strpos($this->currentObjectType,"host") !== False;
|
||||
$isService = strpos($this->currentObjectType, "service") !== false;
|
||||
$isHost = strpos($this->currentObjectType, "host") !== false;
|
||||
|
||||
$name = $this->getObjectIdentifier($object);
|
||||
if($isService === false && $isHost === false) // this would be error in the parser implementation
|
||||
return;
|
||||
if ($isService === false && $isHost === false) { // this would be error in the parser implementation
|
||||
return null;
|
||||
}
|
||||
$property = $this->currentObjectType;
|
||||
if($isService) {
|
||||
if ($isService) {
|
||||
$this->currentObjectType = "service";
|
||||
$property = substr($property,strlen("service"));
|
||||
$property = substr($property, strlen("service"));
|
||||
} else {
|
||||
$this->currentObjectType = "host";
|
||||
$property = substr($property,strlen("host"));
|
||||
$property = substr($property, strlen("host"));
|
||||
}
|
||||
if (!isset($this->icingaState[$this->currentObjectType])) {
|
||||
return $this->deferRegistration($object, $this->currentObjectType . $property);
|
||||
}
|
||||
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) {
|
||||
if (strpos($property, "group") !== false) {
|
||||
$sourceIdentifier = $this->getMembers($object);
|
||||
foreach($sourceIdentifier as $id) {
|
||||
foreach ($sourceIdentifier as $id) {
|
||||
$source = $this->icingaState[$this->currentObjectType][$id];
|
||||
if(!isset($source->$property))
|
||||
if (!isset($source->$property)) {
|
||||
$source->$property = array();
|
||||
}
|
||||
array_push($source->$property, $name);
|
||||
}
|
||||
} else {
|
||||
$source = $this->icingaState[$this->currentObjectType][$this->getObjectIdentifier($object)];
|
||||
if(!isset($source->$property))
|
||||
if (!isset($source->$property)) {
|
||||
$source->$property = array();
|
||||
}
|
||||
array_push($source->$property, $object);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function deferRegistration($object,$objType)
|
||||
/**
|
||||
* @param $object
|
||||
* @param $objType
|
||||
*/
|
||||
protected function deferRegistration($object, $objType)
|
||||
{
|
||||
$this->deferred[] = array($object,$objType);
|
||||
$this->deferred[] = array($object, $objType);
|
||||
}
|
||||
|
||||
protected function processDeferred() {
|
||||
foreach($this->deferred as $obj) {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected function processDeferred()
|
||||
{
|
||||
foreach ($this->deferred as $obj) {
|
||||
$this->currentObjectType = $obj[1];
|
||||
$this->registerObjectAsProperty($obj[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $object
|
||||
* @return array
|
||||
*/
|
||||
protected function getMembers(&$object)
|
||||
{
|
||||
$members = explode(",",$object->members);
|
||||
if($this->currentObjectType == "service") {
|
||||
$members = explode(",", $object->members);
|
||||
if ($this->currentObjectType == "service") {
|
||||
$res = array();
|
||||
for($i=0;$i<count($members);$i+=2) {
|
||||
$res[] = $members[$i].";".$members[$i+1];
|
||||
for ($i = 0; $i < count($members); $i += 2) {
|
||||
$res[] = $members[$i] . ";" . $members[$i + 1];
|
||||
}
|
||||
return $res;
|
||||
} else {
|
||||
|
@ -241,24 +337,29 @@ class Parser
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $object
|
||||
* @return bool|string
|
||||
*/
|
||||
protected function getObjectIdentifier(&$object)
|
||||
{
|
||||
if ($this->currentObjectType == "service") {
|
||||
return $object->host_name.";".$object->service_description;
|
||||
return $object->host_name . ";" . $object->service_description;
|
||||
}
|
||||
$name = $this->currentObjectType."_name";
|
||||
if(isset($object->{$name}))
|
||||
$name = $this->currentObjectType . "_name";
|
||||
if (isset($object->{$name})) {
|
||||
return $object->{$name};
|
||||
}
|
||||
return false;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return null
|
||||
*/
|
||||
public function getRuntimeState()
|
||||
{
|
||||
return $this->icingaState;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,20 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Protocol\Statusdat;
|
||||
|
||||
use Icinga\Protocol;
|
||||
|
||||
/**
|
||||
* Class Query
|
||||
* @package Icinga\Protocol\Statusdat
|
||||
*/
|
||||
class Query extends Protocol\AbstractQuery
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public static $VALID_TARGETS = array(
|
||||
"hosts" => array("host"),
|
||||
"services" => array("service"),
|
||||
|
@ -18,76 +28,153 @@ class Query extends Protocol\AbstractQuery
|
|||
"servicecomments" => array("servicecomment")
|
||||
);
|
||||
|
||||
/**
|
||||
* @var IReader|null
|
||||
*/
|
||||
private $reader = null;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $source = "";
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $columns = array();
|
||||
|
||||
/**
|
||||
* @var null
|
||||
*/
|
||||
private $limit = null;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $offset = 0;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $order_columns = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $groupColumns = array();
|
||||
|
||||
/**
|
||||
* @var null
|
||||
*/
|
||||
private $groupByFn = null;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $filter = array();
|
||||
|
||||
// Magic indexes
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const FN_SCOPE = 0;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const FN_NAME = 1;
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasOrder()
|
||||
{
|
||||
return !empty($this->order_columns);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasColumns()
|
||||
{
|
||||
return !empty($this->columns);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getColumns()
|
||||
{
|
||||
return $this->columns;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasLimit()
|
||||
{
|
||||
return $this->limit !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasOffset()
|
||||
{
|
||||
return $this->offset !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null
|
||||
*/
|
||||
public function getLimit()
|
||||
{
|
||||
return $this->limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|null
|
||||
*/
|
||||
public function getOffset()
|
||||
{
|
||||
return $this->offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param IReader $reader
|
||||
*/
|
||||
public function __construct(IReader $reader)
|
||||
{
|
||||
$this->reader = $reader;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $key
|
||||
* @param null $val
|
||||
* @return $this
|
||||
*/
|
||||
public function where($key, $val = null)
|
||||
{
|
||||
$this->filter[] = array($key, $val);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $columns
|
||||
* @param null $dir
|
||||
* @return $this
|
||||
*/
|
||||
public function order($columns, $dir = null)
|
||||
{
|
||||
if($dir && strtolower($dir) == "desc")
|
||||
if ($dir && strtolower($dir) == "desc") {
|
||||
$dir = self::SORT_DESC;
|
||||
else
|
||||
} else {
|
||||
$dir = self::SORT_ASC;
|
||||
if(!is_array($columns))
|
||||
}
|
||||
if (!is_array($columns)) {
|
||||
$columns = array($columns);
|
||||
foreach($columns as $col) {
|
||||
}
|
||||
foreach ($columns as $col) {
|
||||
|
||||
if (($pos = strpos($col, ' ')) !== false) {
|
||||
$dir = strtoupper(substr($col, $pos + 1));
|
||||
|
@ -106,6 +193,12 @@ class Query extends Protocol\AbstractQuery
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null $count
|
||||
* @param int $offset
|
||||
* @return $this
|
||||
* @throws Exception
|
||||
*/
|
||||
public function limit($count = null, $offset = 0)
|
||||
{
|
||||
if ((is_null($count) || is_integer($count)) && (is_null($offset) || is_integer($offset))) {
|
||||
|
@ -117,12 +210,19 @@ class Query extends Protocol\AbstractQuery
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $table
|
||||
* @param null $columns
|
||||
* @return $this
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function from($table, $columns = null)
|
||||
{
|
||||
if (isset(self::$VALID_TARGETS[$table]))
|
||||
if (isset(self::$VALID_TARGETS[$table])) {
|
||||
$this->source = $table;
|
||||
else
|
||||
throw new \Exception("Unknown from target for status.dat :". $table);
|
||||
} else {
|
||||
throw new \Exception("Unknown from target for status.dat :" . $table);
|
||||
}
|
||||
$this->columns = $columns;
|
||||
return $this;
|
||||
}
|
||||
|
@ -158,99 +258,131 @@ class Query extends Protocol\AbstractQuery
|
|||
return $result;
|
||||
}
|
||||
|
||||
private function orderIndices(array &$indices) {
|
||||
if(!empty($this->order_columns)) {
|
||||
foreach($indices as $type=>&$subindices) {
|
||||
/**
|
||||
* @param array $indices
|
||||
*/
|
||||
private function orderIndices(array &$indices)
|
||||
{
|
||||
if (!empty($this->order_columns)) {
|
||||
foreach ($indices as $type => &$subindices) {
|
||||
$this->currentType = $type; // we're singlethreaded, so let's do it a bit dirty
|
||||
usort($subindices,array($this,"orderResult"));
|
||||
usort($subindices, array($this, "orderResult"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function orderResult($a,$b) {
|
||||
$o1 = &$this->reader->getObjectByName($this->currentType,$a);
|
||||
$o2 = &$this->reader->getObjectByName($this->currentType,$b);
|
||||
/**
|
||||
* @param $a
|
||||
* @param $b
|
||||
* @return int
|
||||
*/
|
||||
private function orderResult($a, $b)
|
||||
{
|
||||
$o1 = & $this->reader->getObjectByName($this->currentType, $a);
|
||||
$o2 = & $this->reader->getObjectByName($this->currentType, $b);
|
||||
$result = 0;
|
||||
foreach($this->order_columns as $col) {
|
||||
foreach ($this->order_columns as $col) {
|
||||
|
||||
$result += $col[1]*strnatcasecmp($o1->{$col[0]},$o2->{$col[0]});
|
||||
$result += $col[1] * strnatcasecmp($o1->{$col[0]}, $o2->{$col[0]});
|
||||
}
|
||||
if($result > 0)
|
||||
if ($result > 0) {
|
||||
return 1;
|
||||
if($result < 0)
|
||||
}
|
||||
if ($result < 0) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $indices
|
||||
*/
|
||||
private function limitIndices(array &$indices)
|
||||
{
|
||||
foreach($indices as $type=>$subindices){
|
||||
$indices[$type] = array_slice($subindices,$this->offset,$this->limit);
|
||||
foreach ($indices as $type => $subindices) {
|
||||
$indices[$type] = array_slice($subindices, $this->offset, $this->limit);
|
||||
}
|
||||
}
|
||||
|
||||
public function groupByFunction($fn,$scope=null)
|
||||
/**
|
||||
* @param $fn
|
||||
* @param null $scope
|
||||
* @return $this
|
||||
*/
|
||||
public function groupByFunction($fn, $scope = null)
|
||||
{
|
||||
$this->groupByFn = array($scope ? $scope : $this,$fn);
|
||||
$this->groupByFn = array($scope ? $scope : $this, $fn);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $columns
|
||||
* @return $this
|
||||
*/
|
||||
public function groupByColumns($columns)
|
||||
{
|
||||
if(!is_array($columns))
|
||||
if (!is_array($columns)) {
|
||||
$columns = array($columns);
|
||||
}
|
||||
$this->groupColumns = $columns;
|
||||
$this->groupByFn = array($this,"columnGroupFn");
|
||||
$this->groupByFn = array($this, "columnGroupFn");
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $indices
|
||||
* @return array
|
||||
*/
|
||||
private function columnGroupFn(array &$indices)
|
||||
{
|
||||
$cols = $this->groupColumns;
|
||||
$result = array();
|
||||
foreach($indices as $type=>$subindices) {
|
||||
foreach($subindices as $objectIndex) {
|
||||
$r = &$this->reader->getObjectByName($type,$objectIndex);
|
||||
foreach ($indices as $type => $subindices) {
|
||||
foreach ($subindices as $objectIndex) {
|
||||
$r = & $this->reader->getObjectByName($type, $objectIndex);
|
||||
$hash = "";
|
||||
$cols = array();
|
||||
foreach($this->groupColumns as $col) {
|
||||
$hash = md5($hash.$r->$col);
|
||||
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,
|
||||
if (!isset($result[$hash])) {
|
||||
$result[$hash] = (object)array(
|
||||
"columns" => (object)$cols,
|
||||
"count" => 0
|
||||
);
|
||||
}
|
||||
$result[$hash]->count++;
|
||||
}
|
||||
}
|
||||
return array_values($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getResult()
|
||||
{
|
||||
|
||||
$indices = &$this->getFilteredIndices();
|
||||
$indices = & $this->getFilteredIndices();
|
||||
$this->orderIndices($indices);
|
||||
if($this->groupByFn) {
|
||||
if ($this->groupByFn) {
|
||||
$scope = $this->groupByFn[self::FN_SCOPE];
|
||||
$fn = $this->groupByFn[self::FN_NAME];
|
||||
$fn = $this->groupByFn[self::FN_NAME];
|
||||
|
||||
return $scope->$fn($indices);
|
||||
}
|
||||
}
|
||||
|
||||
$this->limitIndices($indices);
|
||||
|
||||
$result = array();
|
||||
$state = &$this->reader->getObjects();
|
||||
foreach ($indices as $type=>$subindices) {
|
||||
$state = & $this->reader->getObjects();
|
||||
foreach ($indices as $type => $subindices) {
|
||||
|
||||
foreach($subindices as $index) {
|
||||
$result[] = &$state[$type][$index];
|
||||
foreach ($subindices as $index) {
|
||||
$result[] = & $state[$type][$index];
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,89 +1,156 @@
|
|||
<?php
|
||||
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Protocol\Statusdat\Query;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* @var null
|
||||
*/
|
||||
private $name = null;
|
||||
|
||||
/**
|
||||
* @var null
|
||||
*/
|
||||
public $CB = null;
|
||||
|
||||
/**
|
||||
* @param $token
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function getOperatorType($token)
|
||||
{
|
||||
switch (strtoupper($token)) {
|
||||
case ">":
|
||||
$this->CB = "IS_GREATER";
|
||||
$this->CB = "isGreater";
|
||||
break;
|
||||
case "<":
|
||||
$this->CB = "IS_LESS";
|
||||
$this->CB = "isLess";
|
||||
break;
|
||||
case ">=":
|
||||
$this->CB = "IS_GREATER_EQ";
|
||||
$this->CB = "isGreaterEq";
|
||||
break;
|
||||
case "<=":
|
||||
$this->CB = "IS_LESS_EQ";
|
||||
$this->CB = "isLessEq";
|
||||
break;
|
||||
case "=":
|
||||
$this->CB = "IS_EQUAL";
|
||||
$this->CB = "isEqual";
|
||||
break;
|
||||
case "LIKE":
|
||||
$this->CB = "IS_LIKE";
|
||||
$this->CB = "isLike";
|
||||
break;
|
||||
case "!=":
|
||||
$this->CB = "IS_NOT_EQUAL";
|
||||
$this->CB = "isNotEqual";
|
||||
break;
|
||||
case "IN":
|
||||
$this->CB = "IS_IN";
|
||||
$this->CB = "isIn";
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new \Exception("Unknown operator $token in expression $this->expression !");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private function extractAggregationFunction(&$tokens) {
|
||||
/**
|
||||
* @param $tokens
|
||||
* @return mixed
|
||||
*/
|
||||
private function extractAggregationFunction(&$tokens)
|
||||
{
|
||||
$token = $tokens[0];
|
||||
$value = array();
|
||||
if(preg_match("/COUNT\{(.*)\}/",$token,$value) == false)
|
||||
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");
|
||||
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->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]);
|
||||
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;
|
||||
|
@ -91,61 +158,91 @@ class Expression implements IQueryPart
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null $expression
|
||||
* @param array $values
|
||||
*/
|
||||
public function __construct($expression = null, &$values = array())
|
||||
{
|
||||
if ($expression)
|
||||
if ($expression) {
|
||||
$this->fromString($expression, $values);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $base
|
||||
* @param array $idx
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function filter(array &$base, &$idx = array())
|
||||
{
|
||||
if (!$idx)
|
||||
if (!$idx) {
|
||||
$idx = array_keys($base);
|
||||
}
|
||||
$this->basedata = $base;
|
||||
return array_filter($idx, array($this,"filterFn"));
|
||||
return array_filter($idx, array($this, "filterFn"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getValue()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null
|
||||
*/
|
||||
public function getField()
|
||||
{
|
||||
return $this->field;
|
||||
}
|
||||
|
||||
protected function filterFn($idx) {
|
||||
/**
|
||||
* @param $idx
|
||||
* @return bool
|
||||
*/
|
||||
protected function filterFn($idx)
|
||||
{
|
||||
$values = $this->getFieldValues($idx);
|
||||
|
||||
if($values === False)
|
||||
if ($values === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if($this->CB == "IS_IN" ) {
|
||||
return count(array_intersect($values,$this->value)) > 0;
|
||||
if ($this->CB == "IS_IN") {
|
||||
return count(array_intersect($values, $this->value)) > 0;
|
||||
}
|
||||
if($this->CB == "IS_NOT_IN" )
|
||||
return count(array_intersect($values,$this->value)) == 0;
|
||||
if($this->function) {
|
||||
$values = call_user_func($this->function,$values);
|
||||
if(!is_array($values))
|
||||
if ($this->CB == "IS_NOT_IN") {
|
||||
return count(array_intersect($values, $this->value)) == 0;
|
||||
}
|
||||
if ($this->function) {
|
||||
$values = call_user_func($this->function, $values);
|
||||
if (!is_array($values)) {
|
||||
$values = array($values);
|
||||
}
|
||||
}
|
||||
foreach($values as $val)
|
||||
if($this->{$this->CB}($val))
|
||||
foreach ($values as $val) {
|
||||
if ($this->{$this->CB}($val)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private function getFieldValues($idx) {
|
||||
/**
|
||||
* @param $idx
|
||||
* @return array
|
||||
*/
|
||||
private function getFieldValues($idx)
|
||||
{
|
||||
$res = $this->basedata[$idx];
|
||||
foreach($this->fields as $field) {
|
||||
if(!is_array($res)) {
|
||||
if(!isset($res->$field)) {
|
||||
foreach ($this->fields as $field) {
|
||||
if (!is_array($res)) {
|
||||
if (!isset($res->$field)) {
|
||||
$res = array();
|
||||
break;
|
||||
}
|
||||
|
@ -157,60 +254,87 @@ class Expression implements IQueryPart
|
|||
// 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(!isset($sub->$field))
|
||||
foreach ($res as $sub) {
|
||||
if (!isset($sub->$field)) {
|
||||
continue;
|
||||
if(!is_array($sub->$field))
|
||||
}
|
||||
if (!is_array($sub->$field)) {
|
||||
$swap[] = $sub->$field;
|
||||
else {
|
||||
$swap = array_merge($swap,$sub->$field);
|
||||
} else {
|
||||
$swap = array_merge($swap, $sub->$field);
|
||||
}
|
||||
}
|
||||
$res = $swap;
|
||||
}
|
||||
if(!is_array($res))
|
||||
if (!is_array($res)) {
|
||||
return array($res);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
public function IS_GREATER($value)
|
||||
/**
|
||||
* @param $value
|
||||
* @return bool
|
||||
*/
|
||||
public function isGreater($value)
|
||||
{
|
||||
return $value > $this->value;
|
||||
}
|
||||
|
||||
public function IS_LESS($value)
|
||||
/**
|
||||
* @param $value
|
||||
* @return bool
|
||||
*/
|
||||
public function isLess($value)
|
||||
{
|
||||
return $value < $this->value;
|
||||
}
|
||||
|
||||
public function IS_LIKE($value)
|
||||
/**
|
||||
* @param $value
|
||||
* @return bool
|
||||
*/
|
||||
public function isLike($value)
|
||||
{
|
||||
|
||||
return preg_match("/^".str_replace("%", ".*", $this->value)."$/", $value) ? true : false;
|
||||
return preg_match("/^" . str_replace("%", ".*", $this->value) . "$/", $value) ? true : false;
|
||||
}
|
||||
|
||||
public function IS_EQUAL($value)
|
||||
/**
|
||||
* @param $value
|
||||
* @return bool
|
||||
*/
|
||||
public function isEqual($value)
|
||||
{
|
||||
if(!is_numeric($value))
|
||||
return strtolower($value) ==strtolower($this->value);
|
||||
if (!is_numeric($value)) {
|
||||
return strtolower($value) == strtolower($this->value);
|
||||
}
|
||||
return $value == $this->value;
|
||||
}
|
||||
|
||||
public function IS_NOT_EQUAL($value)
|
||||
/**
|
||||
* @param $value
|
||||
* @return bool
|
||||
*/
|
||||
public function isNotEqual($value)
|
||||
{
|
||||
return $value != $this->value;
|
||||
}
|
||||
|
||||
public function IS_GREATER_EQ($value)
|
||||
/**
|
||||
* @param $value
|
||||
* @return bool
|
||||
*/
|
||||
public function isGreaterEq($value)
|
||||
{
|
||||
return $value >= $this->value;
|
||||
}
|
||||
|
||||
public function IS_LESS_EQ($value)
|
||||
/**
|
||||
* @param $value
|
||||
* @return bool
|
||||
*/
|
||||
public function isLessEq($value)
|
||||
{
|
||||
return $value <= $this->value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,49 +1,130 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Protocol\Statusdat\Query;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* @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 \Exception
|
||||
*/
|
||||
private function tokenize()
|
||||
{
|
||||
$token = 0;
|
||||
|
@ -54,17 +135,28 @@ class Group implements IQueryPart
|
|||
|
||||
if ($token === self::GROUP_BEGIN) {
|
||||
|
||||
if ($subgroupCount == 0) // check if this is a nested group, if so then it's considered part of the subexpression
|
||||
/**
|
||||
* 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)
|
||||
if ($subgroupCount < 1) {
|
||||
throw new \Exception("Invalid Query: unexpected ')' at pos " . $this->parsePos);
|
||||
}
|
||||
$subgroupCount--;
|
||||
if ($subgroupCount == 0) // check if this is a nested group, if so then it's considered part of the subexpression
|
||||
/*
|
||||
* check if this is a nested group, if so then it's
|
||||
* considered part of the subexpression
|
||||
*/
|
||||
if ($subgroupCount == 0) {
|
||||
$this->addSubgroupFromExpression();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -92,12 +184,16 @@ class Group implements IQueryPart
|
|||
|
||||
$this->subExpressionLength = $this->parsePos - $this->subExpressionStart;
|
||||
}
|
||||
if ($subgroupCount > 0)
|
||||
if ($subgroupCount > 0) {
|
||||
throw new \Exception("Unexpected end of query, are you missing a parenthesis?");
|
||||
}
|
||||
|
||||
$this->startNewSubExpression();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $type
|
||||
*/
|
||||
private function createImplicitGroup($type)
|
||||
{
|
||||
$group = new Group();
|
||||
|
@ -110,25 +206,35 @@ class Group implements IQueryPart
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function startNewSubExpression()
|
||||
{
|
||||
if ($this->getCurrentSubExpression() != "") {
|
||||
if (!$this->expressionClass)
|
||||
if (!$this->expressionClass) {
|
||||
$this->items[] = new Expression($this->getCurrentSubExpression(), $this->value);
|
||||
else
|
||||
} 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()
|
||||
{
|
||||
|
||||
|
@ -143,23 +249,32 @@ class Group implements IQueryPart
|
|||
$this->subExpressionLength = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function isEOF()
|
||||
{
|
||||
if ($this->parsePos >= strlen($this->expression))
|
||||
if ($this->parsePos >= strlen($this->expression)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|string
|
||||
*/
|
||||
private function getNextToken()
|
||||
{
|
||||
if ($this->isEOF())
|
||||
if ($this->isEOF()) {
|
||||
return self::EOF;
|
||||
}
|
||||
|
||||
// skip whitespaces
|
||||
while ($this->expression[$this->parsePos] == " ") {
|
||||
$this->parsePos++;
|
||||
if ($this->isEOF())
|
||||
if ($this->isEOF()) {
|
||||
return self::EOF;
|
||||
}
|
||||
}
|
||||
if ($this->expression[$this->parsePos] == self::GROUP_BEGIN) {
|
||||
$this->parsePos++;
|
||||
|
@ -169,11 +284,23 @@ class Group implements IQueryPart
|
|||
$this->parsePos++;
|
||||
return self::GROUP_END;
|
||||
}
|
||||
if (substr_compare($this->expression, self::CONJUNCTION_AND, $this->parsePos, strlen(self::CONJUNCTION_AND), true) === 0) {
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
|
@ -181,12 +308,22 @@ class Group implements IQueryPart
|
|||
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;
|
||||
|
@ -197,24 +334,33 @@ class Group implements IQueryPart
|
|||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param null $expression
|
||||
* @param array $value
|
||||
*/
|
||||
public function __construct($expression = null, &$value = array())
|
||||
{
|
||||
if ($expression)
|
||||
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) {
|
||||
$idx += $subFilter->filter($base, array_keys($base));
|
||||
}
|
||||
} else {
|
||||
if (!$idx)
|
||||
if (!$idx) {
|
||||
$idx = array_keys($base);
|
||||
}
|
||||
foreach ($this->items as $subFilter) {
|
||||
$idx = array_intersect($idx, $subFilter->filter($base, $idx));
|
||||
}
|
||||
|
@ -223,4 +369,3 @@ class Group implements IQueryPart
|
|||
return $idx;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,25 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Protocol\Statusdat\Query;
|
||||
|
||||
|
||||
/**
|
||||
* Class IQueryPart
|
||||
* @package Icinga\Protocol\Statusdat\Query
|
||||
*/
|
||||
interface IQueryPart
|
||||
{
|
||||
public function __construct($expression = null,&$value = array());
|
||||
public function filter(array &$base, &$idx=null);
|
||||
/**
|
||||
* @param null $expression
|
||||
* @param array $value
|
||||
*/
|
||||
public function __construct($expression = null, &$value = array());
|
||||
|
||||
/**
|
||||
* @param array $base
|
||||
* @param null $idx
|
||||
* @return mixed
|
||||
*/
|
||||
public function filter(array &$base, &$idx = null);
|
||||
}
|
||||
|
|
|
@ -1,121 +1,146 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Protocol\Statusdat;
|
||||
|
||||
use Icinga\Backend\MonitoringObjectList;
|
||||
use Icinga\Exception as Exception;
|
||||
use Icinga\Benchmark as Benchmark;
|
||||
|
||||
class ObjectContainer extends \stdClass {
|
||||
public $ref;
|
||||
public $reader;
|
||||
|
||||
public function __construct(\stdClass &$obj,IReader &$reader) {
|
||||
$this->ref = &$obj;
|
||||
$this->reader = &$reader;
|
||||
|
||||
}
|
||||
public function __get($attribute) {
|
||||
$exploded = explode(".",$attribute);
|
||||
$result = $this->ref;
|
||||
foreach($exploded as $elem) {
|
||||
|
||||
$result = $result->$elem;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class Reader
|
||||
* @package Icinga\Protocol\Statusdat
|
||||
*/
|
||||
class Reader implements IReader
|
||||
{
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const DEFAULT_CACHE_LIFETIME = 300;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const STATUSDAT_DEFAULT_CACHE_PATH = "/cache";
|
||||
|
||||
|
||||
/**
|
||||
* @var null
|
||||
*/
|
||||
private $lastState = null;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $hasRuntimeState = false;
|
||||
|
||||
/**
|
||||
* @var null
|
||||
*/
|
||||
private $objectCache = null;
|
||||
|
||||
/**
|
||||
* @var null
|
||||
*/
|
||||
private $statusCache = null;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $newState = false;
|
||||
|
||||
/**
|
||||
* @var null
|
||||
*/
|
||||
private $parser = null;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $noCache = false;
|
||||
|
||||
/**
|
||||
* @param $config
|
||||
* @param null $parser
|
||||
* @param bool $noCache
|
||||
*/
|
||||
public function __construct($config = \Zend_Config, $parser = null, $noCache = false)
|
||||
{
|
||||
$this->noCache = $noCache;
|
||||
$this->config = $config;
|
||||
$this->parser = $parser;
|
||||
if(!$noCache) {
|
||||
if (!$noCache) {
|
||||
$this->cache = $this->initializeCaches($config);
|
||||
if($this->fromCache()) {
|
||||
if ($this->fromCache()) {
|
||||
$this->createHostServiceConnections();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(!$this->lastState)
|
||||
if (!$this->lastState) {
|
||||
$this->parseObjectsCacheFile();
|
||||
if(!$this->hasRuntimeState);
|
||||
$this->parseStatusDatFile();
|
||||
if(!$noCache && $this->newState)
|
||||
$this->statusCache->save($this->parser->getRuntimeState(),'objects'.md5($this->config->objects_file));
|
||||
}
|
||||
if (!$this->hasRuntimeState) {
|
||||
;
|
||||
}
|
||||
$this->parseStatusDatFile();
|
||||
if (!$noCache && $this->newState) {
|
||||
$this->statusCache->save($this->parser->getRuntimeState(), 'objects' . md5($this->config->objects_file));
|
||||
}
|
||||
$this->createHostServiceConnections();
|
||||
|
||||
}
|
||||
|
||||
private function createHostServiceConnections()
|
||||
/**
|
||||
* @throws Exception\ConfigurationError
|
||||
*/
|
||||
private function initializeCaches()
|
||||
{
|
||||
if (!isset($this->lastState["service"])) {
|
||||
return;
|
||||
$defaultCachePath = "/tmp/" . self::STATUSDAT_DEFAULT_CACHE_PATH;
|
||||
|
||||
$cachePath = $this->config->get('cache_path', $defaultCachePath);
|
||||
$maxCacheLifetime = intval($this->config->get('cache_path', self::DEFAULT_CACHE_LIFETIME));
|
||||
if (!is_writeable($cachePath)) {
|
||||
throw new Exception\ConfigurationError(
|
||||
"Cache path $cachePath is not writable, check your configuration"
|
||||
);
|
||||
}
|
||||
|
||||
foreach ($this->lastState["service"] as &$service) {
|
||||
$host = &$this->lastState["host"][$service->host_name];
|
||||
if(!isset($host->services))
|
||||
$host->services = array();
|
||||
$host->services[$service->service_description] = &$service;
|
||||
$service->host = &$host;
|
||||
}
|
||||
}
|
||||
|
||||
public function select()
|
||||
{
|
||||
return new Query($this);
|
||||
}
|
||||
|
||||
public function fetchAll(Query $query)
|
||||
{
|
||||
return new \Icinga\Backend\MonitoringObjectList(
|
||||
$query->getResult(),
|
||||
$query->getView()
|
||||
$backendOptions = array(
|
||||
'cache_dir' => $cachePath
|
||||
);
|
||||
// the objects cache might exist for months and is still valid
|
||||
$this->objectCache = $this->initCache($this->config->objects_file, $backendOptions, null);
|
||||
$this->statusCache = $this->initCache($this->config->status_file, $backendOptions, $maxCacheLifetime);
|
||||
|
||||
}
|
||||
|
||||
public function getState()
|
||||
/**
|
||||
* @param $file
|
||||
* @param $backend
|
||||
* @param $lifetime
|
||||
* @return \Zend_Cache_Core|\Zend_Cache_Frontend
|
||||
*/
|
||||
private function initCache($file, $backend, $lifetime)
|
||||
{
|
||||
return $this->lastState;
|
||||
}
|
||||
|
||||
public function getObjects()
|
||||
{
|
||||
return $this->lastState;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public function getObjectNames($type) {
|
||||
return isset($this->lastState[$type]) ? array_keys($this->lastState[$type]) : null;
|
||||
$frontendOptions = array(
|
||||
'lifetime' => $lifetime,
|
||||
'automatic_serialization' => true,
|
||||
'master_files' => array($file)
|
||||
);
|
||||
return \Zend_Cache::factory('Core', 'File', $frontendOptions, $backend);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function fromCache()
|
||||
{
|
||||
if(!$this->readObjectsCache()) {
|
||||
if (!$this->readObjectsCache()) {
|
||||
$this->newState = true;
|
||||
return false;
|
||||
}
|
||||
if(!$this->readStatusCache()){
|
||||
if (!$this->readStatusCache()) {
|
||||
$this->newState = true;
|
||||
return false;
|
||||
}
|
||||
|
@ -124,71 +149,143 @@ class Reader implements IReader
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function readObjectsCache()
|
||||
{
|
||||
$this->lastState = $this->objectCache->load('objects'.md5($this->config->objects_file));
|
||||
if($this->lastState == false)
|
||||
$this->lastState = $this->objectCache->load('objects' . md5($this->config->objects_file));
|
||||
if ($this->lastState == false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function readStatusCache()
|
||||
{
|
||||
$statusInfo = $this->stateCache->load('state'.md5($this->config->status_file));
|
||||
if($statusInfo == false)
|
||||
$statusInfo = $this->stateCache->load('state' . md5($this->config->status_file));
|
||||
if ($statusInfo == false) {
|
||||
return false;
|
||||
}
|
||||
$this->hasRuntimeState = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
private function initializeCaches()
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function createHostServiceConnections()
|
||||
{
|
||||
$defaultCachePath = "/tmp/".self::STATUSDAT_DEFAULT_CACHE_PATH;
|
||||
|
||||
$cachePath = $this->config->get('cache_path',$defaultCachePath);
|
||||
$maxCacheLifetime = intval($this->config->get('cache_path',self::DEFAULT_CACHE_LIFETIME));
|
||||
if(!is_writeable($cachePath))
|
||||
throw new \Icinga\Exception\ConfigurationError("Cache path $cachePath is not writable, check your configuration");
|
||||
|
||||
|
||||
$backendOptions = array(
|
||||
'cache_dir' => $cachePath
|
||||
);
|
||||
// the objects cache might exist for months and is still valid
|
||||
$this->objectCache = $this->initCache($this->config->objects_file,$backendOptions,NULL);
|
||||
$this->statusCache = $this->initCache($this->config->status_file,$backendOptions,$maxCacheLifetime);
|
||||
if (!isset($this->lastState["service"])) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($this->lastState["service"] as &$service) {
|
||||
$host = & $this->lastState["host"][$service->host_name];
|
||||
if (!isset($host->services)) {
|
||||
$host->services = array();
|
||||
}
|
||||
$host->services[$service->service_description] = & $service;
|
||||
$service->host = & $host;
|
||||
}
|
||||
}
|
||||
|
||||
private function initCache($file, $backend, $lifetime)
|
||||
{
|
||||
$frontendOptions = array(
|
||||
'lifetime' => $lifetime,
|
||||
'automatic_serialization' => true,
|
||||
'master_files' => array($file)
|
||||
);
|
||||
return \Zend_Cache::factory('Core','File',$frontendOptions,$backend);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception\ConfigurationError
|
||||
*/
|
||||
private function parseObjectsCacheFile()
|
||||
{
|
||||
if(!is_readable($this->config->objects_file))
|
||||
throw new \Icinga\Exception\ConfigurationError("Can't read objects-file {$this->config->objects_file}, check your configuration");
|
||||
if(!$this->parser)
|
||||
$this->parser = new Parser(fopen($this->config->objects_file,"r"));
|
||||
if (!is_readable($this->config->objects_file)) {
|
||||
throw new Exception\ConfigurationError(
|
||||
"Can't read objects-file {$this->config->objects_file}, check your configuration"
|
||||
);
|
||||
}
|
||||
if (!$this->parser) {
|
||||
$this->parser = new Parser(fopen($this->config->objects_file, "r"));
|
||||
}
|
||||
$this->parser->parseObjectsFile();
|
||||
$this->lastState = &$this->parser->getRuntimeState();
|
||||
$this->lastState = & $this->parser->getRuntimeState();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception\ConfigurationError
|
||||
*/
|
||||
private function parseStatusDatFile()
|
||||
{
|
||||
if(!is_readable($this->config->status_file))
|
||||
throw new \Icinga\Exception\ConfigurationError("Can't read status-file {$this->config->status_file}, check your configuration");
|
||||
if(!$this->parser)
|
||||
$this->parser = new Parser(fopen($this->config->status_file,"r"),$this->lastState);
|
||||
$this->parser->parseRuntimeState(fopen($this->config->status_file,"r"));
|
||||
$this->lastState = &$this->parser->getRuntimeState();
|
||||
if(!$this->noCache)
|
||||
$this->statusCache->save(array("true" => true),"state".md5($this->config->objects_file));
|
||||
if (!is_readable($this->config->status_file)) {
|
||||
throw new Exception\ConfigurationError(
|
||||
"Can't read status-file {$this->config->status_file}, check your configuration"
|
||||
);
|
||||
}
|
||||
if (!$this->parser) {
|
||||
$this->parser = new Parser(fopen($this->config->status_file, "r"), $this->lastState);
|
||||
}
|
||||
$this->parser->parseRuntimeState(fopen($this->config->status_file, "r"));
|
||||
$this->lastState = & $this->parser->getRuntimeState();
|
||||
if (!$this->noCache) {
|
||||
$this->statusCache->save(array("true" => true), "state" . md5($this->config->objects_file));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Query
|
||||
*/
|
||||
public function select()
|
||||
{
|
||||
return new Query($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Query $query
|
||||
* @return MonitoringObjectList
|
||||
*/
|
||||
public function fetchAll(Query $query)
|
||||
{
|
||||
return new MonitoringObjectList(
|
||||
$query->getResult(),
|
||||
$query->getView()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function getState()
|
||||
{
|
||||
return $this->lastState;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function getObjects()
|
||||
{
|
||||
return $this->lastState;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $type
|
||||
* @param $name
|
||||
* @return ObjectContainer|mixed|null
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $type
|
||||
* @return array|null
|
||||
*/
|
||||
public function getObjectNames($type)
|
||||
{
|
||||
return isset($this->lastState[$type]) ? array_keys($this->lastState[$type]) : null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,34 +1,57 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Protocol\Statusdat;
|
||||
|
||||
/**
|
||||
* Class RuntimeStateContainer
|
||||
* @package Icinga\Protocol\Statusdat
|
||||
*/
|
||||
class RuntimeStateContainer extends \stdClass
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $runtimeState = "";
|
||||
public function __construct($str = "") {
|
||||
|
||||
/**
|
||||
* @param string $str
|
||||
*/
|
||||
public function __construct($str = "")
|
||||
{
|
||||
$this->runtimeState = $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $attr
|
||||
* @return bool
|
||||
*/
|
||||
public function __isset($attr)
|
||||
{
|
||||
try {
|
||||
$this->__get($attr);
|
||||
return true;
|
||||
} catch(\InvalidArgumentException $e) {
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $attr
|
||||
* @return mixed
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __get($attr)
|
||||
{
|
||||
|
||||
$start = strpos($this->runtimeState,$attr."=");
|
||||
if($start === False)
|
||||
$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));
|
||||
$start += strlen($attr . "=");
|
||||
$len = strpos($this->runtimeState, "\n", $start) - $start;
|
||||
$this->$attr = trim(substr($this->runtimeState, $start, $len));
|
||||
|
||||
return $this->$attr;
|
||||
}
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
/**
|
||||
* Action controller
|
||||
*/
|
||||
namespace Icinga\Web;
|
||||
|
||||
use Icinga\Authentication\Auth;
|
||||
use Icinga\Application\Benchmark;
|
||||
use Icinga\Exception;
|
||||
use Icinga\Application\Config;
|
||||
use Icinga\Pdf\File;
|
||||
use Icinga\Web\Notification;
|
||||
use Zend_Layout as ZfLayout;
|
||||
use Zend_Controller_Action as ZfController;
|
||||
|
@ -24,6 +24,7 @@ use Zend_Controller_Action_HelperBroker as ZfActionHelper;
|
|||
* @copyright Copyright (c) 2013 Icinga-Web Team <info@icinga.org>
|
||||
* @author Icinga-Web Team <info@icinga.org>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
|
||||
* @package Icinga\Web
|
||||
*/
|
||||
class ActionController extends ZfController
|
||||
{
|
||||
|
@ -35,6 +36,9 @@ class ActionController extends ZfController
|
|||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $replaceLayout = false;
|
||||
|
||||
/**
|
||||
|
@ -59,10 +63,19 @@ class ActionController extends ZfController
|
|||
*/
|
||||
protected $action_name;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $handlesAuthentication = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $modifiesSession = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $allowAccess = false;
|
||||
|
||||
/**
|
||||
|
@ -80,23 +93,24 @@ class ActionController extends ZfController
|
|||
) {
|
||||
Benchmark::measure('Action::__construct()');
|
||||
if (Auth::getInstance()->isAuthenticated()
|
||||
&& ! $this->modifiesSession
|
||||
&& ! Notification::getInstance()->hasMessages()
|
||||
&& !$this->modifiesSession
|
||||
&& !Notification::getInstance()->hasMessages()
|
||||
) {
|
||||
session_write_close();
|
||||
}
|
||||
$this->module_name = $request->getModuleName();
|
||||
$this->module_name = $request->getModuleName();
|
||||
$this->controller_name = $request->getControllerName();
|
||||
$this->action_name = $request->getActionName();
|
||||
$this->action_name = $request->getActionName();
|
||||
|
||||
$this->loadConfig();
|
||||
$this->setRequest($request)
|
||||
->setResponse($response)
|
||||
->_setInvokeArgs($invokeArgs);
|
||||
->setResponse($response)
|
||||
->_setInvokeArgs($invokeArgs);
|
||||
$this->_helper = new ZfActionHelper($this);
|
||||
|
||||
if ($this->handlesAuthentication()
|
||||
|| Auth::getInstance()->isAuthenticated()) {
|
||||
|| Auth::getInstance()->isAuthenticated()
|
||||
) {
|
||||
$this->allowAccess = true;
|
||||
$this->init();
|
||||
}
|
||||
|
@ -128,7 +142,7 @@ class ActionController extends ZfController
|
|||
* Helper function creating a new widget
|
||||
*
|
||||
* @param string $name The widget name
|
||||
* @param string $properties Optional widget properties
|
||||
* @param array|string $properties Optional widget properties
|
||||
*
|
||||
* @return Widget\AbstractWidget
|
||||
*/
|
||||
|
@ -142,8 +156,9 @@ class ActionController extends ZfController
|
|||
*
|
||||
* TODO: This has not been implemented yet
|
||||
*
|
||||
* @param $uri
|
||||
* @param string $permission Permission name
|
||||
* @param string $object No idea what this should have been :-)
|
||||
* @internal param string $object No idea what this should have been :-)
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
|
@ -160,11 +175,12 @@ class ActionController extends ZfController
|
|||
* @param string $permission Permission name
|
||||
* @param string $object No idea what this should have been :-)
|
||||
*
|
||||
* @throws \Exception
|
||||
* @return self
|
||||
*/
|
||||
final protected function assertPermission($permission, $object = null)
|
||||
{
|
||||
if (! $this->hasPermission($permission, $object)) {
|
||||
if (!$this->hasPermission($permission, $object)) {
|
||||
// TODO: Log violation, create dedicated Exception class
|
||||
throw new \Exception('Permission denied');
|
||||
}
|
||||
|
@ -179,7 +195,7 @@ class ActionController extends ZfController
|
|||
public function preDispatch()
|
||||
{
|
||||
Benchmark::measure('Action::preDispatch()');
|
||||
if (! $this->allowAccess) {
|
||||
if (!$this->allowAccess) {
|
||||
$this->_request->setModuleName('default')
|
||||
->setControllerName('authentication')
|
||||
->setActionName('login')
|
||||
|
@ -194,11 +210,18 @@ class ActionController extends ZfController
|
|||
//$this->quickRedirect('/authentication/login?a=e');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $url
|
||||
* @param array $params
|
||||
*/
|
||||
public function redirectNow($url, array $params = array())
|
||||
{
|
||||
$this->_helper->Redirector->gotoUrlAndExit($url);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function handlesAuthentication()
|
||||
{
|
||||
return $this->handlesAuthentication;
|
||||
|
@ -212,8 +235,8 @@ class ActionController extends ZfController
|
|||
protected function renderBenchmark()
|
||||
{
|
||||
return '<pre class="benchmark">'
|
||||
. Benchmark::renderToHtml()
|
||||
. '</pre>';
|
||||
. Benchmark::renderToHtml()
|
||||
. '</pre>';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -230,51 +253,51 @@ class ActionController extends ZfController
|
|||
public function postDispatch()
|
||||
{
|
||||
Benchmark::measure('Action::postDispatch()');
|
||||
|
||||
|
||||
|
||||
|
||||
// TODO: Move this elsewhere, this is just an ugly test:
|
||||
if ($this->_request->getParam('filetype') === 'pdf') {
|
||||
|
||||
|
||||
// Snippet stolen from less compiler in public/css.php:
|
||||
|
||||
require_once 'vendor/lessphp/lessc.inc.php';
|
||||
$less = new \lessc;
|
||||
$cssdir = dirname(ICINGA_LIBDIR) . '/public/css';
|
||||
// TODO: We need a way to retrieve public dir, even if located elsewhere
|
||||
// TODO: We need a way to retrieve public dir, even if located elsewhere
|
||||
|
||||
$css = $less->compileFile($cssdir . '/pdfprint.less');
|
||||
/*
|
||||
foreach ($app->moduleManager()->getLoadedModules() as $name => $module) {
|
||||
if ($module->hasCss()) {
|
||||
$css .= $less->compile(
|
||||
'.icinga-module.module-'
|
||||
. $name
|
||||
. " {\n"
|
||||
. file_get_contents($module->getCssFilename())
|
||||
. "}\n\n"
|
||||
);
|
||||
}
|
||||
}
|
||||
*/
|
||||
/*
|
||||
foreach ($app->moduleManager()->getLoadedModules() as $name => $module) {
|
||||
if ($module->hasCss()) {
|
||||
$css .= $less->compile(
|
||||
'.icinga-module.module-'
|
||||
. $name
|
||||
. " {\n"
|
||||
. file_get_contents($module->getCssFilename())
|
||||
. "}\n\n"
|
||||
);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// END of CSS test
|
||||
|
||||
$this->render(
|
||||
|
||||
$this->render(
|
||||
null,
|
||||
$this->_helper->viewRenderer->getResponseSegment(),
|
||||
$this->_helper->viewRenderer->getNoController()
|
||||
);
|
||||
$html = '<style>' . $css . '</style>' . (string) $this->getResponse();
|
||||
$html = '<style>' . $css . '</style>' . (string)$this->getResponse();
|
||||
|
||||
$pdf = new \Icinga\Pdf\File();
|
||||
$pdf = new File();
|
||||
$pdf->AddPage();
|
||||
$pdf->writeHTMLCell(0, 0, '', '', $html, 0, 1, 0, true, '', true);
|
||||
$pdf->Output('docs.pdf', 'I');
|
||||
exit;
|
||||
}
|
||||
// END of PDF test
|
||||
|
||||
|
||||
|
||||
|
||||
if ($this->_request->isXmlHttpRequest()) {
|
||||
if ($this->replaceLayout || $this->_getParam('_render') === 'body') {
|
||||
$this->_helper->layout()->setLayout('just-the-body');
|
||||
|
@ -288,9 +311,9 @@ class ActionController extends ZfController
|
|||
$nhtml = '<ul class="notification">';
|
||||
foreach ($notification->getMessages() as $msg) {
|
||||
$nhtml .= '<li>['
|
||||
. $msg->type
|
||||
. '] '
|
||||
. htmlspecialchars($msg->message);
|
||||
. $msg->type
|
||||
. '] '
|
||||
. htmlspecialchars($msg->message);
|
||||
}
|
||||
$nhtml .= '</ul>';
|
||||
$this->getResponse()->append('notification', $nhtml);
|
||||
|
@ -308,16 +331,15 @@ class ActionController extends ZfController
|
|||
*
|
||||
* TODO: Could this make use of Icinga\Web\Session once done?
|
||||
*
|
||||
* @param int $maxAge Max allowed token age
|
||||
* @param int $maxAge Max allowed token age
|
||||
* @param string $sessionId A specific session id (useful for tests?)
|
||||
*
|
||||
* return bool
|
||||
* @return bool
|
||||
*/
|
||||
public function hasValidToken($maxAge = 600, $sessionId = null)
|
||||
{
|
||||
$sessionId = $sessionId ? $sessionId : session_id();
|
||||
$seed = $this->_getParam('seed');
|
||||
if (! is_numeric($seed)) {
|
||||
if (!is_numeric($seed)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -332,10 +354,10 @@ class ActionController extends ZfController
|
|||
*
|
||||
* TODO: Could this make use of Icinga\Web\Session once done?
|
||||
*
|
||||
* @param int $maxAge Max allowed token age
|
||||
* @param int $maxAge Max allowed token age
|
||||
* @param string $sessionId A specific session id (useful for tests?)
|
||||
*
|
||||
* return array
|
||||
* @return array
|
||||
*/
|
||||
public function getSeedTokenPair($maxAge = 600, $sessionId = null)
|
||||
{
|
||||
|
|
|
@ -1,15 +1,32 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Web;
|
||||
|
||||
use Icinga\Application\Logger as Log;
|
||||
use Icinga\Exception\ProgrammingError;
|
||||
|
||||
class Hook
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected static $hooks = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected static $instances = array();
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public static $BASE_NS = 'Icinga\\Web\\Hook\\';
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static function clean()
|
||||
{
|
||||
self::$hooks = array();
|
||||
|
@ -17,7 +34,12 @@ class Hook
|
|||
self::$BASE_NS = 'Icinga\\Web\\Hook\\';
|
||||
}
|
||||
|
||||
public static function has($name,$key=null)
|
||||
/**
|
||||
* @param $name
|
||||
* @param null $key
|
||||
* @return bool
|
||||
*/
|
||||
public static function has($name, $key = null)
|
||||
{
|
||||
if ($key !== null) {
|
||||
return isset(self::$hooks[$name][$key]);
|
||||
|
@ -26,9 +48,14 @@ class Hook
|
|||
}
|
||||
}
|
||||
|
||||
public static function createInstance($name,$key)
|
||||
/**
|
||||
* @param $name
|
||||
* @param $key
|
||||
* @return null
|
||||
*/
|
||||
public static function createInstance($name, $key)
|
||||
{
|
||||
if (!self::has($name,$key)) {
|
||||
if (!self::has($name, $key)) {
|
||||
return null;
|
||||
}
|
||||
if (isset(self::$instances[$name][$key])) {
|
||||
|
@ -48,43 +75,63 @@ class Hook
|
|||
unset(self::$hooks[$name][$key]);
|
||||
return null;
|
||||
}
|
||||
self::assertValidHook($instance,$name);
|
||||
self::assertValidHook($instance, $name);
|
||||
self::$instances[$name][$key] = $instance;
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $instance
|
||||
* @param $name
|
||||
* @throws \Icinga\Exception\ProgrammingError
|
||||
*/
|
||||
private static function assertValidHook(&$instance, $name)
|
||||
{
|
||||
$base_class = self::$BASE_NS.ucfirst($name);
|
||||
if (! $instance instanceof $base_class) {
|
||||
throw new ProgrammingError(sprintf(
|
||||
'%s is not an instance of %s',
|
||||
get_class($instance),
|
||||
$base_class
|
||||
));
|
||||
$base_class = self::$BASE_NS . ucfirst($name);
|
||||
if (!$instance instanceof $base_class) {
|
||||
throw new ProgrammingError(
|
||||
sprintf(
|
||||
'%s is not an instance of %s',
|
||||
get_class($instance),
|
||||
$base_class
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @return array
|
||||
*/
|
||||
public static function all($name)
|
||||
{
|
||||
if (!self::has($name)) {
|
||||
return array();
|
||||
}
|
||||
foreach (self::$hooks[$name] as $key=>$hook) {
|
||||
if(self::createInstance($name,$key) === null)
|
||||
foreach (self::$hooks[$name] as $key => $hook) {
|
||||
if (self::createInstance($name, $key) === null) {
|
||||
return array();
|
||||
}
|
||||
}
|
||||
return self::$instances[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @return null
|
||||
*/
|
||||
public static function first($name)
|
||||
{
|
||||
return self::createInstance($name,key(self::$hooks[$name]));
|
||||
return self::createInstance($name, key(self::$hooks[$name]));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param $key
|
||||
* @param $class
|
||||
*/
|
||||
public static function register($name, $key, $class)
|
||||
{
|
||||
self::$hooks[$name][$key] = $class;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,12 +24,12 @@ class ExpressionTest extends \PHPUnit_Framework_TestCase
|
|||
{
|
||||
$assertions = array(
|
||||
"expression > ?" => "IS_GREATER",
|
||||
"expression >= ?" => "IS_GREATER_EQ",
|
||||
"expression <= ?" => "IS_LESS_EQ",
|
||||
"expression < ?" => "IS_LESS",
|
||||
"expression = ?" => "IS_EQUAL",
|
||||
"expression != ?" => "IS_NOT_EQUAL",
|
||||
"expression like ?" => "IS_LIKE",
|
||||
"expression >= ?" => "isGreaterEq",
|
||||
"expression <= ?" => "isLessEq",
|
||||
"expression < ?" => "isLess",
|
||||
"expression = ?" => "isEqual",
|
||||
"expression != ?" => "isNotEqual",
|
||||
"expression like ?" => "isLike",
|
||||
"expression IN ? " => "IS_IN"
|
||||
);
|
||||
|
||||
|
|
Loading…
Reference in New Issue