summaryrefslogtreecommitdiffstats
path: root/library/Director/Integration/MonitoringModule/Monitoring.php
diff options
context:
space:
mode:
Diffstat (limited to 'library/Director/Integration/MonitoringModule/Monitoring.php')
-rw-r--r--library/Director/Integration/MonitoringModule/Monitoring.php200
1 files changed, 200 insertions, 0 deletions
diff --git a/library/Director/Integration/MonitoringModule/Monitoring.php b/library/Director/Integration/MonitoringModule/Monitoring.php
new file mode 100644
index 0000000..5a2dfde
--- /dev/null
+++ b/library/Director/Integration/MonitoringModule/Monitoring.php
@@ -0,0 +1,200 @@
+<?php
+
+namespace Icinga\Module\Director\Integration\MonitoringModule;
+
+use Exception;
+use Icinga\Application\Icinga;
+use Icinga\Authentication\Auth;
+use Icinga\Data\Filter\Filter;
+use Icinga\Exception\ConfigurationError;
+use Icinga\Module\Director\Auth\MonitoringRestriction;
+use Icinga\Module\Director\Auth\Permission;
+use Icinga\Module\Director\Auth\Restriction;
+use Icinga\Module\Director\Integration\BackendInterface;
+use Icinga\Module\Monitoring\Backend\MonitoringBackend;
+use Icinga\Web\Url;
+
+class Monitoring implements BackendInterface
+{
+ /** @var ?MonitoringBackend */
+ protected $backend;
+
+ /** @var Auth */
+ protected $auth;
+
+ public function __construct(Auth $auth)
+ {
+ $this->auth = $auth;
+ $this->initializeMonitoringBackend();
+ }
+
+ public function getHostUrl(?string $hostName): ?Url
+ {
+ if ($hostName === null) {
+ return null;
+ }
+
+ return Url::fromPath('monitoring/host/show', ['host' => $hostName]);
+ }
+
+ public function hasHost(?string $hostName): bool
+ {
+ if ($hostName === null || ! $this->isAvailable()) {
+ return false;
+ }
+
+ try {
+ return $this->selectHost($hostName)->fetchOne() === $hostName;
+ } catch (Exception $_) {
+ return false;
+ }
+ }
+
+ public function hasService(?string $hostName, ?string $serviceName): bool
+ {
+ if ($hostName === null || $serviceName === null || ! $this->isAvailable()) {
+ return false;
+ }
+
+ try {
+ return $this->rowIsService(
+ $this->selectService($hostName, $serviceName)->fetchRow(),
+ $hostName,
+ $serviceName
+ );
+ } catch (Exception $_) {
+ return false;
+ }
+ }
+
+ public function canModifyService(?string $hostName, ?string $serviceName): bool
+ {
+ if (! $this->isAvailable() || $hostName === null || $serviceName === null) {
+ return false;
+ }
+ if ($this->auth->hasPermission(Permission::MONITORING_SERVICES)) {
+ $restriction = null;
+ foreach ($this->auth->getRestrictions(Restriction::MONITORING_RW_OBJECT_FILTER) as $restriction) {
+ if ($this->hasServiceWithFilter($hostName, $serviceName, Filter::fromQueryString($restriction))) {
+ return true;
+ }
+ }
+ if ($restriction === null) {
+ return $this->hasService($hostName, $serviceName);
+ }
+ }
+
+ return false;
+ }
+
+ public function canModifyHost(?string $hostName): bool
+ {
+ if ($hostName !== null && $this->isAvailable() && $this->auth->hasPermission(Permission::MONITORING_HOSTS)) {
+ $restriction = null;
+ foreach ($this->auth->getRestrictions(Restriction::MONITORING_RW_OBJECT_FILTER) as $restriction) {
+ if ($this->hasHostWithFilter($hostName, Filter::fromQueryString($restriction))) {
+ return true;
+ }
+ }
+ if ($restriction === null) {
+ return $this->hasHost($hostName);
+ }
+ }
+
+ return false;
+ }
+
+ protected function hasHostWithFilter($hostname, Filter $filter): bool
+ {
+ try {
+ return $this->selectHost($hostname)->applyFilter($filter)->fetchOne() === $hostname;
+ } catch (Exception $e) {
+ return false;
+ }
+ }
+
+ protected function hasServiceWithFilter($hostname, $service, Filter $filter): bool
+ {
+ try {
+ return $this->rowIsService(
+ $this->selectService($hostname, $service)->applyFilter($filter)->fetchRow(),
+ $hostname,
+ $service
+ );
+ } catch (Exception $e) {
+ return false;
+ }
+ }
+
+ protected function selectHost($hostname)
+ {
+ return $this->selectHostStatus($hostname, [
+ 'hostname' => 'host_name',
+ ]);
+ }
+
+ protected function selectHostStatus($hostname, $columns)
+ {
+ return $this->restrictQuery(
+ $this->backend
+ ->select()
+ ->from('hostStatus', $columns)
+ ->where('host_name', $hostname)
+ );
+ }
+
+ protected function selectService($hostname, $service)
+ {
+ return $this->selectServiceStatus($hostname, $service, [
+ 'hostname' => 'host_name',
+ 'service' => 'service_description',
+ ]);
+ }
+
+ protected function selectServiceStatus($hostname, $service, $columns)
+ {
+ return $this->restrictQuery(
+ $this->backend
+ ->select()
+ ->from('serviceStatus', $columns)
+ ->where('host_name', $hostname)
+ ->where('service_description', $service)
+ );
+ }
+
+ protected function restrictQuery($query)
+ {
+ $query->applyFilter(MonitoringRestriction::getObjectsFilter($this->auth));
+ return $query;
+ }
+
+ protected function rowIsService($row, $hostname, $service): bool
+ {
+ return (array) $row === [
+ 'hostname' => $hostname,
+ 'service' => $service,
+ ];
+ }
+
+ protected function initializeMonitoringBackend()
+ {
+ $app = Icinga::app();
+ $modules = $app->getModuleManager();
+ if (!$modules->hasLoaded('monitoring') && $app->isCli()) {
+ $modules->loadEnabledModules();
+ }
+
+ if ($modules->hasLoaded('monitoring')) {
+ try {
+ $this->backend = MonitoringBackend::instance();
+ } catch (ConfigurationError $e) {
+ $this->backend = null;
+ }
+ }
+ }
+
+ protected function isAvailable(): bool
+ {
+ return $this->backend !== null;
+ }
+}