parent
29097463be
commit
c27d9c7387
|
@ -3,6 +3,7 @@
|
||||||
namespace Icinga\Module\Director\Controllers;
|
namespace Icinga\Module\Director\Controllers;
|
||||||
|
|
||||||
use gipfl\Web\Widget\Hint;
|
use gipfl\Web\Widget\Hint;
|
||||||
|
use Icinga\Module\Director\Monitoring;
|
||||||
use ipl\Html\Html;
|
use ipl\Html\Html;
|
||||||
use gipfl\IcingaWeb2\Link;
|
use gipfl\IcingaWeb2\Link;
|
||||||
use gipfl\IcingaWeb2\Url;
|
use gipfl\IcingaWeb2\Url;
|
||||||
|
@ -30,15 +31,59 @@ class HostController extends ObjectController
|
||||||
{
|
{
|
||||||
protected function checkDirectorPermissions()
|
protected function checkDirectorPermissions()
|
||||||
{
|
{
|
||||||
if (in_array($this->getRequest()->getActionName(), [
|
if ($this->isServiceAction() && (new Monitoring())->authCanEditService(
|
||||||
|
$this->Auth(),
|
||||||
|
$this->getParam('name'),
|
||||||
|
$this->getParam('service')
|
||||||
|
)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->isServicesReadOnlyAction()) {
|
||||||
|
$this->assertPermission('director/monitoring/services-ro');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->hasPermission('director/hosts')) { // faster
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->canModifyHostViaMonitoringPermissions($this->getParam('name'))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->assertPermission('director/hosts'); // complain about default hosts permission
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function isServicesReadOnlyAction()
|
||||||
|
{
|
||||||
|
return in_array($this->getRequest()->getActionName(), [
|
||||||
'servicesro',
|
'servicesro',
|
||||||
'findservice',
|
'findservice',
|
||||||
'invalidservice'
|
'invalidservice',
|
||||||
])) {
|
]);
|
||||||
$this->assertPermission('director/monitoring/services-ro');
|
}
|
||||||
} else {
|
|
||||||
$this->assertPermission('director/hosts');
|
protected function isServiceAction()
|
||||||
|
{
|
||||||
|
return in_array($this->getRequest()->getActionName(), [
|
||||||
|
'servicesro',
|
||||||
|
'findservice',
|
||||||
|
'invalidservice',
|
||||||
|
'servicesetservice',
|
||||||
|
'appliedservice',
|
||||||
|
'inheritedservice',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function canModifyHostViaMonitoringPermissions($hostname)
|
||||||
|
{
|
||||||
|
if ($this->hasPermission('director/monitoring/hosts')) {
|
||||||
|
$monitoring = new Monitoring();
|
||||||
|
return $monitoring->authCanEditHost($this->Auth(), $hostname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -4,6 +4,7 @@ namespace Icinga\Module\Director\Controllers;
|
||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
use Icinga\Module\Director\Forms\IcingaServiceForm;
|
use Icinga\Module\Director\Forms\IcingaServiceForm;
|
||||||
|
use Icinga\Module\Director\Monitoring;
|
||||||
use Icinga\Module\Director\Web\Controller\ObjectController;
|
use Icinga\Module\Director\Web\Controller\ObjectController;
|
||||||
use Icinga\Module\Director\Objects\IcingaServiceSet;
|
use Icinga\Module\Director\Objects\IcingaServiceSet;
|
||||||
use Icinga\Module\Director\Objects\IcingaService;
|
use Icinga\Module\Director\Objects\IcingaService;
|
||||||
|
@ -25,6 +26,10 @@ class ServiceController extends ObjectController
|
||||||
|
|
||||||
protected function checkDirectorPermissions()
|
protected function checkDirectorPermissions()
|
||||||
{
|
{
|
||||||
|
if ($this->hasPermission('director/monitoring/services')) {
|
||||||
|
$monitoring = new Monitoring();
|
||||||
|
return $monitoring->authCanEditService($this->Auth(), $this->getParam('host'), $this->getParam('name'));
|
||||||
|
}
|
||||||
$this->assertPermission('director/hosts');
|
$this->assertPermission('director/hosts');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,14 @@ $this->providePermission(
|
||||||
'director/monitoring/services-ro',
|
'director/monitoring/services-ro',
|
||||||
$this->translate('Allow readonly users to see where a Service came from')
|
$this->translate('Allow readonly users to see where a Service came from')
|
||||||
);
|
);
|
||||||
|
$this->providePermission(
|
||||||
|
'director/monitoring/hosts',
|
||||||
|
$this->translate('Allow users to modify Hosts they are allowed to see in the monitoring module')
|
||||||
|
);
|
||||||
|
$this->providePermission(
|
||||||
|
'director/monitoring/services',
|
||||||
|
$this->translate('Allow users to modify Service they are allowed to see in the monitoring module')
|
||||||
|
);
|
||||||
$this->providePermission('director/*', $this->translate('Allow unrestricted access to Icinga Director'));
|
$this->providePermission('director/*', $this->translate('Allow unrestricted access to Icinga Director'));
|
||||||
|
|
||||||
$this->provideRestriction(
|
$this->provideRestriction(
|
||||||
|
@ -41,6 +49,14 @@ $this->provideRestriction(
|
||||||
'Limit access to the given comma-separated list of hostgroups'
|
'Limit access to the given comma-separated list of hostgroups'
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$this->provideRestriction(
|
||||||
|
'director/monitoring/rw-object-filter',
|
||||||
|
$this->translate(
|
||||||
|
'Additional (monitoring module) object filter to further restrict write access'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
$this->providePermission(
|
$this->providePermission(
|
||||||
'director/groups-for-restricted-hosts',
|
'director/groups-for-restricted-hosts',
|
||||||
$this->translate('Allow users with Hostgroup restrictions to access the Groups field')
|
$this->translate('Allow users with Hostgroup restrictions to access the Groups field')
|
||||||
|
|
|
@ -14,6 +14,9 @@ next (will be 1.9.0)
|
||||||
### Import and Sync
|
### Import and Sync
|
||||||
* FEATURE: introduce 'disable' as your purge action on Sync (#2285)
|
* FEATURE: introduce 'disable' as your purge action on Sync (#2285)
|
||||||
|
|
||||||
|
### Permissions and Restrictions
|
||||||
|
* FEATURE: allow using monitoring module permissions (#2304)
|
||||||
|
|
||||||
### User Interface
|
### User Interface
|
||||||
* FIX: allow switching DB config while connection is failing (#2300)
|
* FIX: allow switching DB config while connection is failing (#2300)
|
||||||
* FIX: show Override button when all Fields belong to Field Categories (#2303)
|
* FIX: show Override button when all Fields belong to Field Categories (#2303)
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
namespace Icinga\Module\Director;
|
namespace Icinga\Module\Director;
|
||||||
|
|
||||||
use Icinga\Application\Icinga;
|
use Icinga\Application\Icinga;
|
||||||
|
use Icinga\Authentication\Auth;
|
||||||
|
use Icinga\Data\Filter\Filter;
|
||||||
use Icinga\Module\Monitoring\Backend\MonitoringBackend;
|
use Icinga\Module\Monitoring\Backend\MonitoringBackend;
|
||||||
|
|
||||||
class Monitoring
|
class Monitoring
|
||||||
|
@ -29,43 +31,115 @@ class Monitoring
|
||||||
|
|
||||||
public function hasHost($hostname)
|
public function hasHost($hostname)
|
||||||
{
|
{
|
||||||
return $this->backend->select()->from('hostStatus', array(
|
return $this->backend->select()->from('hostStatus', [
|
||||||
'hostname' => 'host_name',
|
'hostname' => 'host_name',
|
||||||
))->where('host_name', $hostname)->fetchOne() === $hostname;
|
])->where('host_name', $hostname)->fetchOne() === $hostname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasService($hostname, $service)
|
||||||
|
{
|
||||||
|
return (array) $this->prepareServiceKeyColumnQuery($hostname, $service)->fetchRow() === [
|
||||||
|
'hostname' => $hostname,
|
||||||
|
'service' => $service,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function authCanEditHost(Auth $auth, $hostname)
|
||||||
|
{
|
||||||
|
if ($auth->hasPermission('director/monitoring/hosts')) {
|
||||||
|
$restriction = null;
|
||||||
|
foreach ($auth->getRestrictions('director/monitoring/rw-object-filter') as $restriction) {
|
||||||
|
if ($this->hasHostWithExtraFilter($hostname, Filter::fromQueryString($restriction))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($restriction === null) {
|
||||||
|
return $this->hasHost($hostname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function authCanEditService(Auth $auth, $hostname, $service)
|
||||||
|
{
|
||||||
|
if ($auth->hasPermission('director/monitoring/services')) {
|
||||||
|
$restriction = null;
|
||||||
|
foreach ($auth->getRestrictions('director/monitoring/rw-object-filter') as $restriction) {
|
||||||
|
if ($this->hasServiceWithExtraFilter($hostname, $service, Filter::fromQueryString($restriction))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($restriction === null) {
|
||||||
|
return $this->hasService($hostname, $service);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasHostWithExtraFilter($hostname, Filter $filter)
|
||||||
|
{
|
||||||
|
return $this->backend->select()->from('hostStatus', [
|
||||||
|
'hostname' => 'host_name',
|
||||||
|
])->where('host_name', $hostname)->applyFilter($filter)->fetchOne() === $hostname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasServiceWithExtraFilter($hostname, $service, Filter $filter)
|
||||||
|
{
|
||||||
|
return (array) $this
|
||||||
|
->prepareServiceKeyColumnQuery($hostname, $service)
|
||||||
|
->applyFilter($filter)
|
||||||
|
->fetchRow() === [
|
||||||
|
'hostname' => $hostname,
|
||||||
|
'service' => $service,
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getHostState($hostname)
|
public function getHostState($hostname)
|
||||||
{
|
{
|
||||||
$hostStates = array(
|
$hostStates = [
|
||||||
'0' => 'up',
|
'0' => 'up',
|
||||||
'1' => 'down',
|
'1' => 'down',
|
||||||
'2' => 'unreachable',
|
'2' => 'unreachable',
|
||||||
'99' => 'pending',
|
'99' => 'pending',
|
||||||
);
|
];
|
||||||
|
|
||||||
$query = $this->backend->select()->from('hostStatus', array(
|
$query = $this->backend->select()->from('hostStatus', [
|
||||||
'hostname' => 'host_name',
|
'hostname' => 'host_name',
|
||||||
'state' => 'host_state',
|
'state' => 'host_state',
|
||||||
'problem' => 'host_problem',
|
'problem' => 'host_problem',
|
||||||
'acknowledged' => 'host_acknowledged',
|
'acknowledged' => 'host_acknowledged',
|
||||||
'in_downtime' => 'host_in_downtime',
|
'in_downtime' => 'host_in_downtime',
|
||||||
'output' => 'host_output',
|
'output' => 'host_output',
|
||||||
))->where('host_name', $hostname);
|
])->where('host_name', $hostname);
|
||||||
|
|
||||||
$res = $query->fetchRow();
|
$res = $query->fetchRow();
|
||||||
if ($res === false) {
|
if ($res === false) {
|
||||||
$res = (object) array(
|
$res = (object) [
|
||||||
'hostname' => $hostname,
|
'hostname' => $hostname,
|
||||||
'state' => '99',
|
'state' => '99',
|
||||||
'problem' => '0',
|
'problem' => '0',
|
||||||
'acknowledged' => '0',
|
'acknowledged' => '0',
|
||||||
'in_downtime' => '0',
|
'in_downtime' => '0',
|
||||||
'output' => null,
|
'output' => null,
|
||||||
);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
$res->state = $hostStates[$res->state];
|
$res->state = $hostStates[$res->state];
|
||||||
|
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function prepareServiceKeyColumnQuery($hostname, $service)
|
||||||
|
{
|
||||||
|
return $this->backend
|
||||||
|
->select()
|
||||||
|
->from('serviceStatus', [
|
||||||
|
'hostname' => 'host_name',
|
||||||
|
'service' => 'service_description',
|
||||||
|
])
|
||||||
|
->where('host_name', $hostname)
|
||||||
|
->where('service_description', $service);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,9 @@ namespace Icinga\Module\Director\ProvidedHook\Monitoring;
|
||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
use Icinga\Application\Config;
|
use Icinga\Application\Config;
|
||||||
|
use Icinga\Authentication\Auth;
|
||||||
use Icinga\Module\Director\Db;
|
use Icinga\Module\Director\Db;
|
||||||
|
use Icinga\Module\Director\Monitoring;
|
||||||
use Icinga\Module\Director\Objects\IcingaHost;
|
use Icinga\Module\Director\Objects\IcingaHost;
|
||||||
use Icinga\Module\Director\Util;
|
use Icinga\Module\Director\Util;
|
||||||
use Icinga\Module\Monitoring\Hook\HostActionsHook;
|
use Icinga\Module\Monitoring\Hook\HostActionsHook;
|
||||||
|
@ -37,7 +39,19 @@ class HostActions extends HostActionsHook
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$allowEdit = false;
|
||||||
if (Util::hasPermission('director/hosts') && IcingaHost::exists($hostname, $db)) {
|
if (Util::hasPermission('director/hosts') && IcingaHost::exists($hostname, $db)) {
|
||||||
|
$allowEdit = true;
|
||||||
|
}
|
||||||
|
$auth = Auth::getInstance();
|
||||||
|
if (Util::hasPermission('director/monitoring/hosts')) {
|
||||||
|
$monitoring = new Monitoring();
|
||||||
|
if ($monitoring->authCanEditHost($auth, $hostname)) {
|
||||||
|
$allowEdit = IcingaHost::exists($hostname, $db);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($allowEdit) {
|
||||||
$actions[mt('director', 'Modify')] = Url::fromPath(
|
$actions[mt('director', 'Modify')] = Url::fromPath(
|
||||||
'director/host/edit',
|
'director/host/edit',
|
||||||
array('name' => $hostname)
|
array('name' => $hostname)
|
||||||
|
|
|
@ -4,7 +4,9 @@ namespace Icinga\Module\Director\ProvidedHook\Monitoring;
|
||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
use Icinga\Application\Config;
|
use Icinga\Application\Config;
|
||||||
|
use Icinga\Authentication\Auth;
|
||||||
use Icinga\Module\Director\Db;
|
use Icinga\Module\Director\Db;
|
||||||
|
use Icinga\Module\Director\Monitoring;
|
||||||
use Icinga\Module\Director\Objects\IcingaHost;
|
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;
|
||||||
|
@ -36,6 +38,7 @@ class ServiceActions extends ServiceActionsHook
|
||||||
}
|
}
|
||||||
|
|
||||||
$hostname = $service->host_name;
|
$hostname = $service->host_name;
|
||||||
|
$serviceName = $service->service_description;
|
||||||
if (Util::hasPermission('director/inspect')) {
|
if (Util::hasPermission('director/inspect')) {
|
||||||
$actions[mt('director', 'Inspect')] = Url::fromPath('director/inspect/object', [
|
$actions[mt('director', 'Inspect')] = Url::fromPath('director/inspect/object', [
|
||||||
'type' => 'service',
|
'type' => 'service',
|
||||||
|
@ -43,23 +46,27 @@ class ServiceActions extends ServiceActionsHook
|
||||||
'name' => sprintf(
|
'name' => sprintf(
|
||||||
'%s!%s',
|
'%s!%s',
|
||||||
$hostname,
|
$hostname,
|
||||||
$service->service_description
|
$serviceName
|
||||||
)
|
)
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$title = null;
|
||||||
if (Util::hasPermission('director/hosts')) {
|
if (Util::hasPermission('director/hosts')) {
|
||||||
$title = mt('director', 'Modify');
|
$title = mt('director', 'Modify');
|
||||||
|
} elseif (Util::hasPermission('director/monitoring/services')) {
|
||||||
|
$monitoring = new Monitoring();
|
||||||
|
if ($monitoring->authCanEditService(Auth::getInstance(), $hostname, $serviceName)) {
|
||||||
|
$title = mt('director', 'Modify');
|
||||||
|
}
|
||||||
} elseif (Util::hasPermission('director/monitoring/services-ro')) {
|
} elseif (Util::hasPermission('director/monitoring/services-ro')) {
|
||||||
$title = mt('director', 'Configuration');
|
$title = mt('director', 'Configuration');
|
||||||
} else {
|
|
||||||
return $actions;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IcingaHost::exists($hostname, $db)) {
|
if ($title && IcingaHost::exists($hostname, $db)) {
|
||||||
$actions[$title] = Url::fromPath('director/host/findservice', [
|
$actions[$title] = Url::fromPath('director/host/findservice', [
|
||||||
'name' => $hostname,
|
'name' => $hostname,
|
||||||
'service' => $service->service_description
|
'service' => $serviceName
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -138,7 +138,7 @@ class ObjectTabs extends Tabs
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($object->getShortTableName() === 'host') {
|
if ($object->getShortTableName() === 'host' && $auth->hasPermission('director/hosts')) {
|
||||||
$this->add('agent', [
|
$this->add('agent', [
|
||||||
'url' => 'director/host/agent',
|
'url' => 'director/host/agent',
|
||||||
'urlParams' => $params,
|
'urlParams' => $params,
|
||||||
|
|
Loading…
Reference in New Issue