parent
29097463be
commit
c27d9c7387
|
@ -3,6 +3,7 @@
|
|||
namespace Icinga\Module\Director\Controllers;
|
||||
|
||||
use gipfl\Web\Widget\Hint;
|
||||
use Icinga\Module\Director\Monitoring;
|
||||
use ipl\Html\Html;
|
||||
use gipfl\IcingaWeb2\Link;
|
||||
use gipfl\IcingaWeb2\Url;
|
||||
|
@ -30,15 +31,59 @@ class HostController extends ObjectController
|
|||
{
|
||||
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',
|
||||
'findservice',
|
||||
'invalidservice'
|
||||
])) {
|
||||
$this->assertPermission('director/monitoring/services-ro');
|
||||
} else {
|
||||
$this->assertPermission('director/hosts');
|
||||
'invalidservice',
|
||||
]);
|
||||
}
|
||||
|
||||
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 Icinga\Module\Director\Forms\IcingaServiceForm;
|
||||
use Icinga\Module\Director\Monitoring;
|
||||
use Icinga\Module\Director\Web\Controller\ObjectController;
|
||||
use Icinga\Module\Director\Objects\IcingaServiceSet;
|
||||
use Icinga\Module\Director\Objects\IcingaService;
|
||||
|
@ -25,6 +26,10 @@ class ServiceController extends ObjectController
|
|||
|
||||
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');
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,14 @@ $this->providePermission(
|
|||
'director/monitoring/services-ro',
|
||||
$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->provideRestriction(
|
||||
|
@ -41,6 +49,14 @@ $this->provideRestriction(
|
|||
'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(
|
||||
'director/groups-for-restricted-hosts',
|
||||
$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
|
||||
* FEATURE: introduce 'disable' as your purge action on Sync (#2285)
|
||||
|
||||
### Permissions and Restrictions
|
||||
* FEATURE: allow using monitoring module permissions (#2304)
|
||||
|
||||
### User Interface
|
||||
* FIX: allow switching DB config while connection is failing (#2300)
|
||||
* FIX: show Override button when all Fields belong to Field Categories (#2303)
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
namespace Icinga\Module\Director;
|
||||
|
||||
use Icinga\Application\Icinga;
|
||||
use Icinga\Authentication\Auth;
|
||||
use Icinga\Data\Filter\Filter;
|
||||
use Icinga\Module\Monitoring\Backend\MonitoringBackend;
|
||||
|
||||
class Monitoring
|
||||
|
@ -29,43 +31,115 @@ class Monitoring
|
|||
|
||||
public function hasHost($hostname)
|
||||
{
|
||||
return $this->backend->select()->from('hostStatus', array(
|
||||
return $this->backend->select()->from('hostStatus', [
|
||||
'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)
|
||||
{
|
||||
$hostStates = array(
|
||||
$hostStates = [
|
||||
'0' => 'up',
|
||||
'1' => 'down',
|
||||
'2' => 'unreachable',
|
||||
'99' => 'pending',
|
||||
);
|
||||
];
|
||||
|
||||
$query = $this->backend->select()->from('hostStatus', array(
|
||||
$query = $this->backend->select()->from('hostStatus', [
|
||||
'hostname' => 'host_name',
|
||||
'state' => 'host_state',
|
||||
'problem' => 'host_problem',
|
||||
'acknowledged' => 'host_acknowledged',
|
||||
'in_downtime' => 'host_in_downtime',
|
||||
'output' => 'host_output',
|
||||
))->where('host_name', $hostname);
|
||||
])->where('host_name', $hostname);
|
||||
|
||||
$res = $query->fetchRow();
|
||||
if ($res === false) {
|
||||
$res = (object) array(
|
||||
$res = (object) [
|
||||
'hostname' => $hostname,
|
||||
'state' => '99',
|
||||
'problem' => '0',
|
||||
'acknowledged' => '0',
|
||||
'in_downtime' => '0',
|
||||
'output' => null,
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
$res->state = $hostStates[$res->state];
|
||||
|
||||
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 Icinga\Application\Config;
|
||||
use Icinga\Authentication\Auth;
|
||||
use Icinga\Module\Director\Db;
|
||||
use Icinga\Module\Director\Monitoring;
|
||||
use Icinga\Module\Director\Objects\IcingaHost;
|
||||
use Icinga\Module\Director\Util;
|
||||
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)) {
|
||||
$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(
|
||||
'director/host/edit',
|
||||
array('name' => $hostname)
|
||||
|
|
|
@ -4,7 +4,9 @@ namespace Icinga\Module\Director\ProvidedHook\Monitoring;
|
|||
|
||||
use Exception;
|
||||
use Icinga\Application\Config;
|
||||
use Icinga\Authentication\Auth;
|
||||
use Icinga\Module\Director\Db;
|
||||
use Icinga\Module\Director\Monitoring;
|
||||
use Icinga\Module\Director\Objects\IcingaHost;
|
||||
use Icinga\Module\Director\Util;
|
||||
use Icinga\Module\Monitoring\Hook\ServiceActionsHook;
|
||||
|
@ -36,6 +38,7 @@ class ServiceActions extends ServiceActionsHook
|
|||
}
|
||||
|
||||
$hostname = $service->host_name;
|
||||
$serviceName = $service->service_description;
|
||||
if (Util::hasPermission('director/inspect')) {
|
||||
$actions[mt('director', 'Inspect')] = Url::fromPath('director/inspect/object', [
|
||||
'type' => 'service',
|
||||
|
@ -43,23 +46,27 @@ class ServiceActions extends ServiceActionsHook
|
|||
'name' => sprintf(
|
||||
'%s!%s',
|
||||
$hostname,
|
||||
$service->service_description
|
||||
$serviceName
|
||||
)
|
||||
]);
|
||||
}
|
||||
|
||||
$title = null;
|
||||
if (Util::hasPermission('director/hosts')) {
|
||||
$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')) {
|
||||
$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', [
|
||||
'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', [
|
||||
'url' => 'director/host/agent',
|
||||
'urlParams' => $params,
|
||||
|
|
Loading…
Reference in New Issue