Skip to content

Commit

Permalink
add support for icingadb as only icingaweb2 data backend (#2635)
Browse files Browse the repository at this point in the history
  • Loading branch information
nilmerg authored Jan 16, 2024
2 parents 12cca3e + a850ff1 commit 6851778
Show file tree
Hide file tree
Showing 18 changed files with 526 additions and 145 deletions.
1 change: 1 addition & 0 deletions .github/workflows/php.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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: |
Expand Down
78 changes: 62 additions & 16 deletions application/controllers/HostController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

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;
Expand Down Expand Up @@ -33,17 +35,19 @@ protected function checkDirectorPermissions()
{
$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
Expand Down Expand Up @@ -134,11 +138,35 @@ protected function addServicesHeader()

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);
}

/**
Expand Down Expand Up @@ -261,7 +289,7 @@ public function servicesAction()
*/
public function servicesroAction()
{
$this->assertPermission(Permission::MONITORING_SERVICES_RO);
$this->assertPermission($this->getServicesReadOnlyPermission());
$host = $this->getHostObject();
$service = $this->params->getRequired('service');
$db = $this->db();
Expand Down Expand Up @@ -564,13 +592,19 @@ protected function addOptionalMonitoringLink()
{
$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();
Expand Down Expand Up @@ -611,4 +645,16 @@ protected function getHostObject()
}
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;
}
}
14 changes: 7 additions & 7 deletions application/controllers/ServiceController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
54 changes: 41 additions & 13 deletions configuration.php
Original file line number Diff line number Diff line change
@@ -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'));
Expand Down Expand Up @@ -37,22 +41,46 @@
$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'
));
Expand Down
3 changes: 3 additions & 0 deletions library/Director/Auth/Permission.php
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
1 change: 1 addition & 0 deletions library/Director/Auth/Restriction.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
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"
Expand Down
34 changes: 0 additions & 34 deletions library/Director/DirectorObject/Lookup/ServiceFinder.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,38 +51,4 @@ public static function find(IcingaHost $host, $serviceName)

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 changes: 55 additions & 0 deletions library/Director/Integration/BackendInterface.php
Original file line number Diff line number Diff line change
@@ -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;
}
Loading

0 comments on commit 6851778

Please sign in to comment.