2015-06-30 11:19:31 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace Icinga\Module\Director\Web\Controller;
|
|
|
|
|
2016-11-08 02:00:38 +01:00
|
|
|
use Icinga\Data\Filter\FilterChain;
|
|
|
|
use Icinga\Data\Filter\FilterExpression;
|
2016-10-14 20:32:34 +02:00
|
|
|
use Icinga\Exception\NotFoundError;
|
2016-05-19 11:01:13 +02:00
|
|
|
use Icinga\Data\Filter\Filter;
|
2017-06-21 01:21:09 +02:00
|
|
|
use Icinga\Module\Director\Forms\IcingaMultiEditForm;
|
2017-08-21 09:50:08 +02:00
|
|
|
use Icinga\Module\Director\Objects\IcingaHost;
|
2016-05-19 11:01:13 +02:00
|
|
|
use Icinga\Module\Director\Objects\IcingaObject;
|
2017-08-16 08:17:31 +02:00
|
|
|
use Icinga\Module\Director\RestApi\IcingaObjectsHandler;
|
2017-06-21 01:21:09 +02:00
|
|
|
use Icinga\Module\Director\Web\ActionBar\ObjectsActionBar;
|
|
|
|
use Icinga\Module\Director\Web\ActionBar\TemplateActionBar;
|
2017-07-13 11:48:16 +02:00
|
|
|
use Icinga\Module\Director\Web\Table\ApplyRulesTable;
|
2017-06-21 01:21:09 +02:00
|
|
|
use Icinga\Module\Director\Web\Table\ObjectSetTable;
|
|
|
|
use Icinga\Module\Director\Web\Table\ObjectsTable;
|
|
|
|
use Icinga\Module\Director\Web\Table\TemplatesTable;
|
|
|
|
use Icinga\Module\Director\Web\Tabs\ObjectsTabs;
|
|
|
|
use Icinga\Module\Director\Web\Tree\TemplateTreeRenderer;
|
2017-10-09 15:23:27 +02:00
|
|
|
use dipl\Html\Link;
|
2017-10-11 10:51:43 +02:00
|
|
|
use Icinga\Module\Director\Web\Widget\AdditionalTableActions;
|
2016-05-19 11:01:13 +02:00
|
|
|
|
2015-06-30 11:19:31 +02:00
|
|
|
abstract class ObjectsController extends ActionController
|
|
|
|
{
|
2016-02-17 19:35:29 +01:00
|
|
|
protected $isApified = true;
|
|
|
|
|
2017-07-20 22:29:23 +02:00
|
|
|
/** @var ObjectsTable */
|
|
|
|
protected $table;
|
|
|
|
|
2017-06-21 01:21:09 +02:00
|
|
|
protected function checkDirectorPermissions()
|
2015-06-30 11:19:31 +02:00
|
|
|
{
|
2017-08-15 02:51:59 +02:00
|
|
|
if ($this->getRequest()->getActionName() !== 'sets') {
|
|
|
|
$this->assertPermission('director/' . $this->getPluralBaseType());
|
|
|
|
}
|
2015-06-30 11:19:31 +02:00
|
|
|
}
|
2017-08-25 22:42:38 +02:00
|
|
|
|
2017-06-21 01:21:09 +02:00
|
|
|
/**
|
|
|
|
* @return $this
|
|
|
|
*/
|
|
|
|
protected function addObjectsTabs()
|
2015-06-30 11:19:31 +02:00
|
|
|
{
|
2017-06-21 01:21:09 +02:00
|
|
|
$tabName = $this->getRequest()->getActionName();
|
|
|
|
if (substr($this->getType(), -5) === 'Group') {
|
|
|
|
$tabName = 'groups';
|
2015-07-30 09:45:32 +02:00
|
|
|
}
|
2017-07-20 09:53:31 +02:00
|
|
|
$this->tabs(new ObjectsTabs($this->getBaseType(), $this->Auth()))
|
|
|
|
->activate($tabName);
|
2016-01-25 14:55:51 +01:00
|
|
|
|
2017-06-21 01:21:09 +02:00
|
|
|
return $this;
|
2015-06-30 11:19:31 +02:00
|
|
|
}
|
|
|
|
|
2017-08-16 08:17:31 +02:00
|
|
|
protected function apiRequestHandler()
|
|
|
|
{
|
2017-09-18 10:23:36 +02:00
|
|
|
$request = $this->getRequest();
|
2017-08-21 09:50:08 +02:00
|
|
|
$table = $this->getTable();
|
2017-09-18 10:23:36 +02:00
|
|
|
if ($request->getControllerName() === 'services'
|
2017-08-21 09:50:08 +02:00
|
|
|
&& $host = $this->params->get('host')
|
|
|
|
) {
|
|
|
|
$host = IcingaHost::load($host, $this->db());
|
|
|
|
$table->getQuery()->where('host_id = ?', $host->get('id'));
|
|
|
|
}
|
|
|
|
|
2017-09-18 10:23:36 +02:00
|
|
|
if ($request->getActionName() === 'templates') {
|
|
|
|
$table->filterObjectType('template');
|
|
|
|
}
|
|
|
|
|
2017-08-16 08:17:31 +02:00
|
|
|
return (new IcingaObjectsHandler(
|
2017-09-18 10:23:36 +02:00
|
|
|
$request,
|
2017-08-16 08:17:31 +02:00
|
|
|
$this->getResponse(),
|
|
|
|
$this->db()
|
2017-08-21 09:50:08 +02:00
|
|
|
))->setTable($table);
|
2017-08-16 08:17:31 +02:00
|
|
|
}
|
|
|
|
|
2017-06-21 01:21:09 +02:00
|
|
|
public function indexAction()
|
2017-03-06 21:46:22 +01:00
|
|
|
{
|
2017-08-02 15:54:03 +02:00
|
|
|
if ($this->getRequest()->isApiRequest()) {
|
2017-08-16 08:17:31 +02:00
|
|
|
$this->apiRequestHandler()->dispatch();
|
2017-08-02 15:54:03 +02:00
|
|
|
return;
|
|
|
|
}
|
2017-10-11 10:55:20 +02:00
|
|
|
|
2017-06-21 01:21:09 +02:00
|
|
|
$type = $this->getType();
|
2017-10-11 10:55:20 +02:00
|
|
|
if ($this->params->get('format') === 'json') {
|
|
|
|
$filename = sprintf(
|
|
|
|
"director-${type}_%s.json",
|
|
|
|
date('YmdHis')
|
|
|
|
);
|
|
|
|
$this->getResponse()->setHeader('Content-disposition', "attachment; filename=$filename", true);
|
|
|
|
$this->apiRequestHandler()->dispatch();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-06-21 01:21:09 +02:00
|
|
|
$this
|
|
|
|
->addObjectsTabs()
|
|
|
|
->setAutorefreshInterval(10)
|
2016-09-17 00:25:11 +02:00
|
|
|
->addTitle($this->translate(ucfirst($this->getPluralType())))
|
2017-06-21 01:21:09 +02:00
|
|
|
->actions(new ObjectsActionBar($type, $this->url()));
|
|
|
|
|
2017-07-31 10:37:08 +02:00
|
|
|
if ($type === 'command' && $this->params->get('type') === 'external_object') {
|
|
|
|
$this->tabs()->activate('external');
|
|
|
|
}
|
|
|
|
|
2017-08-02 15:54:03 +02:00
|
|
|
// Hint: might be used in controllers extending this
|
|
|
|
$this->table = $this->getTable();
|
|
|
|
$this->table->renderTo($this);
|
2017-10-11 10:51:43 +02:00
|
|
|
(new AdditionalTableActions($this->getAuth(), $this->url()))
|
|
|
|
->appendTo($this->actions());
|
2017-08-02 15:54:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
protected function getTable()
|
|
|
|
{
|
|
|
|
return ObjectsTable::create($this->getType(), $this->db())
|
|
|
|
->setAuth($this->getAuth());
|
2017-03-06 21:46:22 +01:00
|
|
|
}
|
|
|
|
|
2016-10-13 21:07:41 +02:00
|
|
|
public function editAction()
|
|
|
|
{
|
2016-10-14 20:32:34 +02:00
|
|
|
$type = ucfirst($this->getType());
|
|
|
|
|
|
|
|
if (empty($this->multiEdit)) {
|
|
|
|
throw new NotFoundError('Cannot edit multiple "%s" instances', $type);
|
|
|
|
}
|
|
|
|
|
2017-04-19 19:46:40 +02:00
|
|
|
$objects = $this->loadMultiObjectsFromParams();
|
2017-06-21 01:21:09 +02:00
|
|
|
$formName = 'icinga' . $type;
|
2017-07-21 13:26:59 +02:00
|
|
|
$form = IcingaMultiEditForm::load()
|
2017-04-19 19:46:40 +02:00
|
|
|
->setObjects($objects)
|
|
|
|
->pickElementsFrom($this->loadForm($formName), $this->multiEdit);
|
|
|
|
if ($type === 'Service') {
|
2017-07-21 13:26:59 +02:00
|
|
|
$form->setListUrl('director/services');
|
|
|
|
} elseif ($type === 'Host') {
|
|
|
|
$form->setListUrl('director/hosts');
|
2017-04-19 19:46:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
$form->handleRequest();
|
2017-06-21 01:21:09 +02:00
|
|
|
|
|
|
|
$this
|
|
|
|
->addSingleTab($this->translate('Multiple objects'))
|
|
|
|
->addTitle(
|
|
|
|
$this->translate('Modify %d objects'),
|
|
|
|
count($objects)
|
|
|
|
)->content()->add($form);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Loads the TemplatesTable or the TemplateTreeRenderer
|
|
|
|
*
|
|
|
|
* Passing render=tree switches to the tree view.
|
|
|
|
*/
|
|
|
|
public function templatesAction()
|
|
|
|
{
|
2017-09-18 10:23:36 +02:00
|
|
|
if ($this->getRequest()->isApiRequest()) {
|
|
|
|
$this->apiRequestHandler()->dispatch();
|
|
|
|
return;
|
|
|
|
}
|
2017-06-21 01:21:09 +02:00
|
|
|
$type = $this->getType();
|
2017-07-27 12:12:12 +02:00
|
|
|
$shortType = IcingaObject::createByType($type)->getShortTableName();
|
2017-06-21 01:21:09 +02:00
|
|
|
$this
|
|
|
|
->assertPermission('director/admin')
|
|
|
|
->addObjectsTabs()
|
2017-07-28 09:56:17 +02:00
|
|
|
->setAutorefreshInterval(10)
|
2017-06-21 01:21:09 +02:00
|
|
|
->addTitle(
|
|
|
|
$this->translate('All your %s Templates'),
|
|
|
|
$this->translate(ucfirst($type))
|
|
|
|
)
|
2017-07-27 12:12:12 +02:00
|
|
|
->actions(new TemplateActionBar($shortType, $this->url()));
|
2017-06-21 01:21:09 +02:00
|
|
|
|
|
|
|
$this->params->get('render') === 'tree'
|
2017-07-27 12:12:12 +02:00
|
|
|
? TemplateTreeRenderer::showType($shortType, $this, $this->db())
|
|
|
|
: TemplatesTable::create($shortType, $this->db())->renderTo($this);
|
2017-06-21 01:21:09 +02:00
|
|
|
}
|
|
|
|
|
2017-07-14 11:20:11 +02:00
|
|
|
protected function assertApplyRulePermission()
|
|
|
|
{
|
|
|
|
return $this->assertPermission('director/admin');
|
|
|
|
}
|
|
|
|
|
2017-06-21 01:21:09 +02:00
|
|
|
public function applyrulesAction()
|
|
|
|
{
|
2017-07-14 11:36:25 +02:00
|
|
|
$type = $this->getType();
|
|
|
|
$tType = $this->translate(ucfirst($type));
|
2017-06-21 01:21:09 +02:00
|
|
|
$this
|
2017-07-14 11:20:11 +02:00
|
|
|
->assertApplyRulePermission()
|
2017-06-21 01:21:09 +02:00
|
|
|
->addObjectsTabs()
|
2017-07-28 09:56:17 +02:00
|
|
|
->setAutorefreshInterval(10)
|
2017-07-13 11:48:16 +02:00
|
|
|
->addTitle(
|
|
|
|
$this->translate('All your %s Apply Rules'),
|
2017-07-14 11:36:25 +02:00
|
|
|
$tType
|
2017-07-13 11:48:16 +02:00
|
|
|
);
|
2017-06-21 01:21:09 +02:00
|
|
|
$this->actions()/*->add(
|
|
|
|
$this->getBackToDashboardLink()
|
|
|
|
)*/->add(
|
|
|
|
Link::create(
|
|
|
|
$this->translate('Add'),
|
2017-07-14 11:36:25 +02:00
|
|
|
"director/$type/add",
|
2017-07-14 11:40:57 +02:00
|
|
|
['type' => 'apply'],
|
2017-06-21 01:21:09 +02:00
|
|
|
[
|
2017-07-14 11:36:25 +02:00
|
|
|
'title' => sprintf(
|
|
|
|
$this->translate('Create a new %s Apply Rule'),
|
|
|
|
$tType
|
|
|
|
),
|
2017-07-11 08:33:03 +02:00
|
|
|
'class' => 'icon-plus',
|
|
|
|
'data-base-target' => '_next'
|
2017-06-21 01:21:09 +02:00
|
|
|
]
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
2017-07-13 11:48:16 +02:00
|
|
|
$table = new ApplyRulesTable($this->db());
|
|
|
|
$table->setType($this->getType());
|
|
|
|
$table->renderTo($this);
|
2017-06-21 01:21:09 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public function setsAction()
|
|
|
|
{
|
|
|
|
$type = $this->getType();
|
2017-07-25 14:47:35 +02:00
|
|
|
$tType = $this->translate(ucfirst($type));
|
2017-06-21 01:21:09 +02:00
|
|
|
$this
|
2017-08-15 02:51:59 +02:00
|
|
|
->assertPermission('director/' . $this->getBaseType() . '_sets')
|
2017-06-21 01:21:09 +02:00
|
|
|
->addObjectsTabs()
|
|
|
|
->requireSupportFor('Sets')
|
2017-07-28 09:56:17 +02:00
|
|
|
->setAutorefreshInterval(10)
|
2017-06-21 01:21:09 +02:00
|
|
|
->addTitle(
|
|
|
|
$this->translate('Icinga %s Sets'),
|
2017-07-25 14:47:35 +02:00
|
|
|
$tType
|
2017-06-21 01:21:09 +02:00
|
|
|
);
|
|
|
|
|
2017-08-15 02:51:59 +02:00
|
|
|
$this->actions()->add(
|
2017-07-25 14:47:35 +02:00
|
|
|
Link::create(
|
|
|
|
$this->translate('Add'),
|
|
|
|
"director/${type}set/add",
|
|
|
|
null,
|
|
|
|
[
|
|
|
|
'title' => sprintf(
|
|
|
|
$this->translate('Create a new %s Set'),
|
|
|
|
$tType
|
|
|
|
),
|
|
|
|
'class' => 'icon-plus',
|
|
|
|
'data-base-target' => '_next'
|
|
|
|
]
|
|
|
|
)
|
|
|
|
);
|
|
|
|
|
2017-06-21 01:21:09 +02:00
|
|
|
ObjectSetTable::create($type, $this->db())->renderTo($this);
|
2017-04-19 19:46:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
protected function loadMultiObjectsFromParams()
|
|
|
|
{
|
2016-10-13 21:07:41 +02:00
|
|
|
$filter = Filter::fromQueryString($this->params->toString());
|
2017-06-21 01:21:09 +02:00
|
|
|
$type = $this->getType();
|
2016-10-13 21:07:41 +02:00
|
|
|
$objects = array();
|
|
|
|
$db = $this->db();
|
2016-11-08 02:00:38 +01:00
|
|
|
/** @var $filter FilterChain */
|
2016-10-13 21:07:41 +02:00
|
|
|
foreach ($filter->filters() as $sub) {
|
2016-11-08 02:00:38 +01:00
|
|
|
/** @var $sub FilterChain */
|
2016-10-13 21:07:41 +02:00
|
|
|
foreach ($sub->filters() as $ex) {
|
2016-11-08 02:00:38 +01:00
|
|
|
/** @var $ex FilterChain|FilterExpression */
|
2017-04-19 19:46:40 +02:00
|
|
|
$col = $ex->getColumn();
|
|
|
|
if ($ex->isExpression()) {
|
|
|
|
if ($col === 'name') {
|
|
|
|
$name = $ex->getExpression();
|
2017-06-21 01:21:09 +02:00
|
|
|
$objects[$name] = IcingaObject::loadByType($type, $name, $db);
|
2017-04-19 19:46:40 +02:00
|
|
|
} elseif ($col === 'id') {
|
|
|
|
$name = $ex->getExpression();
|
2017-06-21 01:21:09 +02:00
|
|
|
$objects[$name] = IcingaObject::loadByType($type, ['id' => $name], $db);
|
2017-04-19 19:46:40 +02:00
|
|
|
}
|
2016-10-13 21:07:41 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-10-14 20:32:34 +02:00
|
|
|
|
2017-04-19 19:46:40 +02:00
|
|
|
return $objects;
|
2016-10-13 21:07:41 +02:00
|
|
|
}
|
|
|
|
|
2017-06-21 01:21:09 +02:00
|
|
|
/**
|
|
|
|
* @param $feature
|
|
|
|
* @return $this
|
|
|
|
* @throws NotFoundError
|
|
|
|
*/
|
|
|
|
protected function requireSupportFor($feature)
|
2016-05-19 11:01:13 +02:00
|
|
|
{
|
2017-06-21 01:21:09 +02:00
|
|
|
if ($this->supports($feature) !== true) {
|
|
|
|
throw new NotFoundError(
|
|
|
|
'%s does not support %s',
|
|
|
|
$this->getType(),
|
|
|
|
$feature
|
|
|
|
);
|
|
|
|
}
|
2016-05-19 11:01:13 +02:00
|
|
|
|
2017-06-21 01:21:09 +02:00
|
|
|
return $this;
|
2015-07-30 09:49:01 +02:00
|
|
|
}
|
|
|
|
|
2017-06-21 01:21:09 +02:00
|
|
|
protected function supports($feature)
|
2016-10-13 11:13:21 +02:00
|
|
|
{
|
2017-06-21 01:21:09 +02:00
|
|
|
$func = "supports$feature";
|
|
|
|
return IcingaObject::createByType($this->getType())->$func();
|
2016-10-13 11:13:21 +02:00
|
|
|
}
|
|
|
|
|
2017-06-21 01:21:09 +02:00
|
|
|
protected function getBaseType()
|
2015-06-30 11:19:31 +02:00
|
|
|
{
|
2017-06-21 01:21:09 +02:00
|
|
|
$type = $this->getType();
|
|
|
|
if (substr($type, -5) === 'Group') {
|
|
|
|
return substr($type, 0, -5);
|
|
|
|
} else {
|
|
|
|
return $type;
|
2015-06-30 11:19:31 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function getType()
|
|
|
|
{
|
|
|
|
// Strip final 's' and upcase an eventual 'group'
|
|
|
|
return preg_replace(
|
2016-09-17 00:25:11 +02:00
|
|
|
array('/group$/', '/period$/', '/argument$/', '/apiuser$/', '/dependencie$/'),
|
|
|
|
array('Group', 'Period', 'Argument', 'ApiUser', 'dependency'),
|
2015-07-30 09:45:32 +02:00
|
|
|
str_replace(
|
|
|
|
'template',
|
2016-02-26 11:58:37 +01:00
|
|
|
'',
|
2015-07-30 09:45:32 +02:00
|
|
|
substr($this->getRequest()->getControllerName(), 0, -1)
|
|
|
|
)
|
2015-06-30 11:19:31 +02:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2017-06-21 01:21:09 +02:00
|
|
|
protected function getPluralType()
|
2015-06-30 11:19:31 +02:00
|
|
|
{
|
2017-08-25 22:42:38 +02:00
|
|
|
return preg_replace('/cys$/', 'cies', $this->getType() . 's');
|
2017-06-21 01:21:09 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
protected function getPluralBaseType()
|
|
|
|
{
|
2017-08-25 22:42:38 +02:00
|
|
|
return preg_replace('/cys$/', 'cies', $this->getBaseType() . 's');
|
2015-06-30 11:19:31 +02:00
|
|
|
}
|
|
|
|
}
|