summaryrefslogtreecommitdiffstats
path: root/library/Director/DirectorObject/Lookup
diff options
context:
space:
mode:
Diffstat (limited to 'library/Director/DirectorObject/Lookup')
-rw-r--r--library/Director/DirectorObject/Lookup/AppliedServiceInfo.php109
-rw-r--r--library/Director/DirectorObject/Lookup/AppliedServiceSetServiceInfo.php127
-rw-r--r--library/Director/DirectorObject/Lookup/InheritedServiceInfo.php94
-rw-r--r--library/Director/DirectorObject/Lookup/ServiceFinder.php79
-rw-r--r--library/Director/DirectorObject/Lookup/ServiceInfo.php46
-rw-r--r--library/Director/DirectorObject/Lookup/ServiceSetServiceInfo.php121
-rw-r--r--library/Director/DirectorObject/Lookup/SingleServiceInfo.php83
7 files changed, 659 insertions, 0 deletions
diff --git a/library/Director/DirectorObject/Lookup/AppliedServiceInfo.php b/library/Director/DirectorObject/Lookup/AppliedServiceInfo.php
new file mode 100644
index 0000000..abda497
--- /dev/null
+++ b/library/Director/DirectorObject/Lookup/AppliedServiceInfo.php
@@ -0,0 +1,109 @@
+<?php
+
+namespace Icinga\Module\Director\DirectorObject\Lookup;
+
+use gipfl\IcingaWeb2\Url;
+use Icinga\Data\Filter\Filter;
+use Icinga\Module\Director\Db;
+use Icinga\Module\Director\Objects\HostApplyMatches;
+use Icinga\Module\Director\Objects\IcingaHost;
+use Ramsey\Uuid\Uuid;
+use Ramsey\Uuid\UuidInterface;
+
+/**
+ * A Service Apply Rule matching this Host, generating a Service with the given
+ * name
+ */
+class AppliedServiceInfo implements ServiceInfo
+{
+ /** @var string */
+ protected $hostName;
+
+ /** @var string */
+ protected $serviceName;
+
+ /** @var int */
+ protected $serviceApplyRuleId;
+
+ /** @var UuidInterface */
+ protected $uuid;
+
+ public function __construct($hostName, $serviceName, $serviceApplyRuleId, UuidInterface $uuid)
+ {
+ $this->hostName = $hostName;
+ $this->serviceName= $serviceName;
+ $this->serviceApplyRuleId = $serviceApplyRuleId;
+ $this->uuid = $uuid;
+ }
+
+ public static function find(IcingaHost $host, $serviceName)
+ {
+ $matcher = HostApplyMatches::prepare($host);
+ $connection = $host->getConnection();
+ foreach (static::fetchApplyRulesByServiceName($connection, $serviceName) as $rule) {
+ if ($matcher->matchesFilter($rule->filter)) {
+ return new static($host->getObjectName(), $serviceName, (int) $rule->id, $rule->uuid);
+ }
+ }
+
+ return null;
+ }
+
+ public function getHostName()
+ {
+ return $this->hostName;
+ }
+
+ /**
+ * @return int
+ */
+ public function getServiceApplyRuleId()
+ {
+ return $this->serviceApplyRuleId;
+ }
+
+ public function getName()
+ {
+ return $this->serviceName;
+ }
+
+ public function getUuid()
+ {
+ return $this->uuid;
+ }
+
+ public function getUrl()
+ {
+ return Url::fromPath('director/host/appliedservice', [
+ 'name' => $this->hostName,
+ 'service_id' => $this->serviceApplyRuleId,
+ ]);
+ }
+
+ public function requiresOverrides()
+ {
+ return true;
+ }
+
+ protected static function fetchApplyRulesByServiceName(Db $connection, $serviceName)
+ {
+ $db = $connection->getDbAdapter();
+ $query = $db->select()
+ ->from(['s' => 'icinga_service'], [
+ 'id' => 's.id',
+ 'uuid' => 's.uuid',
+ 'name' => 's.object_name',
+ 'assign_filter' => 's.assign_filter',
+ ])
+ ->where('object_name = ?', $serviceName)
+ ->where('object_type = ? AND assign_filter IS NOT NULL', 'apply');
+
+ $allRules = $db->fetchAll($query);
+ foreach ($allRules as $rule) {
+ $rule->uuid = Uuid::fromBytes(Db\DbUtil::binaryResult($rule->uuid));
+ $rule->filter = Filter::fromQueryString($rule->assign_filter);
+ }
+
+ return $allRules;
+ }
+}
diff --git a/library/Director/DirectorObject/Lookup/AppliedServiceSetServiceInfo.php b/library/Director/DirectorObject/Lookup/AppliedServiceSetServiceInfo.php
new file mode 100644
index 0000000..b5785d5
--- /dev/null
+++ b/library/Director/DirectorObject/Lookup/AppliedServiceSetServiceInfo.php
@@ -0,0 +1,127 @@
+<?php
+
+namespace Icinga\Module\Director\DirectorObject\Lookup;
+
+use gipfl\IcingaWeb2\Url;
+use Icinga\Data\Filter\Filter;
+use Icinga\Module\Director\Db;
+use Icinga\Module\Director\Objects\HostApplyMatches;
+use Icinga\Module\Director\Objects\IcingaHost;
+use Ramsey\Uuid\Uuid;
+use Ramsey\Uuid\UuidInterface;
+
+/**
+ * A Service that makes part of a Service Set Apply Rule matching this Host,
+ * generating a Service with the given name
+ */
+class AppliedServiceSetServiceInfo implements ServiceInfo
+{
+ /** @var string */
+ protected $hostName;
+
+ /** @var string */
+ protected $serviceName;
+
+ /** @var string */
+ protected $serviceSetName;
+
+ /** @var UuidInterface */
+ protected $uuid;
+
+ public function __construct($hostName, $serviceName, $serviceSetName, UuidInterface $uuid)
+ {
+ $this->hostName = $hostName;
+ $this->serviceName = $serviceName;
+ $this->serviceSetName = $serviceSetName;
+ $this->uuid = $uuid;
+ }
+
+ public static function find(IcingaHost $host, $serviceName)
+ {
+ $matcher = HostApplyMatches::prepare($host);
+ $connection = $host->getConnection();
+ foreach (static::fetchServiceSetApplyRulesByServiceName($connection, $host->get('id'), $serviceName) as $rule) {
+ if ($matcher->matchesFilter($rule->filter)) {
+ return new static(
+ $host->getObjectName(),
+ $serviceName,
+ $rule->service_set_name,
+ $rule->uuid
+ );
+ }
+ }
+
+ return null;
+ }
+
+ public function getHostName()
+ {
+ return $this->hostName;
+ }
+
+ public function getUuid()
+ {
+ return $this->uuid;
+ }
+
+ /**
+ * @return string
+ */
+ public function getServiceSetName()
+ {
+ return $this->serviceSetName;
+ }
+
+ public function getName()
+ {
+ return $this->serviceName;
+ }
+
+ public function getUrl()
+ {
+ return Url::fromPath('director/host/servicesetservice', [
+ 'name' => $this->hostName,
+ 'service' => $this->serviceName,
+ 'set' => $this->serviceSetName,
+ ]);
+ }
+
+ public function requiresOverrides()
+ {
+ return true;
+ }
+
+ protected static function fetchServiceSetApplyRulesByServiceName(Db $connection, $hostId, $serviceName)
+ {
+ $db = $connection->getDbAdapter();
+ $query = $db->select()
+ ->from(['s' => 'icinga_service'], [
+ 'id' => 's.id',
+ 'uuid' => 'ss.uuid',
+ 'name' => 's.object_name',
+ 'assign_filter' => 'ss.assign_filter',
+ 'service_set_name' => 'ss.object_name',
+ ])
+ ->join(
+ ['ss' => 'icinga_service_set'],
+ 's.service_set_id = ss.id',
+ []
+ )
+ ->where('s.object_name = ?', $serviceName)
+ ->where('ss.assign_filter IS NOT NULL')
+ ->where( // Ignore deactivated Services:
+ 'NOT EXISTS (SELECT 1 FROM icinga_host_service_blacklist hsb'
+ . ' WHERE hsb.host_id = ? AND hsb.service_id = s.id)',
+ (int) $hostId
+ );
+ ;
+
+ $allRules = $db->fetchAll($query);
+ foreach ($allRules as $rule) {
+ $rule->uuid = Uuid::fromBytes(Db\DbUtil::binaryResult($rule->uuid));
+ $rule->filter = Filter::fromQueryString($rule->assign_filter);
+ }
+
+ return $allRules;
+ }
+}
diff --git a/library/Director/DirectorObject/Lookup/InheritedServiceInfo.php b/library/Director/DirectorObject/Lookup/InheritedServiceInfo.php
new file mode 100644
index 0000000..875d5fb
--- /dev/null
+++ b/library/Director/DirectorObject/Lookup/InheritedServiceInfo.php
@@ -0,0 +1,94 @@
+<?php
+
+namespace Icinga\Module\Director\DirectorObject\Lookup;
+
+use gipfl\IcingaWeb2\Url;
+use Icinga\Module\Director\Objects\IcingaHost;
+use Icinga\Module\Director\Objects\IcingaService;
+use Icinga\Module\Director\Repository\IcingaTemplateRepository;
+use Ramsey\Uuid\UuidInterface;
+
+/**
+ * A Service attached to a parent Service Template. This is a shortcut for
+ * 'assign where "Template Name" in templates'
+ */
+class InheritedServiceInfo implements ServiceInfo
+{
+ /** @var string */
+ protected $hostName;
+
+ /** @var string */
+ protected $hostTemplateName;
+
+ /** @var string */
+ protected $serviceName;
+
+ /** @var UuidInterface */
+ protected $uuid;
+
+ public function __construct($hostName, $hostTemplateName, $serviceName, UuidInterface $uuid)
+ {
+ $this->hostName = $hostName;
+ $this->hostTemplateName = $hostTemplateName;
+ $this->serviceName= $serviceName;
+ $this->uuid = $uuid;
+ }
+
+ public static function find(IcingaHost $host, $serviceName)
+ {
+ $db = $host->getConnection();
+ foreach (IcingaTemplateRepository::instanceByObject($host)->getTemplatesFor($host, true) as $parent) {
+ $key = [
+ 'host_id' => $parent->get('id'),
+ 'object_name' => $serviceName
+ ];
+ if (IcingaService::exists($key, $db)) {
+ return new static(
+ $host->getObjectName(),
+ $parent->getObjectName(),
+ $serviceName,
+ IcingaService::load($key, $db)->getUniqueId()
+ );
+ }
+ }
+
+ return false;
+ }
+
+ public function getHostName()
+ {
+ return $this->hostName;
+ }
+
+ public function getUuid()
+ {
+ return $this->uuid;
+ }
+
+ /**
+ * @return string
+ */
+ public function getHostTemplateName()
+ {
+ return $this->hostTemplateName;
+ }
+
+ public function getName()
+ {
+ return $this->serviceName;
+ }
+
+ public function getUrl()
+ {
+ return Url::fromPath('director/host/inheritedservice', [
+ 'name' => $this->hostName,
+ 'service' => $this->serviceName,
+ 'inheritedFrom' => $this->hostTemplateName
+ ]);
+ }
+
+ public function requiresOverrides()
+ {
+ return true;
+ }
+}
diff --git a/library/Director/DirectorObject/Lookup/ServiceFinder.php b/library/Director/DirectorObject/Lookup/ServiceFinder.php
new file mode 100644
index 0000000..fb8d74c
--- /dev/null
+++ b/library/Director/DirectorObject/Lookup/ServiceFinder.php
@@ -0,0 +1,79 @@
+<?php
+
+namespace Icinga\Module\Director\DirectorObject\Lookup;
+
+use gipfl\IcingaWeb2\Url;
+use Icinga\Authentication\Auth;
+use Icinga\Module\Director\Objects\HostApplyMatches;
+use Icinga\Module\Director\Objects\IcingaHost;
+use RuntimeException;
+
+class ServiceFinder
+{
+ /** @var IcingaHost */
+ protected $host;
+
+ /** @var ?Auth */
+ protected $auth;
+
+ /** @var IcingaHost[] */
+ protected $parents;
+
+ /** @var HostApplyMatches */
+ protected $applyMatcher;
+
+ /** @var \Icinga\Module\Director\Db */
+ protected $db;
+
+ public function __construct(IcingaHost $host, Auth $auth = null)
+ {
+ $this->host = $host;
+ $this->auth = $auth;
+ $this->db = $host->getConnection();
+ }
+
+ public static function find(IcingaHost $host, $serviceName)
+ {
+ foreach ([
+ SingleServiceInfo::class,
+ InheritedServiceInfo::class,
+ ServiceSetServiceInfo::class,
+ AppliedServiceInfo::class,
+ AppliedServiceSetServiceInfo::class,
+ ] as $class) {
+ /** @var ServiceInfo $class */
+ if ($info = $class::find($host, $serviceName)) {
+ return $info;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * @param $serviceName
+ * @return Url
+ */
+ public function getRedirectionUrl($serviceName)
+ {
+ if ($this->auth === null) {
+ throw new RuntimeException('Auth is required for ServiceFinder when dealing when asking for URLs');
+ }
+ if ($this->auth->hasPermission('director/host')) {
+ if ($info = $this::find($this->host, $serviceName)) {
+ return $info->getUrl();
+ }
+ }
+ if ($this->auth->hasPermission('director/monitoring/services-ro')) {
+ return Url::fromPath('director/host/servicesro', [
+ 'name' => $this->host->getObjectName(),
+ 'service' => $serviceName
+ ]);
+ }
+
+ return Url::fromPath('director/host/invalidservice', [
+ 'name' => $this->host->getObjectName(),
+ 'service' => $serviceName,
+ ]);
+ }
+}
diff --git a/library/Director/DirectorObject/Lookup/ServiceInfo.php b/library/Director/DirectorObject/Lookup/ServiceInfo.php
new file mode 100644
index 0000000..3c8c51b
--- /dev/null
+++ b/library/Director/DirectorObject/Lookup/ServiceInfo.php
@@ -0,0 +1,46 @@
+<?php
+
+namespace Icinga\Module\Director\DirectorObject\Lookup;
+
+use gipfl\IcingaWeb2\Url;
+use Icinga\Module\Director\Objects\IcingaHost;
+use Ramsey\Uuid\UuidInterface;
+
+interface ServiceInfo
+{
+ /**
+ * The final Service name
+ *
+ * @return string
+ */
+ public function getName();
+
+ /**
+ * The host the final (rendered, processed) Service belongs to
+ *
+ * @return string
+ */
+ public function getHostName();
+
+ /**
+ * @return Url
+ */
+ public function getUrl();
+
+ /**
+ * @return UuidInterface
+ */
+ public function getUuid();
+
+ /**
+ * @return bool
+ */
+ public function requiresOverrides();
+
+ /**
+ * @param IcingaHost $host
+ * @param $serviceName
+ * @return ServiceInfo|false
+ */
+ public static function find(IcingaHost $host, $serviceName);
+}
diff --git a/library/Director/DirectorObject/Lookup/ServiceSetServiceInfo.php b/library/Director/DirectorObject/Lookup/ServiceSetServiceInfo.php
new file mode 100644
index 0000000..a980da8
--- /dev/null
+++ b/library/Director/DirectorObject/Lookup/ServiceSetServiceInfo.php
@@ -0,0 +1,121 @@
+<?php
+
+namespace Icinga\Module\Director\DirectorObject\Lookup;
+
+use gipfl\IcingaWeb2\Url;
+use Icinga\Module\Director\Objects\IcingaHost;
+use Icinga\Module\Director\Repository\IcingaTemplateRepository;
+use Ramsey\Uuid\Uuid;
+use Ramsey\Uuid\UuidInterface;
+
+/**
+ * A service belonging to a Service Set, attached either directly to the given
+ * Host or to one of it's inherited Host Templates
+ */
+class ServiceSetServiceInfo implements ServiceInfo
+{
+ /** @var string */
+ protected $hostName;
+
+ /** @var string */
+ protected $serviceName;
+
+ /** @var string */
+ protected $serviceSetName;
+
+ /** @var UuidInterface */
+ protected $uuid;
+
+ public function __construct($hostName, $serviceName, $serviceSetName, UuidInterface $uuid)
+ {
+ $this->hostName = $hostName;
+ $this->serviceName = $serviceName;
+ $this->serviceSetName = $serviceSetName;
+ $this->uuid = $uuid;
+ }
+
+ public static function find(IcingaHost $host, $serviceName)
+ {
+ $ids = [$host->get('id')];
+
+ foreach (IcingaTemplateRepository::instanceByObject($host)->getTemplatesFor($host, true) as $parent) {
+ $ids[] = $parent->get('id');
+ }
+
+ $db = $host->getConnection()->getDbAdapter();
+ $query = $db->select()
+ ->from(
+ ['s' => 'icinga_service'],
+ [
+ 'service_set_name' => 'ss.object_name',
+ 'uuid' => 's.uuid',
+ ]
+ )->join(
+ ['ss' => 'icinga_service_set'],
+ 's.service_set_id = ss.id',
+ []
+ )->join(
+ ['hsi' => 'icinga_service_set_inheritance'],
+ 'hsi.parent_service_set_id = ss.id',
+ []
+ )->join(
+ ['hs' => 'icinga_service_set'],
+ 'hs.id = hsi.service_set_id',
+ []
+ )->where('hs.host_id IN (?)', $ids)
+ ->where('s.object_name = ?', $serviceName)
+ ->where( // Ignore deactivated Services:
+ 'NOT EXISTS (SELECT 1 FROM icinga_host_service_blacklist hsb'
+ . ' WHERE hsb.host_id = ? AND hsb.service_id = s.id)',
+ (int) $host->get('id')
+ );
+
+ if ($row = $db->fetchRow($query)) {
+ return new static(
+ $host->getObjectName(),
+ $serviceName,
+ $row->service_set_name,
+ Uuid::fromBytes($row->uuid)
+ );
+ }
+
+ return null;
+ }
+
+ public function getHostName()
+ {
+ return $this->hostName;
+ }
+
+ public function getName()
+ {
+ return $this->serviceName;
+ }
+
+ public function getUuid()
+ {
+ return $this->uuid;
+ }
+
+ /**
+ * @return string
+ */
+ public function getServiceSetName()
+ {
+ return $this->serviceSetName;
+ }
+
+ public function getUrl()
+ {
+ return Url::fromPath('director/host/servicesetservice', [
+ 'name' => $this->hostName,
+ 'service' => $this->serviceName,
+ 'set' => $this->serviceSetName,
+ ]);
+ }
+
+ public function requiresOverrides()
+ {
+ return true;
+ }
+}
diff --git a/library/Director/DirectorObject/Lookup/SingleServiceInfo.php b/library/Director/DirectorObject/Lookup/SingleServiceInfo.php
new file mode 100644
index 0000000..af54fc7
--- /dev/null
+++ b/library/Director/DirectorObject/Lookup/SingleServiceInfo.php
@@ -0,0 +1,83 @@
+<?php
+
+namespace Icinga\Module\Director\DirectorObject\Lookup;
+
+use gipfl\IcingaWeb2\Url;
+use Icinga\Module\Director\Objects\IcingaHost;
+use Icinga\Module\Director\Objects\IcingaService;
+use Ramsey\Uuid\UuidInterface;
+
+/**
+ * A single service, directly attached to a Host Object. Overrides might
+ * still be used when use_var_overrides is true.
+ */
+class SingleServiceInfo implements ServiceInfo
+{
+ /** @var string */
+ protected $hostName;
+
+ /** @var string */
+ protected $serviceName;
+
+ /** @var bool */
+ protected $useOverrides;
+
+ /** @var UuidInterface */
+ protected $uuid;
+
+ public function __construct($hostName, $serviceName, UuidInterface $uuid, $useOverrides)
+ {
+ $this->hostName = $hostName;
+ $this->serviceName = $serviceName;
+ $this->useOverrides = $useOverrides;
+ $this->uuid = $uuid;
+ }
+
+ public static function find(IcingaHost $host, $serviceName)
+ {
+ $keyParams = [
+ 'host_id' => $host->get('id'),
+ 'object_name' => $serviceName
+ ];
+ $connection = $host->getConnection();
+ if (IcingaService::exists($keyParams, $connection)) {
+ $service = IcingaService::load($keyParams, $connection);
+ $useOverrides = $service->getResolvedVar('use_var_overrides') === 'y';
+
+ return new static($host->getObjectName(), $serviceName, $service->getUniqueId(), $useOverrides);
+ }
+
+ return false;
+ }
+
+ public function getHostName()
+ {
+ return $this->hostName;
+ }
+
+ public function getName()
+ {
+ return $this->serviceName;
+ }
+
+ /**
+ * @return UuidInterface
+ */
+ public function getUuid()
+ {
+ return $this->uuid;
+ }
+
+ public function getUrl()
+ {
+ return Url::fromPath('director/service/edit', [
+ 'host' => $this->hostName,
+ 'name' => $this->serviceName,
+ ]);
+ }
+
+ public function requiresOverrides()
+ {
+ return $this->useOverrides;
+ }
+}