From 1a0ddfb08b62ec0d7435d4d0ede88cba2c01c6a1 Mon Sep 17 00:00:00 2001 From: Ravi Kumar Kempapura Srinivasa Date: Tue, 28 Apr 2020 01:08:24 +0200 Subject: [PATCH] Add IcingaDB MySQL backend in businessprocess IcingaDB MySQL backend is added to the businessprocess module to obtain information regarding monitored nodes. ref #276 --- application/controllers/HostController.php | 45 +++- application/controllers/NodeController.php | 9 +- application/controllers/ProcessController.php | 11 +- application/controllers/ServiceController.php | 47 +++- application/forms/AddNodeForm.php | 12 +- application/forms/DeleteNodeForm.php | 2 +- application/forms/EditNodeForm.php | 11 +- application/forms/ProcessForm.php | 8 +- library/Businessprocess/BpConfig.php | 20 +- library/Businessprocess/Common/EnumList.php | 85 +++++++ .../Common/IcingadbDatabase.php | 43 ++++ library/Businessprocess/IcingaDbBackend.php | 78 ++++++ .../Businessprocess/State/IcingaDbState.php | 225 ++++++++++++++++++ .../Web/Component/Dashboard.php | 8 +- library/Businessprocess/Web/Controller.php | 91 +++++++ .../Web/Form/BpConfigBaseForm.php | 4 +- 16 files changed, 665 insertions(+), 34 deletions(-) create mode 100644 library/Businessprocess/Common/EnumList.php create mode 100644 library/Businessprocess/Common/IcingadbDatabase.php create mode 100644 library/Businessprocess/IcingaDbBackend.php create mode 100644 library/Businessprocess/State/IcingaDbState.php diff --git a/application/controllers/HostController.php b/application/controllers/HostController.php index 134ab5b..6672cfc 100644 --- a/application/controllers/HostController.php +++ b/application/controllers/HostController.php @@ -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; diff --git a/application/controllers/NodeController.php b/application/controllers/NodeController.php index dc6c5fc..ac7c1f1 100644 --- a/application/controllers/NodeController.php +++ b/application/controllers/NodeController.php @@ -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) { diff --git a/application/controllers/ProcessController.php b/application/controllers/ProcessController.php index b4fb3ef..719266a 100644 --- a/application/controllers/ProcessController.php +++ b/application/controllers/ProcessController.php @@ -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; } diff --git a/application/controllers/ServiceController.php b/application/controllers/ServiceController.php index 17bb474..3838c04 100644 --- a/application/controllers/ServiceController.php +++ b/application/controllers/ServiceController.php @@ -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; diff --git a/application/forms/AddNodeForm.php b/application/forms/AddNodeForm.php index 1d87305..d86f228 100644 --- a/application/forms/AddNodeForm.php +++ b/application/forms/AddNodeForm.php @@ -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; } diff --git a/application/forms/DeleteNodeForm.php b/application/forms/DeleteNodeForm.php index d06f8df..a36731f 100644 --- a/application/forms/DeleteNodeForm.php +++ b/application/forms/DeleteNodeForm.php @@ -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; diff --git a/application/forms/EditNodeForm.php b/application/forms/EditNodeForm.php index 588c6de..cf57c66 100644 --- a/application/forms/EditNodeForm.php +++ b/application/forms/EditNodeForm.php @@ -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; } diff --git a/application/forms/ProcessForm.php b/application/forms/ProcessForm.php index 4cc3bcf..bd894e8 100644 --- a/application/forms/ProcessForm.php +++ b/application/forms/ProcessForm.php @@ -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; diff --git a/library/Businessprocess/BpConfig.php b/library/Businessprocess/BpConfig.php index c49d262..98f3622 100644 --- a/library/Businessprocess/BpConfig.php +++ b/library/Businessprocess/BpConfig.php @@ -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; diff --git a/library/Businessprocess/Common/EnumList.php b/library/Businessprocess/Common/EnumList.php new file mode 100644 index 0000000..4717223 --- /dev/null +++ b/library/Businessprocess/Common/EnumList.php @@ -0,0 +1,85 @@ +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'; + } +} \ No newline at end of file diff --git a/library/Businessprocess/Common/IcingadbDatabase.php b/library/Businessprocess/Common/IcingadbDatabase.php new file mode 100644 index 0000000..fe5d93a --- /dev/null +++ b/library/Businessprocess/Common/IcingadbDatabase.php @@ -0,0 +1,43 @@ +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; + } +} diff --git a/library/Businessprocess/IcingaDbBackend.php b/library/Businessprocess/IcingaDbBackend.php new file mode 100644 index 0000000..11f40cc --- /dev/null +++ b/library/Businessprocess/IcingaDbBackend.php @@ -0,0 +1,78 @@ +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; + } +} diff --git a/library/Businessprocess/State/IcingaDbState.php b/library/Businessprocess/State/IcingaDbState.php new file mode 100644 index 0000000..25229bf --- /dev/null +++ b/library/Businessprocess/State/IcingaDbState.php @@ -0,0 +1,225 @@ +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); + } + } +} diff --git a/library/Businessprocess/Web/Component/Dashboard.php b/library/Businessprocess/Web/Component/Dashboard.php index eb3b092..1b66d34 100644 --- a/library/Businessprocess/Web/Component/Dashboard.php +++ b/library/Businessprocess/Web/Component/Dashboard.php @@ -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, diff --git a/library/Businessprocess/Web/Controller.php b/library/Businessprocess/Web/Controller.php index d1104d8..3079fab 100644 --- a/library/Businessprocess/Web/Controller.php +++ b/library/Businessprocess/Web/Controller.php @@ -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)_' + )), + $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; + } } diff --git a/library/Businessprocess/Web/Form/BpConfigBaseForm.php b/library/Businessprocess/Web/Form/BpConfigBaseForm.php index b8bcbbd..437d68d 100644 --- a/library/Businessprocess/Web/Form/BpConfigBaseForm.php +++ b/library/Businessprocess/Web/Form/BpConfigBaseForm.php @@ -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)