HostServiceRedirector: new implementation for...
...service links. Fallback route and more fixes #689
This commit is contained in:
parent
d5807495a0
commit
0f4fd471e2
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
namespace Icinga\Module\Director\Controllers;
|
namespace Icinga\Module\Director\Controllers;
|
||||||
|
|
||||||
|
use dipl\Html\Html;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Icinga\Module\Director\CustomVariable\CustomVariableDictionary;
|
use Icinga\Module\Director\CustomVariable\CustomVariableDictionary;
|
||||||
use Icinga\Module\Director\Db\AppliedServiceSetLoader;
|
use Icinga\Module\Director\Db\AppliedServiceSetLoader;
|
||||||
|
@ -19,6 +20,7 @@ use Icinga\Module\Director\Web\Table\IcingaHostAppliedForServiceTable;
|
||||||
use Icinga\Module\Director\Web\Table\IcingaHostAppliedServicesTable;
|
use Icinga\Module\Director\Web\Table\IcingaHostAppliedServicesTable;
|
||||||
use Icinga\Module\Director\Web\Table\IcingaHostServiceTable;
|
use Icinga\Module\Director\Web\Table\IcingaHostServiceTable;
|
||||||
use Icinga\Module\Director\Web\Table\IcingaServiceSetServiceTable;
|
use Icinga\Module\Director\Web\Table\IcingaServiceSetServiceTable;
|
||||||
|
use Icinga\Module\Director\Web\Widget\HostServiceRedirector;
|
||||||
use Icinga\Web\Url;
|
use Icinga\Web\Url;
|
||||||
use dipl\Html\Link;
|
use dipl\Html\Link;
|
||||||
|
|
||||||
|
@ -29,6 +31,10 @@ class HostController extends ObjectController
|
||||||
$this->assertPermission('director/hosts');
|
$this->assertPermission('director/hosts');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return HostgroupRestriction
|
||||||
|
* @throws \Icinga\Exception\ConfigurationError
|
||||||
|
*/
|
||||||
protected function getHostgroupRestriction()
|
protected function getHostgroupRestriction()
|
||||||
{
|
{
|
||||||
return new HostgroupRestriction($this->db(), $this->Auth());
|
return new HostgroupRestriction($this->db(), $this->Auth());
|
||||||
|
@ -40,6 +46,12 @@ class HostController extends ObjectController
|
||||||
$this->addOptionalMonitoringLink();
|
$this->addOptionalMonitoringLink();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws \Icinga\Exception\ConfigurationError
|
||||||
|
* @throws \Icinga\Exception\Http\HttpNotFoundException
|
||||||
|
* @throws \Icinga\Exception\IcingaException
|
||||||
|
* @throws \Icinga\Exception\ProgrammingError
|
||||||
|
*/
|
||||||
public function serviceAction()
|
public function serviceAction()
|
||||||
{
|
{
|
||||||
$host = $this->getHostObject();
|
$host = $this->getHostObject();
|
||||||
|
@ -53,6 +65,12 @@ class HostController extends ObjectController
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws \Icinga\Exception\ConfigurationError
|
||||||
|
* @throws \Icinga\Exception\Http\HttpNotFoundException
|
||||||
|
* @throws \Icinga\Exception\IcingaException
|
||||||
|
* @throws \Icinga\Exception\ProgrammingError
|
||||||
|
*/
|
||||||
public function servicesetAction()
|
public function servicesetAction()
|
||||||
{
|
{
|
||||||
$host = $this->getHostObject();
|
$host = $this->getHostObject();
|
||||||
|
@ -66,6 +84,11 @@ class HostController extends ObjectController
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws \Icinga\Exception\Http\HttpNotFoundException
|
||||||
|
* @throws \Icinga\Exception\IcingaException
|
||||||
|
* @throws \Icinga\Exception\ProgrammingError
|
||||||
|
*/
|
||||||
protected function addServicesHeader()
|
protected function addServicesHeader()
|
||||||
{
|
{
|
||||||
$host = $this->getHostObject();
|
$host = $this->getHostObject();
|
||||||
|
@ -85,6 +108,40 @@ class HostController extends ObjectController
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws \Icinga\Exception\ConfigurationError
|
||||||
|
* @throws \Icinga\Exception\IcingaException
|
||||||
|
* @throws \Icinga\Exception\ProgrammingError
|
||||||
|
*/
|
||||||
|
public function findserviceAction()
|
||||||
|
{
|
||||||
|
$host = $this->getHostObject();
|
||||||
|
$redirector = new HostServiceRedirector($host);
|
||||||
|
$this->redirectNow(
|
||||||
|
$redirector->getRedirectionUrl($this->params->get('service'))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws \Icinga\Exception\IcingaException
|
||||||
|
*/
|
||||||
|
public function invalidserviceAction()
|
||||||
|
{
|
||||||
|
$this->content()->add(
|
||||||
|
Html::tag('p', ['class' => 'error'], sprintf(
|
||||||
|
$this->translate('No such service: %s'),
|
||||||
|
$this->params->get('service')
|
||||||
|
))
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->servicesAction();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws \Icinga\Exception\ConfigurationError
|
||||||
|
* @throws \Icinga\Exception\IcingaException
|
||||||
|
* @throws \Icinga\Exception\ProgrammingError
|
||||||
|
*/
|
||||||
public function servicesAction()
|
public function servicesAction()
|
||||||
{
|
{
|
||||||
$this->addServicesHeader();
|
$this->addServicesHeader();
|
||||||
|
@ -149,6 +206,12 @@ class HostController extends ObjectController
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param IcingaHost $host
|
||||||
|
* @param IcingaHost|null $affectedHost
|
||||||
|
* @throws \Icinga\Exception\ConfigurationError
|
||||||
|
* @throws \Icinga\Exception\IcingaException
|
||||||
|
*/
|
||||||
protected function addHostServiceSetTables(IcingaHost $host, IcingaHost $affectedHost = null)
|
protected function addHostServiceSetTables(IcingaHost $host, IcingaHost $affectedHost = null)
|
||||||
{
|
{
|
||||||
$db = $this->db();
|
$db = $this->db();
|
||||||
|
@ -183,6 +246,12 @@ class HostController extends ObjectController
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws \Icinga\Exception\ConfigurationError
|
||||||
|
* @throws \Icinga\Exception\IcingaException
|
||||||
|
* @throws \Icinga\Exception\NotFoundError
|
||||||
|
* @throws \Icinga\Exception\ProgrammingError
|
||||||
|
*/
|
||||||
public function appliedserviceAction()
|
public function appliedserviceAction()
|
||||||
{
|
{
|
||||||
$db = $this->db();
|
$db = $this->db();
|
||||||
|
@ -216,6 +285,12 @@ class HostController extends ObjectController
|
||||||
$this->commonForServices();
|
$this->commonForServices();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws \Icinga\Exception\ConfigurationError
|
||||||
|
* @throws \Icinga\Exception\IcingaException
|
||||||
|
* @throws \Icinga\Exception\NotFoundError
|
||||||
|
* @throws \Icinga\Exception\ProgrammingError
|
||||||
|
*/
|
||||||
public function inheritedserviceAction()
|
public function inheritedserviceAction()
|
||||||
{
|
{
|
||||||
$db = $this->db();
|
$db = $this->db();
|
||||||
|
@ -252,6 +327,12 @@ class HostController extends ObjectController
|
||||||
$this->commonForServices();
|
$this->commonForServices();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws \Icinga\Exception\ConfigurationError
|
||||||
|
* @throws \Icinga\Exception\IcingaException
|
||||||
|
* @throws \Icinga\Exception\NotFoundError
|
||||||
|
* @throws \Icinga\Exception\ProgrammingError
|
||||||
|
*/
|
||||||
public function removesetAction()
|
public function removesetAction()
|
||||||
{
|
{
|
||||||
// TODO: clean this up, use POST
|
// TODO: clean this up, use POST
|
||||||
|
@ -276,6 +357,13 @@ class HostController extends ObjectController
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws \Icinga\Exception\ConfigurationError
|
||||||
|
* @throws \Icinga\Exception\Http\HttpNotFoundException
|
||||||
|
* @throws \Icinga\Exception\IcingaException
|
||||||
|
* @throws \Icinga\Exception\NotFoundError
|
||||||
|
* @throws \Icinga\Exception\ProgrammingError
|
||||||
|
*/
|
||||||
public function servicesetserviceAction()
|
public function servicesetserviceAction()
|
||||||
{
|
{
|
||||||
$db = $this->db();
|
$db = $this->db();
|
||||||
|
@ -314,6 +402,11 @@ class HostController extends ObjectController
|
||||||
$this->commonForServices();
|
$this->commonForServices();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws \Icinga\Exception\Http\HttpNotFoundException
|
||||||
|
* @throws \Icinga\Exception\IcingaException
|
||||||
|
* @throws \Icinga\Exception\ProgrammingError
|
||||||
|
*/
|
||||||
protected function commonForServices()
|
protected function commonForServices()
|
||||||
{
|
{
|
||||||
$host = $this->object;
|
$host = $this->object;
|
||||||
|
@ -326,6 +419,12 @@ class HostController extends ObjectController
|
||||||
$this->tabs()->activate('services');
|
$this->tabs()->activate('services');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws \Icinga\Exception\Http\HttpNotFoundException
|
||||||
|
* @throws \Icinga\Exception\IcingaException
|
||||||
|
* @throws \Icinga\Exception\NotFoundError
|
||||||
|
* @throws \Icinga\Exception\ProgrammingError
|
||||||
|
*/
|
||||||
public function agentAction()
|
public function agentAction()
|
||||||
{
|
{
|
||||||
$selfService = new SelfService($this->getHostObject(), $this->api());
|
$selfService = new SelfService($this->getHostObject(), $this->api());
|
||||||
|
@ -365,6 +464,10 @@ class HostController extends ObjectController
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws \Icinga\Exception\IcingaException
|
||||||
|
* @throws \Icinga\Exception\ProgrammingError
|
||||||
|
*/
|
||||||
protected function addOptionalInspectLink()
|
protected function addOptionalInspectLink()
|
||||||
{
|
{
|
||||||
if (! $this->hasPermission('director/inspect')) {
|
if (! $this->hasPermission('director/inspect')) {
|
||||||
|
|
|
@ -5,6 +5,7 @@ namespace Icinga\Module\Director\ProvidedHook\Monitoring;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Icinga\Application\Config;
|
use Icinga\Application\Config;
|
||||||
use Icinga\Module\Director\Db;
|
use Icinga\Module\Director\Db;
|
||||||
|
use Icinga\Module\Director\Objects\IcingaHost;
|
||||||
use Icinga\Module\Director\Util;
|
use Icinga\Module\Director\Util;
|
||||||
use Icinga\Module\Monitoring\Hook\ServiceActionsHook;
|
use Icinga\Module\Monitoring\Hook\ServiceActionsHook;
|
||||||
use Icinga\Module\Monitoring\Object\Service;
|
use Icinga\Module\Monitoring\Object\Service;
|
||||||
|
@ -17,31 +18,41 @@ class ServiceActions extends ServiceActionsHook
|
||||||
try {
|
try {
|
||||||
return $this->getThem($service);
|
return $this->getThem($service);
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
return array();
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Service $service
|
||||||
|
* @return array
|
||||||
|
* @throws \Icinga\Exception\ProgrammingError
|
||||||
|
*/
|
||||||
protected function getThem(Service $service)
|
protected function getThem(Service $service)
|
||||||
{
|
{
|
||||||
$actions = array();
|
$actions = [];
|
||||||
$db = $this->db();
|
$db = $this->db();
|
||||||
if (! $db) {
|
if (! $db) {
|
||||||
return array();
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$hostname = $service->host_name;
|
||||||
if (Util::hasPermission('director/inspect')) {
|
if (Util::hasPermission('director/inspect')) {
|
||||||
$actions['Inspect'] = Url::fromPath(
|
$actions['Inspect'] = Url::fromPath('director/inspect/object', [
|
||||||
'director/inspect/object',
|
'type' => 'service',
|
||||||
array(
|
'plural' => 'services',
|
||||||
'type' => 'service',
|
'name' => sprintf(
|
||||||
'plural' => 'services',
|
'%s!%s',
|
||||||
'name' => sprintf(
|
$hostname,
|
||||||
'%s!%s',
|
$service->service_description
|
||||||
$service->host_name,
|
|
||||||
$service->service_description
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
);
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IcingaHost::exists($hostname, $db)) {
|
||||||
|
$actions['Modify'] = Url::fromPath('director/host/findservice', [
|
||||||
|
'name' => $hostname,
|
||||||
|
'service' => $service->service_description
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $actions;
|
return $actions;
|
||||||
|
|
|
@ -0,0 +1,210 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Icinga\Module\Director\Web\Widget;
|
||||||
|
|
||||||
|
use dipl\Web\Url;
|
||||||
|
use Icinga\Data\Filter\Filter;
|
||||||
|
use Icinga\Module\Director\Objects\HostApplyMatches;
|
||||||
|
use Icinga\Module\Director\Objects\IcingaHost;
|
||||||
|
use Icinga\Module\Director\Objects\IcingaService;
|
||||||
|
use Icinga\Module\Director\Repository\IcingaTemplateRepository;
|
||||||
|
|
||||||
|
class HostServiceRedirector
|
||||||
|
{
|
||||||
|
/** @var IcingaHost */
|
||||||
|
protected $host;
|
||||||
|
|
||||||
|
/** @var IcingaHost[] */
|
||||||
|
protected $parents;
|
||||||
|
|
||||||
|
/** @var HostApplyMatches */
|
||||||
|
protected $applyMatcher;
|
||||||
|
|
||||||
|
/** @var \Icinga\Module\Director\Db */
|
||||||
|
protected $db;
|
||||||
|
|
||||||
|
public function __construct(IcingaHost $host)
|
||||||
|
{
|
||||||
|
$this->host = $host;
|
||||||
|
$this->db = $host->getConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $serviceName
|
||||||
|
* @return Url
|
||||||
|
* @throws \Icinga\Exception\IcingaException
|
||||||
|
* @throws \Icinga\Exception\ProgrammingError
|
||||||
|
*/
|
||||||
|
public function getRedirectionUrl($serviceName)
|
||||||
|
{
|
||||||
|
if ($url = $this->getSingleServiceUrl($serviceName)) {
|
||||||
|
return $url;
|
||||||
|
} elseif ($url = $this->getParentServiceUrl($serviceName)) {
|
||||||
|
return $url;
|
||||||
|
} elseif ($url = $this->getAppliedServiceUrl($serviceName)) {
|
||||||
|
return $url;
|
||||||
|
} elseif ($url = $this->getServiceSetServiceUrl($serviceName)) {
|
||||||
|
return $url;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Url::fromPath('director/host/invalidservice', [
|
||||||
|
'name' => $this->host->getObjectName(),
|
||||||
|
'service' => $serviceName,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return IcingaHost[]
|
||||||
|
* @throws \Icinga\Exception\ProgrammingError
|
||||||
|
*/
|
||||||
|
protected function getParents()
|
||||||
|
{
|
||||||
|
if ($this->parents === null) {
|
||||||
|
$this->parents = IcingaTemplateRepository::instanceByObject(
|
||||||
|
$this->host
|
||||||
|
)->getTemplatesFor($this->host, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->parents;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $serviceName
|
||||||
|
* @return Url|null
|
||||||
|
* @throws \Icinga\Exception\IcingaException
|
||||||
|
* @throws \Icinga\Exception\ProgrammingError
|
||||||
|
*/
|
||||||
|
protected function getSingleServiceUrl($serviceName)
|
||||||
|
{
|
||||||
|
if (IcingaService::exists([
|
||||||
|
'host_id' => $this->host->get('id'),
|
||||||
|
'object_name' => $serviceName
|
||||||
|
], $this->db)) {
|
||||||
|
return Url::fromPath('director/service/edit', [
|
||||||
|
'name' => $serviceName,
|
||||||
|
'host' => $this->host->getObjectName()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $serviceName
|
||||||
|
* @return Url|null
|
||||||
|
* @throws \Icinga\Exception\IcingaException
|
||||||
|
* @throws \Icinga\Exception\ProgrammingError
|
||||||
|
*/
|
||||||
|
protected function getParentServiceUrl($serviceName)
|
||||||
|
{
|
||||||
|
foreach ($this->getParents() as $parent) {
|
||||||
|
if (IcingaService::exists([
|
||||||
|
'host_id' => $parent->get('id'),
|
||||||
|
'object_name' => $serviceName
|
||||||
|
], $this->db)) {
|
||||||
|
return Url::fromPath('director/host/inheritedservice', [
|
||||||
|
'name' => $this->host->getObjectName(),
|
||||||
|
'service' => $serviceName,
|
||||||
|
'inheritedFrom' => $parent->getObjectName()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $serviceName
|
||||||
|
* @return Url|null
|
||||||
|
* @throws \Icinga\Exception\IcingaException
|
||||||
|
* @throws \Icinga\Exception\ProgrammingError
|
||||||
|
*/
|
||||||
|
protected function getServiceSetServiceUrl($serviceName)
|
||||||
|
{
|
||||||
|
$ids = [$this->host->get('id')];
|
||||||
|
|
||||||
|
foreach ($this->getParents() as $parent) {
|
||||||
|
$ids[] = $parent->get('id');
|
||||||
|
}
|
||||||
|
|
||||||
|
$db = $this->db->getDbAdapter();
|
||||||
|
$query = $db->select()
|
||||||
|
->from(
|
||||||
|
['s' => 'icinga_service'],
|
||||||
|
['service_set_name' => 'ss.object_name',]
|
||||||
|
)->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);
|
||||||
|
|
||||||
|
if ($row = $db->fetchRow($query)) {
|
||||||
|
return Url::fromPath('director/host/servicesetservice', [
|
||||||
|
'name' => $this->host->getObjectName(),
|
||||||
|
'service' => $serviceName,
|
||||||
|
'set' => $row->service_set_name
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $serviceName
|
||||||
|
* @return Url|null
|
||||||
|
* @throws \Icinga\Exception\ProgrammingError
|
||||||
|
*/
|
||||||
|
protected function getAppliedServiceUrl($serviceName)
|
||||||
|
{
|
||||||
|
$matcher = $this->getHostApplyMatcher();
|
||||||
|
foreach ($this->fetchAllApplyRulesForService($serviceName) as $rule) {
|
||||||
|
if ($matcher->matchesFilter($rule->filter)) {
|
||||||
|
return Url::fromPath('director/host/appliedservice', [
|
||||||
|
'name' => $this->host->getObjectName(),
|
||||||
|
'service_id' => $rule->id,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getHostApplyMatcher()
|
||||||
|
{
|
||||||
|
if ($this->applyMatcher === null) {
|
||||||
|
$this->applyMatcher = HostApplyMatches::prepare($this->host);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->applyMatcher;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function fetchAllApplyRulesForService($serviceName)
|
||||||
|
{
|
||||||
|
$db = $this->db->getDbAdapter();
|
||||||
|
$query = $db->select()->from(
|
||||||
|
['s' => 'icinga_service'],
|
||||||
|
[
|
||||||
|
'id' => 's.id',
|
||||||
|
'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->filter = Filter::fromQueryString($rule->assign_filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $allRules;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue