Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for icingadb as only icingaweb2 data backend #2635

Merged
merged 22 commits into from
Jan 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
1c60901
add support for icingadb as only icingaweb2 data backend
EmTeedee Oct 12, 2022
b28b36f
move classes into subfolder
EmTeedee Dec 29, 2022
89134e0
Remove obsolate class `Backend` and its usages
sukhwinder33445 Nov 17, 2023
9baa3c4
Remove redudant class `MonitorBackendMonitoring` and adjuct code acco…
sukhwinder33445 Nov 17, 2023
604667c
Relocate Backend classes
sukhwinder33445 Nov 17, 2023
8ea8a62
BackendInterface: Add phpDocs
sukhwinder33445 Nov 17, 2023
956cce8
Cleanup code
sukhwinder33445 Nov 17, 2023
677f5dc
Monitoring/IcingadbBackend: Handle if $hostName or $serviceName is null
sukhwinder33445 Nov 17, 2023
eeaf877
IcingadbBackend: Always check if module is available
sukhwinder33445 Nov 17, 2023
db7181c
Backend: Remove unnecessary calls to isAvailable()
sukhwinder33445 Nov 17, 2023
a272b0d
Introduce icingadb permissions/restrictions
sukhwinder33445 Nov 17, 2023
1048c33
configuration.php: Only provide monitoring/icingadb permissions/restr…
sukhwinder33445 Nov 17, 2023
26f8769
Icingadb (Host/Service)Actions: Fix permissions and code style
sukhwinder33445 Nov 20, 2023
4e6528e
ServiceController: Remove redudant if condition
sukhwinder33445 Nov 20, 2023
8a489bc
HostController: Move ServiceFinder::getRedirectionUrl() method code t…
sukhwinder33445 Nov 21, 2023
f52d05d
IcingadbBackend: Apply director restrictions properly
sukhwinder33445 Nov 21, 2023
4ef7f56
ActionController::backend(): Add condition to check which backend sho…
sukhwinder33445 Nov 21, 2023
d26a619
ServiceController: Use given properties to get host/service name
sukhwinder33445 Nov 30, 2023
d30a56a
Fix phpcs issues
sukhwinder33445 Nov 21, 2023
147170e
phpstan: Add icingadb module
sukhwinder33445 Dec 4, 2023
2461724
IcingadbBackend: Drop icingadb restriction check and only check for d…
sukhwinder33445 Jan 15, 2024
a850ff1
IcingadbBackend: Remove isAvailable method and property
sukhwinder33445 Jan 16, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)
sukhwinder33445 marked this conversation as resolved.
Show resolved Hide resolved
) {
$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