diff --git a/library/Director/ProvidedHook/Icingadb/CustomVarRenderer.php b/library/Director/ProvidedHook/Icingadb/CustomVarRenderer.php index 7d78e2d0e..942403ae1 100644 --- a/library/Director/ProvidedHook/Icingadb/CustomVarRenderer.php +++ b/library/Director/ProvidedHook/Icingadb/CustomVarRenderer.php @@ -6,10 +6,13 @@ use Icinga\Exception\ConfigurationError; use Icinga\Exception\NotFoundError; use Icinga\Module\Director\Db; +use Icinga\Module\Director\Db\AppliedServiceSetLoader; use Icinga\Module\Director\Objects\IcingaHost; use Icinga\Module\Director\Objects\IcingaService; +use Icinga\Module\Director\Objects\IcingaServiceSet; use Icinga\Module\Director\Objects\IcingaTemplateResolver; use Icinga\Module\Director\Web\Form\IcingaObjectFieldLoader; +use Icinga\Module\Director\Web\Table\IcingaHostAppliedServicesTable; use Icinga\Module\Icingadb\Hook\CustomVarRendererHook; use Icinga\Module\Icingadb\Model\Host; use Icinga\Module\Icingadb\Model\Service; @@ -73,33 +76,83 @@ public function prefetchForObject(Model $object): bool try { $directorHostObj = IcingaHost::load($host->name, $db); + $directorServiceObj = null; if ($service !== null) { - $directorServiceObj = IcingaService::loadOptional([ - 'host_id' => $directorHostObj->get('id'), - 'object_name' => $service->name - ], $db); - - if ($directorServiceObj === null) { - $templateResolver = new IcingaTemplateResolver($directorHostObj); + $serviceOrigin = ['direct', 'applied', 'inherited', 'service-set']; + $serviceName = $service->name; + $i = 0; + do { + if ($serviceOrigin[$i] === 'direct') { + $directorServiceObj = IcingaService::loadOptional([ + 'host_id' => $directorHostObj->get('id'), + 'object_name' => $serviceName + ], $db); + } elseif ($serviceOrigin[$i] === 'inherited') { + $templateResolver = new IcingaTemplateResolver($directorHostObj); + + $parentIds = $templateResolver->listParentIds(); + + $query = $db->getDbAdapter()->select()->from('icinga_service') + ->where('object_name = ?', $serviceName) + ->where('host_id IN (?)', $parentIds); + + $directorServices = IcingaService::loadAll( + $db, + $query, + 'object_name' + ); + + $directorServiceObj = current($directorServices); + } elseif ($serviceOrigin[$i] === 'applied') { + $appliedFilterQuery = IcingaHostAppliedServicesTable::load($directorHostObj)->getQuery(); + + foreach ($appliedFilterQuery->fetchAll() as $appliedService) { + if ($appliedService->name === $serviceName) { + + $query = $db->getDbAdapter()->select()->from('icinga_service') + ->where('object_name = ?', $serviceName) + ->where("object_type = 'apply'") + ->where('assign_filter = ?', $appliedService->assign_filter); + + $directorAppliedServices = IcingaService::loadAll( + $db, + $query, + 'object_name' + ); + + $directorServiceObj = current($directorAppliedServices); + + break; + } + } + } elseif ($serviceOrigin[$i] === 'service-set') { + $templateResolver = new IcingaTemplateResolver($directorHostObj); - $parents = $templateResolver->listParentIds(); + $hostServiceSets = $directorHostObj->fetchServiceSets() + + AppliedServiceSetLoader::fetchForHost($directorHostObj); - $query = $db->getDbAdapter()->select()->from('icinga_service') - ->where('object_name = ?', $service->name) - ->where('host_id IN (?)', $parents); + $parents = $templateResolver->fetchParents(); - $directorServices = IcingaService::loadAll( - $db, - $query, - 'object_name' - ); + foreach ($parents as $parent) { + $hostServiceSets += $parent->fetchServiceSets(); + $hostServiceSets += AppliedServiceSetLoader::fetchForHost($parent); + } - $directorServiceObj = current($directorServices); + foreach ($hostServiceSets as $hostServiceSet) { + foreach ($hostServiceSet->getServiceObjects() as $setServiceObject) { + if ($setServiceObject->getObjectName() === $serviceName) { + $directorServiceObj = $setServiceObject; - if (! $directorServiceObj) { + break 2; + } + } + } + } else { return false; } - } + + $i++; + } while (! $directorServiceObj); } } catch (NotFoundError $_) { return false;