mirror of
https://github.com/Icinga/icingadb-web.git
synced 2026-05-28 04:36:06 -04:00
Merge pull request #161 from Icinga/feature/native-command-implementation
Native command implementation
This commit is contained in:
commit
fa2b9d5847
72 changed files with 4108 additions and 683 deletions
147
application/controllers/CommandTransportController.php
Normal file
147
application/controllers/CommandTransportController.php
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Controllers;
|
||||
|
||||
use GuzzleHttp\Psr7\ServerRequest;
|
||||
use Icinga\Application\Config;
|
||||
use Icinga\Data\Filter\Filter;
|
||||
use Icinga\Forms\ConfirmRemovalForm;
|
||||
use Icinga\Module\Icingadb\Command\Transport\CommandTransportConfig;
|
||||
use Icinga\Module\Icingadb\Forms\ApiTransportForm;
|
||||
use Icinga\Module\Icingadb\Widget\ItemList\CommandTransportList;
|
||||
use ipl\Html\HtmlString;
|
||||
use ipl\Web\Widget\ButtonLink;
|
||||
|
||||
class CommandTransportController extends ConfigController
|
||||
{
|
||||
public function init()
|
||||
{
|
||||
$this->assertPermission('config/modules');
|
||||
}
|
||||
|
||||
public function indexAction()
|
||||
{
|
||||
$list = new CommandTransportList((new CommandTransportConfig())->select());
|
||||
|
||||
$this->addControl(
|
||||
(new ButtonLink(
|
||||
t('Create Command Transport'),
|
||||
'icingadb/command-transport/add',
|
||||
'plus'
|
||||
))->setBaseTarget('_next')
|
||||
);
|
||||
|
||||
$this->addContent($list);
|
||||
|
||||
$this->mergeTabs($this->Module()->getConfigTabs());
|
||||
$this->getTabs()->disableLegacyExtensions();
|
||||
$this->view->title = $this->getTabs()
|
||||
->activate('command-transports')
|
||||
->getActiveTab()
|
||||
->getLabel();
|
||||
}
|
||||
|
||||
public function showAction()
|
||||
{
|
||||
$transportName = $this->params->getRequired('name');
|
||||
|
||||
$transportConfig = (new CommandTransportConfig())
|
||||
->select()
|
||||
->where('name', $transportName)
|
||||
->fetchRow();
|
||||
if ($transportConfig === false) {
|
||||
$this->httpNotFound(t('Unknown transport'));
|
||||
}
|
||||
|
||||
$form = new ApiTransportForm();
|
||||
$form->populate((array) $transportConfig);
|
||||
$form->on(ApiTransportForm::ON_SUCCESS, function (ApiTransportForm $form) use ($transportName) {
|
||||
(new CommandTransportConfig())->update(
|
||||
'transport',
|
||||
$form->getValues(),
|
||||
Filter::where('name', $transportName)
|
||||
);
|
||||
|
||||
$this->redirectNow('icingadb/command-transport');
|
||||
});
|
||||
|
||||
$form->handleRequest(ServerRequest::fromGlobals());
|
||||
|
||||
$this->addContent($form);
|
||||
|
||||
$this->setTitle(sprintf($this->translate('Command Transport: %s'), $transportName));
|
||||
$this->getTabs()->disableLegacyExtensions();
|
||||
}
|
||||
|
||||
public function addAction()
|
||||
{
|
||||
$form = new ApiTransportForm();
|
||||
$form->on(ApiTransportForm::ON_SUCCESS, function (ApiTransportForm $form) {
|
||||
(new CommandTransportConfig())->insert('transport', $form->getValues());
|
||||
$this->redirectNow('icingadb/command-transport');
|
||||
});
|
||||
|
||||
$form->handleRequest(ServerRequest::fromGlobals());
|
||||
|
||||
$this->addContent($form);
|
||||
|
||||
$this->setTitle($this->translate('Add Command Transport'));
|
||||
$this->getTabs()->disableLegacyExtensions();
|
||||
}
|
||||
|
||||
public function removeAction()
|
||||
{
|
||||
$transportName = $this->params->getRequired('name');
|
||||
|
||||
$form = new ConfirmRemovalForm();
|
||||
$form->setAttrib('style', 'text-align:center;');
|
||||
$form->setOnSuccess(function () use ($transportName) {
|
||||
(new CommandTransportConfig())->delete(
|
||||
'transport',
|
||||
Filter::where('name', $transportName)
|
||||
);
|
||||
|
||||
$this->redirectNow('icingadb/command-transport');
|
||||
});
|
||||
|
||||
$form->handleRequest();
|
||||
|
||||
$this->addContent(HtmlString::create($form->render()));
|
||||
|
||||
$this->setTitle($this->translate('Remove Command Transport: %s'), $transportName);
|
||||
$this->getTabs()->disableLegacyExtensions();
|
||||
}
|
||||
|
||||
public function sortAction()
|
||||
{
|
||||
$transportName = $this->params->getRequired('name');
|
||||
$newPosition = (int) $this->params->getRequired('pos');
|
||||
|
||||
$config = $this->Config('commandtransports');
|
||||
if (! $config->hasSection($transportName)) {
|
||||
$this->httpNotFound(t('Unknown transport'));
|
||||
}
|
||||
|
||||
if ($newPosition < 0 || $newPosition > $config->count()) {
|
||||
$this->httpBadRequest(t('Position out of bounds'));
|
||||
}
|
||||
|
||||
$transports = $config->getConfigObject()->toArray();
|
||||
$transportNames = array_keys($transports);
|
||||
|
||||
array_splice($transportNames, array_search($transportName, $transportNames, true), 1);
|
||||
array_splice($transportNames, $newPosition, 0, [$transportName]);
|
||||
|
||||
$sortedTransports = [];
|
||||
foreach ($transportNames as $name) {
|
||||
$sortedTransports[$name] = $transports[$name];
|
||||
}
|
||||
|
||||
$newConfig = Config::fromArray($sortedTransports);
|
||||
$newConfig->saveIni($config->getConfigFile());
|
||||
|
||||
$this->redirectNow('icingadb/command-transport');
|
||||
}
|
||||
}
|
||||
|
|
@ -6,19 +6,16 @@ namespace Icinga\Module\Icingadb\Controllers;
|
|||
|
||||
use GuzzleHttp\Psr7\ServerRequest;
|
||||
use Icinga\Module\Icingadb\Common\Links;
|
||||
use Icinga\Module\Icingadb\Forms\Command\Object\DeleteCommentForm;
|
||||
use Icinga\Module\Icingadb\Model\Comment;
|
||||
use Icinga\Module\Icingadb\Web\Control\SearchBar\ObjectSuggestions;
|
||||
use Icinga\Module\Icingadb\Web\Controller;
|
||||
use Icinga\Module\Icingadb\Widget\ContinueWith;
|
||||
use Icinga\Module\Icingadb\Widget\ItemList\CommentList;
|
||||
use Icinga\Module\Icingadb\Widget\ShowMore;
|
||||
use Icinga\Module\Monitoring\Forms\Command\Object\DeleteCommentsCommandForm;
|
||||
use ipl\Html\HtmlDocument;
|
||||
use ipl\Html\HtmlString;
|
||||
use ipl\Web\Filter\QueryString;
|
||||
use ipl\Web\Url;
|
||||
use ipl\Web\Widget\ActionLink;
|
||||
use ipl\Web\Widget\Icon;
|
||||
|
||||
class CommentsController extends Controller
|
||||
{
|
||||
|
|
@ -109,6 +106,8 @@ class CommentsController extends Controller
|
|||
|
||||
public function deleteAction()
|
||||
{
|
||||
// TODO: Check permission
|
||||
|
||||
$this->setTitle(t('Remove Comments'));
|
||||
|
||||
$db = $this->getDb();
|
||||
|
|
@ -124,40 +123,19 @@ class CommentsController extends Controller
|
|||
|
||||
$this->filter($comments);
|
||||
|
||||
$deleteCommentsForm = (new DeleteCommentsCommandForm())
|
||||
->addDescription(sprintf(
|
||||
t('Confirm removal of %d comments.'),
|
||||
$comments->count()
|
||||
))
|
||||
->setComments($comments)
|
||||
->setRedirectUrl(Links::comments())
|
||||
->create();
|
||||
$form = (new DeleteCommentForm())
|
||||
->setObjects($comments)
|
||||
->setRedirectUrl(Links::comments()->getAbsoluteUrl())
|
||||
->on(DeleteCommentForm::ON_SUCCESS, function ($form) {
|
||||
// This forces the column to reload nearly instantly after the redirect
|
||||
// and ensures the effect of the command is visible to the user asap
|
||||
$this->getResponse()->setAutoRefreshInterval(1);
|
||||
|
||||
$deleteCommentsForm->removeElement('btn_submit');
|
||||
$this->redirectNow($form->getRedirectUrl());
|
||||
})
|
||||
->handleRequest(ServerRequest::fromGlobals());
|
||||
|
||||
$deleteCommentsForm->addElement(
|
||||
'button',
|
||||
'btn_submit',
|
||||
[
|
||||
'class' => 'cancel-button spinner',
|
||||
'decorators' => [
|
||||
'ViewHelper',
|
||||
['HtmlTag', ['tag' => 'div', 'class' => 'control-group form-controls']]
|
||||
],
|
||||
'escape' => false,
|
||||
'ignore' => true,
|
||||
'label' => (new HtmlDocument())
|
||||
->add([new Icon('trash'), t('Remove Comments')])
|
||||
->setSeparator(' ')
|
||||
->render(),
|
||||
'title' => t('Remove comments'),
|
||||
'type' => 'submit'
|
||||
]
|
||||
);
|
||||
|
||||
$deleteCommentsForm->handleRequest();
|
||||
|
||||
$this->addContent(HtmlString::create($deleteCommentsForm->render()));
|
||||
$this->addContent($form);
|
||||
}
|
||||
|
||||
public function detailsAction()
|
||||
|
|
@ -191,15 +169,16 @@ class CommentsController extends Controller
|
|||
sprintf(t('Show all %d comments'), $comments->count())
|
||||
));
|
||||
|
||||
$this->addContent((new ActionLink(
|
||||
sprintf(t('Remove %d comments'), $comments->count()),
|
||||
Links::commentsDelete()->setQueryString(QueryString::render($this->getFilter())),
|
||||
'trash',
|
||||
[
|
||||
'data-icinga-modal' => true,
|
||||
'data-no-icinga-ajax' => true
|
||||
]
|
||||
))->setAttribute('class', 'cancel-button'));
|
||||
// TODO: Check permission
|
||||
$this->addContent(
|
||||
(new DeleteCommentForm())
|
||||
->setObjects($comments)
|
||||
->setAction(
|
||||
Links::commentsDelete()
|
||||
->setQueryString(QueryString::render($this->getFilter()))
|
||||
->getAbsoluteUrl()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function completeAction()
|
||||
|
|
|
|||
|
|
@ -4,22 +4,15 @@
|
|||
|
||||
namespace Icinga\Module\Icingadb\Controllers;
|
||||
|
||||
use Exception;
|
||||
use Icinga\Application\Config;
|
||||
use Icinga\Exception\NotFoundError;
|
||||
use Icinga\Forms\ConfirmRemovalForm;
|
||||
use Icinga\Module\Icingadb\Forms\DatabaseConfigForm;
|
||||
use Icinga\Module\Icingadb\Forms\RedisConfigForm;
|
||||
use Icinga\Module\Icingadb\Web\Controller;
|
||||
use Icinga\Module\Monitoring\Forms\Config\SecurityConfigForm;
|
||||
use Icinga\Module\Monitoring\Forms\Config\TransportConfigForm;
|
||||
use Icinga\Module\Monitoring\Forms\Config\TransportReorderForm;
|
||||
use Icinga\Web\Form;
|
||||
use Icinga\Web\Notification;
|
||||
use Icinga\Web\Widget\Tab;
|
||||
use Icinga\Web\Widget\Tabs;
|
||||
use ipl\Html\HtmlString;
|
||||
use ipl\Web\Widget\ButtonLink;
|
||||
|
||||
class ConfigController extends Controller
|
||||
{
|
||||
|
|
@ -30,142 +23,6 @@ class ConfigController extends Controller
|
|||
// parent::init();
|
||||
// }
|
||||
|
||||
public function commandTransportsAction()
|
||||
{
|
||||
$form = new TransportReorderForm();
|
||||
|
||||
$form->handleRequest();
|
||||
|
||||
$this->mergeTabs($this->Module()->getConfigTabs()->activate('command-transports'));
|
||||
|
||||
$this->addControl(
|
||||
(new ButtonLink(
|
||||
t('Create Command Transport'),
|
||||
'icingadb/config/create-command-transport',
|
||||
'plus'
|
||||
))->setBaseTarget('_next')
|
||||
);
|
||||
|
||||
$this->addFormToContent($form);
|
||||
}
|
||||
|
||||
public function createCommandTransportAction()
|
||||
{
|
||||
$this->setTitle(t('Create Command Transport'));
|
||||
|
||||
$form = (new TransportConfigForm())
|
||||
->setIniConfig(Config::module('monitoring', 'commandtransports'))
|
||||
->setRedirectUrl('icingadb/config/command-transports');
|
||||
|
||||
$form->setOnSuccess(function (TransportConfigForm $form) {
|
||||
try {
|
||||
$form->add($form::transformEmptyValuesToNull($form->getValues()));
|
||||
} catch (Exception $e) {
|
||||
$form->error($e->getMessage());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($form->save()) {
|
||||
Notification::success(t('Command transport successfully created'));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
$form->handleRequest();
|
||||
|
||||
$this->addFormToContent($form);
|
||||
}
|
||||
|
||||
public function deleteCommandTransportAction()
|
||||
{
|
||||
$this->setTitle(t('Delete Command Transport'));
|
||||
|
||||
$transportName = $this->params->getRequired('transport');
|
||||
|
||||
$transportConfigForm = (new TransportConfigForm())
|
||||
->setIniConfig(Config::module('monitoring', 'commandtransports'));
|
||||
|
||||
$confirmRemovalForm = (new ConfirmRemovalForm())
|
||||
->setRedirectUrl('icingadb/config/command-transports');
|
||||
|
||||
$confirmRemovalForm->setOnSuccess(
|
||||
function (ConfirmRemovalForm $form) use ($transportName, $transportConfigForm) {
|
||||
try {
|
||||
$transportConfigForm->delete($transportName);
|
||||
} catch (Exception $e) {
|
||||
$form->error($e->getMessage());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($transportConfigForm->save()) {
|
||||
Notification::success(sprintf(
|
||||
t('Command transport "%s" successfully removed'),
|
||||
$transportName
|
||||
));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
);
|
||||
|
||||
$confirmRemovalForm->handleRequest();
|
||||
|
||||
$this->addFormToContent($confirmRemovalForm);
|
||||
}
|
||||
|
||||
public function updateCommandTransportAction()
|
||||
{
|
||||
$this->setTitle(t('Update Command Transport'));
|
||||
|
||||
$transportName = $this->params->getRequired('transport');
|
||||
|
||||
$form = (new TransportConfigForm())
|
||||
->setIniConfig(Config::module('monitoring', 'commandtransports'))
|
||||
->setRedirectUrl('icingadb/config/command-transports');
|
||||
|
||||
$form->setOnSuccess(function (TransportConfigForm $form) use ($transportName) {
|
||||
try {
|
||||
$form->edit($transportName, array_map(
|
||||
function ($v) {
|
||||
return $v !== '' ? $v : null;
|
||||
},
|
||||
$form->getValues()
|
||||
));
|
||||
} catch (Exception $e) {
|
||||
$form->error($e->getMessage());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($form->save()) {
|
||||
Notification::success(sprintf(
|
||||
t('Command transport "%s" successfully updated'),
|
||||
$transportName
|
||||
));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
try {
|
||||
$form->load($transportName);
|
||||
$form->handleRequest();
|
||||
} catch (NotFoundError $_) {
|
||||
$this->httpNotFound(sprintf(t('Command transport "%s" not found'), $transportName));
|
||||
}
|
||||
|
||||
$this->addFormToContent($form);
|
||||
}
|
||||
|
||||
public function databaseAction()
|
||||
{
|
||||
$form = (new DatabaseConfigForm())
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ namespace Icinga\Module\Icingadb\Controllers;
|
|||
|
||||
use GuzzleHttp\Psr7\ServerRequest;
|
||||
use Icinga\Module\Icingadb\Common\Links;
|
||||
use Icinga\Module\Icingadb\Forms\Command\Object\DeleteDowntimeForm;
|
||||
use Icinga\Module\Icingadb\Model\Downtime;
|
||||
use Icinga\Module\Icingadb\Web\Control\SearchBar\ObjectSuggestions;
|
||||
use Icinga\Module\Icingadb\Web\Controller;
|
||||
|
|
@ -114,6 +115,8 @@ class DowntimesController extends Controller
|
|||
|
||||
public function deleteAction()
|
||||
{
|
||||
// TODO: Check permission
|
||||
|
||||
$this->setTitle(t('Cancel Downtimes'));
|
||||
|
||||
$db = $this->getDb();
|
||||
|
|
@ -129,40 +132,19 @@ class DowntimesController extends Controller
|
|||
|
||||
$this->filter($downtimes);
|
||||
|
||||
$cancelDowntimesForm = (new DeleteDowntimesCommandForm())
|
||||
->addDescription(sprintf(
|
||||
t('Confirm cancellation of %d downtimes.'),
|
||||
$downtimes->count()
|
||||
))
|
||||
->setDowntimes($downtimes)
|
||||
->setRedirectUrl(Links::downtimes())
|
||||
->create();
|
||||
$form = (new DeleteDowntimeForm())
|
||||
->setObjects($downtimes)
|
||||
->setRedirectUrl(Links::downtimes()->getAbsoluteUrl())
|
||||
->on(DeleteDowntimeForm::ON_SUCCESS, function ($form) {
|
||||
// This forces the column to reload nearly instantly after the redirect
|
||||
// and ensures the effect of the command is visible to the user asap
|
||||
$this->getResponse()->setAutoRefreshInterval(1);
|
||||
|
||||
$cancelDowntimesForm->removeElement('btn_submit');
|
||||
$this->redirectNow($form->getRedirectUrl());
|
||||
})
|
||||
->handleRequest(ServerRequest::fromGlobals());
|
||||
|
||||
$cancelDowntimesForm->addElement(
|
||||
'button',
|
||||
'btn_submit',
|
||||
[
|
||||
'class' => 'cancel-button spinner',
|
||||
'decorators' => [
|
||||
'ViewHelper',
|
||||
['HtmlTag', ['tag' => 'div', 'class' => 'control-group form-controls']]
|
||||
],
|
||||
'escape' => false,
|
||||
'ignore' => true,
|
||||
'label' => (new HtmlDocument())
|
||||
->add([new Icon('trash'), t('Cancel Downtimes')])
|
||||
->setSeparator(' ')
|
||||
->render(),
|
||||
'title' => t('Cancel downtimes'),
|
||||
'type' => 'submit'
|
||||
]
|
||||
);
|
||||
|
||||
$cancelDowntimesForm->handleRequest();
|
||||
|
||||
$this->addContent(HtmlString::create($cancelDowntimesForm->render()));
|
||||
$this->addContent($form);
|
||||
}
|
||||
|
||||
public function detailsAction()
|
||||
|
|
@ -196,15 +178,16 @@ class DowntimesController extends Controller
|
|||
sprintf(t('Show all %d downtimes'), $downtimes->count())
|
||||
));
|
||||
|
||||
$this->addContent((new ActionLink(
|
||||
sprintf(t('Cancel %d downtimes'), $downtimes->count()),
|
||||
Links::downtimesDelete()->setQueryString(QueryString::render($this->getFilter())),
|
||||
'trash',
|
||||
[
|
||||
'data-icinga-modal' => true,
|
||||
'data-no-icinga-ajax' => true
|
||||
]
|
||||
))->setAttribute('class', 'cancel-button'));
|
||||
// TODO: Check permission
|
||||
$this->addContent(
|
||||
(new DeleteDowntimeForm())
|
||||
->setObjects($downtimes)
|
||||
->setAction(
|
||||
Links::downtimesDelete()
|
||||
->setQueryString(QueryString::render($this->getFilter()))
|
||||
->getAbsoluteUrl()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function completeAction()
|
||||
|
|
|
|||
|
|
@ -4,16 +4,18 @@
|
|||
|
||||
namespace Icinga\Module\Icingadb\Controllers;
|
||||
|
||||
use Icinga\Module\Icingadb\Compat\CompatBackend;
|
||||
use GuzzleHttp\Psr7\ServerRequest;
|
||||
use Icinga\Module\Icingadb\Command\Instance\ToggleInstanceFeatureCommand;
|
||||
use Icinga\Module\Icingadb\Common\Links;
|
||||
use Icinga\Module\Icingadb\Forms\Command\Instance\ToggleInstanceFeaturesForm;
|
||||
use Icinga\Module\Icingadb\Model\HoststateSummary;
|
||||
use Icinga\Module\Icingadb\Model\Instance;
|
||||
use Icinga\Module\Icingadb\Model\ServicestateSummary;
|
||||
use Icinga\Module\Icingadb\Web\Controller;
|
||||
use Icinga\Module\Icingadb\Widget\Health;
|
||||
use Icinga\Module\Icingadb\Widget\VerticalKeyValue;
|
||||
use Icinga\Module\Monitoring\Forms\Command\Instance\ToggleInstanceFeaturesCommandForm;
|
||||
use ipl\Html\Html;
|
||||
use ipl\Html\HtmlString;
|
||||
use ipl\Web\Url;
|
||||
|
||||
class HealthController extends Controller
|
||||
{
|
||||
|
|
@ -83,22 +85,27 @@ class HealthController extends Controller
|
|||
['class' => 'instance-commands'],
|
||||
Html::tag('h2', t('Feature Commands'))
|
||||
);
|
||||
$programStatus = (object) [
|
||||
'active_host_checks_enabled' => $instance->icinga2_active_host_checks_enabled,
|
||||
'active_service_checks_enabled' => $instance->icinga2_active_service_checks_enabled,
|
||||
'event_handlers_enabled' => $instance->icinga2_event_handlers_enabled,
|
||||
'flap_detection_enabled' => $instance->icinga2_flap_detection_enabled,
|
||||
'notifications_enabled' => $instance->icinga2_notifications_enabled,
|
||||
'process_performance_data' => $instance->icinga2_performance_data_enabled,
|
||||
'program_version' => $instance->icinga2_version
|
||||
];
|
||||
$toggleInstanceFeaturesCommandForm = new ToggleInstanceFeaturesCommandForm();
|
||||
$toggleInstanceFeaturesCommandForm
|
||||
->setBackend(new CompatBackend())
|
||||
->setStatus($programStatus)
|
||||
->load($programStatus)
|
||||
->handleRequest();
|
||||
$featureCommands->add(HtmlString::create($toggleInstanceFeaturesCommandForm->render()));
|
||||
$toggleInstanceFeaturesCommandForm = new ToggleInstanceFeaturesForm([
|
||||
ToggleInstanceFeatureCommand::FEATURE_ACTIVE_HOST_CHECKS =>
|
||||
$instance->icinga2_active_host_checks_enabled,
|
||||
ToggleInstanceFeatureCommand::FEATURE_ACTIVE_SERVICE_CHECKS =>
|
||||
$instance->icinga2_active_service_checks_enabled,
|
||||
ToggleInstanceFeatureCommand::FEATURE_EVENT_HANDLERS =>
|
||||
$instance->icinga2_event_handlers_enabled,
|
||||
ToggleInstanceFeatureCommand::FEATURE_FLAP_DETECTION =>
|
||||
$instance->icinga2_flap_detection_enabled,
|
||||
ToggleInstanceFeatureCommand::FEATURE_NOTIFICATIONS =>
|
||||
$instance->icinga2_notifications_enabled,
|
||||
ToggleInstanceFeatureCommand::FEATURE_PERFORMANCE_DATA =>
|
||||
$instance->icinga2_performance_data_enabled
|
||||
]);
|
||||
$toggleInstanceFeaturesCommandForm->setObjects([$instance]);
|
||||
$toggleInstanceFeaturesCommandForm->on(ToggleInstanceFeaturesForm::ON_SUCCESS, function () {
|
||||
$this->redirectNow(Url::fromPath('icingadb/health')->getAbsoluteUrl());
|
||||
});
|
||||
$toggleInstanceFeaturesCommandForm->handleRequest(ServerRequest::fromGlobals());
|
||||
|
||||
$featureCommands->add($toggleInstanceFeaturesCommandForm);
|
||||
$this->addContent($featureCommands);
|
||||
|
||||
$this->setAutorefreshInterval(30);
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ namespace Icinga\Module\Icingadb\Controllers;
|
|||
use GuzzleHttp\Psr7\ServerRequest;
|
||||
use Icinga\Module\Icingadb\Common\CommandActions;
|
||||
use Icinga\Module\Icingadb\Common\Links;
|
||||
use Icinga\Module\Icingadb\Compat\FeatureStatus;
|
||||
use Icinga\Module\Icingadb\Model\Host;
|
||||
use Icinga\Module\Icingadb\Model\HoststateSummary;
|
||||
use Icinga\Module\Icingadb\Util\FeatureStatus;
|
||||
use Icinga\Module\Icingadb\Web\Control\SearchBar\ObjectSuggestions;
|
||||
use Icinga\Module\Icingadb\Web\Controller;
|
||||
use Icinga\Module\Icingadb\Widget\ContinueWith;
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ namespace Icinga\Module\Icingadb\Controllers;
|
|||
use GuzzleHttp\Psr7\ServerRequest;
|
||||
use Icinga\Module\Icingadb\Common\CommandActions;
|
||||
use Icinga\Module\Icingadb\Common\Links;
|
||||
use Icinga\Module\Icingadb\Compat\FeatureStatus;
|
||||
use Icinga\Module\Icingadb\Model\Service;
|
||||
use Icinga\Module\Icingadb\Model\ServicestateSummary;
|
||||
use Icinga\Module\Icingadb\Util\FeatureStatus;
|
||||
use Icinga\Module\Icingadb\Web\Control\SearchBar\ObjectSuggestions;
|
||||
use Icinga\Module\Icingadb\Web\Controller;
|
||||
use Icinga\Module\Icingadb\Widget\ContinueWith;
|
||||
|
|
|
|||
102
application/forms/ApiTransportForm.php
Normal file
102
application/forms/ApiTransportForm.php
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Forms;
|
||||
|
||||
use Icinga\Data\ConfigObject;
|
||||
use Icinga\Module\Icingadb\Command\Transport\CommandTransport;
|
||||
use Icinga\Module\Icingadb\Command\Transport\CommandTransportException;
|
||||
use Icinga\Web\Session;
|
||||
use ipl\Web\Common\CsrfCounterMeasure;
|
||||
use ipl\Web\Compat\CompatForm;
|
||||
|
||||
class ApiTransportForm extends CompatForm
|
||||
{
|
||||
use CsrfCounterMeasure;
|
||||
|
||||
protected function assemble()
|
||||
{
|
||||
// TODO: Use a validator to check if a name is not already in use
|
||||
$this->addElement('text', 'name', [
|
||||
'required' => true,
|
||||
'label' => t('Transport Name')
|
||||
]);
|
||||
|
||||
$this->addElement('hidden', 'transport', [
|
||||
'value' => 'api'
|
||||
]);
|
||||
|
||||
$this->addElement('text', 'host', [
|
||||
'required' => true,
|
||||
'id' => 'api_transport_host',
|
||||
'label' => t('Host'),
|
||||
'description' => t('Hostname or address of the Icinga master')
|
||||
]);
|
||||
|
||||
// TODO: Don't rely only on browser validation
|
||||
$this->addElement('number', 'port', [
|
||||
'required' => true,
|
||||
'label' => t('Port'),
|
||||
'value' => 5665,
|
||||
'min' => 1,
|
||||
'max' => 65536
|
||||
]);
|
||||
|
||||
$this->addElement('text', 'username', [
|
||||
'required' => true,
|
||||
'label' => t('API Username'),
|
||||
'description' => t('User to authenticate with using HTTP Basic Auth')
|
||||
]);
|
||||
|
||||
// TODO: Use a password element
|
||||
$this->addElement('text', 'password', [
|
||||
'required' => true,
|
||||
'label' => t('API Password')
|
||||
]);
|
||||
|
||||
$this->addElement('submit', 'btn_submit', [
|
||||
'label' => t('Save')
|
||||
]);
|
||||
|
||||
$this->addElement($this->createCsrfCounterMeasure(Session::getSession()->getId()));
|
||||
}
|
||||
|
||||
public function validate()
|
||||
{
|
||||
parent::validate();
|
||||
if (! $this->isValid) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ($this->getPopulatedValue('force_creation') === 'n') {
|
||||
return $this;
|
||||
}
|
||||
|
||||
try {
|
||||
CommandTransport::createTransport(new ConfigObject($this->getValues()))->probe();
|
||||
} catch (CommandTransportException $e) {
|
||||
$this->addMessage(
|
||||
sprintf(t('Failed to successfully validate the configuration: %s'), $e->getMessage())
|
||||
);
|
||||
|
||||
$forceCheckbox = $this->createElement(
|
||||
'checkbox',
|
||||
'force_creation',
|
||||
[
|
||||
'ignore' => true,
|
||||
'label' => t('Force Changes'),
|
||||
'description' => t('Check this box to enforce changes without connectivity validation')
|
||||
]
|
||||
);
|
||||
|
||||
$this->registerElement($forceCheckbox);
|
||||
$this->decorate($forceCheckbox);
|
||||
$this->prepend($forceCheckbox);
|
||||
|
||||
$this->isValid = false;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
125
application/forms/Command/CommandForm.php
Normal file
125
application/forms/Command/CommandForm.php
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Forms\Command;
|
||||
|
||||
use Exception;
|
||||
use Icinga\Application\Logger;
|
||||
use Icinga\Module\Icingadb\Command\IcingaCommand;
|
||||
use Icinga\Module\Icingadb\Command\Transport\CommandTransport;
|
||||
use Icinga\Web\Notification;
|
||||
use Icinga\Web\Session;
|
||||
use ipl\Html\Form;
|
||||
use ipl\Orm\Model;
|
||||
use ipl\Web\Common\CsrfCounterMeasure;
|
||||
|
||||
abstract class CommandForm extends Form
|
||||
{
|
||||
use CsrfCounterMeasure;
|
||||
|
||||
protected $defaultAttributes = ['class' => 'icinga-form icinga-controls'];
|
||||
|
||||
/** @var mixed */
|
||||
protected $objects;
|
||||
|
||||
/**
|
||||
* Set the objects to issue the command for
|
||||
*
|
||||
* @param mixed $objects A traversable that is also countable
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setObjects($objects)
|
||||
{
|
||||
$this->objects = $objects;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the objects to issue the command for
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getObjects()
|
||||
{
|
||||
return $this->objects;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and add form elements representing the command's options
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
abstract protected function assembleElements();
|
||||
|
||||
/**
|
||||
* Create and add a submit button to the form
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
abstract protected function assembleSubmitButton();
|
||||
|
||||
/**
|
||||
* Get the command to issue for the given object
|
||||
*
|
||||
* @param Model $object
|
||||
*
|
||||
* @return IcingaCommand|IcingaCommand[]|null NULL in case no command should be issued for the object
|
||||
*/
|
||||
abstract protected function getCommand(Model $object);
|
||||
|
||||
protected function assemble()
|
||||
{
|
||||
$this->assembleElements();
|
||||
$this->assembleSubmitButton();
|
||||
$this->addElement($this->createCsrfCounterMeasure(Session::getSession()->getId()));
|
||||
}
|
||||
|
||||
protected function onSuccess()
|
||||
{
|
||||
$errors = [];
|
||||
foreach ($this->getObjects() as $object) {
|
||||
$commands = $this->getCommand($object);
|
||||
if ($commands === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($commands instanceof IcingaCommand) {
|
||||
$commands = [$commands];
|
||||
}
|
||||
|
||||
foreach ($commands as $command) {
|
||||
try {
|
||||
$this->sendCommand($command);
|
||||
} catch (Exception $e) {
|
||||
Logger::error($e->getMessage());
|
||||
$errors[] = $e->getMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (! empty($errors)) {
|
||||
if (count($errors) > 1) {
|
||||
Notification::warning(
|
||||
t('Some commands were not transmitted. Please check the log. The first error follows.')
|
||||
);
|
||||
}
|
||||
|
||||
Notification::error($errors[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Transmit the given command
|
||||
*
|
||||
* @param IcingaCommand $command
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function sendCommand(IcingaCommand $command)
|
||||
{
|
||||
(new CommandTransport())->send($command);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Forms\Command\Instance;
|
||||
|
||||
use Icinga\Module\Icingadb\Command\Instance\ToggleInstanceFeatureCommand;
|
||||
use Icinga\Module\Icingadb\Common\Auth;
|
||||
use Icinga\Module\Icingadb\Forms\Command\CommandForm;
|
||||
use ipl\Orm\Model;
|
||||
use ipl\Web\FormDecorator\IcingaFormDecorator;
|
||||
|
||||
class ToggleInstanceFeaturesForm extends CommandForm
|
||||
{
|
||||
use Auth;
|
||||
|
||||
protected $features;
|
||||
|
||||
protected $featureStatus;
|
||||
|
||||
public function __construct($featureStatus)
|
||||
{
|
||||
$this->featureStatus = $featureStatus;
|
||||
$this->features = [
|
||||
ToggleInstanceFeatureCommand::FEATURE_ACTIVE_HOST_CHECKS =>
|
||||
t('Active Host Checks'),
|
||||
ToggleInstanceFeatureCommand::FEATURE_ACTIVE_SERVICE_CHECKS =>
|
||||
t('Active Service Checks'),
|
||||
ToggleInstanceFeatureCommand::FEATURE_EVENT_HANDLERS =>
|
||||
t('Event Handlers'),
|
||||
ToggleInstanceFeatureCommand::FEATURE_FLAP_DETECTION =>
|
||||
t('Flap Detection'),
|
||||
ToggleInstanceFeatureCommand::FEATURE_NOTIFICATIONS =>
|
||||
t('Notifications'),
|
||||
ToggleInstanceFeatureCommand::FEATURE_PERFORMANCE_DATA =>
|
||||
t('Performance Data')
|
||||
];
|
||||
|
||||
$this->getAttributes()->add('class', 'instance-features');
|
||||
}
|
||||
|
||||
protected function assembleElements()
|
||||
{
|
||||
$disabled = ! $this->getAuth()->hasPermission('monitoring/command/feature/instance');
|
||||
$decorator = new IcingaFormDecorator();
|
||||
|
||||
foreach ($this->features as $feature => $label) {
|
||||
$this->addElement(
|
||||
'checkbox',
|
||||
$feature,
|
||||
[
|
||||
'class' => 'autosubmit',
|
||||
'label' => $label,
|
||||
'disabled' => $disabled,
|
||||
'value' => (bool) $this->featureStatus[$feature]
|
||||
]
|
||||
);
|
||||
$decorator->decorate($this->getElement($feature));
|
||||
}
|
||||
}
|
||||
|
||||
protected function assembleSubmitButton()
|
||||
{
|
||||
}
|
||||
|
||||
protected function getCommand(Model $object)
|
||||
{
|
||||
foreach ($this->features as $feature => $spec) {
|
||||
$featureState = $this->getElement($feature)->isChecked();
|
||||
|
||||
if ((int) $featureState === (int) $this->featureStatus[$feature]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$command = new ToggleInstanceFeatureCommand();
|
||||
$command->setFeature($feature);
|
||||
$command->setEnabled((int) $featureState);
|
||||
|
||||
yield $command;
|
||||
}
|
||||
}
|
||||
}
|
||||
159
application/forms/Command/Object/AcknowledgeProblemForm.php
Normal file
159
application/forms/Command/Object/AcknowledgeProblemForm.php
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Forms\Command\Object;
|
||||
|
||||
use DateInterval;
|
||||
use DateTime;
|
||||
use Icinga\Application\Config;
|
||||
use Icinga\Module\Icingadb\Command\Object\AcknowledgeProblemCommand;
|
||||
use Icinga\Module\Icingadb\Common\Auth;
|
||||
use Icinga\Module\Icingadb\Forms\Command\CommandForm;
|
||||
use ipl\Html\HtmlElement;
|
||||
use ipl\Orm\Model;
|
||||
use ipl\Web\FormDecorator\IcingaFormDecorator;
|
||||
use ipl\Web\Widget\Icon;
|
||||
|
||||
class AcknowledgeProblemForm extends CommandForm
|
||||
{
|
||||
use Auth;
|
||||
|
||||
protected function assembleElements()
|
||||
{
|
||||
$this->add(new HtmlElement('div', ['class' => 'form-description'], [
|
||||
new Icon('info-circle', ['class' => 'form-description-icon']),
|
||||
new HtmlElement('ul', null, [
|
||||
new HtmlElement('li', null, t(
|
||||
'This command is used to acknowledge host or service problems. When a problem is acknowledged,'
|
||||
. ' future notifications about problems are temporarily disabled until the host or service'
|
||||
. ' recovers.'
|
||||
))
|
||||
])
|
||||
]));
|
||||
|
||||
$config = Config::module('icingadb');
|
||||
$decorator = new IcingaFormDecorator();
|
||||
|
||||
$this->addElement(
|
||||
'textarea',
|
||||
'comment',
|
||||
[
|
||||
'required' => true,
|
||||
'label' => t('Comment'),
|
||||
'description' => t(
|
||||
'If you work with other administrators, you may find it useful to share information about'
|
||||
. ' the host or service that is having problems. Make sure you enter a brief description of'
|
||||
. ' what you are doing.'
|
||||
)
|
||||
]
|
||||
);
|
||||
$decorator->decorate($this->getElement('comment'));
|
||||
|
||||
$this->addElement(
|
||||
'checkbox',
|
||||
'persistent',
|
||||
[
|
||||
'label' => t('Persistent Comment'),
|
||||
'value' => (bool) $config->get('settings', 'acknowledge_persistent', false),
|
||||
'description' => t(
|
||||
'If you want the comment to remain even when the acknowledgement is removed, check this'
|
||||
. ' option.'
|
||||
)
|
||||
]
|
||||
);
|
||||
$decorator->decorate($this->getElement('persistent'));
|
||||
|
||||
$this->addElement(
|
||||
'checkbox',
|
||||
'notify',
|
||||
[
|
||||
'label' => t('Send Notification'),
|
||||
'value' => (bool) $config->get('settings', 'acknowledge_notify', true),
|
||||
'description' => t(
|
||||
'If you want an acknowledgement notification to be sent out to the appropriate contacts,'
|
||||
. ' check this option.'
|
||||
)
|
||||
]
|
||||
);
|
||||
$decorator->decorate($this->getElement('notify'));
|
||||
|
||||
$this->addElement(
|
||||
'checkbox',
|
||||
'sticky',
|
||||
[
|
||||
'label' => t('Sticky Acknowledgement'),
|
||||
'value' => (bool) $config->get('settings', 'acknowledge_sticky', false),
|
||||
'description' => t(
|
||||
'If you want the acknowledgement to remain until the host or service recovers even if the host'
|
||||
. ' or service changes state, check this option.'
|
||||
)
|
||||
]
|
||||
);
|
||||
$decorator->decorate($this->getElement('sticky'));
|
||||
|
||||
$acknowledgeExpire = (bool) $config->get('settings', 'acknowledge_expire', false);
|
||||
|
||||
$this->addElement(
|
||||
'checkbox',
|
||||
'expire',
|
||||
[
|
||||
'ignore' => true,
|
||||
'class' => 'autosubmit',
|
||||
'value' => $acknowledgeExpire,
|
||||
'label' => t('Use Expire Time'),
|
||||
'description' => t('If the acknowledgement should expire, check this option.')
|
||||
]
|
||||
);
|
||||
$decorator->decorate($this->getElement('expire'));
|
||||
|
||||
if ($acknowledgeExpire || $this->getPopulatedValue('expire') === 'y') {
|
||||
$expireTime = new DateTime();
|
||||
$expireTime->add(new DateInterval($config->get('settings', 'acknowledge_expire_time', 'PT1H')));
|
||||
|
||||
$this->addElement(
|
||||
'localDateTime',
|
||||
'expire_time',
|
||||
[
|
||||
'required' => true,
|
||||
'value' => $expireTime,
|
||||
'label' => t('Expire Time'),
|
||||
'description' => t('Choose the date and time when Icinga should delete the acknowledgement.')
|
||||
]
|
||||
);
|
||||
$decorator->decorate($this->getElement('expire_time'));
|
||||
}
|
||||
}
|
||||
|
||||
protected function assembleSubmitButton()
|
||||
{
|
||||
$this->addElement(
|
||||
'submit',
|
||||
'btn_submit',
|
||||
[
|
||||
'required' => true,
|
||||
'label' => tp('Acknowledge problem', 'Acknowledge problems', count($this->getObjects()))
|
||||
]
|
||||
);
|
||||
|
||||
(new IcingaFormDecorator())->decorate($this->getElement('btn_submit'));
|
||||
}
|
||||
|
||||
protected function getCommand(Model $object)
|
||||
{
|
||||
$command = new AcknowledgeProblemCommand();
|
||||
$command->setObject($object);
|
||||
$command->setComment($this->getValue('comment'));
|
||||
$command->setAuthor($this->getAuth()->getUser()->getUsername());
|
||||
$command->setNotify($this->getElement('notify')->isChecked());
|
||||
$command->setSticky($this->getElement('sticky')->isChecked());
|
||||
$command->setPersistent($this->getElement('persistent')->isChecked());
|
||||
|
||||
if (($expireTime = $this->getValue('expire_time')) !== null) {
|
||||
/** @var DateTime $expireTime */
|
||||
$command->setExpireTime($expireTime->getTimestamp());
|
||||
}
|
||||
|
||||
return $command;
|
||||
}
|
||||
}
|
||||
110
application/forms/Command/Object/AddCommentForm.php
Normal file
110
application/forms/Command/Object/AddCommentForm.php
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Forms\Command\Object;
|
||||
|
||||
use DateInterval;
|
||||
use DateTime;
|
||||
use Icinga\Application\Config;
|
||||
use Icinga\Module\Icingadb\Command\Object\AddCommentCommand;
|
||||
use Icinga\Module\Icingadb\Common\Auth;
|
||||
use Icinga\Module\Icingadb\Forms\Command\CommandForm;
|
||||
use ipl\Html\HtmlElement;
|
||||
use ipl\Orm\Model;
|
||||
use ipl\Web\FormDecorator\IcingaFormDecorator;
|
||||
use ipl\Web\Widget\Icon;
|
||||
|
||||
class AddCommentForm extends CommandForm
|
||||
{
|
||||
use Auth;
|
||||
|
||||
protected function assembleElements()
|
||||
{
|
||||
$this->add(new HtmlElement('div', ['class' => 'form-description'], [
|
||||
new Icon('info-circle', ['class' => 'form-description-icon']),
|
||||
new HtmlElement('ul', null, [
|
||||
new HtmlElement('li', null, t('This command is used to add host or service comments.'))
|
||||
])
|
||||
]));
|
||||
|
||||
$decorator = new IcingaFormDecorator();
|
||||
|
||||
$this->addElement(
|
||||
'textarea',
|
||||
'comment',
|
||||
[
|
||||
'required' => true,
|
||||
'label' => t('Comment'),
|
||||
'description' => t(
|
||||
'If you work with other administrators, you may find it useful to share information about'
|
||||
. ' the host or service that is having problems. Make sure you enter a brief description of'
|
||||
. ' what you are doing.'
|
||||
)
|
||||
]
|
||||
);
|
||||
$decorator->decorate($this->getElement('comment'));
|
||||
|
||||
$config = Config::module('icingadb');
|
||||
$commentExpire = (bool) $config->get('settings', 'comment_expire', false);
|
||||
|
||||
$this->addElement(
|
||||
'checkbox',
|
||||
'expire',
|
||||
[
|
||||
'ignore' => true,
|
||||
'class' => 'autosubmit',
|
||||
'value' => $commentExpire,
|
||||
'label' => t('Use Expire Time'),
|
||||
'description' => t('If the comment should expire, check this option.')
|
||||
]
|
||||
);
|
||||
$decorator->decorate($this->getElement('expire'));
|
||||
|
||||
if ($commentExpire || $this->getPopulatedValue('expire') === 'y') {
|
||||
$expireTime = new DateTime();
|
||||
$expireTime->add(new DateInterval($config->get('settings', 'comment_expire_time', 'PT1H')));
|
||||
|
||||
$this->addElement(
|
||||
'localDateTime',
|
||||
'expire_time',
|
||||
[
|
||||
'required' => true,
|
||||
'value' => $expireTime,
|
||||
'label' => t('Expire Time'),
|
||||
'description' => t('Choose the date and time when Icinga should delete the comment.')
|
||||
]
|
||||
);
|
||||
$decorator->decorate($this->getElement('expire_time'));
|
||||
}
|
||||
}
|
||||
|
||||
protected function assembleSubmitButton()
|
||||
{
|
||||
$this->addElement(
|
||||
'submit',
|
||||
'btn_submit',
|
||||
[
|
||||
'required' => true,
|
||||
'label' => tp('Add comment', 'Add comments', count($this->getObjects()))
|
||||
]
|
||||
);
|
||||
|
||||
(new IcingaFormDecorator())->decorate($this->getElement('btn_submit'));
|
||||
}
|
||||
|
||||
protected function getCommand(Model $object)
|
||||
{
|
||||
$command = new AddCommentCommand();
|
||||
$command->setObject($object);
|
||||
$command->setComment($this->getValue('comment'));
|
||||
$command->setAuthor($this->getAuth()->getUser()->getUsername());
|
||||
|
||||
if (($expireTime = $this->getValue('expire_time'))) {
|
||||
/** @var DateTime $expireTime */
|
||||
$command->setExpireTime($expireTime->getTimestamp());
|
||||
}
|
||||
|
||||
return $command;
|
||||
}
|
||||
}
|
||||
63
application/forms/Command/Object/CheckNowForm.php
Normal file
63
application/forms/Command/Object/CheckNowForm.php
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Forms\Command\Object;
|
||||
|
||||
use Icinga\Module\Icingadb\Command\Object\ScheduleCheckCommand;
|
||||
use Icinga\Module\Icingadb\Common\Auth;
|
||||
use Icinga\Module\Icingadb\Forms\Command\CommandForm;
|
||||
use Icinga\Web\Notification;
|
||||
use ipl\Orm\Model;
|
||||
use ipl\Web\Widget\Icon;
|
||||
|
||||
class CheckNowForm extends CommandForm
|
||||
{
|
||||
use Auth;
|
||||
|
||||
protected $defaultAttributes = ['class' => 'inline'];
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->on(self::ON_SUCCESS, function () {
|
||||
Notification::success(tp('Scheduling check..', 'Scheduling checks..', count($this->getObjects())));
|
||||
});
|
||||
}
|
||||
|
||||
protected function assembleElements()
|
||||
{
|
||||
}
|
||||
|
||||
protected function assembleSubmitButton()
|
||||
{
|
||||
$this->addElement(
|
||||
'submitButton',
|
||||
'btn_submit',
|
||||
[
|
||||
'class' => ['link-button', 'spinner'],
|
||||
'label' => [
|
||||
new Icon('sync-alt'),
|
||||
t('Check Now')
|
||||
],
|
||||
'title' => t('Schedule the next active check to run immediately')
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
protected function getCommand(Model $object)
|
||||
{
|
||||
if (
|
||||
! $object->active_checks_enabled
|
||||
&& ! $this->getAuth()->hasPermission('monitoring/command/schedule-check')
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$command = new ScheduleCheckCommand();
|
||||
$command->setObject($object);
|
||||
$command->setCheckTime(time());
|
||||
$command->setForced();
|
||||
|
||||
return $command;
|
||||
}
|
||||
}
|
||||
47
application/forms/Command/Object/DeleteCommentForm.php
Normal file
47
application/forms/Command/Object/DeleteCommentForm.php
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Forms\Command\Object;
|
||||
|
||||
use Icinga\Module\Icingadb\Command\Object\DeleteCommentCommand;
|
||||
use Icinga\Module\Icingadb\Common\Auth;
|
||||
use Icinga\Module\Icingadb\Forms\Command\CommandForm;
|
||||
use ipl\Orm\Model;
|
||||
use ipl\Web\Common\RedirectOption;
|
||||
use ipl\Web\Widget\Icon;
|
||||
|
||||
class DeleteCommentForm extends CommandForm
|
||||
{
|
||||
use Auth;
|
||||
use RedirectOption;
|
||||
|
||||
protected function assembleElements()
|
||||
{
|
||||
$this->addElement($this->createRedirectOption());
|
||||
}
|
||||
|
||||
protected function assembleSubmitButton()
|
||||
{
|
||||
$this->addElement(
|
||||
'submitButton',
|
||||
'btn_submit',
|
||||
[
|
||||
'class' => ['cancel-button', 'spinner'],
|
||||
'label' => [
|
||||
new Icon('trash'),
|
||||
tp('Remove Comment', 'Remove Comments', count($this->getObjects()))
|
||||
]
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
protected function getCommand(Model $object)
|
||||
{
|
||||
$command = new DeleteCommentCommand();
|
||||
$command->setCommentName($object->name);
|
||||
$command->setAuthor($this->getAuth()->getUser()->getUsername());
|
||||
|
||||
return $command;
|
||||
}
|
||||
}
|
||||
49
application/forms/Command/Object/DeleteDowntimeForm.php
Normal file
49
application/forms/Command/Object/DeleteDowntimeForm.php
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Forms\Command\Object;
|
||||
|
||||
use Icinga\Module\Icingadb\Command\Object\DeleteDowntimeCommand;
|
||||
use Icinga\Module\Icingadb\Common\Auth;
|
||||
use Icinga\Module\Icingadb\Forms\Command\CommandForm;
|
||||
use ipl\Orm\Model;
|
||||
use ipl\Web\Common\RedirectOption;
|
||||
use ipl\Web\Widget\Icon;
|
||||
|
||||
class DeleteDowntimeForm extends CommandForm
|
||||
{
|
||||
use Auth;
|
||||
use RedirectOption;
|
||||
|
||||
protected $defaultAttributes = ['class' => 'inline'];
|
||||
|
||||
protected function assembleElements()
|
||||
{
|
||||
$this->addElement($this->createRedirectOption());
|
||||
}
|
||||
|
||||
protected function assembleSubmitButton()
|
||||
{
|
||||
$this->addElement(
|
||||
'submitButton',
|
||||
'btn_submit',
|
||||
[
|
||||
'class' => ['cancel-button', 'spinner'],
|
||||
'label' => [
|
||||
new Icon('trash'),
|
||||
tp('Delete downtime', 'Delete donwtimes', count($this->getObjects()))
|
||||
]
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
protected function getCommand(Model $object)
|
||||
{
|
||||
$command = new DeleteDowntimeCommand();
|
||||
$command->setDowntimeName($object->name);
|
||||
$command->setAuthor($this->getAuth()->getUser()->getUsername());
|
||||
|
||||
return $command;
|
||||
}
|
||||
}
|
||||
111
application/forms/Command/Object/ProcessCheckResultForm.php
Normal file
111
application/forms/Command/Object/ProcessCheckResultForm.php
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Forms\Command\Object;
|
||||
|
||||
use Icinga\Module\Icingadb\Command\Object\ProcessCheckResultCommand;
|
||||
use Icinga\Module\Icingadb\Forms\Command\CommandForm;
|
||||
use Icinga\Module\Icingadb\Model\Host;
|
||||
use ipl\Html\HtmlElement;
|
||||
use ipl\Orm\Model;
|
||||
use ipl\Web\FormDecorator\IcingaFormDecorator;
|
||||
use ipl\Web\Widget\Icon;
|
||||
|
||||
class ProcessCheckResultForm extends CommandForm
|
||||
{
|
||||
protected function assembleElements()
|
||||
{
|
||||
$this->add(new HtmlElement('div', ['class' => 'form-description'], [
|
||||
new Icon('info-circle', ['class' => 'form-description-icon']),
|
||||
new HtmlElement('ul', null, [
|
||||
new HtmlElement('li', null, t(
|
||||
'This command is used to submit passive host or service check results.'
|
||||
))
|
||||
])
|
||||
]));
|
||||
|
||||
$decorator = new IcingaFormDecorator();
|
||||
|
||||
foreach ($this->getObjects() as $object) {
|
||||
/** @var Model $object */
|
||||
// Nasty, but as getObjects() returns everything but an object with a real
|
||||
// iterator interface this is the only way to fetch just the first element
|
||||
break;
|
||||
}
|
||||
|
||||
$this->addElement(
|
||||
'select',
|
||||
'status',
|
||||
[
|
||||
'required' => true,
|
||||
'label' => t('Status'),
|
||||
'description' => t('The state this check result should report'),
|
||||
'multiOptions' => $object instanceof Host ? [
|
||||
ProcessCheckResultCommand::HOST_UP => t('UP', 'icinga.state'),
|
||||
ProcessCheckResultCommand::HOST_DOWN => t('DOWN', 'icinga.state')
|
||||
] : [
|
||||
ProcessCheckResultCommand::SERVICE_OK => t('OK', 'icinga.state'),
|
||||
ProcessCheckResultCommand::SERVICE_WARNING => t('WARNING', 'icinga.state'),
|
||||
ProcessCheckResultCommand::SERVICE_CRITICAL => t('CRITICAL', 'icinga.state'),
|
||||
ProcessCheckResultCommand::SERVICE_UNKNOWN => t('UNKNOWN', 'icinga.state')
|
||||
]
|
||||
]
|
||||
);
|
||||
$decorator->decorate($this->getElement('status'));
|
||||
|
||||
$this->addElement(
|
||||
'text',
|
||||
'output',
|
||||
[
|
||||
'required' => true,
|
||||
'label' => t('Output'),
|
||||
'description' => t('The plugin output of this check result')
|
||||
]
|
||||
);
|
||||
$decorator->decorate($this->getElement('output'));
|
||||
|
||||
$this->addElement(
|
||||
'text',
|
||||
'perfdata',
|
||||
[
|
||||
'allowEmpty' => true,
|
||||
'label' => t('Performance Data'),
|
||||
'description' => t(
|
||||
'The performance data of this check result. Leave empty'
|
||||
. ' if this check result has no performance data'
|
||||
)
|
||||
]
|
||||
);
|
||||
$decorator->decorate($this->getElement('perfdata'));
|
||||
}
|
||||
|
||||
protected function assembleSubmitButton()
|
||||
{
|
||||
$this->addElement(
|
||||
'submit',
|
||||
'btn_submit',
|
||||
[
|
||||
'required' => true,
|
||||
'label' => tp(
|
||||
'Submit Passive Check Result',
|
||||
'Submit Passive Check Results',
|
||||
count($this->getObjects())
|
||||
)
|
||||
]
|
||||
);
|
||||
|
||||
(new IcingaFormDecorator())->decorate($this->getElement('btn_submit'));
|
||||
}
|
||||
|
||||
protected function getCommand(Model $object)
|
||||
{
|
||||
$command = new ProcessCheckResultCommand();
|
||||
$command->setObject($object);
|
||||
$command->setStatus($this->getValue('status'));
|
||||
$command->setOutput($this->getValue('output'));
|
||||
$command->setPerformanceData($this->getValue('perfdata'));
|
||||
|
||||
return $command;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Forms\Command\Object;
|
||||
|
||||
use Icinga\Module\Icingadb\Command\Object\RemoveAcknowledgementCommand;
|
||||
use Icinga\Module\Icingadb\Common\Auth;
|
||||
use Icinga\Module\Icingadb\Forms\Command\CommandForm;
|
||||
use ipl\Orm\Model;
|
||||
use ipl\Web\Widget\Icon;
|
||||
|
||||
class RemoveAcknowledgementForm extends CommandForm
|
||||
{
|
||||
use Auth;
|
||||
|
||||
protected $defaultAttributes = ['class' => 'inline'];
|
||||
|
||||
protected function assembleElements()
|
||||
{
|
||||
}
|
||||
|
||||
protected function assembleSubmitButton()
|
||||
{
|
||||
$this->addElement(
|
||||
'submitButton',
|
||||
'btn_submit',
|
||||
[
|
||||
'class' => ['link-button', 'spinner'],
|
||||
'label' => [
|
||||
new Icon('trash'),
|
||||
tp('Remove acknowledgement', 'Remove acknowledgements', count($this->getObjects()))
|
||||
]
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
protected function getCommand(Model $object)
|
||||
{
|
||||
$command = new RemoveAcknowledgementCommand();
|
||||
$command->setObject($object);
|
||||
$command->setAuthor($this->getAuth()->getUser()->getUsername());
|
||||
|
||||
return $command;
|
||||
}
|
||||
}
|
||||
81
application/forms/Command/Object/ScheduleCheckForm.php
Normal file
81
application/forms/Command/Object/ScheduleCheckForm.php
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Forms\Command\Object;
|
||||
|
||||
use DateInterval;
|
||||
use DateTime;
|
||||
use Icinga\Module\Icingadb\Command\Object\ScheduleCheckCommand;
|
||||
use Icinga\Module\Icingadb\Forms\Command\CommandForm;
|
||||
use ipl\Html\HtmlElement;
|
||||
use ipl\Orm\Model;
|
||||
use ipl\Web\FormDecorator\IcingaFormDecorator;
|
||||
use ipl\Web\Widget\Icon;
|
||||
|
||||
class ScheduleCheckForm extends CommandForm
|
||||
{
|
||||
protected function assembleElements()
|
||||
{
|
||||
$this->add(new HtmlElement('div', ['class' => 'form-description'], [
|
||||
new Icon('info-circle', ['class' => 'form-description-icon']),
|
||||
new HtmlElement('ul', null, [
|
||||
new HtmlElement('li', null, t(
|
||||
'This command is used to schedule the next check of hosts or services. Icinga'
|
||||
. ' will re-queue the hosts or services to be checked at the time you specify.'
|
||||
))
|
||||
])
|
||||
]));
|
||||
|
||||
$decorator = new IcingaFormDecorator();
|
||||
|
||||
$this->addElement(
|
||||
'localDateTime',
|
||||
'check_time',
|
||||
[
|
||||
'required' => true,
|
||||
'label' => t('Check Time'),
|
||||
'description' => t('Set the date and time when the check should be scheduled.'),
|
||||
'value' => (new DateTime())->add(new DateInterval('PT1H'))
|
||||
]
|
||||
);
|
||||
$decorator->decorate($this->getElement('check_time'));
|
||||
|
||||
$this->addElement(
|
||||
'checkbox',
|
||||
'force_check',
|
||||
[
|
||||
'label' => t('Force Check'),
|
||||
'description' => t(
|
||||
'If you select this option, Icinga will force a check regardless of both what time the'
|
||||
. ' scheduled check occurs and whether or not checks are enabled.'
|
||||
)
|
||||
]
|
||||
);
|
||||
$decorator->decorate($this->getElement('force_check'));
|
||||
}
|
||||
|
||||
protected function assembleSubmitButton()
|
||||
{
|
||||
$this->addElement(
|
||||
'submit',
|
||||
'btn_submit',
|
||||
[
|
||||
'required' => true,
|
||||
'label' => tp('Schedule check', 'Schedule checks', count($this->getObjects()))
|
||||
]
|
||||
);
|
||||
|
||||
(new IcingaFormDecorator())->decorate($this->getElement('btn_submit'));
|
||||
}
|
||||
|
||||
protected function getCommand(Model $object)
|
||||
{
|
||||
$command = new ScheduleCheckCommand();
|
||||
$command->setObject($object);
|
||||
$command->setForced($this->getElement('force_check')->isChecked());
|
||||
$command->setCheckTime($this->getValue('check_time')->getTimestamp());
|
||||
|
||||
return $command;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Forms\Command\Object;
|
||||
|
||||
use Icinga\Application\Config;
|
||||
use Icinga\Module\Icingadb\Command\Object\PropagateHostDowntimeCommand;
|
||||
use Icinga\Module\Icingadb\Command\Object\ScheduleHostDowntimeCommand;
|
||||
use ipl\Orm\Model;
|
||||
use ipl\Web\FormDecorator\IcingaFormDecorator;
|
||||
|
||||
class ScheduleHostDowntimeForm extends ScheduleServiceDowntimeForm
|
||||
{
|
||||
protected function assembleElements()
|
||||
{
|
||||
parent::assembleElements();
|
||||
|
||||
$decorator = new IcingaFormDecorator();
|
||||
$config = Config::module('icingadb');
|
||||
|
||||
$this->addElement(
|
||||
'checkbox',
|
||||
'all_services',
|
||||
[
|
||||
'label' => t('All Services'),
|
||||
'description' => t(
|
||||
'Sets downtime for all services for the matched host objects. If child options are set,'
|
||||
. ' all child hosts and their services will schedule a downtime too.'
|
||||
),
|
||||
'value' => (bool) $config->get('settings', 'hostdowntime_all_services', false)
|
||||
]
|
||||
);
|
||||
$decorator->decorate($this->getElement('all_services'));
|
||||
|
||||
$this->addElement(
|
||||
'select',
|
||||
'child_options',
|
||||
array(
|
||||
'description' => t('Schedule child downtimes.'),
|
||||
'label' => t('Child Options'),
|
||||
'multiOptions' => [
|
||||
0 => t('Do nothing with child hosts'),
|
||||
1 => t('Schedule triggered downtime for all child hosts'),
|
||||
2 => t('Schedule non-triggered downtime for all child hosts')
|
||||
]
|
||||
)
|
||||
);
|
||||
$decorator->decorate($this->getElement('child_options'));
|
||||
}
|
||||
|
||||
protected function getCommand(Model $object)
|
||||
{
|
||||
if (($childOptions = (int) $this->getValue('child_options'))) {
|
||||
$command = new PropagateHostDowntimeCommand();
|
||||
$command->setTriggered($childOptions === 1);
|
||||
} else {
|
||||
$command = new ScheduleHostDowntimeCommand();
|
||||
}
|
||||
|
||||
$command->setObject($object);
|
||||
$command->setComment($this->getValue('comment'));
|
||||
$command->setAuthor($this->getAuth()->getUser()->getUsername());
|
||||
$command->setStart($this->getValue('start')->getTimestamp());
|
||||
$command->setEnd($this->getValue('end')->getTimestamp());
|
||||
$command->setForAllServices($this->getElement('all_services')->isChecked());
|
||||
|
||||
if ($this->getElement('flexible')->isChecked()) {
|
||||
$command->setFixed(false);
|
||||
$command->setDuration(
|
||||
$this->getValue('hours') * 3600 + $this->getValue('minutes') * 60
|
||||
);
|
||||
}
|
||||
|
||||
return $command;
|
||||
}
|
||||
}
|
||||
178
application/forms/Command/Object/ScheduleServiceDowntimeForm.php
Normal file
178
application/forms/Command/Object/ScheduleServiceDowntimeForm.php
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Forms\Command\Object;
|
||||
|
||||
use DateInterval;
|
||||
use DateTime;
|
||||
use Icinga\Module\Icingadb\Command\Object\ScheduleServiceDowntimeCommand;
|
||||
use Icinga\Module\Icingadb\Common\Auth;
|
||||
use Icinga\Module\Icingadb\Forms\Command\CommandForm;
|
||||
use ipl\Html\HtmlElement;
|
||||
use ipl\Orm\Model;
|
||||
use ipl\Validator\CallbackValidator;
|
||||
use ipl\Web\FormDecorator\IcingaFormDecorator;
|
||||
use ipl\Web\Widget\Icon;
|
||||
|
||||
class ScheduleServiceDowntimeForm extends CommandForm
|
||||
{
|
||||
use Auth;
|
||||
|
||||
protected function assembleElements()
|
||||
{
|
||||
$this->add(new HtmlElement('div', ['class' => 'form-description'], [
|
||||
new Icon('info-circle', ['class' => 'form-description-icon']),
|
||||
new HtmlElement('ul', null, [
|
||||
new HtmlElement('li', null, t(
|
||||
'This command is used to schedule host and service downtimes. During the downtime specified'
|
||||
. ' by the start and end time, Icinga will not send notifications out about the hosts and'
|
||||
. ' services. When the scheduled downtime expires, Icinga will send out notifications for'
|
||||
. ' the hosts and services as it normally would.'
|
||||
))
|
||||
])
|
||||
]));
|
||||
|
||||
$decorator = new IcingaFormDecorator();
|
||||
|
||||
$this->addElement(
|
||||
'textarea',
|
||||
'comment',
|
||||
[
|
||||
'required' => true,
|
||||
'label' => t('Comment'),
|
||||
'description' => t(
|
||||
'If you work with other administrators, you may find it useful to share information about'
|
||||
. ' the host or service that is having problems. Make sure you enter a brief description of'
|
||||
. ' what you are doing.'
|
||||
)
|
||||
]
|
||||
);
|
||||
$decorator->decorate($this->getElement('comment'));
|
||||
|
||||
$this->addElement(
|
||||
'localDateTime',
|
||||
'start',
|
||||
[
|
||||
'required' => true,
|
||||
'value' => new DateTime(),
|
||||
'label' => t('Start Time'),
|
||||
'description' => t('Set the start date and time for the downtime.')
|
||||
]
|
||||
);
|
||||
$decorator->decorate($this->getElement('start'));
|
||||
|
||||
$this->addElement(
|
||||
'localDateTime',
|
||||
'end',
|
||||
[
|
||||
'required' => true,
|
||||
'label' => t('End Time'),
|
||||
'description' => t('Set the end date and time for the downtime.'),
|
||||
'value' => (new DateTime())->add(new DateInterval('PT1H')),
|
||||
'validators' => ['Callback' => function ($value, $validator) {
|
||||
/** @var CallbackValidator $validator */
|
||||
|
||||
if ($value <= $this->getValue('start')) {
|
||||
$validator->addMessage(t('The end time must be greater than the start time'));
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($value <= (new DateTime())) {
|
||||
$validator->addMessage(t('A downtime must not be in the past'));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}]
|
||||
]
|
||||
);
|
||||
$decorator->decorate($this->getElement('end'));
|
||||
|
||||
$this->addElement(
|
||||
'checkbox',
|
||||
'flexible',
|
||||
[
|
||||
'class' => 'autosubmit',
|
||||
'label' => t('Flexible'),
|
||||
'description' => t(
|
||||
'To make this a flexible downtime, check this option. A flexible downtime starts when the host'
|
||||
. ' or service enters a problem state sometime between the start and end times you specified.'
|
||||
. ' It then lasts as long as the duration time you enter.'
|
||||
)
|
||||
]
|
||||
);
|
||||
$decorator->decorate($this->getElement('flexible'));
|
||||
|
||||
if ($this->getPopulatedValue('flexible') === 'y') {
|
||||
$hoursInput = $this->createElement(
|
||||
'number',
|
||||
'hours',
|
||||
[
|
||||
'required' => true,
|
||||
'label' => t('Duration'),
|
||||
'value' => 2,
|
||||
'min' => 0
|
||||
]
|
||||
);
|
||||
$this->registerElement($hoursInput);
|
||||
$decorator->decorate($hoursInput);
|
||||
|
||||
$minutesInput = $this->createElement(
|
||||
'number',
|
||||
'minutes',
|
||||
[
|
||||
'required' => true,
|
||||
'value' => 0,
|
||||
'min' => 0
|
||||
]
|
||||
);
|
||||
$this->registerElement($minutesInput);
|
||||
$minutesInput->addWrapper(
|
||||
new HtmlElement('label', null, new HtmlElement('span', null, t('Minutes')))
|
||||
);
|
||||
|
||||
$hoursInput->getWrapper()
|
||||
->add($minutesInput)
|
||||
->getAttributes()->add('class', 'downtime-duration');
|
||||
$hoursInput->prependWrapper(
|
||||
new HtmlElement('label', null, new HtmlElement('span', null, t('Hours')))
|
||||
);
|
||||
|
||||
$this->add($hoursInput);
|
||||
}
|
||||
}
|
||||
|
||||
protected function assembleSubmitButton()
|
||||
{
|
||||
$this->addElement(
|
||||
'submit',
|
||||
'btn_submit',
|
||||
[
|
||||
'required' => true,
|
||||
'label' => tp('Schedule downtime', 'Schedule downtimes', count($this->getObjects()))
|
||||
]
|
||||
);
|
||||
|
||||
(new IcingaFormDecorator())->decorate($this->getElement('btn_submit'));
|
||||
}
|
||||
|
||||
protected function getCommand(Model $object)
|
||||
{
|
||||
$command = new ScheduleServiceDowntimeCommand();
|
||||
$command->setObject($object);
|
||||
$command->setComment($this->getValue('comment'));
|
||||
$command->setAuthor($this->getAuth()->getUser()->getUsername());
|
||||
$command->setStart($this->getValue('start')->getTimestamp());
|
||||
$command->setEnd($this->getValue('end')->getTimestamp());
|
||||
|
||||
if ($this->getElement('flexible')->isChecked()) {
|
||||
$command->setFixed(false);
|
||||
$command->setDuration(
|
||||
$this->getValue('hours') * 3600 + $this->getValue('minutes') * 60
|
||||
);
|
||||
}
|
||||
|
||||
return $command;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Forms\Command\Object;
|
||||
|
||||
use Icinga\Application\Config;
|
||||
use Icinga\Module\Icingadb\Command\Object\SendCustomNotificationCommand;
|
||||
use Icinga\Module\Icingadb\Common\Auth;
|
||||
use Icinga\Module\Icingadb\Forms\Command\CommandForm;
|
||||
use ipl\Html\HtmlElement;
|
||||
use ipl\Orm\Model;
|
||||
use ipl\Web\FormDecorator\IcingaFormDecorator;
|
||||
use ipl\Web\Widget\Icon;
|
||||
|
||||
class SendCustomNotificationForm extends CommandForm
|
||||
{
|
||||
use Auth;
|
||||
|
||||
protected function assembleElements()
|
||||
{
|
||||
$this->add(new HtmlElement('div', ['class' => 'form-description'], [
|
||||
new Icon('info-circle', ['class' => 'form-description-icon']),
|
||||
new HtmlElement('ul', null, [
|
||||
new HtmlElement('li', null, t(
|
||||
'This command is used to send custom notifications about hosts or services.'
|
||||
))
|
||||
])
|
||||
]));
|
||||
|
||||
$config = Config::module('icingadb');
|
||||
$decorator = new IcingaFormDecorator();
|
||||
|
||||
$this->addElement(
|
||||
'textarea',
|
||||
'comment',
|
||||
[
|
||||
'required' => true,
|
||||
'label' => t('Comment'),
|
||||
'description' => t(
|
||||
'Enter a brief description on why you\'re sending this notification. It will be sent with it.'
|
||||
)
|
||||
]
|
||||
);
|
||||
$decorator->decorate($this->getElement('comment'));
|
||||
|
||||
$this->addElement(
|
||||
'checkbox',
|
||||
'forced',
|
||||
[
|
||||
'label' => t('Forced'),
|
||||
'value' => (bool) $config->get('settings', 'custom_notification_forced', false),
|
||||
'description' => t(
|
||||
'If you check this option, the notification is sent regardless'
|
||||
. ' of downtimes or whether notifications are enabled or not.'
|
||||
)
|
||||
]
|
||||
);
|
||||
$decorator->decorate($this->getElement('forced'));
|
||||
}
|
||||
|
||||
protected function assembleSubmitButton()
|
||||
{
|
||||
$this->addElement(
|
||||
'submit',
|
||||
'btn_submit',
|
||||
[
|
||||
'required' => true,
|
||||
'label' => tp('Send custom notification', 'Send custom notifications', count($this->getObjects()))
|
||||
]
|
||||
);
|
||||
|
||||
(new IcingaFormDecorator())->decorate($this->getElement('btn_submit'));
|
||||
}
|
||||
|
||||
protected function getCommand(Model $object)
|
||||
{
|
||||
$command = new SendCustomNotificationCommand();
|
||||
$command->setObject($object);
|
||||
$command->setComment($this->getValue('comment'));
|
||||
$command->setForced($this->getElement('forced')->isChecked());
|
||||
$command->setAuthor($this->getAuth()->getUser()->getUsername());
|
||||
|
||||
return $command;
|
||||
}
|
||||
}
|
||||
113
application/forms/Command/Object/ToggleObjectFeaturesForm.php
Normal file
113
application/forms/Command/Object/ToggleObjectFeaturesForm.php
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Forms\Command\Object;
|
||||
|
||||
use Icinga\Module\Icingadb\Command\Object\ToggleObjectFeatureCommand;
|
||||
use Icinga\Module\Icingadb\Common\Auth;
|
||||
use Icinga\Module\Icingadb\Forms\Command\CommandForm;
|
||||
use ipl\Orm\Model;
|
||||
use ipl\Web\FormDecorator\IcingaFormDecorator;
|
||||
|
||||
class ToggleObjectFeaturesForm extends CommandForm
|
||||
{
|
||||
use Auth;
|
||||
|
||||
const LEAVE_UNCHANGED = 'noop';
|
||||
|
||||
protected $features;
|
||||
|
||||
protected $featureStatus;
|
||||
|
||||
public function __construct($featureStatus)
|
||||
{
|
||||
$this->featureStatus = $featureStatus;
|
||||
$this->features = [
|
||||
ToggleObjectFeatureCommand::FEATURE_ACTIVE_CHECKS => [
|
||||
'label' => t('Active Checks'),
|
||||
'permission' => 'monitoring/command/feature/object/active-checks'
|
||||
],
|
||||
ToggleObjectFeatureCommand::FEATURE_PASSIVE_CHECKS => [
|
||||
'label' => t('Passive Checks'),
|
||||
'permission' => 'monitoring/command/feature/object/passive-checks'
|
||||
],
|
||||
ToggleObjectFeatureCommand::FEATURE_NOTIFICATIONS => [
|
||||
'label' => t('Notifications'),
|
||||
'permission' => 'monitoring/command/feature/object/notifications'
|
||||
],
|
||||
ToggleObjectFeatureCommand::FEATURE_EVENT_HANDLER => [
|
||||
'label' => t('Event Handler'),
|
||||
'permission' => 'monitoring/command/feature/object/event-handler'
|
||||
],
|
||||
ToggleObjectFeatureCommand::FEATURE_FLAP_DETECTION => [
|
||||
'label' => t('Flap Detection'),
|
||||
'permission' => 'monitoring/command/feature/object/flap-detection'
|
||||
]
|
||||
];
|
||||
|
||||
$this->getAttributes()->add('class', 'object-features');
|
||||
}
|
||||
|
||||
protected function assembleElements()
|
||||
{
|
||||
$decorator = new IcingaFormDecorator();
|
||||
foreach ($this->features as $feature => $spec) {
|
||||
$options = [
|
||||
'class' => 'autosubmit',
|
||||
'disabled' => ! $this->getAuth()->hasPermission($spec['permission']),
|
||||
'label' => $spec['label']
|
||||
];
|
||||
if ($this->featureStatus[$feature] === 2) {
|
||||
$this->addElement(
|
||||
'select',
|
||||
$feature,
|
||||
$options + [
|
||||
'description' => t('Multiple Values'),
|
||||
'options' => [
|
||||
self::LEAVE_UNCHANGED => t('Leave Unchanged'),
|
||||
t('Disable All'),
|
||||
t('Enable All')
|
||||
]
|
||||
]
|
||||
);
|
||||
$decorator->decorate($this->getElement($feature));
|
||||
|
||||
$this->getElement($feature)
|
||||
->getWrapper()
|
||||
->getAttributes()
|
||||
->add('class', 'indeterminate');
|
||||
} else {
|
||||
$options['value'] = (bool) $this->featureStatus[$feature];
|
||||
$this->addElement('checkbox', $feature, $options);
|
||||
$decorator->decorate($this->getElement($feature));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function assembleSubmitButton()
|
||||
{
|
||||
}
|
||||
|
||||
protected function getCommand(Model $object)
|
||||
{
|
||||
foreach ($this->features as $feature => $spec) {
|
||||
$featureState = $this->getElement($feature)->isChecked();
|
||||
|
||||
if (
|
||||
! $this->getAuth()->hasPermission($spec['permission'])
|
||||
|| $featureState === self::LEAVE_UNCHANGED
|
||||
|| (int) $featureState === (int) $this->featureStatus[$feature]
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$command = new ToggleObjectFeatureCommand();
|
||||
$command->setObject($object);
|
||||
$command->setFeature($feature);
|
||||
$command->setEnabled((int) $featureState);
|
||||
|
||||
yield $command;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2020 Icinga GmbH | GPLv2 */
|
||||
|
||||
/** @var \Icinga\Web\View $this */
|
||||
/** @var \Icinga\Module\Monitoring\Forms\Config\TransportReorderForm $form */
|
||||
?>
|
||||
<form id="<?= $form->getId() ?>" name="<?= $form->getName() ?>" enctype="<?= $form->getEncType() ?>"
|
||||
method="<?= $form->getMethod() ?>" action="<?= $form->getAction() ?>">
|
||||
<table class="table-row-selectable common-table" data-base-target="_next">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?= $this->translate('Transport') ?></th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
$i = -1;
|
||||
$transportConfig = $form->getConfig();
|
||||
$total = $transportConfig->count();
|
||||
foreach ($transportConfig as $transportName => $config):
|
||||
++$i;
|
||||
?>
|
||||
<tr>
|
||||
<td>
|
||||
<?= $this->qlink(
|
||||
$transportName,
|
||||
'icingadb/config/update-command-transport',
|
||||
['transport' => $transportName],
|
||||
[
|
||||
'icon' => 'edit',
|
||||
'title' => sprintf($this->translate('Update command transport %s'), $transportName)
|
||||
]
|
||||
); ?>
|
||||
<span class="config-label-meta">(<?= sprintf(
|
||||
$this->translate('Type: %s'),
|
||||
ucfirst($config->get('transport', 'local'))
|
||||
) ?>)
|
||||
</span>
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<?= $this->qlink(
|
||||
'',
|
||||
'icingadb/config/delete-command-transport',
|
||||
['transport' => $transportName],
|
||||
array(
|
||||
'class' => 'action-link',
|
||||
'icon' => 'cancel',
|
||||
'title' => sprintf($this->translate('Delete command transport %s'), $transportName)
|
||||
)
|
||||
); ?>
|
||||
</td>
|
||||
<td class="icon-col text-right" data-base-target="_self">
|
||||
<?php if ($i > 0): ?>
|
||||
<button type="submit" name="transport_newpos" class="link-button icon-only animated move-up"
|
||||
value="<?= $this->escape(($i - 1) . '|' . $transportName) ?>"
|
||||
title="<?= $this->translate('Move up in order') ?>"
|
||||
aria-label="<?= $this->escape(sprintf($this->translate('Move command transport %s upwards'), $transportName)) ?>">
|
||||
<?= $this->icon('up-small') ?>
|
||||
</button>
|
||||
<?php endif ?>
|
||||
<?php if ($i + 1 < $total): ?>
|
||||
<button type="submit" name="transport_newpos" class="link-button icon-only animated move-down"
|
||||
value="<?= $this->escape(($i + 1) . '|' . $transportName) ?>"
|
||||
title="<?= $this->translate('Move down in order') ?>"
|
||||
aria-label="<?= $this->escape(sprintf($this->translate('Move command transport %s downwards'), $transportName)) ?>">
|
||||
<?= $this->icon('down-small') ?>
|
||||
</button>
|
||||
<?php endif ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?= $form->getElement($form->getTokenElementName()) ?>
|
||||
<?= $form->getElement($form->getUidElementName()) ?>
|
||||
</form>
|
||||
|
|
@ -212,7 +212,7 @@ namespace Icinga\Module\Icingadb
|
|||
$this->provideConfigTab('command-transports', [
|
||||
'label' => t('Command Transports'),
|
||||
'title' => t('Configure command transports'),
|
||||
'url' => 'config/command-transports'
|
||||
'url' => 'command-transport'
|
||||
]);
|
||||
$this->provideConfigTab('security', [
|
||||
'label' => t('Security'),
|
||||
|
|
|
|||
85
library/Icingadb/Command/IcingaApiCommand.php
Normal file
85
library/Icingadb/Command/IcingaApiCommand.php
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Command;
|
||||
|
||||
class IcingaApiCommand
|
||||
{
|
||||
/**
|
||||
* Command data
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* Name of the endpoint
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $endpoint;
|
||||
|
||||
/**
|
||||
* Create a new Icinga 2 API command
|
||||
*
|
||||
* @param string $endpoint
|
||||
* @param array $data
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public static function create($endpoint, array $data)
|
||||
{
|
||||
return (new static())
|
||||
->setEndpoint($endpoint)
|
||||
->setData($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the command data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getData()
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the command data
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setData($data)
|
||||
{
|
||||
$this->data = $data;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the endpoint
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getEndpoint()
|
||||
{
|
||||
return $this->endpoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name of the endpoint
|
||||
*
|
||||
* @param string $endpoint
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setEndpoint($endpoint)
|
||||
{
|
||||
$this->endpoint = $endpoint;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
22
library/Icingadb/Command/IcingaCommand.php
Normal file
22
library/Icingadb/Command/IcingaCommand.php
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Command;
|
||||
|
||||
/**
|
||||
* Base class for commands sent to an Icinga instance
|
||||
*/
|
||||
abstract class IcingaCommand
|
||||
{
|
||||
/**
|
||||
* Get the name of the command
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
$nsParts = explode('\\', get_called_class());
|
||||
return substr_replace(end($nsParts), '', -7); // Remove 'Command' Suffix
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Command\Instance;
|
||||
|
||||
use Icinga\Module\Icingadb\Command\IcingaCommand;
|
||||
|
||||
/**
|
||||
* Enable or disable a feature of an Icinga instance
|
||||
*/
|
||||
class ToggleInstanceFeatureCommand extends IcingaCommand
|
||||
{
|
||||
/**
|
||||
* Feature for enabling or disabling active host checks on an Icinga instance
|
||||
*/
|
||||
const FEATURE_ACTIVE_HOST_CHECKS = 'active_host_checks_enabled';
|
||||
|
||||
/**
|
||||
* Feature for enabling or disabling active service checks on an Icinga instance
|
||||
*/
|
||||
const FEATURE_ACTIVE_SERVICE_CHECKS = 'active_service_checks_enabled';
|
||||
|
||||
/**
|
||||
* Feature for enabling or disabling host and service event handlers on an Icinga instance
|
||||
*/
|
||||
const FEATURE_EVENT_HANDLERS = 'event_handlers_enabled';
|
||||
|
||||
/**
|
||||
* Feature for enabling or disabling host and service flap detection on an Icinga instance
|
||||
*/
|
||||
const FEATURE_FLAP_DETECTION = 'flap_detection_enabled';
|
||||
|
||||
/**
|
||||
* Feature for enabling or disabling host and service notifications on an Icinga instance
|
||||
*/
|
||||
const FEATURE_NOTIFICATIONS = 'notifications_enabled';
|
||||
|
||||
/**
|
||||
* Feature for enabling or disabling the processing of host and service performance data on an Icinga instance
|
||||
*/
|
||||
const FEATURE_PERFORMANCE_DATA = 'process_performance_data';
|
||||
|
||||
/**
|
||||
* Feature that is to be enabled or disabled
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $feature;
|
||||
|
||||
/**
|
||||
* Whether the feature should be enabled or disabled
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $enabled;
|
||||
|
||||
/**
|
||||
* Set the feature that is to be enabled or disabled
|
||||
*
|
||||
* @param string $feature
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setFeature($feature)
|
||||
{
|
||||
$this->feature = (string) $feature;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the feature that is to be enabled or disabled
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFeature()
|
||||
{
|
||||
return $this->feature;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether the feature should be enabled or disabled
|
||||
*
|
||||
* @param bool $enabled
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setEnabled($enabled = true)
|
||||
{
|
||||
$this->enabled = (bool) $enabled;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether the feature should be enabled or disabled
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getEnabled()
|
||||
{
|
||||
return $this->enabled;
|
||||
}
|
||||
}
|
||||
140
library/Icingadb/Command/Object/AcknowledgeProblemCommand.php
Normal file
140
library/Icingadb/Command/Object/AcknowledgeProblemCommand.php
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Command\Object;
|
||||
|
||||
/**
|
||||
* Acknowledge a host or service problem
|
||||
*/
|
||||
class AcknowledgeProblemCommand extends WithCommentCommand
|
||||
{
|
||||
/**
|
||||
* Whether the acknowledgement is sticky
|
||||
*
|
||||
* Sticky acknowledgements remain until the host or service recovers. Non-sticky acknowledgements will be
|
||||
* automatically removed when the host or service state changes.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $sticky = false;
|
||||
|
||||
/**
|
||||
* Whether to send a notification about the acknowledgement
|
||||
|
||||
* @var bool
|
||||
*/
|
||||
protected $notify = false;
|
||||
|
||||
/**
|
||||
* Whether the comment associated with the acknowledgement is persistent
|
||||
*
|
||||
* Persistent comments are not lost the next time the monitoring host restarts.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $persistent = false;
|
||||
|
||||
/**
|
||||
* Optional time when the acknowledgement should expire
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $expireTime;
|
||||
|
||||
/**
|
||||
* Set whether the acknowledgement is sticky
|
||||
*
|
||||
* @param bool $sticky
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setSticky($sticky = true)
|
||||
{
|
||||
$this->sticky = (bool) $sticky;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the acknowledgement sticky?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getSticky()
|
||||
{
|
||||
return $this->sticky;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether to send a notification about the acknowledgement
|
||||
*
|
||||
* @param bool $notify
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setNotify($notify = true)
|
||||
{
|
||||
$this->notify = (bool) $notify;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether to send a notification about the acknowledgement
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getNotify()
|
||||
{
|
||||
return $this->notify;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether the comment associated with the acknowledgement is persistent
|
||||
*
|
||||
* @param bool $persistent
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setPersistent($persistent = true)
|
||||
{
|
||||
$this->persistent = (bool) $persistent;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the comment associated with the acknowledgement is persistent?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getPersistent()
|
||||
{
|
||||
return $this->persistent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the time when the acknowledgement should expire
|
||||
*
|
||||
* @param int $expireTime
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setExpireTime($expireTime)
|
||||
{
|
||||
$this->expireTime = (int) $expireTime;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the time when the acknowledgement should expire
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getExpireTime()
|
||||
{
|
||||
return $this->expireTime;
|
||||
}
|
||||
}
|
||||
42
library/Icingadb/Command/Object/AddCommentCommand.php
Normal file
42
library/Icingadb/Command/Object/AddCommentCommand.php
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Command\Object;
|
||||
|
||||
/**
|
||||
* Add a comment to a host or service
|
||||
*/
|
||||
class AddCommentCommand extends WithCommentCommand
|
||||
{
|
||||
/**
|
||||
* Optional time when the acknowledgement should expire
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $expireTime;
|
||||
|
||||
/**
|
||||
* Set the time when the acknowledgement should expire
|
||||
*
|
||||
* @param int $expireTime
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setExpireTime($expireTime)
|
||||
{
|
||||
$this->expireTime = (int) $expireTime;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the time when the acknowledgement should expire
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getExpireTime()
|
||||
{
|
||||
return $this->expireTime;
|
||||
}
|
||||
}
|
||||
39
library/Icingadb/Command/Object/CommandAuthor.php
Normal file
39
library/Icingadb/Command/Object/CommandAuthor.php
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Command\Object;
|
||||
|
||||
trait CommandAuthor
|
||||
{
|
||||
/**
|
||||
* Author of the command
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $author;
|
||||
|
||||
/**
|
||||
* Set the author
|
||||
*
|
||||
* @param string $author
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setAuthor($author)
|
||||
{
|
||||
$this->author = (string) $author;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the author
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAuthor()
|
||||
{
|
||||
return $this->author;
|
||||
}
|
||||
}
|
||||
46
library/Icingadb/Command/Object/DeleteCommentCommand.php
Normal file
46
library/Icingadb/Command/Object/DeleteCommentCommand.php
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Command\Object;
|
||||
|
||||
use Icinga\Module\Icingadb\Command\IcingaCommand;
|
||||
|
||||
/**
|
||||
* Delete a host or service comment
|
||||
*/
|
||||
class DeleteCommentCommand extends IcingaCommand
|
||||
{
|
||||
use CommandAuthor;
|
||||
|
||||
/**
|
||||
* Name of the comment
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $commentName;
|
||||
|
||||
/**
|
||||
* Get the name of the comment
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCommentName()
|
||||
{
|
||||
return $this->commentName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name of the comment
|
||||
*
|
||||
* @param string $commentName
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setCommentName($commentName)
|
||||
{
|
||||
$this->commentName = $commentName;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
52
library/Icingadb/Command/Object/DeleteDowntimeCommand.php
Normal file
52
library/Icingadb/Command/Object/DeleteDowntimeCommand.php
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Command\Object;
|
||||
|
||||
use Icinga\Module\Icingadb\Command\IcingaCommand;
|
||||
|
||||
/**
|
||||
* Delete a host or service downtime
|
||||
*/
|
||||
class DeleteDowntimeCommand extends IcingaCommand
|
||||
{
|
||||
use CommandAuthor;
|
||||
|
||||
/**
|
||||
* Name of the downtime (Icinga 2.4+)
|
||||
*
|
||||
* Required for removing the downtime via Icinga 2's API.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $downtimeName;
|
||||
|
||||
/**
|
||||
* Get the name of the downtime (Icinga 2.4+)
|
||||
*
|
||||
* Required for removing the downtime via Icinga 2's API.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDowntimeName()
|
||||
{
|
||||
return $this->downtimeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name of the downtime (Icinga 2.4+)
|
||||
*
|
||||
* Required for removing the downtime via Icinga 2's API.
|
||||
*
|
||||
* @param string $downtimeName
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setDowntimeName($downtimeName)
|
||||
{
|
||||
$this->downtimeName = $downtimeName;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
45
library/Icingadb/Command/Object/ObjectCommand.php
Normal file
45
library/Icingadb/Command/Object/ObjectCommand.php
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Command\Object;
|
||||
|
||||
use Icinga\Module\Icingadb\Command\IcingaCommand;
|
||||
use ipl\Orm\Model;
|
||||
|
||||
/**
|
||||
* Base class for commands that involve a monitored object, i.e. a host or service
|
||||
*/
|
||||
abstract class ObjectCommand extends IcingaCommand
|
||||
{
|
||||
/**
|
||||
* Involved object
|
||||
*
|
||||
* @var Model
|
||||
*/
|
||||
protected $object;
|
||||
|
||||
/**
|
||||
* Set the involved object
|
||||
*
|
||||
* @param Model $object
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setObject(Model $object)
|
||||
{
|
||||
$this->object = $object;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the involved object
|
||||
*
|
||||
* @return Model
|
||||
*/
|
||||
public function getObject()
|
||||
{
|
||||
return $this->object;
|
||||
}
|
||||
}
|
||||
134
library/Icingadb/Command/Object/ProcessCheckResultCommand.php
Normal file
134
library/Icingadb/Command/Object/ProcessCheckResultCommand.php
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Command\Object;
|
||||
|
||||
/**
|
||||
* Submit a passive check result for a host or service
|
||||
*/
|
||||
class ProcessCheckResultCommand extends ObjectCommand
|
||||
{
|
||||
/**
|
||||
* Host up
|
||||
*/
|
||||
const HOST_UP = 0;
|
||||
|
||||
/**
|
||||
* Host down
|
||||
*/
|
||||
const HOST_DOWN = 1;
|
||||
|
||||
/**
|
||||
* Service ok
|
||||
*/
|
||||
const SERVICE_OK = 0;
|
||||
|
||||
/**
|
||||
* Service warning
|
||||
*/
|
||||
const SERVICE_WARNING = 1;
|
||||
|
||||
/**
|
||||
* Service critical
|
||||
*/
|
||||
const SERVICE_CRITICAL = 2;
|
||||
|
||||
/**
|
||||
* Service unknown
|
||||
*/
|
||||
const SERVICE_UNKNOWN = 3;
|
||||
|
||||
/**
|
||||
* Status code of the host or service check result
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $status;
|
||||
|
||||
/**
|
||||
* Text output of the host or service check result
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $output;
|
||||
|
||||
/**
|
||||
* Optional performance data of the host or service check result
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $performanceData;
|
||||
|
||||
/**
|
||||
* Set the status code of the host or service check result
|
||||
*
|
||||
* @param int $status
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setStatus($status)
|
||||
{
|
||||
$this->status = (int) $status;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the status code of the host or service check result
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getStatus()
|
||||
{
|
||||
return $this->status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the text output of the host or service check result
|
||||
*
|
||||
* @param string $output
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setOutput($output)
|
||||
{
|
||||
$this->output = (string) $output;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text output of the host or service check result
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getOutput()
|
||||
{
|
||||
return $this->output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the performance data of the host or service check result
|
||||
*
|
||||
* @param string $performanceData
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setPerformanceData($performanceData)
|
||||
{
|
||||
$this->performanceData = (string) $performanceData;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the performance data of the host or service check result
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPerformanceData()
|
||||
{
|
||||
return $this->performanceData;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Command\Object;
|
||||
|
||||
/**
|
||||
* Schedule and propagate host downtime
|
||||
*/
|
||||
class PropagateHostDowntimeCommand extends ScheduleHostDowntimeCommand
|
||||
{
|
||||
/**
|
||||
* Whether the downtime for child hosts are all set to be triggered by this' host downtime
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $triggered = false;
|
||||
|
||||
/**
|
||||
* Set whether the downtime for child hosts are all set to be triggered by this' host downtime
|
||||
*
|
||||
* @param bool $triggered
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setTriggered($triggered = true)
|
||||
{
|
||||
$this->triggered = (bool) $triggered;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether the downtime for child hosts are all set to be triggered by this' host downtime
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getTriggered()
|
||||
{
|
||||
return $this->triggered;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Command\Object;
|
||||
|
||||
/**
|
||||
* Remove a problem acknowledgement from a host or service
|
||||
*/
|
||||
class RemoveAcknowledgementCommand extends ObjectCommand
|
||||
{
|
||||
use CommandAuthor;
|
||||
}
|
||||
80
library/Icingadb/Command/Object/ScheduleCheckCommand.php
Normal file
80
library/Icingadb/Command/Object/ScheduleCheckCommand.php
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Command\Object;
|
||||
|
||||
/**
|
||||
* Schedule a check
|
||||
*/
|
||||
class ScheduleCheckCommand extends ObjectCommand
|
||||
{
|
||||
/**
|
||||
* Time when the next check of a host or service is to be scheduled
|
||||
*
|
||||
* If active checks are disabled on a host- or service-specific or program-wide basis or the host or service is
|
||||
* already scheduled to be checked at an earlier time, etc. The check may not actually be scheduled at the time
|
||||
* specified. This behaviour can be overridden by setting `ScheduledCheck::$forced' to true.
|
||||
*
|
||||
* @var int Unix timestamp
|
||||
*/
|
||||
protected $checkTime;
|
||||
|
||||
/**
|
||||
* Whether the check is forced
|
||||
*
|
||||
* Forced checks are performed regardless of what time it is (e.g. time period restrictions are ignored) and whether
|
||||
* or not active checks are enabled on a host- or service-specific or program-wide basis.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $forced = false;
|
||||
|
||||
/**
|
||||
* Set the time when the next check of a host or service is to be scheduled
|
||||
*
|
||||
* @param int $checkTime Unix timestamp
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setCheckTime($checkTime)
|
||||
{
|
||||
$this->checkTime = (int) $checkTime;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the time when the next check of a host or service is to be scheduled
|
||||
*
|
||||
* @return int Unix timestamp
|
||||
*/
|
||||
public function getCheckTime()
|
||||
{
|
||||
return $this->checkTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether the check is forced
|
||||
*
|
||||
* @param bool $forced
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setForced($forced = true)
|
||||
{
|
||||
$this->forced = (bool) $forced;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether the check is forced
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getForced()
|
||||
{
|
||||
return $this->forced;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Command\Object;
|
||||
|
||||
/**
|
||||
* Schedule a host downtime
|
||||
*/
|
||||
class ScheduleHostDowntimeCommand extends ScheduleServiceDowntimeCommand
|
||||
{
|
||||
/**
|
||||
* Whether to schedule a downtime for all services associated with a particular host
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $forAllServices = false;
|
||||
|
||||
/**
|
||||
* Set whether to schedule a downtime for all services associated with a particular host
|
||||
*
|
||||
* @param bool $forAllServices
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setForAllServices($forAllServices = true)
|
||||
{
|
||||
$this->forAllServices = (bool) $forAllServices;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether to schedule a downtime for all services associated with a particular host
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getForAllServices()
|
||||
{
|
||||
return $this->forAllServices;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,184 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Command\Object;
|
||||
|
||||
/**
|
||||
* Schedule a service downtime
|
||||
*/
|
||||
class ScheduleServiceDowntimeCommand extends AddCommentCommand
|
||||
{
|
||||
/**
|
||||
* Downtime starts at the exact time specified
|
||||
*
|
||||
* If `Downtime::$fixed' is set to false, the time between `Downtime::$start' and `Downtime::$end' at which a
|
||||
* host or service transitions to a problem state determines the time at which the downtime actually starts.
|
||||
* The downtime will then last for `Downtime::$duration' seconds.
|
||||
*
|
||||
* @var int Unix timestamp
|
||||
*/
|
||||
protected $start;
|
||||
|
||||
/**
|
||||
* Downtime ends at the exact time specified
|
||||
*
|
||||
* If `Downtime::$fixed' is set to false, the time between `Downtime::$start' and `Downtime::$end' at which a
|
||||
* host or service transitions to a problem state determines the time at which the downtime actually starts.
|
||||
* The downtime will then last for `Downtime::$duration' seconds.
|
||||
*
|
||||
* @var int Unix timestamp
|
||||
*/
|
||||
protected $end;
|
||||
|
||||
/**
|
||||
* Whether it's a fixed or flexible downtime
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $fixed = true;
|
||||
|
||||
/**
|
||||
* ID of the downtime which triggers this downtime
|
||||
*
|
||||
* The start of this downtime is triggered by the start of the other scheduled host or service downtime.
|
||||
*
|
||||
* @var int|null
|
||||
*/
|
||||
protected $triggerId;
|
||||
|
||||
/**
|
||||
* The duration in seconds the downtime must last if it's a flexible downtime
|
||||
*
|
||||
* If `Downtime::$fixed' is set to false, the downtime will last for the duration in seconds specified, even
|
||||
* if the host or service recovers before the downtime expires.
|
||||
*
|
||||
* @var int|null
|
||||
*/
|
||||
protected $duration;
|
||||
|
||||
/**
|
||||
* Set the time when the downtime should start
|
||||
*
|
||||
* @param int $start Unix timestamp
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setStart($start)
|
||||
{
|
||||
$this->start = (int) $start;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the time when the downtime should start
|
||||
*
|
||||
* @return int Unix timestamp
|
||||
*/
|
||||
public function getStart()
|
||||
{
|
||||
return $this->start;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the time when the downtime should end
|
||||
*
|
||||
* @param int $end Unix timestamp
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setEnd($end)
|
||||
{
|
||||
$this->end = (int) $end;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the time when the downtime should end
|
||||
*
|
||||
* @return int Unix timestamp
|
||||
*/
|
||||
public function getEnd()
|
||||
{
|
||||
return $this->end;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether it's a fixed or flexible downtime
|
||||
*
|
||||
* @param boolean $fixed
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setFixed($fixed = true)
|
||||
{
|
||||
$this->fixed = (bool) $fixed;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the downtime fixed?
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function getFixed()
|
||||
{
|
||||
return $this->fixed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the ID of the downtime which triggers this downtime
|
||||
*
|
||||
* @param int $triggerId
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setTriggerId($triggerId)
|
||||
{
|
||||
$this->triggerId = (int) $triggerId;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ID of the downtime which triggers this downtime
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getTriggerId()
|
||||
{
|
||||
return $this->triggerId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the duration in seconds the downtime must last if it's a flexible downtime
|
||||
*
|
||||
* @param int $duration
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setDuration($duration)
|
||||
{
|
||||
$this->duration = (int) $duration;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the duration in seconds the downtime must last if it's a flexible downtime
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getDuration()
|
||||
{
|
||||
return $this->duration;
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return 'ScheduleDowntime';
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Command\Object;
|
||||
|
||||
/**
|
||||
* Send custom notifications for a host or service
|
||||
*/
|
||||
class SendCustomNotificationCommand extends WithCommentCommand
|
||||
{
|
||||
/**
|
||||
* Whether the notification is forced
|
||||
*
|
||||
* Forced notifications are sent out regardless of time restrictions and whether or not notifications are enabled.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $forced;
|
||||
|
||||
/**
|
||||
* Get whether to force the notification
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getForced()
|
||||
{
|
||||
return $this->forced;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether to force the notification
|
||||
*
|
||||
* @param bool $forced
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setForced($forced = true)
|
||||
{
|
||||
$this->forced = $forced;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
102
library/Icingadb/Command/Object/ToggleObjectFeatureCommand.php
Normal file
102
library/Icingadb/Command/Object/ToggleObjectFeatureCommand.php
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Command\Object;
|
||||
|
||||
/**
|
||||
* Enable or disable a feature of an Icinga object, i.e. host or service
|
||||
*/
|
||||
class ToggleObjectFeatureCommand extends ObjectCommand
|
||||
{
|
||||
/**
|
||||
* Feature for enabling or disabling active checks of a host or service
|
||||
*/
|
||||
const FEATURE_ACTIVE_CHECKS = 'active_checks_enabled';
|
||||
|
||||
/**
|
||||
* Feature for enabling or disabling passive checks of a host or service
|
||||
*/
|
||||
const FEATURE_PASSIVE_CHECKS = 'passive_checks_enabled';
|
||||
|
||||
/**
|
||||
* Feature for enabling or disabling notifications for a host or service
|
||||
*
|
||||
* Notifications will be sent out only if notifications are enabled on a program-wide basis as well.
|
||||
*/
|
||||
const FEATURE_NOTIFICATIONS = 'notifications_enabled';
|
||||
|
||||
/**
|
||||
* Feature for enabling or disabling event handler for a host or service
|
||||
*/
|
||||
const FEATURE_EVENT_HANDLER = 'event_handler_enabled';
|
||||
|
||||
/**
|
||||
* Feature for enabling or disabling flap detection for a host or service.
|
||||
*
|
||||
* In order to enable flap detection flap detection must be enabled on a program-wide basis as well.
|
||||
*/
|
||||
const FEATURE_FLAP_DETECTION = 'flapping_enabled';
|
||||
|
||||
/**
|
||||
* Feature that is to be enabled or disabled
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $feature;
|
||||
|
||||
/**
|
||||
* Whether the feature should be enabled or disabled
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $enabled;
|
||||
|
||||
/**
|
||||
* Set the feature that is to be enabled or disabled
|
||||
*
|
||||
* @param string $feature
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setFeature($feature)
|
||||
{
|
||||
$this->feature = (string) $feature;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the feature that is to be enabled or disabled
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFeature()
|
||||
{
|
||||
return $this->feature;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether the feature should be enabled or disabled
|
||||
*
|
||||
* @param bool $enabled
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setEnabled($enabled = true)
|
||||
{
|
||||
$this->enabled = (bool) $enabled;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether the feature should be enabled or disabled
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getEnabled()
|
||||
{
|
||||
return $this->enabled;
|
||||
}
|
||||
}
|
||||
44
library/Icingadb/Command/Object/WithCommentCommand.php
Normal file
44
library/Icingadb/Command/Object/WithCommentCommand.php
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Command\Object;
|
||||
|
||||
/**
|
||||
* Base class for commands adding comments
|
||||
*/
|
||||
abstract class WithCommentCommand extends ObjectCommand
|
||||
{
|
||||
use CommandAuthor;
|
||||
|
||||
/**
|
||||
* Comment
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $comment;
|
||||
|
||||
/**
|
||||
* Set the comment
|
||||
*
|
||||
* @param string $comment
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setComment($comment)
|
||||
{
|
||||
$this->comment = (string) $comment;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the comment
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getComment()
|
||||
{
|
||||
return $this->comment;
|
||||
}
|
||||
}
|
||||
305
library/Icingadb/Command/Renderer/IcingaApiCommandRenderer.php
Normal file
305
library/Icingadb/Command/Renderer/IcingaApiCommandRenderer.php
Normal file
|
|
@ -0,0 +1,305 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Command\Renderer;
|
||||
|
||||
use Icinga\Module\Icingadb\Command\IcingaApiCommand;
|
||||
use Icinga\Module\Icingadb\Model\Host;
|
||||
use Icinga\Module\Icingadb\Model\Service;
|
||||
use Icinga\Module\Icingadb\Command\Instance\ToggleInstanceFeatureCommand;
|
||||
use Icinga\Module\Icingadb\Command\Object\AcknowledgeProblemCommand;
|
||||
use Icinga\Module\Icingadb\Command\Object\AddCommentCommand;
|
||||
use Icinga\Module\Icingadb\Command\Object\DeleteCommentCommand;
|
||||
use Icinga\Module\Icingadb\Command\Object\DeleteDowntimeCommand;
|
||||
use Icinga\Module\Icingadb\Command\Object\ProcessCheckResultCommand;
|
||||
use Icinga\Module\Icingadb\Command\Object\PropagateHostDowntimeCommand;
|
||||
use Icinga\Module\Icingadb\Command\Object\RemoveAcknowledgementCommand;
|
||||
use Icinga\Module\Icingadb\Command\Object\ScheduleHostDowntimeCommand;
|
||||
use Icinga\Module\Icingadb\Command\Object\ScheduleCheckCommand;
|
||||
use Icinga\Module\Icingadb\Command\Object\ScheduleServiceDowntimeCommand;
|
||||
use Icinga\Module\Icingadb\Command\Object\SendCustomNotificationCommand;
|
||||
use Icinga\Module\Icingadb\Command\Object\ToggleObjectFeatureCommand;
|
||||
use Icinga\Module\Icingadb\Command\IcingaCommand;
|
||||
use InvalidArgumentException;
|
||||
use ipl\Orm\Model;
|
||||
|
||||
/**
|
||||
* Icinga command renderer for the Icinga command file
|
||||
*/
|
||||
class IcingaApiCommandRenderer implements IcingaCommandRendererInterface
|
||||
{
|
||||
/**
|
||||
* Name of the Icinga application object
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $app = 'app';
|
||||
|
||||
/**
|
||||
* Get the name of the Icinga application object
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getApp()
|
||||
{
|
||||
return $this->app;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name of the Icinga application object
|
||||
*
|
||||
* @param string $app
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setApp($app)
|
||||
{
|
||||
$this->app = $app;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply filter to query data
|
||||
*
|
||||
* @param array $data
|
||||
* @param Model $object
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function applyFilter(array &$data, Model $object)
|
||||
{
|
||||
if ($object instanceof Host) {
|
||||
$data['host'] = $object->name;
|
||||
} else {
|
||||
/** @var Service $object */
|
||||
$data['service'] = sprintf('%s!%s', $object->host->name, $object->name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a command
|
||||
*
|
||||
* @param IcingaCommand $command
|
||||
*
|
||||
* @return IcingaApiCommand
|
||||
*/
|
||||
public function render(IcingaCommand $command)
|
||||
{
|
||||
$renderMethod = 'render' . $command->getName();
|
||||
if (! method_exists($this, $renderMethod)) {
|
||||
throw new InvalidArgumentException(
|
||||
sprintf('Can\'t render command. Method %s not found', $renderMethod)
|
||||
);
|
||||
}
|
||||
|
||||
return $this->$renderMethod($command);
|
||||
}
|
||||
|
||||
public function renderAddComment(AddCommentCommand $command)
|
||||
{
|
||||
$endpoint = 'actions/add-comment';
|
||||
$data = [
|
||||
'author' => $command->getAuthor(),
|
||||
'comment' => $command->getComment()
|
||||
];
|
||||
|
||||
if ($command->getExpireTime() !== null) {
|
||||
$data['expiry'] = $command->getExpireTime();
|
||||
}
|
||||
|
||||
$this->applyFilter($data, $command->getObject());
|
||||
return IcingaApiCommand::create($endpoint, $data);
|
||||
}
|
||||
|
||||
public function renderSendCustomNotification(SendCustomNotificationCommand $command)
|
||||
{
|
||||
$endpoint = 'actions/send-custom-notification';
|
||||
$data = [
|
||||
'author' => $command->getAuthor(),
|
||||
'comment' => $command->getComment(),
|
||||
'force' => $command->getForced()
|
||||
];
|
||||
|
||||
$this->applyFilter($data, $command->getObject());
|
||||
return IcingaApiCommand::create($endpoint, $data);
|
||||
}
|
||||
|
||||
public function renderProcessCheckResult(ProcessCheckResultCommand $command)
|
||||
{
|
||||
$endpoint = 'actions/process-check-result';
|
||||
$data = [
|
||||
'exit_status' => $command->getStatus(),
|
||||
'plugin_output' => $command->getOutput(),
|
||||
'performance_data' => $command->getPerformanceData()
|
||||
];
|
||||
|
||||
$this->applyFilter($data, $command->getObject());
|
||||
return IcingaApiCommand::create($endpoint, $data);
|
||||
}
|
||||
|
||||
public function renderScheduleCheck(ScheduleCheckCommand $command)
|
||||
{
|
||||
$endpoint = 'actions/reschedule-check';
|
||||
$data = [
|
||||
'next_check' => $command->getCheckTime(),
|
||||
'force' => $command->getForced()
|
||||
];
|
||||
|
||||
$this->applyFilter($data, $command->getObject());
|
||||
return IcingaApiCommand::create($endpoint, $data);
|
||||
}
|
||||
|
||||
public function renderScheduleDowntime(ScheduleServiceDowntimeCommand $command)
|
||||
{
|
||||
$endpoint = 'actions/schedule-downtime';
|
||||
$data = [
|
||||
'author' => $command->getAuthor(),
|
||||
'comment' => $command->getComment(),
|
||||
'start_time' => $command->getStart(),
|
||||
'end_time' => $command->getEnd(),
|
||||
'duration' => $command->getDuration(),
|
||||
'fixed' => $command->getFixed(),
|
||||
'trigger_name' => $command->getTriggerId()
|
||||
];
|
||||
|
||||
if ($command instanceof PropagateHostDowntimeCommand) {
|
||||
$data['child_options'] = $command->getTriggered() ? 1 : 2;
|
||||
}
|
||||
|
||||
if ($command instanceof ScheduleHostDowntimeCommand && $command->getForAllServices()) {
|
||||
$data['all_services'] = true;
|
||||
}
|
||||
|
||||
$this->applyFilter($data, $command->getObject());
|
||||
return IcingaApiCommand::create($endpoint, $data);
|
||||
}
|
||||
|
||||
public function renderAcknowledgeProblem(AcknowledgeProblemCommand $command)
|
||||
{
|
||||
$endpoint = 'actions/acknowledge-problem';
|
||||
$data = [
|
||||
'author' => $command->getAuthor(),
|
||||
'comment' => $command->getComment(),
|
||||
'sticky' => $command->getSticky(),
|
||||
'notify' => $command->getNotify(),
|
||||
'persistent' => $command->getPersistent()
|
||||
];
|
||||
|
||||
if ($command->getExpireTime() !== null) {
|
||||
$data['expiry'] = $command->getExpireTime();
|
||||
}
|
||||
|
||||
$this->applyFilter($data, $command->getObject());
|
||||
return IcingaApiCommand::create($endpoint, $data);
|
||||
}
|
||||
|
||||
public function renderToggleObjectFeature(ToggleObjectFeatureCommand $command)
|
||||
{
|
||||
switch ($command->getFeature()) {
|
||||
case ToggleObjectFeatureCommand::FEATURE_ACTIVE_CHECKS:
|
||||
$attr = 'enable_active_checks';
|
||||
break;
|
||||
case ToggleObjectFeatureCommand::FEATURE_PASSIVE_CHECKS:
|
||||
$attr = 'enable_passive_checks';
|
||||
break;
|
||||
case ToggleObjectFeatureCommand::FEATURE_NOTIFICATIONS:
|
||||
$attr = 'enable_notifications';
|
||||
break;
|
||||
case ToggleObjectFeatureCommand::FEATURE_EVENT_HANDLER:
|
||||
$attr = 'enable_event_handler';
|
||||
break;
|
||||
case ToggleObjectFeatureCommand::FEATURE_FLAP_DETECTION:
|
||||
$attr = 'enable_flapping';
|
||||
break;
|
||||
default:
|
||||
throw new InvalidArgumentException($command->getFeature());
|
||||
}
|
||||
|
||||
$endpoint = 'objects/';
|
||||
$object = $command->getObject();
|
||||
if ($object instanceof Host) {
|
||||
$endpoint .= 'hosts';
|
||||
} else {
|
||||
/** @var Service $object */
|
||||
$endpoint .= 'services';
|
||||
}
|
||||
|
||||
$data = [
|
||||
'attrs' => [
|
||||
$attr => $command->getEnabled()
|
||||
]
|
||||
];
|
||||
|
||||
$this->applyFilter($data, $object);
|
||||
return IcingaApiCommand::create($endpoint, $data);
|
||||
}
|
||||
|
||||
public function renderDeleteComment(DeleteCommentCommand $command)
|
||||
{
|
||||
$endpoint = 'actions/remove-comment';
|
||||
$data = [
|
||||
'author' => $command->getAuthor(),
|
||||
'comment' => $command->getCommentName()
|
||||
];
|
||||
|
||||
return IcingaApiCommand::create($endpoint, $data);
|
||||
}
|
||||
|
||||
public function renderDeleteDowntime(DeleteDowntimeCommand $command)
|
||||
{
|
||||
$endpoint = 'actions/remove-downtime';
|
||||
$data = [
|
||||
'author' => $command->getAuthor(),
|
||||
'downtime' => $command->getDowntimeName()
|
||||
];
|
||||
|
||||
return IcingaApiCommand::create($endpoint, $data);
|
||||
}
|
||||
|
||||
public function renderRemoveAcknowledgement(RemoveAcknowledgementCommand $command)
|
||||
{
|
||||
$endpoint = 'actions/remove-acknowledgement';
|
||||
$data = ['author' => $command->getAuthor()];
|
||||
|
||||
$this->applyFilter($data, $command->getObject());
|
||||
return IcingaApiCommand::create($endpoint, $data);
|
||||
}
|
||||
|
||||
public function renderToggleInstanceFeature(ToggleInstanceFeatureCommand $command)
|
||||
{
|
||||
$endpoint = 'objects/icingaapplications/' . $this->getApp();
|
||||
|
||||
switch ($command->getFeature()) {
|
||||
case ToggleInstanceFeatureCommand::FEATURE_ACTIVE_HOST_CHECKS:
|
||||
$attr = 'enable_host_checks';
|
||||
break;
|
||||
case ToggleInstanceFeatureCommand::FEATURE_ACTIVE_SERVICE_CHECKS:
|
||||
$attr = 'enable_service_checks';
|
||||
break;
|
||||
case ToggleInstanceFeatureCommand::FEATURE_EVENT_HANDLERS:
|
||||
$attr = 'enable_event_handlers';
|
||||
break;
|
||||
case ToggleInstanceFeatureCommand::FEATURE_FLAP_DETECTION:
|
||||
$attr = 'enable_flapping';
|
||||
break;
|
||||
case ToggleInstanceFeatureCommand::FEATURE_NOTIFICATIONS:
|
||||
$attr = 'enable_notifications';
|
||||
break;
|
||||
case ToggleInstanceFeatureCommand::FEATURE_PERFORMANCE_DATA:
|
||||
$attr = 'enable_perfdata';
|
||||
break;
|
||||
default:
|
||||
throw new InvalidArgumentException($command->getFeature());
|
||||
}
|
||||
|
||||
$data = [
|
||||
'attrs' => [
|
||||
$attr => $command->getEnabled()
|
||||
]
|
||||
];
|
||||
|
||||
return IcingaApiCommand::create($endpoint, $data);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Command\Renderer;
|
||||
|
||||
/**
|
||||
* Interface for Icinga command renderer
|
||||
*/
|
||||
interface IcingaCommandRendererInterface
|
||||
{
|
||||
}
|
||||
14
library/Icingadb/Command/Transport/ApiCommandException.php
Normal file
14
library/Icingadb/Command/Transport/ApiCommandException.php
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Command\Transport;
|
||||
|
||||
use Icinga\Exception\IcingaException;
|
||||
|
||||
/**
|
||||
* Exception thrown if a command was not successful
|
||||
*/
|
||||
class ApiCommandException extends IcingaException
|
||||
{
|
||||
}
|
||||
309
library/Icingadb/Command/Transport/ApiCommandTransport.php
Normal file
309
library/Icingadb/Command/Transport/ApiCommandTransport.php
Normal file
|
|
@ -0,0 +1,309 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Command\Transport;
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use Icinga\Application\Hook\AuditHook;
|
||||
use Icinga\Application\Logger;
|
||||
use Icinga\Exception\Json\JsonDecodeException;
|
||||
use Icinga\Module\Icingadb\Command\IcingaApiCommand;
|
||||
use Icinga\Module\Icingadb\Command\IcingaCommand;
|
||||
use Icinga\Module\Icingadb\Command\Renderer\IcingaApiCommandRenderer;
|
||||
use Icinga\Util\Json;
|
||||
|
||||
/**
|
||||
* Command transport over Icinga 2's REST API
|
||||
*/
|
||||
class ApiCommandTransport implements CommandTransportInterface
|
||||
{
|
||||
/**
|
||||
* Transport identifier
|
||||
*/
|
||||
const TRANSPORT = 'api';
|
||||
|
||||
/**
|
||||
* API host
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $host;
|
||||
|
||||
/**
|
||||
* API password
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $password;
|
||||
|
||||
/**
|
||||
* API port
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $port = 5665;
|
||||
|
||||
/**
|
||||
* Command renderer
|
||||
*
|
||||
* @var IcingaApiCommandRenderer
|
||||
*/
|
||||
protected $renderer;
|
||||
|
||||
/**
|
||||
* API username
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $username;
|
||||
|
||||
/**
|
||||
* Create a new API command transport
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->renderer = new IcingaApiCommandRenderer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name of the Icinga application object
|
||||
*
|
||||
* @param string $app
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setApp($app)
|
||||
{
|
||||
$this->renderer->setApp($app);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the API host
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getHost()
|
||||
{
|
||||
return $this->host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the API host
|
||||
*
|
||||
* @param string $host
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setHost($host)
|
||||
{
|
||||
$this->host = $host;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the API password
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPassword()
|
||||
{
|
||||
return $this->password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the API password
|
||||
*
|
||||
* @param string $password
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setPassword($password)
|
||||
{
|
||||
$this->password = $password;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the API port
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getPort()
|
||||
{
|
||||
return $this->port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the API port
|
||||
*
|
||||
* @param int $port
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setPort($port)
|
||||
{
|
||||
$this->port = (int) $port;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the API username
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getUsername()
|
||||
{
|
||||
return $this->username;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the API username
|
||||
*
|
||||
* @param string $username
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setUsername($username)
|
||||
{
|
||||
$this->username = $username;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get URI for endpoint
|
||||
*
|
||||
* @param string $endpoint
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getUriFor($endpoint)
|
||||
{
|
||||
return sprintf('https://%s:%u/v1/%s', $this->getHost(), $this->getPort(), $endpoint);
|
||||
}
|
||||
|
||||
protected function sendCommand(IcingaApiCommand $command)
|
||||
{
|
||||
Logger::debug(
|
||||
'Sending Icinga command "%s" to the API "%s:%u"',
|
||||
$command->getEndpoint(),
|
||||
$this->getHost(),
|
||||
$this->getPort()
|
||||
);
|
||||
|
||||
$data = $command->getData();
|
||||
$payload = Json::encode($data);
|
||||
AuditHook::logActivity(
|
||||
'monitoring/command',
|
||||
"Issued command {$command->getEndpoint()} with the following payload: $payload",
|
||||
$data
|
||||
);
|
||||
|
||||
try {
|
||||
$response = (new Client())
|
||||
->post($this->getUriFor($command->getEndpoint()), [
|
||||
'auth' => [$this->getUsername(), $this->getPassword()],
|
||||
'headers' => ['Accept' => 'application/json'],
|
||||
'json' => $command->getData(),
|
||||
'http_errors' => false,
|
||||
'verify' => false
|
||||
]);
|
||||
} catch (GuzzleException $e) {
|
||||
throw new CommandTransportException(
|
||||
'Can\'t connect to the Icinga 2 API: %u %s',
|
||||
$e->getCode(),
|
||||
$e->getMessage()
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
$responseData = Json::decode((string) $response->getBody(), true);
|
||||
} catch (JsonDecodeException $e) {
|
||||
throw new CommandTransportException(
|
||||
'Got invalid JSON response from the Icinga 2 API: %s',
|
||||
$e->getMessage()
|
||||
);
|
||||
}
|
||||
|
||||
if (! isset($responseData['results']) || empty($responseData['results'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$result = array_pop($responseData['results']);
|
||||
if ($result['code'] < 200 || $result['code'] >= 300) {
|
||||
throw new ApiCommandException(
|
||||
'Can\'t send external Icinga command: %u %s',
|
||||
$result['code'],
|
||||
$result['status']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the Icinga command over the Icinga 2 API
|
||||
*
|
||||
* @param IcingaCommand $command
|
||||
* @param int|null $now
|
||||
*
|
||||
* @throws CommandTransportException
|
||||
*/
|
||||
public function send(IcingaCommand $command, $now = null)
|
||||
{
|
||||
$this->sendCommand($this->renderer->render($command));
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to connect to the API
|
||||
*
|
||||
* @throws CommandTransportException In case the connection was not successful
|
||||
*/
|
||||
public function probe()
|
||||
{
|
||||
try {
|
||||
$response = (new Client())
|
||||
->get($this->getUriFor(null), [
|
||||
'auth' => [$this->getUsername(), $this->getPassword()],
|
||||
'headers' => ['Accept' => 'application/json'],
|
||||
'http_errors' => false,
|
||||
'verify' => false
|
||||
]);
|
||||
} catch (GuzzleException $e) {
|
||||
throw new CommandTransportException(
|
||||
'Can\'t connect to the Icinga 2 API: %u %s',
|
||||
$e->getCode(),
|
||||
$e->getMessage()
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
$responseData = Json::decode((string) $response->getBody(), true);
|
||||
} catch (JsonDecodeException $e) {
|
||||
throw new CommandTransportException(
|
||||
'Got invalid JSON response from the Icinga 2 API: %s',
|
||||
$e->getMessage()
|
||||
);
|
||||
}
|
||||
|
||||
if (! isset($responseData['results']) || empty($responseData['results'])) {
|
||||
throw new CommandTransportException(
|
||||
'Got invalid response from the Icinga 2 API: %s',
|
||||
JSON::encode($responseData)
|
||||
);
|
||||
}
|
||||
|
||||
$result = array_pop($responseData['results']);
|
||||
if (! isset($result['user']) || $result['user'] !== $this->getUsername()) {
|
||||
throw new CommandTransportException(
|
||||
'Got invalid response from the Icinga 2 API: %s',
|
||||
JSON::encode($responseData)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
128
library/Icingadb/Command/Transport/CommandTransport.php
Normal file
128
library/Icingadb/Command/Transport/CommandTransport.php
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Command\Transport;
|
||||
|
||||
use Exception;
|
||||
use Icinga\Application\Config;
|
||||
use Icinga\Application\Logger;
|
||||
use Icinga\Data\ConfigObject;
|
||||
use Icinga\Exception\ConfigurationError;
|
||||
use Icinga\Module\Icingadb\Command\IcingaCommand;
|
||||
|
||||
/**
|
||||
* Command transport
|
||||
*/
|
||||
class CommandTransport implements CommandTransportInterface
|
||||
{
|
||||
/**
|
||||
* Transport configuration
|
||||
*
|
||||
* @var Config
|
||||
*/
|
||||
protected static $config;
|
||||
|
||||
/**
|
||||
* Get transport configuration
|
||||
*
|
||||
* @return Config
|
||||
*
|
||||
* @throws ConfigurationError
|
||||
*/
|
||||
public static function getConfig()
|
||||
{
|
||||
if (static::$config === null) {
|
||||
$config = Config::module('icingadb', 'commandtransports');
|
||||
if ($config->isEmpty()) {
|
||||
throw new ConfigurationError(
|
||||
t('No command transports have been configured in "%s".'),
|
||||
$config->getConfigFile()
|
||||
);
|
||||
}
|
||||
|
||||
static::$config = $config;
|
||||
}
|
||||
|
||||
return static::$config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a transport from config
|
||||
*
|
||||
* @param ConfigObject $config
|
||||
*
|
||||
* @return ApiCommandTransport
|
||||
*
|
||||
* @throws ConfigurationError
|
||||
*/
|
||||
public static function createTransport(ConfigObject $config)
|
||||
{
|
||||
$config = clone $config;
|
||||
switch (strtolower($config->transport)) {
|
||||
case ApiCommandTransport::TRANSPORT:
|
||||
$transport = new ApiCommandTransport();
|
||||
break;
|
||||
default:
|
||||
throw new ConfigurationError(
|
||||
t('Cannot create command transport "%s". Invalid transport defined in "%s". Use one of: %s.'),
|
||||
$config->transport,
|
||||
static::getConfig()->getConfigFile(),
|
||||
join(', ', [ApiCommandTransport::TRANSPORT])
|
||||
);
|
||||
}
|
||||
|
||||
unset($config->transport);
|
||||
foreach ($config as $key => $value) {
|
||||
$method = 'set' . ucfirst($key);
|
||||
if (! method_exists($transport, $method)) {
|
||||
// Ignore settings from config that don't have a setter on the transport instead of throwing an
|
||||
// exception here because the transport should throw an exception if it's not fully set up
|
||||
// when being about to send a command
|
||||
continue;
|
||||
}
|
||||
|
||||
$transport->$method($value);
|
||||
}
|
||||
|
||||
return $transport;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the given command over an appropriate Icinga command transport
|
||||
*
|
||||
* This will try one configured transport after another until the command has been successfully sent.
|
||||
*
|
||||
* @param IcingaCommand $command The command to send
|
||||
* @param int|null $now Timestamp of the command or null for now
|
||||
*
|
||||
* @throws CommandTransportException If sending the Icinga command failed
|
||||
*/
|
||||
public function send(IcingaCommand $command, $now = null)
|
||||
{
|
||||
$errors = [];
|
||||
|
||||
foreach (static::getConfig() as $name => $transportConfig) {
|
||||
$transport = static::createTransport($transportConfig);
|
||||
|
||||
try {
|
||||
$transport->send($command, $now);
|
||||
} catch (CommandTransportException $e) {
|
||||
Logger::error($e);
|
||||
$errors[] = sprintf('%s: %s.', $name, rtrim($e->getMessage(), '.'));
|
||||
continue; // Try the next transport
|
||||
}
|
||||
|
||||
return; // The command was successfully sent
|
||||
}
|
||||
|
||||
if (! empty($errors)) {
|
||||
throw new CommandTransportException(implode("\n", $errors));
|
||||
}
|
||||
|
||||
throw new CommandTransportException(t(
|
||||
'Failed to send external Icinga command. No transport has been configured'
|
||||
. ' for this instance. Please contact your Icinga Web administrator.'
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Command\Transport;
|
||||
|
||||
use Icinga\Repository\IniRepository;
|
||||
|
||||
class CommandTransportConfig extends IniRepository
|
||||
{
|
||||
protected $configs = [
|
||||
'transport' => [
|
||||
'name' => 'commandtransports',
|
||||
'module' => 'icingadb',
|
||||
'keyColumn' => 'name'
|
||||
]
|
||||
];
|
||||
|
||||
protected $queryColumns = [
|
||||
'transport' => [
|
||||
'name',
|
||||
'transport',
|
||||
|
||||
// API options
|
||||
'host',
|
||||
'port',
|
||||
'username',
|
||||
'password'
|
||||
]
|
||||
];
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Command\Transport;
|
||||
|
||||
use Icinga\Exception\IcingaException;
|
||||
|
||||
/**
|
||||
* Exception thrown if a command was not sent
|
||||
*/
|
||||
class CommandTransportException extends IcingaException
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Command\Transport;
|
||||
|
||||
use Icinga\Module\Icingadb\Command\IcingaCommand;
|
||||
|
||||
/**
|
||||
* Interface for Icinga command transports
|
||||
*/
|
||||
interface CommandTransportInterface
|
||||
{
|
||||
/**
|
||||
* Send an Icinga command over the Icinga command transport
|
||||
*
|
||||
* @param IcingaCommand $command The command to send
|
||||
* @param int|null $now Timestamp of the command or null for now
|
||||
*
|
||||
* @throws CommandTransportException If sending the Icinga command failed
|
||||
*/
|
||||
public function send(IcingaCommand $command, $now = null);
|
||||
}
|
||||
33
library/Icingadb/Common/BaseOrderedItemList.php
Normal file
33
library/Icingadb/Common/BaseOrderedItemList.php
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2020 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Common;
|
||||
|
||||
use Icinga\Module\Icingadb\Widget\BaseItemList;
|
||||
|
||||
/**
|
||||
* @method BaseOrderedListItem getItemClass()
|
||||
*/
|
||||
abstract class BaseOrderedItemList extends BaseItemList
|
||||
{
|
||||
protected $tag = 'ol';
|
||||
|
||||
protected function assemble()
|
||||
{
|
||||
$itemClass = $this->getItemClass();
|
||||
|
||||
$i = 0;
|
||||
foreach ($this->data as $data) {
|
||||
$item = new $itemClass($data, $this);
|
||||
$item->setOrder($i++);
|
||||
|
||||
$this->add($item);
|
||||
}
|
||||
|
||||
if ($this->isEmpty()) {
|
||||
$this->setTag('div');
|
||||
$this->add(new EmptyState(t('No items found.')));
|
||||
}
|
||||
}
|
||||
}
|
||||
37
library/Icingadb/Common/BaseOrderedListItem.php
Normal file
37
library/Icingadb/Common/BaseOrderedListItem.php
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2020 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Common;
|
||||
|
||||
use Icinga\Module\Icingadb\Widget\BaseListItem;
|
||||
|
||||
abstract class BaseOrderedListItem extends BaseListItem
|
||||
{
|
||||
/** @var int This element's position */
|
||||
protected $order;
|
||||
|
||||
/**
|
||||
* Set this element's position
|
||||
*
|
||||
* @param int $order
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setOrder($order)
|
||||
{
|
||||
$this->order = (int) $order;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get this element's position
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getOrder()
|
||||
{
|
||||
return $this->order;
|
||||
}
|
||||
}
|
||||
|
|
@ -4,27 +4,18 @@
|
|||
|
||||
namespace Icinga\Module\Icingadb\Common;
|
||||
|
||||
use Icinga\Module\Icingadb\Compat\CompatBackend;
|
||||
use Icinga\Module\Icingadb\Compat\CompatHost;
|
||||
use Icinga\Module\Icingadb\Compat\CompatObjects;
|
||||
use Icinga\Module\Icingadb\Compat\CompatService;
|
||||
use Icinga\Module\Monitoring\Forms\Command\Object\AcknowledgeProblemCommandForm;
|
||||
use Icinga\Module\Monitoring\Forms\Command\Object\AddCommentCommandForm;
|
||||
use Icinga\Module\Monitoring\Forms\Command\Object\CheckNowCommandForm;
|
||||
use Icinga\Module\Monitoring\Forms\Command\Object\DeleteCommentCommandForm;
|
||||
use Icinga\Module\Monitoring\Forms\Command\Object\DeleteCommentsCommandForm;
|
||||
use Icinga\Module\Monitoring\Forms\Command\Object\DeleteDowntimeCommandForm;
|
||||
use Icinga\Module\Monitoring\Forms\Command\Object\DeleteDowntimesCommandForm;
|
||||
use Icinga\Module\Monitoring\Forms\Command\Object\ObjectsCommandForm;
|
||||
use Icinga\Module\Monitoring\Forms\Command\Object\ProcessCheckResultCommandForm;
|
||||
use Icinga\Module\Monitoring\Forms\Command\Object\RemoveAcknowledgementCommandForm;
|
||||
use Icinga\Module\Monitoring\Forms\Command\Object\ScheduleHostCheckCommandForm;
|
||||
use Icinga\Module\Monitoring\Forms\Command\Object\ScheduleHostDowntimeCommandForm;
|
||||
use Icinga\Module\Monitoring\Forms\Command\Object\ScheduleServiceCheckCommandForm;
|
||||
use Icinga\Module\Monitoring\Forms\Command\Object\ScheduleServiceDowntimeCommandForm;
|
||||
use Icinga\Module\Monitoring\Forms\Command\Object\SendCustomNotificationCommandForm;
|
||||
use Icinga\Module\Monitoring\Forms\Command\Object\ToggleObjectFeaturesCommandForm;
|
||||
use ipl\Html\HtmlString;
|
||||
use GuzzleHttp\Psr7\ServerRequest;
|
||||
use Icinga\Module\Icingadb\Forms\Command\CommandForm;
|
||||
use Icinga\Module\Icingadb\Forms\Command\Object\AcknowledgeProblemForm;
|
||||
use Icinga\Module\Icingadb\Forms\Command\Object\AddCommentForm;
|
||||
use Icinga\Module\Icingadb\Forms\Command\Object\CheckNowForm;
|
||||
use Icinga\Module\Icingadb\Forms\Command\Object\ProcessCheckResultForm;
|
||||
use Icinga\Module\Icingadb\Forms\Command\Object\RemoveAcknowledgementForm;
|
||||
use Icinga\Module\Icingadb\Forms\Command\Object\ScheduleCheckForm;
|
||||
use Icinga\Module\Icingadb\Forms\Command\Object\ScheduleHostDowntimeForm;
|
||||
use Icinga\Module\Icingadb\Forms\Command\Object\ScheduleServiceDowntimeForm;
|
||||
use Icinga\Module\Icingadb\Forms\Command\Object\SendCustomNotificationForm;
|
||||
use Icinga\Module\Icingadb\Forms\Command\Object\ToggleObjectFeaturesForm;
|
||||
use ipl\Orm\Model;
|
||||
use ipl\Orm\Query;
|
||||
use ipl\Web\Url;
|
||||
|
|
@ -82,118 +73,80 @@ trait CommandActions
|
|||
return $this->commandTargetModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get command objects
|
||||
*
|
||||
* @return CompatObjects
|
||||
*/
|
||||
protected function getCommandObjects()
|
||||
{
|
||||
switch ($this->getCommandTargetModel()->getTableName()) {
|
||||
case 'host':
|
||||
$compatClass = CompatHost::class;
|
||||
break;
|
||||
case 'service':
|
||||
$compatClass = CompatService::class;
|
||||
break;
|
||||
default:
|
||||
throw new LogicException('Only hosts and services are supported');
|
||||
}
|
||||
|
||||
return new CompatObjects($this->getCommandTargets(), $compatClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle and register the given command form
|
||||
*
|
||||
* @param string|ObjectsCommandForm $form
|
||||
* @param string|CommandForm $form
|
||||
*/
|
||||
protected function handleCommandForm($form)
|
||||
{
|
||||
if (is_string($form)) {
|
||||
$form = new $form([
|
||||
'backend' => new CompatBackend(),
|
||||
'objects' => $this->getCommandObjects()
|
||||
]);
|
||||
/** @var \Icinga\Module\Icingadb\Forms\Command\CommandForm $form */
|
||||
$form = new $form();
|
||||
}
|
||||
|
||||
$form->setRedirectUrl($this->getCommandTargetsUrl());
|
||||
$actionUrl = $this->getRequest()->getUrl();
|
||||
if ($this->view->compact) {
|
||||
$actionUrl = clone $actionUrl;
|
||||
// TODO: This solves https://github.com/Icinga/icingadb-web/issues/124 but I'd like to omit this
|
||||
// entirely. I think it should be solved like https://github.com/Icinga/icingaweb2/pull/4300 so
|
||||
// that a request's url object still has params like showCompact and _dev
|
||||
$actionUrl->getParams()->add('showCompact', true);
|
||||
}
|
||||
|
||||
$form->handleRequest();
|
||||
$this->addContent(HtmlString::create($form->render()));
|
||||
$form->setAction($actionUrl->getAbsoluteUrl());
|
||||
$form->setObjects($this->getCommandTargets());
|
||||
$form->on($form::ON_SUCCESS, function () {
|
||||
// This forces the column to reload nearly instantly after the redirect
|
||||
// and ensures the effect of the command is visible to the user asap
|
||||
$this->getResponse()->setAutoRefreshInterval(1);
|
||||
|
||||
$this->redirectNow($this->getCommandTargetsUrl());
|
||||
});
|
||||
|
||||
$form->handleRequest(ServerRequest::fromGlobals());
|
||||
|
||||
$this->addContent($form);
|
||||
}
|
||||
|
||||
public function acknowledgeAction()
|
||||
{
|
||||
$this->assertPermission('monitoring/command/acknowledge-problem');
|
||||
$this->setTitle(t('Acknowledge Problem'));
|
||||
$this->handleCommandForm(AcknowledgeProblemCommandForm::class);
|
||||
$this->handleCommandForm(AcknowledgeProblemForm::class);
|
||||
}
|
||||
|
||||
public function addCommentAction()
|
||||
{
|
||||
$this->assertPermission('monitoring/command/comment/add');
|
||||
$this->setTitle(t('Add Comment'));
|
||||
$this->handleCommandForm(AddCommentCommandForm::class);
|
||||
$this->handleCommandForm(AddCommentForm::class);
|
||||
}
|
||||
|
||||
public function checkNowAction()
|
||||
{
|
||||
$this->assertPermission('monitoring/command/schedule-check');
|
||||
$this->handleCommandForm(CheckNowCommandForm::class);
|
||||
}
|
||||
|
||||
public function deleteCommentAction()
|
||||
{
|
||||
$this->assertPermission('monitoring/command/comment/delete');
|
||||
$this->handleCommandForm(DeleteCommentCommandForm::class);
|
||||
}
|
||||
|
||||
public function deleteCommentsAction()
|
||||
{
|
||||
$this->assertPermission('monitoring/command/comment/delete');
|
||||
$this->handleCommandForm(DeleteCommentsCommandForm::class);
|
||||
}
|
||||
|
||||
public function deleteDowntimeAction()
|
||||
{
|
||||
$this->assertPermission('monitoring/command/downtime/delete');
|
||||
$this->handleCommandForm(DeleteDowntimeCommandForm::class);
|
||||
}
|
||||
|
||||
public function deleteDowntimesAction()
|
||||
{
|
||||
$this->assertPermission('monitoring/command/downtime/delete');
|
||||
$this->handleCommandForm(DeleteDowntimesCommandForm::class);
|
||||
$this->handleCommandForm(CheckNowForm::class);
|
||||
}
|
||||
|
||||
public function processCheckresultAction()
|
||||
{
|
||||
$this->assertPermission('monitoring/command/process-check-result');
|
||||
$this->setTitle(t('Submit Passive Check Result'));
|
||||
$this->handleCommandForm(ProcessCheckResultCommandForm::class);
|
||||
$this->handleCommandForm(ProcessCheckResultForm::class);
|
||||
}
|
||||
|
||||
public function removeAcknowledgementAction()
|
||||
{
|
||||
$this->assertPermission('monitoring/command/remove-acknowledgement');
|
||||
$this->handleCommandForm(RemoveAcknowledgementCommandForm::class);
|
||||
$this->handleCommandForm(RemoveAcknowledgementForm::class);
|
||||
}
|
||||
|
||||
public function scheduleCheckAction()
|
||||
{
|
||||
$this->assertPermission('monitoring/command/schedule-check');
|
||||
|
||||
switch ($this->getCommandTargetModel()->getTableName()) {
|
||||
case 'host':
|
||||
$this->setTitle(t('Reschedule Host Check'));
|
||||
$this->handleCommandForm(ScheduleHostCheckCommandForm::class);
|
||||
break;
|
||||
case 'service':
|
||||
$this->setTitle(t('Reschedule Service Check'));
|
||||
$this->handleCommandForm(ScheduleServiceCheckCommandForm::class);
|
||||
break;
|
||||
}
|
||||
$this->setTitle(t('Reschedule Check'));
|
||||
$this->handleCommandForm(ScheduleCheckForm::class);
|
||||
}
|
||||
|
||||
public function scheduleDowntimeAction()
|
||||
|
|
@ -203,11 +156,11 @@ trait CommandActions
|
|||
switch ($this->getCommandTargetModel()->getTableName()) {
|
||||
case 'host':
|
||||
$this->setTitle(t('Schedule Host Downtime'));
|
||||
$this->handleCommandForm(ScheduleHostDowntimeCommandForm::class);
|
||||
$this->handleCommandForm(ScheduleHostDowntimeForm::class);
|
||||
break;
|
||||
case 'service':
|
||||
$this->setTitle(t('Schedule Service Downtime'));
|
||||
$this->handleCommandForm(ScheduleServiceDowntimeCommandForm::class);
|
||||
$this->handleCommandForm(ScheduleServiceDowntimeForm::class);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -216,26 +169,22 @@ trait CommandActions
|
|||
{
|
||||
$this->assertPermission('monitoring/command/send-custom-notification');
|
||||
$this->setTitle(t('Send Custom Notification'));
|
||||
$this->handleCommandForm(SendCustomNotificationCommandForm::class);
|
||||
$this->handleCommandForm(SendCustomNotificationForm::class);
|
||||
}
|
||||
|
||||
public function toggleFeaturesAction()
|
||||
{
|
||||
$commandObjects = $this->getCommandObjects();
|
||||
$form = new ToggleObjectFeaturesCommandForm([
|
||||
'backend' => new CompatBackend(),
|
||||
'objects' => $commandObjects
|
||||
]);
|
||||
|
||||
$commandObjects = $this->getCommandTargets();
|
||||
if (count($commandObjects) > 1) {
|
||||
if (! method_exists($this, 'getFeatureStatus')) {
|
||||
throw new LogicException('You must implement getFeatureStatus() first');
|
||||
}
|
||||
|
||||
$form->load($this->getFeatureStatus());
|
||||
$form = new ToggleObjectFeaturesForm($this->getFeatureStatus());
|
||||
} else {
|
||||
foreach ($commandObjects as $object) {
|
||||
$form->load($object);
|
||||
// There's only a single result, a foreach is the most compatible way to retrieve the object
|
||||
$form = new ToggleObjectFeaturesForm($object);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,11 +29,6 @@ abstract class HostLinks
|
|||
return Url::fromPath('icingadb/host/schedule-check', ['name' => $host->name]);
|
||||
}
|
||||
|
||||
public static function cancelDowntime(Host $host)
|
||||
{
|
||||
return Url::fromPath('icingadb/host/delete-downtime', ['name' => $host->name]);
|
||||
}
|
||||
|
||||
public static function comments(Host $host)
|
||||
{
|
||||
return Url::fromPath('icingadb/host/comments', ['name' => $host->name]);
|
||||
|
|
@ -54,11 +49,6 @@ abstract class HostLinks
|
|||
return Url::fromPath('icingadb/host/remove-acknowledgement', ['name' => $host->name]);
|
||||
}
|
||||
|
||||
public static function removeComment(Host $host)
|
||||
{
|
||||
return Url::fromPath('icingadb/host/delete-comment', ['name' => $host->name]);
|
||||
}
|
||||
|
||||
public static function scheduleDowntime(Host $host)
|
||||
{
|
||||
return Url::fromPath('icingadb/host/schedule-downtime', ['name' => $host->name]);
|
||||
|
|
|
|||
|
|
@ -42,14 +42,6 @@ abstract class ServiceLinks
|
|||
);
|
||||
}
|
||||
|
||||
public static function cancelDowntime(Service $service, Host $host)
|
||||
{
|
||||
return Url::fromPath(
|
||||
'icingadb/service/delete-downtime',
|
||||
['name' => $service->name, 'host.name' => $host->name]
|
||||
);
|
||||
}
|
||||
|
||||
public static function comments(Service $service, Host $host)
|
||||
{
|
||||
return Url::fromPath(
|
||||
|
|
@ -82,14 +74,6 @@ abstract class ServiceLinks
|
|||
);
|
||||
}
|
||||
|
||||
public static function removeComment(Service $service, Host $host)
|
||||
{
|
||||
return Url::fromPath(
|
||||
'icingadb/service/delete-comment',
|
||||
['name' => $service->name, 'host.name' => $host->name]
|
||||
);
|
||||
}
|
||||
|
||||
public static function scheduleDowntime(Service $service, Host $host)
|
||||
{
|
||||
return Url::fromPath(
|
||||
|
|
|
|||
|
|
@ -1,35 +0,0 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2020 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Compat;
|
||||
|
||||
use Icinga\Module\Monitoring\Backend\MonitoringBackend;
|
||||
|
||||
class CompatBackend extends MonitoringBackend
|
||||
{
|
||||
/**
|
||||
* @param string $name Ignored
|
||||
* @param mixed $config Ignored
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $programVersion Ignored
|
||||
* @return true
|
||||
*/
|
||||
public function isIcinga2($_ = null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string "2.12", hardcoded
|
||||
*/
|
||||
public function getProgramVersion()
|
||||
{
|
||||
return '2.12';
|
||||
}
|
||||
}
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2020 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Compat;
|
||||
|
||||
use Countable;
|
||||
use IteratorAggregate;
|
||||
use Traversable;
|
||||
|
||||
class CompatObjects implements IteratorAggregate, Countable
|
||||
{
|
||||
protected $query;
|
||||
protected $compatClass;
|
||||
|
||||
public function __construct($query, $compatClass)
|
||||
{
|
||||
$this->query = $query;
|
||||
$this->compatClass = $compatClass;
|
||||
}
|
||||
|
||||
public function getIterator()
|
||||
{
|
||||
foreach ($this->query as $object) {
|
||||
yield new $this->compatClass($object);
|
||||
}
|
||||
}
|
||||
|
||||
public function count()
|
||||
{
|
||||
if ($this->query instanceof Traversable) {
|
||||
return $this->query->count();
|
||||
}
|
||||
|
||||
return count($this->query);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2020 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Compat;
|
||||
|
||||
use ArrayObject;
|
||||
|
||||
class FeatureStatus extends ArrayObject
|
||||
{
|
||||
public function __construct($type, $summary)
|
||||
{
|
||||
$prefix = "{$type}s";
|
||||
|
||||
$featureStatus = [
|
||||
'active_checks_enabled' => $this->getFeatureStatus('active_checks_enabled', $prefix, $summary),
|
||||
'passive_checks_enabled' => $this->getFeatureStatus('passive_checks_enabled', $prefix, $summary),
|
||||
'notifications_enabled' => $this->getFeatureStatus('notifications_enabled', $prefix, $summary),
|
||||
'event_handler_enabled' => $this->getFeatureStatus('event_handler_enabled', $prefix, $summary),
|
||||
'flap_detection_enabled' => $this->getFeatureStatus('flapping_enabled', $prefix, $summary)
|
||||
];
|
||||
|
||||
parent::__construct($featureStatus, ArrayObject::ARRAY_AS_PROPS);
|
||||
}
|
||||
|
||||
protected function getFeatureStatus($feature, $prefix, $summary)
|
||||
{
|
||||
$key = "{$prefix}_{$feature}";
|
||||
$value = (int) $summary->$key;
|
||||
|
||||
if ($value === 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$totalKey = "{$prefix}_total";
|
||||
$total = (int) $summary->$totalKey;
|
||||
|
||||
if ($value === $total) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
50
library/Icingadb/Util/FeatureStatus.php
Normal file
50
library/Icingadb/Util/FeatureStatus.php
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2020 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Util;
|
||||
|
||||
use ArrayObject;
|
||||
use Icinga\Module\Icingadb\Command\Object\ToggleObjectFeatureCommand;
|
||||
|
||||
class FeatureStatus extends ArrayObject
|
||||
{
|
||||
public function __construct($type, $summary)
|
||||
{
|
||||
$prefix = "{$type}s";
|
||||
|
||||
$featureStatus = [
|
||||
ToggleObjectFeatureCommand::FEATURE_ACTIVE_CHECKS =>
|
||||
$this->getFeatureStatus('active_checks_enabled', $prefix, $summary),
|
||||
ToggleObjectFeatureCommand::FEATURE_PASSIVE_CHECKS =>
|
||||
$this->getFeatureStatus('passive_checks_enabled', $prefix, $summary),
|
||||
ToggleObjectFeatureCommand::FEATURE_NOTIFICATIONS =>
|
||||
$this->getFeatureStatus('notifications_enabled', $prefix, $summary),
|
||||
ToggleObjectFeatureCommand::FEATURE_EVENT_HANDLER =>
|
||||
$this->getFeatureStatus('event_handler_enabled', $prefix, $summary),
|
||||
ToggleObjectFeatureCommand::FEATURE_FLAP_DETECTION =>
|
||||
$this->getFeatureStatus('flapping_enabled', $prefix, $summary)
|
||||
];
|
||||
|
||||
parent::__construct($featureStatus, ArrayObject::ARRAY_AS_PROPS);
|
||||
}
|
||||
|
||||
protected function getFeatureStatus($feature, $prefix, $summary)
|
||||
{
|
||||
$key = "{$prefix}_{$feature}";
|
||||
$value = (int) $summary->$key;
|
||||
|
||||
if ($value === 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$totalKey = "{$prefix}_total";
|
||||
$total = (int) $summary->$totalKey;
|
||||
|
||||
if ($value === $total) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
|
@ -12,6 +12,8 @@ use ipl\Web\Url;
|
|||
|
||||
/**
|
||||
* Base class for item lists
|
||||
*
|
||||
* @todo Move this to Icinga\Module\Icingadb\Common
|
||||
*/
|
||||
abstract class BaseItemList extends BaseHtmlElement
|
||||
{
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ use ipl\Web\Filter\QueryString;
|
|||
|
||||
/**
|
||||
* Base class for list items
|
||||
*
|
||||
* @todo Move this to Icinga\Module\Icingadb\Common
|
||||
*/
|
||||
abstract class BaseListItem extends BaseHtmlElement
|
||||
{
|
||||
|
|
|
|||
|
|
@ -6,17 +6,13 @@ namespace Icinga\Module\Icingadb\Widget\Detail;
|
|||
|
||||
use Icinga\Module\Icingadb\Common\Auth;
|
||||
use Icinga\Module\Icingadb\Common\HostLink;
|
||||
use Icinga\Module\Icingadb\Common\HostLinks;
|
||||
use Icinga\Module\Icingadb\Common\Links;
|
||||
use Icinga\Module\Icingadb\Common\MarkdownText;
|
||||
use Icinga\Module\Icingadb\Common\ServiceLink;
|
||||
use Icinga\Module\Icingadb\Common\ServiceLinks;
|
||||
use Icinga\Module\Icingadb\Forms\Command\Object\DeleteCommentForm;
|
||||
use Icinga\Module\Icingadb\Widget\TimeUntil;
|
||||
use Icinga\Module\Monitoring\Forms\Command\Object\DeleteCommentCommandForm;
|
||||
use ipl\Html\BaseHtmlElement;
|
||||
use ipl\Html\Html;
|
||||
use ipl\Html\HtmlDocument;
|
||||
use ipl\Html\HtmlString;
|
||||
use ipl\Web\Widget\Icon;
|
||||
|
||||
class CommentDetail extends BaseHtmlElement
|
||||
{
|
||||
|
|
@ -70,32 +66,14 @@ class CommentDetail extends BaseHtmlElement
|
|||
|
||||
protected function createRemoveCommentForm()
|
||||
{
|
||||
$formData = [
|
||||
'comment_id' => $this->comment->name,
|
||||
'comment_name' => $this->comment->name,
|
||||
'redirect' => '__BACK__'
|
||||
];
|
||||
// TODO: Check permission
|
||||
$action = Links::commentsDelete();
|
||||
$action->setParam('name', $this->comment->name);
|
||||
|
||||
|
||||
if ($this->comment->object_type === 'host') {
|
||||
$action = HostLinks::removeComment($this->comment->host);
|
||||
} else {
|
||||
$action = ServiceLinks::removeComment($this->comment->service, $this->comment->service->host);
|
||||
$formData['comment_is_service'] = true;
|
||||
}
|
||||
|
||||
$removeCommentForm = (new DeleteCommentCommandForm())
|
||||
->create()
|
||||
->populate($formData)
|
||||
->setAction($action);
|
||||
|
||||
$submitButton = $removeCommentForm->getElement('btn_submit');
|
||||
$submitButton->content = (new HtmlDocument())
|
||||
->add([new Icon('trash'), t('Remove Comment')])
|
||||
->setSeparator(' ')
|
||||
->render();
|
||||
|
||||
return new HtmlString($removeCommentForm->render());
|
||||
return (new DeleteCommentForm())
|
||||
->setObjects([$this->comment])
|
||||
->populate(['redirect' => '__BACK__'])
|
||||
->setAction($action->getAbsoluteUrl());
|
||||
}
|
||||
|
||||
protected function assemble()
|
||||
|
|
|
|||
|
|
@ -8,13 +8,12 @@ use Icinga\Date\DateFormatter;
|
|||
use Icinga\Date\DateFormatter as WebDateFormatter;
|
||||
use Icinga\Module\Icingadb\Common\Auth;
|
||||
use Icinga\Module\Icingadb\Common\HostLink;
|
||||
use Icinga\Module\Icingadb\Common\HostLinks;
|
||||
use Icinga\Module\Icingadb\Common\Links;
|
||||
use Icinga\Module\Icingadb\Common\MarkdownText;
|
||||
use Icinga\Module\Icingadb\Common\ServiceLink;
|
||||
use Icinga\Module\Icingadb\Common\ServiceLinks;
|
||||
use Icinga\Module\Icingadb\Forms\Command\Object\DeleteDowntimeForm;
|
||||
use Icinga\Module\Icingadb\Model\Downtime;
|
||||
use Icinga\Module\Icingadb\Widget\HorizontalKeyValue;
|
||||
use Icinga\Module\Monitoring\Forms\Command\Object\DeleteDowntimeCommandForm;
|
||||
use ipl\Html\BaseHtmlElement;
|
||||
use ipl\Html\Html;
|
||||
use ipl\Html\HtmlDocument;
|
||||
|
|
@ -73,31 +72,14 @@ class DowntimeDetail extends BaseHtmlElement
|
|||
|
||||
protected function createCancelDowntimeForm()
|
||||
{
|
||||
$formData = [
|
||||
'downtime_id' => $this->downtime->name,
|
||||
'downtime_name' => $this->downtime->name,
|
||||
'redirect' => '__BACK__'
|
||||
];
|
||||
// TODO: Check permission
|
||||
$action = Links::downtimesDelete();
|
||||
$action->setParam('name', $this->downtime->name);
|
||||
|
||||
if ($this->downtime->object_type === 'host') {
|
||||
$action = HostLinks::cancelDowntime($this->downtime->host);
|
||||
} else {
|
||||
$action = ServiceLinks::cancelDowntime($this->downtime->service, $this->downtime->service->host);
|
||||
$formData['downtime_is_service'] = true;
|
||||
}
|
||||
|
||||
$cancelDowntimeForm = (new DeleteDowntimeCommandForm())
|
||||
->create()
|
||||
->populate($formData)
|
||||
->setAction($action);
|
||||
|
||||
$submitButton = $cancelDowntimeForm->getElement('btn_submit');
|
||||
$submitButton->content = (new HtmlDocument())
|
||||
->add([new Icon('trash'), t('Cancel Downtime')])
|
||||
->setSeparator(' ')
|
||||
->render();
|
||||
|
||||
return new HtmlString($cancelDowntimeForm->render());
|
||||
return (new DeleteDowntimeForm())
|
||||
->setObjects([$this->downtime])
|
||||
->populate(['redirect' => '__BACK__'])
|
||||
->setAction($action->getAbsoluteUrl());
|
||||
}
|
||||
|
||||
protected function createTimeline()
|
||||
|
|
|
|||
|
|
@ -6,11 +6,10 @@ namespace Icinga\Module\Icingadb\Widget\Detail;
|
|||
|
||||
use Icinga\Module\Icingadb\Common\Auth;
|
||||
use Icinga\Module\Icingadb\Common\BaseFilter;
|
||||
use Icinga\Module\Monitoring\Forms\Command\Object\CheckNowCommandForm;
|
||||
use Icinga\Module\Monitoring\Forms\Command\Object\RemoveAcknowledgementCommandForm;
|
||||
use Icinga\Module\Icingadb\Forms\Command\Object\CheckNowForm;
|
||||
use Icinga\Module\Icingadb\Forms\Command\Object\RemoveAcknowledgementForm;
|
||||
use ipl\Html\BaseHtmlElement;
|
||||
use ipl\Html\Html;
|
||||
use ipl\Html\HtmlString;
|
||||
use ipl\Web\Filter\QueryString;
|
||||
use ipl\Web\Url;
|
||||
|
||||
|
|
@ -55,12 +54,11 @@ class MultiselectQuickActions extends BaseHtmlElement
|
|||
$this->summary->$acks > 0
|
||||
&& $this->getAuth()->hasPermission('monitoring/command/remove-acknowledgement')
|
||||
) {
|
||||
$removeAckForm = (new RemoveAcknowledgementCommandForm())
|
||||
$removeAckForm = (new RemoveAcknowledgementForm())
|
||||
->setAction($this->getLink('removeAcknowledgement'))
|
||||
->setLabelEnabled(true)
|
||||
->setObjects([true]);
|
||||
->setObjects(array_fill(0, $this->summary->$acks, null));
|
||||
|
||||
$this->add(Html::tag('li', new HtmlString($removeAckForm->render())));
|
||||
$this->add(Html::tag('li', $removeAckForm));
|
||||
}
|
||||
|
||||
if (
|
||||
|
|
@ -70,10 +68,7 @@ class MultiselectQuickActions extends BaseHtmlElement
|
|||
&& $this->getAuth()->hasPermission('monitoring/command/schedule-check/active-only')
|
||||
)
|
||||
) {
|
||||
$checkNowForm = (new CheckNowCommandForm())
|
||||
->setAction($this->getLink('checkNow'));
|
||||
|
||||
$this->add(Html::tag('li', new HtmlString($checkNowForm->render())));
|
||||
$this->add(Html::tag('li', (new CheckNowForm())->setAction($this->getLink('checkNow'))));
|
||||
}
|
||||
|
||||
if ($this->getAuth()->hasPermission('monitoring/command/comment/add')) {
|
||||
|
|
@ -151,6 +146,7 @@ class MultiselectQuickActions extends BaseHtmlElement
|
|||
protected function getLink($action)
|
||||
{
|
||||
return Url::fromPath("icingadb/{$this->type}s/$action")
|
||||
->setQueryString(QueryString::render($this->getBaseFilter()));
|
||||
->setQueryString(QueryString::render($this->getBaseFilter()))
|
||||
->getAbsoluteUrl();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,12 +12,10 @@ use Icinga\Module\Icingadb\Common\Icons;
|
|||
use Icinga\Module\Icingadb\Common\Links;
|
||||
use Icinga\Module\Icingadb\Common\MarkdownText;
|
||||
use Icinga\Module\Icingadb\Common\ServiceLinks;
|
||||
use Icinga\Module\Icingadb\Compat\CompatBackend;
|
||||
use Icinga\Module\Icingadb\Compat\CompatHost;
|
||||
use Icinga\Module\Icingadb\Compat\CompatObject;
|
||||
use Icinga\Module\Icingadb\Compat\CompatPluginOutput;
|
||||
use Icinga\Module\Icingadb\Compat\CompatService;
|
||||
use Icinga\Module\Icingadb\Compat\CustomvarFilter;
|
||||
use Icinga\Module\Icingadb\Forms\Command\Object\ToggleObjectFeaturesForm;
|
||||
use Icinga\Module\Icingadb\Model\Host;
|
||||
use Icinga\Module\Icingadb\Widget\DowntimeList;
|
||||
use Icinga\Module\Icingadb\Widget\EmptyState;
|
||||
|
|
@ -25,7 +23,6 @@ use Icinga\Module\Icingadb\Widget\HorizontalKeyValue;
|
|||
use Icinga\Module\Icingadb\Widget\ItemList\CommentList;
|
||||
use Icinga\Module\Icingadb\Widget\ShowMore;
|
||||
use Icinga\Module\Icingadb\Widget\TagList;
|
||||
use Icinga\Module\Monitoring\Forms\Command\Object\ToggleObjectFeaturesCommandForm;
|
||||
use Icinga\Module\Monitoring\Hook\DetailviewExtensionHook;
|
||||
use Icinga\Module\Monitoring\Hook\ObjectActionsHook;
|
||||
use Icinga\Web\Helper\Markdown;
|
||||
|
|
@ -364,21 +361,17 @@ class ObjectDetail extends BaseHtmlElement
|
|||
|
||||
protected function createFeatureToggles()
|
||||
{
|
||||
$form = new ToggleObjectFeaturesCommandForm([
|
||||
'backend' => new CompatBackend()
|
||||
]);
|
||||
$form = new ToggleObjectFeaturesForm($this->object);
|
||||
|
||||
if ($this->objectType === 'host') {
|
||||
$form->load(new CompatHost($this->object));
|
||||
$form->setAction(HostLinks::toggleFeatures($this->object));
|
||||
$form->setAction(HostLinks::toggleFeatures($this->object)->getAbsoluteUrl());
|
||||
} else {
|
||||
$form->load(new CompatService($this->object));
|
||||
$form->setAction(ServiceLinks::toggleFeatures($this->object, $this->object->host));
|
||||
$form->setAction(ServiceLinks::toggleFeatures($this->object, $this->object->host)->getAbsoluteUrl());
|
||||
}
|
||||
|
||||
return [
|
||||
Html::tag('h2', t('Feature Commands')),
|
||||
HtmlString::create($form->render())
|
||||
$form
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,13 +7,12 @@ namespace Icinga\Module\Icingadb\Widget\Detail;
|
|||
use Icinga\Chart\Donut;
|
||||
use Icinga\Module\Icingadb\Common\BaseFilter;
|
||||
use Icinga\Module\Icingadb\Common\Links;
|
||||
use Icinga\Module\Icingadb\Compat\CompatBackend;
|
||||
use Icinga\Module\Icingadb\Compat\FeatureStatus;
|
||||
use Icinga\Module\Icingadb\Forms\Command\Object\ToggleObjectFeaturesForm;
|
||||
use Icinga\Module\Icingadb\Util\FeatureStatus;
|
||||
use Icinga\Module\Icingadb\Widget\EmptyState;
|
||||
use Icinga\Module\Icingadb\Widget\HostStateBadges;
|
||||
use Icinga\Module\Icingadb\Widget\ServiceStateBadges;
|
||||
use Icinga\Module\Icingadb\Widget\VerticalKeyValue;
|
||||
use Icinga\Module\Monitoring\Forms\Command\Object\ToggleObjectFeaturesCommandForm;
|
||||
use ipl\Html\BaseHtmlElement;
|
||||
use ipl\Html\Html;
|
||||
use ipl\Html\HtmlString;
|
||||
|
|
@ -127,25 +126,25 @@ class ObjectsDetail extends BaseHtmlElement
|
|||
|
||||
protected function createFeatureToggles()
|
||||
{
|
||||
$form = new ToggleObjectFeaturesCommandForm([
|
||||
'backend' => new CompatBackend()
|
||||
]);
|
||||
|
||||
$form->load(new FeatureStatus($this->type, $this->summary));
|
||||
$form = new ToggleObjectFeaturesForm(new FeatureStatus($this->type, $this->summary));
|
||||
|
||||
if ($this->type === 'host') {
|
||||
$form->setAction(
|
||||
Links::toggleHostsFeatures()->setQueryString(QueryString::render($this->getBaseFilter()))
|
||||
Links::toggleHostsFeatures()
|
||||
->setQueryString(QueryString::render($this->getBaseFilter()))
|
||||
->getAbsoluteUrl()
|
||||
);
|
||||
} else {
|
||||
$form->setAction(
|
||||
Links::toggleServicesFeatures()->setQueryString(QueryString::render($this->getBaseFilter()))
|
||||
Links::toggleServicesFeatures()
|
||||
->setQueryString(QueryString::render($this->getBaseFilter()))
|
||||
->getAbsoluteUrl()
|
||||
);
|
||||
}
|
||||
|
||||
return [
|
||||
Html::tag('h2', t('Feature Commands')),
|
||||
HtmlString::create($form->render())
|
||||
$form
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,13 +7,12 @@ namespace Icinga\Module\Icingadb\Widget\Detail;
|
|||
use Icinga\Module\Icingadb\Common\Auth;
|
||||
use Icinga\Module\Icingadb\Common\HostLinks;
|
||||
use Icinga\Module\Icingadb\Common\ServiceLinks;
|
||||
use Icinga\Module\Icingadb\Forms\Command\Object\CheckNowForm;
|
||||
use Icinga\Module\Icingadb\Forms\Command\Object\RemoveAcknowledgementForm;
|
||||
use Icinga\Module\Icingadb\Model\Host;
|
||||
use Icinga\Module\Icingadb\Model\Service;
|
||||
use Icinga\Module\Monitoring\Forms\Command\Object\CheckNowCommandForm;
|
||||
use Icinga\Module\Monitoring\Forms\Command\Object\RemoveAcknowledgementCommandForm;
|
||||
use ipl\Html\BaseHtmlElement;
|
||||
use ipl\Html\Html;
|
||||
use ipl\Html\HtmlString;
|
||||
use ipl\Web\Widget\Icon;
|
||||
|
||||
class QuickActions extends BaseHtmlElement
|
||||
|
|
@ -37,12 +36,11 @@ class QuickActions extends BaseHtmlElement
|
|||
if ($this->object->state->is_problem) {
|
||||
if ($this->object->state->is_acknowledged) {
|
||||
if ($this->getAuth()->hasPermission('monitoring/command/remove-acknowledgement')) {
|
||||
$removeAckForm = (new RemoveAcknowledgementCommandForm())
|
||||
$removeAckForm = (new RemoveAcknowledgementForm())
|
||||
->setAction($this->getLink('removeAcknowledgement'))
|
||||
->setLabelEnabled(true)
|
||||
->setObjects([true]);
|
||||
->setObjects([$this->object]);
|
||||
|
||||
$this->add(Html::tag('li', new HtmlString($removeAckForm->render())));
|
||||
$this->add(Html::tag('li', $removeAckForm));
|
||||
}
|
||||
} elseif ($this->getAuth()->hasPermission('monitoring/command/acknowledge-problem')) {
|
||||
$this->assembleAction(
|
||||
|
|
@ -61,10 +59,7 @@ class QuickActions extends BaseHtmlElement
|
|||
&& $this->getAuth()->hasPermission('monitoring/command/schedule-check/active-only')
|
||||
)
|
||||
) {
|
||||
$checkNowForm = (new CheckNowCommandForm())
|
||||
->setAction($this->getLink('checkNow'));
|
||||
|
||||
$this->add(Html::tag('li', new HtmlString($checkNowForm->render())));
|
||||
$this->add(Html::tag('li', (new CheckNowForm())->setAction($this->getLink('checkNow'))));
|
||||
}
|
||||
|
||||
if ($this->getAuth()->hasPermission('monitoring/command/comment/add')) {
|
||||
|
|
@ -145,9 +140,9 @@ class QuickActions extends BaseHtmlElement
|
|||
protected function getLink($action)
|
||||
{
|
||||
if ($this->object instanceof Host) {
|
||||
return HostLinks::$action($this->object);
|
||||
return HostLinks::$action($this->object)->getAbsoluteUrl();
|
||||
} else {
|
||||
return ServiceLinks::$action($this->object, $this->object->host);
|
||||
return ServiceLinks::$action($this->object, $this->object->host)->getAbsoluteUrl();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
22
library/Icingadb/Widget/ItemList/CommandTransportList.php
Normal file
22
library/Icingadb/Widget/ItemList/CommandTransportList.php
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Widget\ItemList;
|
||||
|
||||
use Icinga\Module\Icingadb\Common\BaseOrderedItemList;
|
||||
use ipl\Web\Url;
|
||||
|
||||
class CommandTransportList extends BaseOrderedItemList
|
||||
{
|
||||
protected function init()
|
||||
{
|
||||
$this->getAttributes()->add('class', 'command-transport-list');
|
||||
$this->setDetailUrl(Url::fromPath('icingadb/command-transport/show'));
|
||||
}
|
||||
|
||||
protected function getItemClass()
|
||||
{
|
||||
return CommandTransportListItem::class;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
|
||||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
namespace Icinga\Module\Icingadb\Widget\ItemList;
|
||||
|
||||
use Icinga\Module\Icingadb\Common\BaseOrderedListItem;
|
||||
use ipl\Html\BaseHtmlElement;
|
||||
use ipl\Html\HtmlElement;
|
||||
use ipl\Stdlib\Filter;
|
||||
use ipl\Web\Url;
|
||||
use ipl\Web\Widget\Icon;
|
||||
use ipl\Web\Widget\Link;
|
||||
|
||||
class CommandTransportListItem extends BaseOrderedListItem
|
||||
{
|
||||
protected function init()
|
||||
{
|
||||
$this->setDetailFilter(Filter::equal('name', $this->item->name));
|
||||
}
|
||||
|
||||
protected function assembleHeader(BaseHtmlElement $header)
|
||||
{
|
||||
}
|
||||
|
||||
protected function assembleMain(BaseHtmlElement $main)
|
||||
{
|
||||
$main->add(new Link(
|
||||
new HtmlElement('strong', null, $this->item->name),
|
||||
Url::fromPath('icingadb/command-transport/show', ['name' => $this->item->name])
|
||||
));
|
||||
|
||||
$main->add(new Link(
|
||||
new Icon('trash', ['title' => sprintf(t('Remove command transport "%s"'), $this->item->name)]),
|
||||
Url::fromPath('icingadb/command-transport/remove', ['name' => $this->item->name]),
|
||||
[
|
||||
'class' => 'pull-right action-link',
|
||||
'data-icinga-modal' => true,
|
||||
'data-no-icinga-ajax' => true
|
||||
]
|
||||
));
|
||||
|
||||
if ($this->getOrder() + 1 < $this->list->count()) {
|
||||
$main->add((new Link(
|
||||
new Icon('arrow-down'),
|
||||
Url::fromPath('icingadb/command-transport/sort', [
|
||||
'name' => $this->item->name,
|
||||
'pos' => $this->getOrder() + 1
|
||||
]),
|
||||
['class' => 'pull-right action-link']
|
||||
))->setBaseTarget('_self'));
|
||||
}
|
||||
|
||||
if ($this->getOrder() > 0) {
|
||||
$main->add((new Link(
|
||||
new Icon('arrow-up'),
|
||||
Url::fromPath('icingadb/command-transport/sort', [
|
||||
'name' => $this->item->name,
|
||||
'pos' => $this->getOrder() - 1
|
||||
]),
|
||||
['class' => 'pull-right action-link']
|
||||
))->setBaseTarget('_self'));
|
||||
}
|
||||
}
|
||||
|
||||
protected function createVisual()
|
||||
{
|
||||
}
|
||||
}
|
||||
19
public/css/compat/spinner.less
Normal file
19
public/css/compat/spinner.less
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */
|
||||
|
||||
a.spinner.active > i.fa-sync-alt,
|
||||
button.spinner.active > i.fa-sync-alt,
|
||||
i.fa-sync-alt.spinner.active {
|
||||
&:before {
|
||||
// We use a different icon font, hence why the unicode is redefined (overridden) here
|
||||
content: '\f2f1';
|
||||
}
|
||||
}
|
||||
|
||||
a.spinner.active > i.fa-trash,
|
||||
button.spinner.active > i.fa-trash,
|
||||
i.fa-trash.spinner.active {
|
||||
&:before {
|
||||
// We use a different icon font, hence why the unicode is redefined (overridden) here
|
||||
content: '\f1f8';
|
||||
}
|
||||
}
|
||||
21
public/css/form/schedule-service-downtime-form.less
Normal file
21
public/css/form/schedule-service-downtime-form.less
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
.downtime-duration {
|
||||
> label {
|
||||
display: flex;
|
||||
flex: 1 1 auto;
|
||||
flex-flow: row-reverse;
|
||||
|
||||
input {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
span {
|
||||
margin-left: .5em;
|
||||
padding: .5625em 0;
|
||||
line-height: 1.1em;
|
||||
}
|
||||
|
||||
&:not(:last-child) {
|
||||
margin-right: 1.5em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -42,7 +42,7 @@
|
|||
ActionList.prototype.onClick = function (event) {
|
||||
var _this = event.data.self;
|
||||
var $activeItems;
|
||||
var $target = $(this);
|
||||
var $target = $(event.currentTarget);
|
||||
var $item = $target.closest('.list-item');
|
||||
var $list = $item.parent('.action-list');
|
||||
|
||||
|
|
@ -90,7 +90,7 @@
|
|||
$activeItems = $list.find('.list-item.active');
|
||||
|
||||
if ($activeItems.length === 0) {
|
||||
if (_this.icinga.loader.getLinkTargetFor($item).attr('id') === 'col2') {
|
||||
if (_this.icinga.loader.getLinkTargetFor($target).attr('id') === 'col2') {
|
||||
_this.icinga.ui.layout1col();
|
||||
}
|
||||
} else {
|
||||
|
|
@ -107,7 +107,7 @@
|
|||
}
|
||||
|
||||
_this.icinga.loader.loadUrl(
|
||||
url, _this.icinga.loader.getLinkTargetFor($item)
|
||||
url, _this.icinga.loader.getLinkTargetFor($target)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
|
@ -147,7 +147,7 @@
|
|||
|
||||
var $list = $target.find('.action-list');
|
||||
|
||||
if ($list.length && $list.is('[data-icinga-multiselect-url]')) {
|
||||
if ($list.length && $list.is('[data-icinga-multiselect-url], [data-icinga-detail-url]')) {
|
||||
var _this = event.data.self;
|
||||
var detailUrl = _this.icinga.utils.parseUrl(_this.icinga.history.getCol2State().replace(/^#!/, ''));
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue