mirror of
https://github.com/Icinga/icingaweb2-module-businessprocess.git
synced 2026-02-14 08:23:20 -05:00
Add IcingaDB MySQL backend in businessprocess
IcingaDB MySQL backend is added to the businessprocess module to obtain information regarding monitored nodes. ref #276
This commit is contained in:
parent
3fe1c9d1a7
commit
1a0ddfb08b
16 changed files with 665 additions and 34 deletions
|
|
@ -2,21 +2,54 @@
|
|||
|
||||
namespace Icinga\Module\Businessprocess\Controllers;
|
||||
|
||||
use Icinga\Module\Monitoring\Controller;
|
||||
use Icinga\Module\Businessprocess\Common\IcingadbDatabase;
|
||||
use Icinga\Module\Businessprocess\Web\Controller;
|
||||
use Icinga\Module\Icingadb\Model\Host;
|
||||
use Icinga\Module\Monitoring\Backend;
|
||||
use Icinga\Web\Url;
|
||||
|
||||
class HostController extends Controller
|
||||
{
|
||||
use IcingadbDatabase;
|
||||
|
||||
protected $backend;
|
||||
|
||||
protected $allParams;
|
||||
|
||||
|
||||
public function showAction()
|
||||
{
|
||||
$this->allParams = $this->getAllParams();
|
||||
|
||||
$host = $this->params->getRequired('host');
|
||||
|
||||
$query = $this->backend->select()
|
||||
->from('hoststatus', array('host_name'))
|
||||
->where('host_name', $host);
|
||||
if (array_key_exists('backend', $this->allParams)) {
|
||||
if ($this->allParams['backend'] === '_icingadb') {
|
||||
$this->backend = $this->getDb();
|
||||
}
|
||||
$query = Host::on($this->backend);
|
||||
$query->getSelectBase()
|
||||
->where(['host.name = ?' => $host]);
|
||||
$this->applyMonitoringRestriction($query);
|
||||
|
||||
if ($this->applyRestriction('monitoring/filter/objects', $query)->fetchRow() !== false) {
|
||||
$this->redirectNow(Url::fromPath('monitoring/host/show')->setParams($this->params));
|
||||
$queryHost = $query->columns('host.name')->assembleSelect();
|
||||
$queryHost = $this->backend->select($queryHost)->fetch();
|
||||
|
||||
$this->params->add('name', $host);
|
||||
|
||||
if ($queryHost !== false) {
|
||||
$this->redirectNow(Url::fromPath('icingadb/host/index')->setParams($this->params));
|
||||
}
|
||||
|
||||
} else {
|
||||
$this->backend = Backend::createBackend($this->_getParam('backend'));
|
||||
$query = $this->backend->select()
|
||||
->from('hoststatus', array('host_name'))
|
||||
->where('host_name', $host);
|
||||
|
||||
if ($this->applyRestriction('monitoring/filter/objects', $query)->fetchRow() !== false) {
|
||||
$this->redirectNow(Url::fromPath('monitoring/host/show')->setParams($this->params));
|
||||
}
|
||||
}
|
||||
|
||||
$this->view->host = $host;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ namespace Icinga\Module\Businessprocess\Controllers;
|
|||
use Icinga\Module\Businessprocess\Renderer\Breadcrumb;
|
||||
use Icinga\Module\Businessprocess\Renderer\TileRenderer;
|
||||
use Icinga\Module\Businessprocess\Simulation;
|
||||
use Icinga\Module\Businessprocess\State\IcingaDbState;
|
||||
use Icinga\Module\Businessprocess\State\MonitoringState;
|
||||
use Icinga\Module\Businessprocess\Web\Controller;
|
||||
use Icinga\Module\Businessprocess\Web\Url;
|
||||
|
|
@ -81,8 +82,12 @@ class NodeController extends Controller
|
|||
if (empty($parents)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
MonitoringState::apply($config);
|
||||
if ($config->getBackendName() === '_icingadb') {
|
||||
IcingaDbState::apply($config);
|
||||
}
|
||||
else {
|
||||
MonitoringState::apply($config);
|
||||
}
|
||||
$config->applySimulation($simulation);
|
||||
|
||||
foreach ($parents as $parentAndPath) {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ use Icinga\Module\Businessprocess\Renderer\Renderer;
|
|||
use Icinga\Module\Businessprocess\Renderer\TileRenderer;
|
||||
use Icinga\Module\Businessprocess\Renderer\TreeRenderer;
|
||||
use Icinga\Module\Businessprocess\Simulation;
|
||||
use Icinga\Module\Businessprocess\State\IcingaDbState;
|
||||
use Icinga\Module\Businessprocess\State\MonitoringState;
|
||||
use Icinga\Module\Businessprocess\Storage\ConfigDiff;
|
||||
use Icinga\Module\Businessprocess\Storage\LegacyConfigRenderer;
|
||||
|
|
@ -81,11 +82,18 @@ class ProcessController extends Controller
|
|||
$bp = $this->loadModifiedBpConfig();
|
||||
$node = $this->getNode($bp);
|
||||
|
||||
MonitoringState::apply($bp);
|
||||
if ($bp->getBackendName() === '_icingadb') {
|
||||
IcingaDbState::apply($bp);
|
||||
}
|
||||
else {
|
||||
MonitoringState::apply($bp);
|
||||
}
|
||||
|
||||
$this->handleSimulations($bp);
|
||||
|
||||
$this->setTitle($this->translate('Business Process "%s"'), $bp->getTitle());
|
||||
|
||||
|
||||
$renderer = $this->prepareRenderer($bp, $node);
|
||||
|
||||
if (! $this->showFullscreen && ($node === null || ! $renderer->rendersImportedNode())) {
|
||||
|
|
@ -169,7 +177,6 @@ class ProcessController extends Controller
|
|||
}
|
||||
$renderer->setUrl($this->url())
|
||||
->setPath($this->params->getValues('path'));
|
||||
|
||||
$this->renderer = $renderer;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,23 +2,56 @@
|
|||
|
||||
namespace Icinga\Module\Businessprocess\Controllers;
|
||||
|
||||
use Icinga\Module\Monitoring\Controller;
|
||||
use Icinga\Module\Businessprocess\Common\IcingadbDatabase;
|
||||
use Icinga\Module\Businessprocess\Web\Controller;
|
||||
use Icinga\Module\Icingadb\Model\Service;
|
||||
use Icinga\Module\Monitoring\Backend;
|
||||
use Icinga\Web\Url;
|
||||
|
||||
class ServiceController extends Controller
|
||||
{
|
||||
use IcingadbDatabase;
|
||||
|
||||
protected $backend;
|
||||
|
||||
protected $allParams;
|
||||
|
||||
public function showAction()
|
||||
{
|
||||
$this->allParams = $this->getAllParams();
|
||||
|
||||
$host = $this->params->getRequired('host');
|
||||
$service = $this->params->getRequired('service');
|
||||
|
||||
$query = $this->backend->select()
|
||||
->from('servicestatus', array('service_description'))
|
||||
->where('host_name', $host)
|
||||
->where('service_description', $service);
|
||||
if (array_key_exists('backend', $this->allParams)) {
|
||||
if ($this->allParams['backend'] === '_icingadb') {
|
||||
$this->backend = $this->getDb();
|
||||
}
|
||||
$query = Service::on($this->backend)->with('host');
|
||||
$query->getSelectBase()
|
||||
->where(['service_host.name = ?' => $host, 'service.name = ?' => $service]);
|
||||
$this->applyMonitoringRestriction($query);
|
||||
|
||||
if ($this->applyRestriction('monitoring/filter/objects', $query)->fetchRow() !== false) {
|
||||
$this->redirectNow(Url::fromPath('monitoring/service/show')->setParams($this->params));
|
||||
$query = $query->columns('host.name')->assembleSelect();
|
||||
$query = $this->backend->select($query)->fetch();
|
||||
|
||||
$this->params->add('name', $service);
|
||||
$this->params->add('host.name', $host);
|
||||
|
||||
if ($query !== false) {
|
||||
$this->redirectNow(Url::fromPath('icingadb/service/index')->setParams($this->params));
|
||||
}
|
||||
|
||||
} else {
|
||||
$this->backend = Backend::createBackend($this->_getParam('backend'));
|
||||
$query = $this->backend->select()
|
||||
->from('servicestatus', array('service_description'))
|
||||
->where('host_name', $host)
|
||||
->where('service_description', $service);
|
||||
|
||||
if ($this->applyRestriction('monitoring/filter/objects', $query)->fetchRow() !== false) {
|
||||
$this->redirectNow(Url::fromPath('monitoring/service/show')->setParams($this->params));
|
||||
}
|
||||
}
|
||||
|
||||
$this->view->host = $host;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ namespace Icinga\Module\Businessprocess\Forms;
|
|||
use Icinga\Data\Filter\Filter;
|
||||
use Icinga\Module\Businessprocess\BpNode;
|
||||
use Icinga\Module\Businessprocess\BpConfig;
|
||||
use Icinga\Module\Businessprocess\Common\IcingadbDatabase;
|
||||
use Icinga\Module\Businessprocess\Common\EnumList;
|
||||
use Icinga\Module\Businessprocess\ImportedNode;
|
||||
use Icinga\Module\Businessprocess\Modification\ProcessChanges;
|
||||
use Icinga\Module\Businessprocess\MonitoringRestrictions;
|
||||
|
|
@ -18,6 +20,8 @@ class AddNodeForm extends QuickForm
|
|||
{
|
||||
use MonitoringRestrictions;
|
||||
|
||||
use EnumList;
|
||||
|
||||
/** @var MonitoringBackend */
|
||||
protected $backend;
|
||||
|
||||
|
|
@ -37,6 +41,9 @@ class AddNodeForm extends QuickForm
|
|||
/** @var SessionNamespace */
|
||||
protected $session;
|
||||
|
||||
/** @var string $backendName */
|
||||
protected $backendName;
|
||||
|
||||
public function setup()
|
||||
{
|
||||
$view = $this->getView();
|
||||
|
|
@ -401,10 +408,10 @@ class AddNodeForm extends QuickForm
|
|||
}
|
||||
|
||||
/**
|
||||
* @param MonitoringBackend $backend
|
||||
* @param MonitoringBackend|IcingadbDatabase $backend
|
||||
* @return $this
|
||||
*/
|
||||
public function setBackend(MonitoringBackend $backend)
|
||||
public function setBackend($backend)
|
||||
{
|
||||
$this->backend = $backend;
|
||||
return $this;
|
||||
|
|
@ -427,6 +434,7 @@ class AddNodeForm extends QuickForm
|
|||
public function setProcess(BpConfig $process)
|
||||
{
|
||||
$this->bp = $process;
|
||||
$this->backendName = $process->getBackendName();
|
||||
$this->setBackend($process->getBackend());
|
||||
return $this;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ class DeleteNodeForm extends QuickForm
|
|||
* @param MonitoringBackend $backend
|
||||
* @return $this
|
||||
*/
|
||||
public function setBackend(MonitoringBackend $backend)
|
||||
public function setBackend($backend)
|
||||
{
|
||||
$this->backend = $backend;
|
||||
return $this;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ namespace Icinga\Module\Businessprocess\Forms;
|
|||
|
||||
use Icinga\Module\Businessprocess\BpNode;
|
||||
use Icinga\Module\Businessprocess\BpConfig;
|
||||
use Icinga\Module\Businessprocess\Common\IcingadbDatabase;
|
||||
use Icinga\Module\Businessprocess\Common\EnumList;
|
||||
use Icinga\Module\Businessprocess\Modification\ProcessChanges;
|
||||
use Icinga\Module\Businessprocess\MonitoringRestrictions;
|
||||
use Icinga\Module\Businessprocess\Node;
|
||||
|
|
@ -16,9 +18,13 @@ class EditNodeForm extends QuickForm
|
|||
{
|
||||
use MonitoringRestrictions;
|
||||
|
||||
use EnumList;
|
||||
|
||||
/** @var MonitoringBackend */
|
||||
protected $backend;
|
||||
|
||||
protected $backendName;
|
||||
|
||||
/** @var BpConfig */
|
||||
protected $bp;
|
||||
|
||||
|
|
@ -295,10 +301,10 @@ class EditNodeForm extends QuickForm
|
|||
}
|
||||
|
||||
/**
|
||||
* @param MonitoringBackend $backend
|
||||
* @param MonitoringBackend|IcingadbDatabase $backend
|
||||
* @return $this
|
||||
*/
|
||||
public function setBackend(MonitoringBackend $backend)
|
||||
public function setBackend($backend)
|
||||
{
|
||||
$this->backend = $backend;
|
||||
return $this;
|
||||
|
|
@ -311,6 +317,7 @@ class EditNodeForm extends QuickForm
|
|||
public function setProcess(BpConfig $process)
|
||||
{
|
||||
$this->bp = $process;
|
||||
$this->backendName = $process->getBackendName();
|
||||
$this->setBackend($process->getBackend());
|
||||
return $this;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ namespace Icinga\Module\Businessprocess\Forms;
|
|||
|
||||
use Icinga\Module\Businessprocess\BpNode;
|
||||
use Icinga\Module\Businessprocess\BpConfig;
|
||||
use Icinga\Module\Businessprocess\Common\IcingadbDatabase;
|
||||
use Icinga\Module\Businessprocess\IcingaDbBackend;
|
||||
use Icinga\Module\Businessprocess\Modification\ProcessChanges;
|
||||
use Icinga\Module\Businessprocess\Web\Form\QuickForm;
|
||||
use Icinga\Module\Monitoring\Backend\MonitoringBackend;
|
||||
|
|
@ -12,7 +14,7 @@ use Icinga\Web\Session\SessionNamespace;
|
|||
|
||||
class ProcessForm extends QuickForm
|
||||
{
|
||||
/** @var MonitoringBackend */
|
||||
/** @var MonitoringBackend|IcingadbDatabase */
|
||||
protected $backend;
|
||||
|
||||
/** @var BpConfig */
|
||||
|
|
@ -110,10 +112,10 @@ class ProcessForm extends QuickForm
|
|||
}
|
||||
|
||||
/**
|
||||
* @param MonitoringBackend $backend
|
||||
* @param MonitoringBackend|IcingadbDatabase $backend
|
||||
* @return $this
|
||||
*/
|
||||
public function setBackend(MonitoringBackend $backend)
|
||||
public function setBackend($backend)
|
||||
{
|
||||
$this->backend = $backend;
|
||||
return $this;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use Exception;
|
|||
use Icinga\Application\Config;
|
||||
use Icinga\Exception\IcingaException;
|
||||
use Icinga\Exception\NotFoundError;
|
||||
use Icinga\Module\Businessprocess\Common\IcingadbDatabase;
|
||||
use Icinga\Module\Businessprocess\Exception\NestingError;
|
||||
use Icinga\Module\Businessprocess\Modification\ProcessChanges;
|
||||
use Icinga\Module\Businessprocess\Storage\LegacyStorage;
|
||||
|
|
@ -13,6 +14,8 @@ use Icinga\Module\Monitoring\Backend\MonitoringBackend;
|
|||
|
||||
class BpConfig
|
||||
{
|
||||
use IcingadbDatabase;
|
||||
|
||||
const SOFT_STATE = 0;
|
||||
|
||||
const HARD_STATE = 1;
|
||||
|
|
@ -25,9 +28,7 @@ class BpConfig
|
|||
protected $backendName;
|
||||
|
||||
/**
|
||||
* Monitoring backend to retrieve states from
|
||||
*
|
||||
* @var MonitoringBackend
|
||||
* Backend to retrieve states from
|
||||
*/
|
||||
protected $backend;
|
||||
|
||||
|
|
@ -281,7 +282,7 @@ class BpConfig
|
|||
return $this->getMetadata()->has('Backend');
|
||||
}
|
||||
|
||||
public function setBackend(MonitoringBackend $backend)
|
||||
public function setBackend($backend)
|
||||
{
|
||||
$this->backend = $backend;
|
||||
return $this;
|
||||
|
|
@ -290,9 +291,14 @@ class BpConfig
|
|||
public function getBackend()
|
||||
{
|
||||
if ($this->backend === null) {
|
||||
$this->backend = MonitoringBackend::instance(
|
||||
$this->getBackendName()
|
||||
);
|
||||
if ($this->getBackendName() === '_icingadb') {
|
||||
$this->backend = $this->getDb();
|
||||
}
|
||||
else {
|
||||
$this->backend = MonitoringBackend::instance(
|
||||
$this->getBackendName()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->backend;
|
||||
|
|
|
|||
85
library/Businessprocess/Common/EnumList.php
Normal file
85
library/Businessprocess/Common/EnumList.php
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Common;
|
||||
|
||||
use Icinga\Module\Businessprocess\IcingaDbBackend;
|
||||
|
||||
trait EnumList
|
||||
{
|
||||
protected function enumHostForServiceList()
|
||||
{
|
||||
if ($this->useIcingaDbBackend()) {
|
||||
$names = (new IcingaDbBackend())->yieldHostnames();
|
||||
} else {
|
||||
$names = $this->backend
|
||||
->select()
|
||||
->from('hostStatus', ['hostname' => 'host_name'])
|
||||
->applyFilter($this->getRestriction('monitoring/filter/objects'))
|
||||
->order('host_name')
|
||||
->getQuery()
|
||||
->fetchColumn();
|
||||
}
|
||||
|
||||
// fetchPairs doesn't seem to work when using the same column with
|
||||
// different aliases twice
|
||||
$res = array();
|
||||
foreach ($names as $name) {
|
||||
$res[$name] = $name;
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
protected function enumHostList()
|
||||
{
|
||||
if ($this->useIcingaDbBackend()) {
|
||||
$names = (new IcingaDbBackend())->yieldHostnames();
|
||||
} else {
|
||||
$names = $this->backend
|
||||
->select()
|
||||
->from('hostStatus', ['hostname' => 'host_name'])
|
||||
->applyFilter($this->getRestriction('monitoring/filter/objects'))
|
||||
->order('host_name')
|
||||
->getQuery()
|
||||
->fetchColumn();
|
||||
}
|
||||
|
||||
// fetchPairs doesn't seem to work when using the same column with
|
||||
// different aliases twice
|
||||
$res = array();
|
||||
$suffix = ';Hoststatus';
|
||||
foreach ($names as $name) {
|
||||
$res[$name . $suffix] = $name;
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
protected function enumServiceList($host)
|
||||
{
|
||||
if ($this->useIcingaDbBackend()) {
|
||||
$names = (new IcingaDbBackend())->yieldServicenames($host);
|
||||
} else {
|
||||
$names = $this->backend
|
||||
->select()
|
||||
->from('serviceStatus', ['service' => 'service_description'])
|
||||
->where('host_name', $host)
|
||||
->applyFilter($this->getRestriction('monitoring/filter/objects'))
|
||||
->order('service_description')
|
||||
->getQuery()
|
||||
->fetchColumn();
|
||||
}
|
||||
|
||||
$services = array();
|
||||
foreach ($names as $name) {
|
||||
$services[$host . ';' . $name] = $name;
|
||||
}
|
||||
|
||||
return $services;
|
||||
}
|
||||
|
||||
protected function useIcingaDbBackend()
|
||||
{
|
||||
return $this->backendName === '_icingadb';
|
||||
}
|
||||
}
|
||||
43
library/Businessprocess/Common/IcingadbDatabase.php
Normal file
43
library/Businessprocess/Common/IcingadbDatabase.php
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\Common;
|
||||
|
||||
use Icinga\Application\Config as AppConfig;
|
||||
use Icinga\Data\ResourceFactory;
|
||||
use Icinga\Exception\ConfigurationError;
|
||||
use ipl\Sql\Config as SqlConfig;
|
||||
use ipl\Sql\Connection;
|
||||
use PDO;
|
||||
|
||||
trait IcingadbDatabase
|
||||
{
|
||||
/** @var Connection Connection to the Icinga database */
|
||||
private $db;
|
||||
|
||||
/**
|
||||
* Get the connection to the Icinga database
|
||||
*
|
||||
* @return Connection
|
||||
*
|
||||
* @throws ConfigurationError If the related resource configuration does not exist
|
||||
*/
|
||||
public function getDb()
|
||||
{
|
||||
|
||||
if ($this->db === null) {
|
||||
$config = new SqlConfig(ResourceFactory::getResourceConfig(
|
||||
AppConfig::module('icingadb')->get('icingadb', 'resource', 'icingadb')
|
||||
));
|
||||
|
||||
$config->options = [
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ,
|
||||
PDO::MYSQL_ATTR_INIT_COMMAND => "SET SESSION SQL_MODE='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE"
|
||||
. ",ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'"
|
||||
];
|
||||
|
||||
$this->db = new Connection($config);
|
||||
}
|
||||
|
||||
return $this->db;
|
||||
}
|
||||
}
|
||||
78
library/Businessprocess/IcingaDbBackend.php
Normal file
78
library/Businessprocess/IcingaDbBackend.php
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess;
|
||||
|
||||
use Icinga\Module\Businessprocess\Common\IcingadbDatabase;
|
||||
use Icinga\Module\Icingadb\Model\Host;
|
||||
use Icinga\Module\Icingadb\Model\Service;
|
||||
use ipl\Orm\Compat\FilterProcessor;
|
||||
use ipl\Orm\Query;
|
||||
|
||||
class IcingaDbBackend
|
||||
{
|
||||
use MonitoringRestrictions;
|
||||
|
||||
use IcingadbDatabase;
|
||||
|
||||
/** @var BpConfig */
|
||||
protected $config;
|
||||
|
||||
protected $backend;
|
||||
public function __construct()
|
||||
{
|
||||
$this->backend = $this->getDb();
|
||||
}
|
||||
|
||||
public function fetchHosts()
|
||||
{
|
||||
|
||||
$hosts = Host::on($this->getDb())
|
||||
->orderBy('host.name');
|
||||
|
||||
$this->applyMonitoringRestriction($hosts);
|
||||
|
||||
return $hosts;
|
||||
}
|
||||
|
||||
public function fetchServices($host)
|
||||
{
|
||||
$query = Service::on($this->backend)
|
||||
->with('host');
|
||||
|
||||
$query->getSelectBase()
|
||||
->where(['service_host.name = ?' => $host])
|
||||
->orderBy('service.name');
|
||||
|
||||
$this->applyMonitoringRestriction($query);
|
||||
|
||||
$queryServices = $query->assembleSelect();
|
||||
$services = $this->backend->select($queryServices)->fetchAll();
|
||||
var_dump($services);
|
||||
|
||||
return $services;
|
||||
}
|
||||
|
||||
public function yieldHostnames()
|
||||
{
|
||||
foreach ($this->fetchHosts() as $host) {
|
||||
yield $host->name;
|
||||
}
|
||||
}
|
||||
|
||||
public function yieldServicenames($host)
|
||||
{
|
||||
foreach ($this->fetchServices($host) as $service) {
|
||||
yield $service->name;
|
||||
}
|
||||
}
|
||||
|
||||
protected function applyMonitoringRestriction(Query $query)
|
||||
{
|
||||
FilterProcessor::apply(
|
||||
$this->getRestriction('monitoring/filter/objects'),
|
||||
$query
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
225
library/Businessprocess/State/IcingaDbState.php
Normal file
225
library/Businessprocess/State/IcingaDbState.php
Normal file
|
|
@ -0,0 +1,225 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Module\Businessprocess\State;
|
||||
|
||||
use Exception;
|
||||
use Icinga\Application\Benchmark;
|
||||
use Icinga\Module\Businessprocess\BpConfig;
|
||||
use Icinga\Module\Businessprocess\Common\IcingadbDatabase;
|
||||
use Icinga\Module\Businessprocess\IcingaDbBackend;
|
||||
use Icinga\Module\Businessprocess\ServiceNode;
|
||||
use Icinga\Module\Icingadb\Model\Host;
|
||||
use Icinga\Module\Icingadb\Model\Service;
|
||||
|
||||
ini_set("xdebug.var_display_max_children", -1);
|
||||
ini_set("xdebug.var_display_max_data", -1);
|
||||
ini_set("xdebug.var_display_max_depth", -1);
|
||||
|
||||
class IcingaDbState extends IcingaDbBackend
|
||||
{
|
||||
/** @var BpConfig */
|
||||
protected $config;
|
||||
|
||||
/** @var IcingaDbBackend */
|
||||
protected $backend;
|
||||
|
||||
public function __construct(BpConfig $config)
|
||||
{
|
||||
$this->config = $config;
|
||||
$this->backend = $config->getBackend();
|
||||
}
|
||||
|
||||
public static function apply(BpConfig $config)
|
||||
{
|
||||
$self = new static($config);
|
||||
$self->retrieveStatesFromBackend();
|
||||
return $config;
|
||||
}
|
||||
|
||||
public function retrieveStatesFromBackend()
|
||||
{
|
||||
$config = $this->config;
|
||||
|
||||
try {
|
||||
$this->reallyRetrieveStatesFromBackend();
|
||||
} catch (Exception $e) {
|
||||
$config->addError(
|
||||
$config->translate('Could not retrieve process state: %s'),
|
||||
$e->getMessage()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function reallyRetrieveStatesFromBackend()
|
||||
{
|
||||
$config = $this->config;
|
||||
|
||||
Benchmark::measure('Retrieving states for business process ' . $config->getName());
|
||||
$backend = $this->backend;
|
||||
|
||||
$hosts = $config->listInvolvedHostNames();
|
||||
if (empty($hosts)) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$queryHost = Host::on($backend)->with('state');
|
||||
$queryHost->getSelectBase()
|
||||
->where(['host.name IN (?)' => $hosts]);
|
||||
|
||||
$columns = $queryHost->assembleSelect()->getColumns();
|
||||
$resetHostCols = [];
|
||||
foreach ($columns as $column)
|
||||
{
|
||||
$tmpKey = str_replace('.','_',$column);
|
||||
$resetHostCols[] = $tmpKey;
|
||||
}
|
||||
$this->applyMonitoringRestriction($queryHost);
|
||||
|
||||
// /** @var Host $host */
|
||||
$hostList = $queryHost->assembleSelect();
|
||||
$hostList = $backend->select($hostList)->fetchAll();
|
||||
|
||||
foreach ($hostList as $idx => $hst)
|
||||
{
|
||||
$hst = get_object_vars($hst);
|
||||
$hostColVals = array_values($hst);
|
||||
$hst = array_combine($resetHostCols, $hostColVals);
|
||||
$hostList[$idx] = $hst;
|
||||
if($hst['host_state_state_type'] === 'hard') {
|
||||
$hostStateCol = 'host_state_hard_state';
|
||||
} else {
|
||||
$hostStateCol = 'host_state_soft_state';
|
||||
}
|
||||
}
|
||||
|
||||
$hostStatusCols = array(
|
||||
'hostname' => 'host_name',
|
||||
'last_state_change' => 'host_state_last_state_change',
|
||||
'in_downtime' => 'host_state_in_downtime',
|
||||
'ack' => 'host_state_is_acknowledged',
|
||||
'state' => $hostStateCol,
|
||||
'display_name' =>'host_display_name'
|
||||
);
|
||||
$hostStatus = $this->selectArrayCols($hostList,$hostStatusCols);
|
||||
|
||||
Benchmark::measure('Retrieved states for ' . count($hostStatus) . ' hosts in ' . $config->getName());
|
||||
|
||||
$queryService = Service::on($backend)->with([
|
||||
'state',
|
||||
'host',
|
||||
'host.state'
|
||||
]);
|
||||
$queryService->getSelectBase()
|
||||
->where(['service_host.name IN (?)' => $hosts]);
|
||||
|
||||
$columns = $queryService->assembleSelect()->getColumns();
|
||||
$resetServiceCols = [];
|
||||
foreach ($columns as $column)
|
||||
{
|
||||
$tmpKey = str_replace('.','_',$column);
|
||||
$resetServiceCols[] = $tmpKey;
|
||||
}
|
||||
$this->applyMonitoringRestriction($queryService);
|
||||
|
||||
$serviceList = $queryService->assembleSelect();
|
||||
|
||||
$serviceList = $backend->select($serviceList)->fetchAll();
|
||||
|
||||
foreach ($serviceList as $idx => $srvc)
|
||||
{
|
||||
$srvc = get_object_vars($srvc);
|
||||
$serviceColVals = array_values($srvc);
|
||||
$srvc = array_combine($resetServiceCols, $serviceColVals);
|
||||
$serviceList[$idx] = $srvc;
|
||||
if($srvc['service_state_state_type'] === 'hard') {
|
||||
$serviceStateCol = 'service_state_hard_state';
|
||||
} else {
|
||||
$serviceStateCol = 'service_state_soft_state';
|
||||
}
|
||||
}
|
||||
|
||||
$serviceStatusCols = array(
|
||||
'hostname' => 'service_host_name',
|
||||
'service' => 'service_name',
|
||||
'last_state_change' => 'service_state_last_state_change',
|
||||
'in_downtime' => 'service_state_in_downtime',
|
||||
'ack' => 'service_host_state_is_acknowledged',
|
||||
'state' => $serviceStateCol,
|
||||
'display_name' => 'service_display_name',
|
||||
'host_display_name' => 'service_host_display_name'
|
||||
);
|
||||
$serviceStatus = $this->selectArrayCols($serviceList,$serviceStatusCols);
|
||||
|
||||
Benchmark::measure('Retrieved states for ' . count($serviceStatus) . ' services in ' . $config->getName());
|
||||
|
||||
$configs = $config->listInvolvedConfigs();
|
||||
$hostStatus = (object) $hostStatus;
|
||||
$serviceStatus = (object) $serviceStatus;
|
||||
|
||||
foreach ($configs as $cfg) {
|
||||
foreach ($serviceStatus as $row) {
|
||||
$this->handleDbRow($row, $cfg);
|
||||
}
|
||||
foreach ($hostStatus as $row) {
|
||||
$this->handleDbRow($row, $cfg);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Union, single query?
|
||||
Benchmark::measure('Got states for business process ' . $config->getName());
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function selectArrayCols ($array, $cols)
|
||||
{
|
||||
$selectArrayCols = [];
|
||||
foreach ($array as $idx => $subArray)
|
||||
{
|
||||
$tmpArray = [];
|
||||
foreach ($cols as $colKey => $colVal)
|
||||
{
|
||||
$tmpArray[$colKey] = $subArray[$colVal];
|
||||
}
|
||||
$selectArrayCols[$idx] = (object) $tmpArray;
|
||||
}
|
||||
|
||||
return $selectArrayCols;
|
||||
}
|
||||
|
||||
protected function handleDbRow($row, BpConfig $config)
|
||||
{
|
||||
$key = $row->hostname;
|
||||
if (property_exists($row, 'service')) {
|
||||
$key .= ';' . $row->service;
|
||||
} else {
|
||||
$key .= ';Hoststatus';
|
||||
}
|
||||
|
||||
// We fetch more states than we need, so skip unknown ones
|
||||
if (! $config->hasNode($key)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$node = $config->getNode($key);
|
||||
|
||||
if ($row->state !== null) {
|
||||
$node->setState($row->state)->setMissing(false);
|
||||
}
|
||||
if ($row->last_state_change !== null) {
|
||||
$node->setLastStateChange($row->last_state_change);
|
||||
}
|
||||
if ((int) $row->in_downtime === 1) {
|
||||
$node->setDowntime(true);
|
||||
}
|
||||
if ((int) $row->ack === 1) {
|
||||
$node->setAck(true);
|
||||
}
|
||||
|
||||
$node->setAlias($row->display_name);
|
||||
|
||||
if ($node instanceof ServiceNode) {
|
||||
$node->setHostAlias($row->host_display_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
namespace Icinga\Module\Businessprocess\Web\Component;
|
||||
|
||||
use Icinga\Authentication\Auth;
|
||||
use Icinga\Module\Businessprocess\State\IcingaDbState;
|
||||
use Icinga\Module\Businessprocess\State\MonitoringState;
|
||||
use Icinga\Module\Businessprocess\Storage\Storage;
|
||||
use ipl\Html\BaseHtmlElement;
|
||||
|
|
@ -91,7 +92,12 @@ class Dashboard extends BaseHtmlElement
|
|||
}
|
||||
|
||||
$bp = $storage->loadProcess($name);
|
||||
MonitoringState::apply($bp);
|
||||
if ($bp->getBackendName() === '_icingadb') {
|
||||
IcingaDbState::apply($bp);
|
||||
}
|
||||
else {
|
||||
MonitoringState::apply($bp);
|
||||
}
|
||||
|
||||
$this->add(new BpDashboardTile(
|
||||
$bp,
|
||||
|
|
|
|||
|
|
@ -3,6 +3,10 @@
|
|||
namespace Icinga\Module\Businessprocess\Web;
|
||||
|
||||
use Icinga\Application\Icinga;
|
||||
use Icinga\Data\Filter\Filter;
|
||||
use Icinga\Data\Filterable;
|
||||
use Icinga\Exception\ConfigurationError;
|
||||
use Icinga\Exception\QueryException;
|
||||
use Icinga\Module\Businessprocess\BpConfig;
|
||||
use Icinga\Module\Businessprocess\Modification\ProcessChanges;
|
||||
use Icinga\Module\Businessprocess\Storage\LegacyStorage;
|
||||
|
|
@ -12,10 +16,14 @@ use Icinga\Module\Businessprocess\Web\Component\Controls;
|
|||
use Icinga\Module\Businessprocess\Web\Component\Content;
|
||||
use Icinga\Module\Businessprocess\Web\Component\Tabs;
|
||||
use Icinga\Module\Businessprocess\Web\Form\FormLoader;
|
||||
use Icinga\Module\Icingadb\Compat\MonitoringRestrictions;
|
||||
use Icinga\Module\Icingadb\Compat\UrlMigrator;
|
||||
use Icinga\Web\Controller as ModuleController;
|
||||
use Icinga\Web\Notification;
|
||||
use Icinga\Web\View;
|
||||
use ipl\Html\Html;
|
||||
use ipl\Orm\Compat\FilterProcessor;
|
||||
use ipl\Orm\Query;
|
||||
|
||||
class Controller extends ModuleController
|
||||
{
|
||||
|
|
@ -267,4 +275,87 @@ class Controller extends ModuleController
|
|||
|
||||
return $this->storage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a restriction of the authenticated on the given filterable
|
||||
*
|
||||
* @param string $name Name of the restriction
|
||||
* @param Filterable $filterable Filterable to restrict
|
||||
*
|
||||
* @return Filterable The filterable having the restriction applied
|
||||
*/
|
||||
protected function applyRestriction($name, Filterable $filterable)
|
||||
{
|
||||
$filterable->applyFilter($this->getRestriction($name));
|
||||
return $filterable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a restriction of the authenticated
|
||||
*
|
||||
* @param string $name Name of the restriction
|
||||
*
|
||||
* @return Filter Filter object
|
||||
* @throws ConfigurationError If the restriction contains invalid filter columns
|
||||
*/
|
||||
protected function getRestriction($name)
|
||||
{
|
||||
$restriction = Filter::matchAny();
|
||||
$restriction->setAllowedFilterColumns(array(
|
||||
'host_name',
|
||||
'hostgroup_name',
|
||||
'instance_name',
|
||||
'service_description',
|
||||
'servicegroup_name',
|
||||
function ($c) {
|
||||
return preg_match('/^_(?:host|service)_/i', $c);
|
||||
}
|
||||
));
|
||||
foreach ($this->getRestrictions($name) as $filter) {
|
||||
if ($filter === '*') {
|
||||
return Filter::matchAll();
|
||||
}
|
||||
try {
|
||||
$restriction->addFilter(Filter::fromQueryString($filter));
|
||||
} catch (QueryException $e) {
|
||||
throw new ConfigurationError(
|
||||
$this->translate(
|
||||
'Cannot apply restriction %s using the filter %s. You can only use the following columns: %s'
|
||||
),
|
||||
$name,
|
||||
$filter,
|
||||
implode(', ', array(
|
||||
'instance_name',
|
||||
'host_name',
|
||||
'hostgroup_name',
|
||||
'service_description',
|
||||
'servicegroup_name',
|
||||
'_(host|service)_<customvar-name>'
|
||||
)),
|
||||
$e
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ($restriction->isEmpty()) {
|
||||
return Filter::matchAll();
|
||||
}
|
||||
|
||||
return $restriction;
|
||||
}
|
||||
|
||||
public function applyMonitoringRestriction(Query $query, $queryTransformer = null)
|
||||
{
|
||||
if ($queryTransformer === null || UrlMigrator::hasQueryTransformer($queryTransformer)) {
|
||||
$restriction = UrlMigrator::transformFilter(
|
||||
MonitoringRestrictions::getRestriction('monitoring/filter/objects'),
|
||||
$queryTransformer
|
||||
);
|
||||
if ($restriction) {
|
||||
FilterProcessor::apply($restriction, $query);
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,9 @@ abstract class BpConfigBaseForm extends QuickForm
|
|||
protected function listAvailableBackends()
|
||||
{
|
||||
$keys = array_keys(Config::module('monitoring', 'backends')->toArray());
|
||||
return array_combine($keys, $keys);
|
||||
$keys = array_combine($keys, $keys);
|
||||
$keys['_icingadb'] = 'Icinga DB';
|
||||
return $keys;
|
||||
}
|
||||
|
||||
public function setStorage(LegacyStorage $storage)
|
||||
|
|
|
|||
Loading…
Reference in a new issue