mirror of
https://github.com/Icinga/icingaweb2-module-director.git
synced 2025-07-29 00:34:05 +02:00
add support for icingadb as only icingaweb2 data backend (#2635)
This commit is contained in:
commit
6851778863
1
.github/workflows/php.yml
vendored
1
.github/workflows/php.yml
vendored
@ -37,6 +37,7 @@ jobs:
|
||||
sudo git clone --depth 1 -b snapshot/nightly https://github.com/Icinga/icinga-php-thirdparty.git /usr/share/icinga-php/vendor
|
||||
sudo git clone --depth 1 -b snapshot/nightly https://github.com/Icinga/icinga-php-library.git /usr/share/icinga-php/ipl
|
||||
sudo git clone --depth 1 https://github.com/Icinga/icingaweb2-module-cube.git /usr/share/icingaweb2-modules/cube
|
||||
sudo git clone --depth 1 https://github.com/Icinga/icingadb-web.git /usr/share/icingaweb2-modules/icingadb
|
||||
|
||||
- name: Setup Incubator
|
||||
run: |
|
||||
|
@ -4,6 +4,8 @@ namespace Icinga\Module\Director\Controllers;
|
||||
|
||||
use gipfl\Web\Widget\Hint;
|
||||
use Icinga\Module\Director\Auth\Permission;
|
||||
use Icinga\Module\Director\Integration\Icingadb\IcingadbBackend;
|
||||
use Icinga\Module\Director\Integration\MonitoringModule\Monitoring;
|
||||
use Icinga\Module\Director\Web\Table\ObjectsTableService;
|
||||
use ipl\Html\Html;
|
||||
use gipfl\IcingaWeb2\Link;
|
||||
@ -33,17 +35,19 @@ class HostController extends ObjectController
|
||||
{
|
||||
$host = $this->getHostObject();
|
||||
$auth = $this->Auth();
|
||||
$mon = $this->monitoring();
|
||||
if ($this->isServiceAction() && $mon->canModifyService($host, $this->getParam('service'))) {
|
||||
$backend = $this->backend();
|
||||
if ($this->isServiceAction()
|
||||
&& $backend->canModifyService($host->getObjectName(), $this->getParam('service'))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
if ($auth->hasPermission(Permission::MONITORING_SERVICES_RO) && $this->isServicesReadOnlyAction()) {
|
||||
if ($this->isServicesReadOnlyAction() && $auth->hasPermission($this->getServicesReadOnlyPermission())) {
|
||||
return;
|
||||
}
|
||||
if ($auth->hasPermission(Permission::HOSTS)) { // faster
|
||||
return;
|
||||
}
|
||||
if ($mon->canModifyHost($host)) {
|
||||
if ($backend->canModifyHost($host->getObjectName())) {
|
||||
return;
|
||||
}
|
||||
$this->assertPermission(Permission::HOSTS); // complain about default hosts permission
|
||||
@ -134,11 +138,35 @@ class HostController extends ObjectController
|
||||
|
||||
public function findserviceAction()
|
||||
{
|
||||
$auth = $this->Auth();
|
||||
$host = $this->getHostObject();
|
||||
$this->redirectNow(
|
||||
(new ServiceFinder($host, $this->getAuth()))
|
||||
->getRedirectionUrl($this->params->get('service'))
|
||||
);
|
||||
$hostName = $host->getObjectName();
|
||||
$serviceName = $this->params->get('service');
|
||||
$info = ServiceFinder::find($host, $serviceName);
|
||||
$backend = $this->backend();
|
||||
|
||||
if ($info && $auth->hasPermission(Permission::HOSTS)) {
|
||||
$redirectUrl = $info->getUrl();
|
||||
} elseif ($info
|
||||
&& (($backend instanceof Monitoring && $auth->hasPermission(Permission::MONITORING_HOSTS))
|
||||
|| ($backend instanceof IcingadbBackend && $auth->hasPermission(Permission::ICINGADB_HOSTS))
|
||||
)
|
||||
&& $backend->canModifyService($hostName, $serviceName)
|
||||
) {
|
||||
$redirectUrl = $info->getUrl();
|
||||
} elseif ($auth->hasPermission($this->getServicesReadOnlyPermission())) {
|
||||
$redirectUrl = Url::fromPath('director/host/servicesro', [
|
||||
'name' => $hostName,
|
||||
'service' => $serviceName
|
||||
]);
|
||||
} else {
|
||||
$redirectUrl = Url::fromPath('director/host/invalidservice', [
|
||||
'name' => $hostName,
|
||||
'service' => $serviceName,
|
||||
]);
|
||||
}
|
||||
|
||||
$this->redirectNow($redirectUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -261,7 +289,7 @@ class HostController extends ObjectController
|
||||
*/
|
||||
public function servicesroAction()
|
||||
{
|
||||
$this->assertPermission(Permission::MONITORING_SERVICES_RO);
|
||||
$this->assertPermission($this->getServicesReadOnlyPermission());
|
||||
$host = $this->getHostObject();
|
||||
$service = $this->params->getRequired('service');
|
||||
$db = $this->db();
|
||||
@ -564,13 +592,19 @@ class HostController extends ObjectController
|
||||
{
|
||||
$host = $this->object;
|
||||
try {
|
||||
if ($host->isObject() && $host instanceof IcingaHost && $this->monitoring()->hasHost($host)) {
|
||||
$this->actions()->add(Link::create($this->translate('Show'), 'monitoring/host/show', [
|
||||
'host' => $host->getObjectName()
|
||||
], [
|
||||
'class' => 'icon-globe critical',
|
||||
'data-base-target' => '_next'
|
||||
]));
|
||||
$backend = $this->backend();
|
||||
if ($host instanceof IcingaHost
|
||||
&& $host->isObject()
|
||||
&& $backend->hasHost($host->getObjectName())
|
||||
) {
|
||||
$this->actions()->add(
|
||||
Link::create(
|
||||
$this->translate('Show'),
|
||||
$backend->getHostUrl($host->getObjectName()),
|
||||
null,
|
||||
['class' => 'icon-globe critical', 'data-base-target' => '_next']
|
||||
)
|
||||
);
|
||||
|
||||
// Intentionally placed here, show it only for deployed Hosts
|
||||
$this->addOptionalInspectLink();
|
||||
@ -611,4 +645,16 @@ class HostController extends ObjectController
|
||||
}
|
||||
return $this->object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get readOnly permission of the service for the current backend
|
||||
*
|
||||
* @return string permission
|
||||
*/
|
||||
protected function getServicesReadOnlyPermission(): string
|
||||
{
|
||||
return $this->backend() instanceof IcingadbBackend
|
||||
? Permission::ICINGADB_SERVICES_RO
|
||||
: Permission::MONITORING_SERVICES_RO;
|
||||
}
|
||||
}
|
||||
|
@ -29,14 +29,14 @@ class ServiceController extends ObjectController
|
||||
|
||||
protected function checkDirectorPermissions()
|
||||
{
|
||||
if ($this->hasPermission(Permission::MONITORING_SERVICES)) {
|
||||
if ($this->host && $service = $this->object) {
|
||||
if ($this->monitoring()->canModifyService($this->host, $service->getObjectName())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ($this->host
|
||||
&& $this->object
|
||||
&& $this->backend()->canModifyService($this->host->getObjectName(), $this->object->getObjectName())
|
||||
) {
|
||||
return;
|
||||
}
|
||||
$this->assertPermission('director/hosts');
|
||||
|
||||
$this->assertPermission(Permission::HOSTS);
|
||||
}
|
||||
|
||||
public function init()
|
||||
|
@ -1,15 +1,19 @@
|
||||
<?php
|
||||
|
||||
use Icinga\Application\Icinga;
|
||||
use Icinga\Application\Modules\Module;
|
||||
use Icinga\Module\Director\Auth\Permission;
|
||||
use Icinga\Module\Director\Auth\Restriction;
|
||||
use Icinga\Web\Window;
|
||||
|
||||
/** @var \Icinga\Application\Modules\Module $this */
|
||||
/** @var Module $this */
|
||||
if ($this->getConfig()->get('frontend', 'disabled', 'no') === 'yes') {
|
||||
return;
|
||||
}
|
||||
|
||||
$monitoringExists = Module::exists('monitoring');
|
||||
$icingadbExists = Module::exists('icingadb');
|
||||
|
||||
$this->providePermission(Permission::ALL_PERMISSIONS, $this->translate('Allow unrestricted access to Icinga Director'));
|
||||
$this->providePermission(Permission::API, $this->translate('Allow to access the director API'));
|
||||
$this->providePermission(Permission::AUDIT, $this->translate('Allow to access the full audit log'));
|
||||
@ -37,22 +41,46 @@ $this->providePermission(Permission::USERS, $this->translate('Allow to configure
|
||||
$this->providePermission(Permission::SCHEDULED_DOWNTIMES, $this->translate(
|
||||
'Allow to configure notifications (unrestricted)'
|
||||
));
|
||||
$this->providePermission(Permission::MONITORING_HOSTS, $this->translate(
|
||||
'Allow users to modify Hosts they are allowed to see in the monitoring module'
|
||||
));
|
||||
$this->providePermission(Permission::MONITORING_SERVICES, $this->translate(
|
||||
'Allow users to modify Service they are allowed to see in the monitoring module'
|
||||
));
|
||||
$this->providePermission(Permission::MONITORING_SERVICES_RO, $this->translate(
|
||||
'Allow readonly users to see where a Service came from'
|
||||
));
|
||||
|
||||
if ($monitoringExists) {
|
||||
$this->providePermission(Permission::MONITORING_HOSTS, $this->translate(
|
||||
'Allow users to modify Hosts they are allowed to see in the monitoring module'
|
||||
));
|
||||
$this->providePermission(Permission::MONITORING_SERVICES, $this->translate(
|
||||
'Allow users to modify Service they are allowed to see in the monitoring module'
|
||||
));
|
||||
$this->providePermission(Permission::MONITORING_SERVICES_RO, $this->translate(
|
||||
'Allow readonly users to see where a Service came from'
|
||||
));
|
||||
}
|
||||
|
||||
if ($icingadbExists) {
|
||||
$this->providePermission(Permission::ICINGADB_HOSTS, $this->translate(
|
||||
'Allow users to modify Hosts they are allowed to see in Icinga DB Web'
|
||||
));
|
||||
$this->providePermission(Permission::ICINGADB_SERVICES, $this->translate(
|
||||
'Allow users to modify Service they are allowed to see in Icinga DB Web'
|
||||
));
|
||||
$this->providePermission(Permission::ICINGADB_SERVICES_RO, $this->translate(
|
||||
'Allow readonly users to see where a Service came from'
|
||||
));
|
||||
}
|
||||
|
||||
if ($monitoringExists) {
|
||||
$this->provideRestriction(Restriction::MONITORING_RW_OBJECT_FILTER, $this->translate(
|
||||
'Additional (monitoring module) object filter to further restrict write access'
|
||||
));
|
||||
}
|
||||
|
||||
if ($icingadbExists) {
|
||||
$this->provideRestriction(Restriction::ICINGADB_RW_OBJECT_FILTER, $this->translate(
|
||||
'Additional (Icinga DB Web) object filter to further restrict write access'
|
||||
));
|
||||
}
|
||||
|
||||
$this->provideRestriction(Restriction::FILTER_HOSTGROUPS, $this->translate(
|
||||
'Limit access to the given comma-separated list of hostgroups'
|
||||
));
|
||||
$this->provideRestriction(Restriction::MONITORING_RW_OBJECT_FILTER, $this->translate(
|
||||
'Additional (monitoring module) object filter to further restrict write access'
|
||||
));
|
||||
$this->provideRestriction(Restriction::NOTIFICATION_APPLY_FILTER_BY_NAME, $this->translate(
|
||||
'Filter available notification apply rules'
|
||||
));
|
||||
|
@ -17,6 +17,9 @@ class Permission
|
||||
public const MONITORING_SERVICES_RO = 'director/monitoring/services-ro';
|
||||
public const MONITORING_SERVICES = 'director/monitoring/services';
|
||||
public const MONITORING_HOSTS = 'director/monitoring/hosts';
|
||||
public const ICINGADB_SERVICES_RO = 'director/icingadb/services-ro';
|
||||
public const ICINGADB_SERVICES = 'director/icingadb/services';
|
||||
public const ICINGADB_HOSTS = 'director/icingadb/hosts';
|
||||
public const NOTIFICATIONS = 'director/notifications';
|
||||
public const SCHEDULED_DOWNTIMES = 'director/scheduled-downtimes';
|
||||
public const SERVICES = 'director/services';
|
||||
|
@ -5,6 +5,7 @@ namespace Icinga\Module\Director\Auth;
|
||||
class Restriction
|
||||
{
|
||||
public const MONITORING_RW_OBJECT_FILTER = 'director/monitoring/rw-object-filter';
|
||||
public const ICINGADB_RW_OBJECT_FILTER = 'director/icingadb/rw-object-filter';
|
||||
public const FILTER_HOSTGROUPS = 'director/filter/hostgroups';
|
||||
|
||||
// Hint: by-name-Filters are being fetched with variable names, like "director/$type/apply/filter-by-name"
|
||||
|
@ -51,38 +51,4 @@ class ServiceFinder
|
||||
|
||||
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(Permission::HOSTS)) {
|
||||
if ($info = $this::find($this->host, $serviceName)) {
|
||||
return $info->getUrl();
|
||||
}
|
||||
}
|
||||
if ($this->auth->hasPermission(Permission::MONITORING_HOSTS)) {
|
||||
if ($info = $this::find($this->host, $serviceName)) {
|
||||
if ((new Monitoring($this->auth))->canModifyServiceByName($this->host->getObjectName(), $serviceName)) {
|
||||
return $info->getUrl();
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($this->auth->hasPermission(Permission::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,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
55
library/Director/Integration/BackendInterface.php
Normal file
55
library/Director/Integration/BackendInterface.php
Normal file
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace Icinga\Module\Director\Integration;
|
||||
|
||||
use Icinga\Web\Url;
|
||||
|
||||
interface BackendInterface
|
||||
{
|
||||
/**
|
||||
* Whether the backend has the given host
|
||||
*
|
||||
* @param ?string $hostName
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasHost(?string $hostName): bool;
|
||||
|
||||
/**
|
||||
* Whether the backend has the given service of the specified host
|
||||
*
|
||||
* @param ?string $hostName
|
||||
* @param ?string $serviceName
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasService(?string $hostName, ?string $serviceName): bool;
|
||||
|
||||
/**
|
||||
* Whether an authenticated user has the permission (is not restricted) to modify given host
|
||||
*
|
||||
* @param ?string $hostName
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function canModifyHost(?string $hostName): bool;
|
||||
|
||||
/**
|
||||
* Whether an authenticated user has the permission (is not restricted) to modify given service of specified host
|
||||
*
|
||||
* @param ?string $hostName
|
||||
* @param ?string $serviceName
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function canModifyService(?string $hostName, ?string $serviceName): bool;
|
||||
|
||||
/**
|
||||
* Get the url of given host
|
||||
*
|
||||
* @param ?string $hostName
|
||||
*
|
||||
* @return Url
|
||||
*/
|
||||
public function getHostUrl(?string $hostName): ?Url;
|
||||
}
|
127
library/Director/Integration/Icingadb/IcingadbBackend.php
Normal file
127
library/Director/Integration/Icingadb/IcingadbBackend.php
Normal file
@ -0,0 +1,127 @@
|
||||
<?php
|
||||
|
||||
namespace Icinga\Module\Director\Integration\Icingadb;
|
||||
|
||||
use Icinga\Module\Director\Auth\Permission;
|
||||
use Icinga\Module\Director\Auth\Restriction;
|
||||
use Icinga\Module\Director\Integration\BackendInterface;
|
||||
use Icinga\Module\Icingadb\Common\Auth;
|
||||
use Icinga\Module\Icingadb\Common\Database;
|
||||
use Icinga\Module\Icingadb\Model\Host;
|
||||
use Icinga\Module\Icingadb\Model\Service;
|
||||
use Icinga\Web\Url;
|
||||
use ipl\Orm\Query;
|
||||
use ipl\Stdlib\Filter;
|
||||
|
||||
class IcingadbBackend implements BackendInterface
|
||||
{
|
||||
use Database;
|
||||
use Auth;
|
||||
|
||||
public function hasHost(?string $hostName): bool
|
||||
{
|
||||
if ($hostName === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->getHostQuery($hostName)->first() !== null;
|
||||
}
|
||||
|
||||
public function hasService(?string $hostName, ?string $serviceName): bool
|
||||
{
|
||||
if ($hostName === null || $serviceName === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->getServiceQuery($hostName, $serviceName)->first() !== null;
|
||||
}
|
||||
|
||||
public function getHostUrl(?string $hostName): ?Url
|
||||
{
|
||||
if ($hostName === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Url::fromPath('icingadb/host', ['name' => $hostName]);
|
||||
}
|
||||
|
||||
public function canModifyHost(?string $hostName): bool
|
||||
{
|
||||
if ($hostName === null
|
||||
|| ! $this->getAuth()->hasPermission(Permission::ICINGADB_HOSTS)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$query = $this->getHostQuery($hostName);
|
||||
|
||||
return $query->first() !== null;
|
||||
}
|
||||
|
||||
public function canModifyService(?string $hostName, ?string $serviceName): bool
|
||||
{
|
||||
if ($hostName === null
|
||||
|| $serviceName === null
|
||||
|| ! $this->getAuth()->hasPermission(Permission::ICINGADB_SERVICES)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$query = $this->getServiceQuery($hostName, $serviceName);
|
||||
|
||||
return $query->first() !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the query for given host
|
||||
*
|
||||
* @param string $hostName
|
||||
*
|
||||
* @return Query
|
||||
*/
|
||||
protected function getHostQuery(string $hostName): Query
|
||||
{
|
||||
$query = Host::on($this->getDb())
|
||||
->filter(Filter::equal('host.name', $hostName));
|
||||
|
||||
$this->applyDirectorRestrictions($query);
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the query for given host and service
|
||||
*
|
||||
* @param string $hostName
|
||||
* @param string $serviceName
|
||||
*
|
||||
* @return Query
|
||||
*/
|
||||
protected function getServiceQuery(string $hostName, string $serviceName): Query
|
||||
{
|
||||
$query = Service::on($this->getDb())
|
||||
->filter(Filter::all(
|
||||
Filter::equal('service.name', $serviceName),
|
||||
Filter::equal('host.name', $hostName)
|
||||
));
|
||||
|
||||
$this->applyDirectorRestrictions($query);
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply director restrictions on the given query
|
||||
*
|
||||
* @param Query $query
|
||||
*/
|
||||
protected function applyDirectorRestrictions(Query $query): void
|
||||
{
|
||||
$queryFilter = Filter::any();
|
||||
foreach ($this->getAuth()->getRestrictions(Restriction::ICINGADB_RW_OBJECT_FILTER) as $restriction) {
|
||||
$queryFilter->add($this->parseRestriction($restriction, Restriction::ICINGADB_RW_OBJECT_FILTER));
|
||||
}
|
||||
|
||||
$query->filter($queryFilter);
|
||||
}
|
||||
}
|
@ -10,10 +10,11 @@ use Icinga\Exception\ConfigurationError;
|
||||
use Icinga\Module\Director\Auth\MonitoringRestriction;
|
||||
use Icinga\Module\Director\Auth\Permission;
|
||||
use Icinga\Module\Director\Auth\Restriction;
|
||||
use Icinga\Module\Director\Objects\IcingaHost;
|
||||
use Icinga\Module\Director\Integration\BackendInterface;
|
||||
use Icinga\Module\Monitoring\Backend\MonitoringBackend;
|
||||
use Icinga\Web\Url;
|
||||
|
||||
class Monitoring
|
||||
class Monitoring implements BackendInterface
|
||||
{
|
||||
/** @var ?MonitoringBackend */
|
||||
protected $backend;
|
||||
@ -27,83 +28,76 @@ class Monitoring
|
||||
$this->initializeMonitoringBackend();
|
||||
}
|
||||
|
||||
public function isAvailable(): bool
|
||||
public function getHostUrl(?string $hostName): ?Url
|
||||
{
|
||||
return $this->backend !== null;
|
||||
if ($hostName === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Url::fromPath('monitoring/host/show', ['host' => $hostName]);
|
||||
}
|
||||
|
||||
public function hasHost(IcingaHost $host): bool
|
||||
public function hasHost(?string $hostName): bool
|
||||
{
|
||||
return $this->hasHostByName($host->getObjectName());
|
||||
}
|
||||
|
||||
public function hasHostByName($hostname): bool
|
||||
{
|
||||
if (! $this->isAvailable()) {
|
||||
if ($hostName === null || ! $this->isAvailable()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
return $this->selectHost($hostname)->fetchOne() === $hostname;
|
||||
return $this->selectHost($hostName)->fetchOne() === $hostName;
|
||||
} catch (Exception $_) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function hasServiceByName($hostname, $service): bool
|
||||
public function hasService(?string $hostName, ?string $serviceName): bool
|
||||
{
|
||||
if (! $this->isAvailable()) {
|
||||
if ($hostName === null || $serviceName === null || ! $this->isAvailable()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
return $this->rowIsService($this->selectService($hostname, $service)->fetchRow(), $hostname, $service);
|
||||
return $this->rowIsService(
|
||||
$this->selectService($hostName, $serviceName)->fetchRow(),
|
||||
$hostName,
|
||||
$serviceName
|
||||
);
|
||||
} catch (Exception $_) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function canModifyService(IcingaHost $host, $service): bool
|
||||
public function canModifyService(?string $hostName, ?string $serviceName): bool
|
||||
{
|
||||
return $this->canModifyServiceByName($host->getObjectName(), $service);
|
||||
}
|
||||
|
||||
public function canModifyServiceByName($hostname, $service): bool
|
||||
{
|
||||
if (! $this->isAvailable() || $hostname === null || $service === null) {
|
||||
if (! $this->isAvailable() || $hostName === null || $serviceName === null) {
|
||||
return false;
|
||||
}
|
||||
if ($this->auth->hasPermission(Permission::MONITORING_SERVICES)) {
|
||||
$restriction = null;
|
||||
foreach ($this->auth->getRestrictions(Restriction::MONITORING_RW_OBJECT_FILTER) as $restriction) {
|
||||
if ($this->hasServiceWithFilter($hostname, $service, Filter::fromQueryString($restriction))) {
|
||||
if ($this->hasServiceWithFilter($hostName, $serviceName, Filter::fromQueryString($restriction))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if ($restriction === null) {
|
||||
return $this->hasServiceByName($hostname, $service);
|
||||
return $this->hasService($hostName, $serviceName);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function canModifyHost(IcingaHost $host): bool
|
||||
public function canModifyHost(?string $hostName): bool
|
||||
{
|
||||
return $this->canModifyHostByName($host->getObjectName());
|
||||
}
|
||||
|
||||
public function canModifyHostByName($hostname): bool
|
||||
{
|
||||
if ($this->isAvailable() && $this->auth->hasPermission(Permission::MONITORING_HOSTS)) {
|
||||
if ($hostName !== null && $this->isAvailable() && $this->auth->hasPermission(Permission::MONITORING_HOSTS)) {
|
||||
$restriction = null;
|
||||
foreach ($this->auth->getRestrictions(Restriction::MONITORING_RW_OBJECT_FILTER) as $restriction) {
|
||||
if ($this->hasHostWithFilter($hostname, Filter::fromQueryString($restriction))) {
|
||||
if ($this->hasHostWithFilter($hostName, Filter::fromQueryString($restriction))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if ($restriction === null) {
|
||||
return $this->hasHostByName($hostname);
|
||||
return $this->hasHost($hostName);
|
||||
}
|
||||
}
|
||||
|
||||
@ -119,7 +113,7 @@ class Monitoring
|
||||
}
|
||||
}
|
||||
|
||||
public function hasServiceWithFilter($hostname, $service, Filter $filter): bool
|
||||
protected function hasServiceWithFilter($hostname, $service, Filter $filter): bool
|
||||
{
|
||||
try {
|
||||
return $this->rowIsService(
|
||||
@ -132,39 +126,6 @@ class Monitoring
|
||||
}
|
||||
}
|
||||
|
||||
public function getHostState($hostname)
|
||||
{
|
||||
$hostStates = [
|
||||
'0' => 'up',
|
||||
'1' => 'down',
|
||||
'2' => 'unreachable',
|
||||
'99' => 'pending',
|
||||
];
|
||||
|
||||
$query = $this->selectHostStatus($hostname, [
|
||||
'hostname' => 'host_name',
|
||||
'state' => 'host_state',
|
||||
'problem' => 'host_problem',
|
||||
'acknowledged' => 'host_acknowledged',
|
||||
'in_downtime' => 'host_in_downtime',
|
||||
])->where('host_name', $hostname);
|
||||
|
||||
$res = $query->fetchRow();
|
||||
if ($res === false) {
|
||||
$res = (object) [
|
||||
'hostname' => $hostname,
|
||||
'state' => '99',
|
||||
'problem' => '0',
|
||||
'acknowledged' => '0',
|
||||
'in_downtime' => '0',
|
||||
];
|
||||
}
|
||||
|
||||
$res->state = $hostStates[$res->state];
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
protected function selectHost($hostname)
|
||||
{
|
||||
return $this->selectHostStatus($hostname, [
|
||||
@ -231,4 +192,9 @@ class Monitoring
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function isAvailable(): bool
|
||||
{
|
||||
return $this->backend !== null;
|
||||
}
|
||||
}
|
||||
|
78
library/Director/ProvidedHook/Icingadb/HostActions.php
Normal file
78
library/Director/ProvidedHook/Icingadb/HostActions.php
Normal file
@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
namespace Icinga\Module\Director\ProvidedHook\Icingadb;
|
||||
|
||||
use Exception;
|
||||
use Icinga\Application\Config;
|
||||
use Icinga\Module\Director\Auth\Permission;
|
||||
use Icinga\Module\Director\Db;
|
||||
use Icinga\Module\Director\Integration\Icingadb\IcingadbBackend;
|
||||
use Icinga\Module\Director\Objects\IcingaHost;
|
||||
use Icinga\Module\Director\Util;
|
||||
use Icinga\Module\Icingadb\Hook\HostActionsHook;
|
||||
use Icinga\Module\Icingadb\Model\Host;
|
||||
use ipl\Web\Url;
|
||||
use ipl\Web\Widget\Link;
|
||||
|
||||
class HostActions extends HostActionsHook
|
||||
{
|
||||
public function getActionsForObject(Host $host): array
|
||||
{
|
||||
try {
|
||||
return $this->getThem($host);
|
||||
} catch (Exception $e) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
protected function getThem(Host $host): array
|
||||
{
|
||||
$actions = [];
|
||||
$db = $this->db();
|
||||
if (! $db) {
|
||||
return $actions;
|
||||
}
|
||||
$hostname = $host->name;
|
||||
if (Util::hasPermission(Permission::INSPECT)) {
|
||||
$actions[] = new Link(
|
||||
mt('director', 'Inspect'),
|
||||
Url::fromPath(
|
||||
'director/inspect/object',
|
||||
['type' => 'host', 'plural' => 'hosts', 'name' => $hostname]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$allowEdit = false;
|
||||
if (Util::hasPermission(Permission::HOSTS) && IcingaHost::exists($hostname, $db)) {
|
||||
$allowEdit = true;
|
||||
}
|
||||
if (Util::hasPermission(Permission::ICINGADB_HOSTS)) {
|
||||
if ((new IcingadbBackend())->canModifyHost($hostname)) {
|
||||
$allowEdit = IcingaHost::exists($hostname, $db);
|
||||
}
|
||||
}
|
||||
|
||||
if ($allowEdit) {
|
||||
$label = mt('director', 'Modify');
|
||||
$actions[] = new Link(
|
||||
$label,
|
||||
Url::fromPath('director/host/edit', [
|
||||
'name' => $hostname
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
return $actions;
|
||||
}
|
||||
|
||||
protected function db()
|
||||
{
|
||||
$resourceName = Config::module('director')->get('db', 'resource');
|
||||
if (! $resourceName) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return Db::fromResourceName($resourceName);
|
||||
}
|
||||
}
|
10
library/Director/ProvidedHook/Icingadb/IcingadbSupport.php
Normal file
10
library/Director/ProvidedHook/Icingadb/IcingadbSupport.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Icinga\Module\Director\ProvidedHook\Icingadb;
|
||||
|
||||
use Icinga\Module\Icingadb\Hook\IcingadbSupportHook;
|
||||
|
||||
class IcingadbSupport extends IcingadbSupportHook
|
||||
{
|
||||
|
||||
}
|
87
library/Director/ProvidedHook/Icingadb/ServiceActions.php
Normal file
87
library/Director/ProvidedHook/Icingadb/ServiceActions.php
Normal file
@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
namespace Icinga\Module\Director\ProvidedHook\Icingadb;
|
||||
|
||||
use Exception;
|
||||
use Icinga\Application\Config;
|
||||
use Icinga\Module\Director\Auth\Permission;
|
||||
use Icinga\Module\Director\Db;
|
||||
use Icinga\Module\Director\Integration\Icingadb\IcingadbBackend;
|
||||
use Icinga\Module\Director\Objects\IcingaHost;
|
||||
use Icinga\Module\Director\Util;
|
||||
use Icinga\Module\Icingadb\Hook\ServiceActionsHook;
|
||||
use Icinga\Module\Icingadb\Model\Service;
|
||||
use ipl\Web\Url;
|
||||
use ipl\Web\Widget\Link;
|
||||
|
||||
class ServiceActions extends ServiceActionsHook
|
||||
{
|
||||
public function getActionsForObject(Service $service): array
|
||||
{
|
||||
try {
|
||||
return $this->getThem($service);
|
||||
} catch (Exception $e) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Service $service
|
||||
* @return array
|
||||
* @throws \Icinga\Exception\ProgrammingError
|
||||
*/
|
||||
protected function getThem(Service $service)
|
||||
{
|
||||
$actions = [];
|
||||
$db = $this->db();
|
||||
if (! $db) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$hostname = $service->host->name;
|
||||
$serviceName = $service->name;
|
||||
if (Util::hasPermission(Permission::INSPECT)) {
|
||||
$actions[] = new Link(
|
||||
mt('director', 'Inspect'),
|
||||
Url::fromPath('director/inspect/object', [
|
||||
'type' => 'service',
|
||||
'plural' => 'services',
|
||||
'name' => sprintf('%s!%s', $hostname, $serviceName)
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
$title = null;
|
||||
if (Util::hasPermission(Permission::HOSTS)) {
|
||||
$title = mt('director', 'Modify');
|
||||
} elseif (Util::hasPermission(Permission::ICINGADB_SERVICES)) {
|
||||
if ((new IcingadbBackend())->canModifyService($hostname, $serviceName)) {
|
||||
$title = mt('director', 'Modify');
|
||||
}
|
||||
} elseif (Util::hasPermission(Permission::ICINGADB_SERVICES_RO)) {
|
||||
$title = mt('director', 'Configuration');
|
||||
}
|
||||
|
||||
if ($title && IcingaHost::exists($hostname, $db)) {
|
||||
$actions[] = new Link(
|
||||
$title,
|
||||
Url::fromPath('director/host/findservice', [
|
||||
'name' => $hostname,
|
||||
'service' => $serviceName
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
return $actions;
|
||||
}
|
||||
|
||||
protected function db()
|
||||
{
|
||||
$resourceName = Config::module('director')->get('db', 'resource');
|
||||
if (! $resourceName) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return Db::fromResourceName($resourceName);
|
||||
}
|
||||
}
|
@ -45,7 +45,7 @@ class HostActions extends HostActionsHook
|
||||
$allowEdit = true;
|
||||
}
|
||||
if (Util::hasPermission(Permission::MONITORING_HOSTS)) {
|
||||
if ((new Monitoring(Auth::getInstance()))->canModifyHostByName($hostname)) {
|
||||
if ((new Monitoring(Auth::getInstance()))->canModifyHost($hostname)) {
|
||||
$allowEdit = IcingaHost::exists($hostname, $db);
|
||||
}
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ class ServiceActions extends ServiceActionsHook
|
||||
if (Util::hasPermission(Permission::HOSTS)) {
|
||||
$title = mt('director', 'Modify');
|
||||
} elseif (Util::hasPermission(Permission::MONITORING_SERVICES)) {
|
||||
if ((new Monitoring(Auth::getInstance()))->canModifyServiceByName($hostname, $serviceName)) {
|
||||
if ((new Monitoring(Auth::getInstance()))->canModifyService($hostname, $serviceName)) {
|
||||
$title = mt('director', 'Modify');
|
||||
}
|
||||
} elseif (Util::hasPermission(Permission::MONITORING_SERVICES_RO)) {
|
||||
|
@ -4,10 +4,14 @@ namespace Icinga\Module\Director\Web\Controller;
|
||||
|
||||
use gipfl\Translation\StaticTranslator;
|
||||
use Icinga\Application\Benchmark;
|
||||
use Icinga\Application\Modules\Module;
|
||||
use Icinga\Data\Paginatable;
|
||||
use Icinga\Exception\NotFoundError;
|
||||
use Icinga\Exception\ProgrammingError;
|
||||
use Icinga\Module\Director\Integration\Icingadb\IcingadbBackend;
|
||||
use Icinga\Module\Director\Integration\BackendInterface;
|
||||
use Icinga\Module\Director\Integration\MonitoringModule\Monitoring;
|
||||
use Icinga\Module\Director\ProvidedHook\Icingadb\IcingadbSupport;
|
||||
use Icinga\Module\Director\Web\Controller\Extension\CoreApi;
|
||||
use Icinga\Module\Director\Web\Controller\Extension\DirectorDb;
|
||||
use Icinga\Module\Director\Web\Controller\Extension\RestApi;
|
||||
@ -36,8 +40,8 @@ abstract class ActionController extends Controller implements ControlsAndContent
|
||||
/** @var UrlParams Hint for IDE, somehow does not work in web */
|
||||
protected $params;
|
||||
|
||||
/** @var Monitoring */
|
||||
private $monitoring;
|
||||
/** @var BackendInterface */
|
||||
private $backend;
|
||||
|
||||
/**
|
||||
* @throws SecurityException
|
||||
@ -240,14 +244,18 @@ abstract class ActionController extends Controller implements ControlsAndContent
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Monitoring
|
||||
* @return BackendInterface
|
||||
*/
|
||||
protected function monitoring()
|
||||
protected function backend(): BackendInterface
|
||||
{
|
||||
if ($this->monitoring === null) {
|
||||
$this->monitoring = new Monitoring($this->Auth());
|
||||
if ($this->backend === null) {
|
||||
if (Module::exists('icingadb') && IcingadbSupport::useIcingaDbAsBackend()) {
|
||||
$this->backend = new IcingadbBackend();
|
||||
} else {
|
||||
$this->backend = new Monitoring($this->getAuth());
|
||||
}
|
||||
}
|
||||
|
||||
return $this->monitoring;
|
||||
return $this->backend;
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ parameters:
|
||||
- /usr/share/icinga-php
|
||||
- /usr/share/icingaweb2-modules/incubator
|
||||
- /usr/share/icingaweb2-modules/cube
|
||||
- /usr/share/icingaweb2-modules/icingadb
|
||||
|
||||
excludePaths:
|
||||
- library/Director/CoreBeta
|
||||
@ -33,3 +34,4 @@ parameters:
|
||||
- Icinga\Module\Monitoring\DataView\DataView
|
||||
- Icinga\Web\Session\SessionNamespace
|
||||
- Icinga\User\Preferences
|
||||
- ipl\Orm\Model
|
||||
|
@ -66,6 +66,9 @@ use Icinga\Module\Director\ProvidedHook\IcingaDbCubeLinks;
|
||||
if ($this->getConfig()->get('frontend', 'disabled', 'no') !== 'yes') {
|
||||
$this->provideHook('monitoring/HostActions');
|
||||
$this->provideHook('monitoring/ServiceActions');
|
||||
$this->provideHook('icingadb/HostActions');
|
||||
$this->provideHook('icingadb/ServiceActions');
|
||||
$this->provideHook('icingadb/icingadbSupport');
|
||||
$this->provideHook('cube/Actions', CubeLinks::class);
|
||||
$this->provideHook('cube/IcingaDbActions', IcingaDbCubeLinks::class);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user