Implement Icinga Dependency Configuration.
This commit is contained in:
parent
8a6480e40e
commit
6bea1eff41
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Icinga\Module\Director\Clicommands;
|
||||||
|
|
||||||
|
use Icinga\Module\Director\Cli\ObjectCommand;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manage Icinga Dependencies
|
||||||
|
*
|
||||||
|
* Use this command to show, create, modify or delete Icinga Dependency
|
||||||
|
* objects
|
||||||
|
*/
|
||||||
|
class DependencyCommand extends ObjectCommand
|
||||||
|
{
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Icinga\Module\Director\Controllers;
|
||||||
|
|
||||||
|
use Icinga\Module\Director\Web\Controller\ObjectsController;
|
||||||
|
|
||||||
|
class DependenciesController extends ObjectsController
|
||||||
|
{
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Icinga\Module\Director\Controllers;
|
||||||
|
|
||||||
|
use Icinga\Module\Director\Web\Controller\ObjectController;
|
||||||
|
use Icinga\Module\Director\Objects\IcingaDependency;
|
||||||
|
|
||||||
|
class DependencyController extends ObjectController
|
||||||
|
{
|
||||||
|
protected $apply;
|
||||||
|
|
||||||
|
protected function beforeTabs()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function init()
|
||||||
|
{
|
||||||
|
parent::init();
|
||||||
|
|
||||||
|
if ($apply = $this->params->get('apply')) {
|
||||||
|
$this->apply = IcingaDependency::load(
|
||||||
|
array('object_name' => $apply, 'object_type' => 'template'),
|
||||||
|
$this->db()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function loadObject()
|
||||||
|
{
|
||||||
|
if ($this->object === null) {
|
||||||
|
if ($name = $this->params->get('name')) {
|
||||||
|
$params = array('object_name' => $name);
|
||||||
|
$db = $this->db();
|
||||||
|
|
||||||
|
$this->object = IcingaDependency::load($params, $db);
|
||||||
|
} else {
|
||||||
|
parent::loadObject();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function loadForm($name)
|
||||||
|
{
|
||||||
|
$form = parent::loadForm($name);
|
||||||
|
return $form;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function beforeHandlingAddRequest($form)
|
||||||
|
{
|
||||||
|
if ($this->apply) {
|
||||||
|
$form->createApplyRuleFor($this->apply);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Icinga\Module\Director\Controllers;
|
||||||
|
|
||||||
|
use Icinga\Module\Director\Objects\IcingaDependency;
|
||||||
|
use Icinga\Module\Director\Web\Controller\TemplateController;
|
||||||
|
|
||||||
|
class DependencytemplateController extends TemplateController
|
||||||
|
{
|
||||||
|
protected function requireTemplate()
|
||||||
|
{
|
||||||
|
return IcingaDependency::load([
|
||||||
|
'object_name' => $this->params->get('name')
|
||||||
|
], $this->db());
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,6 +6,7 @@ use Icinga\Module\Director\Objects\IcingaService;
|
||||||
use Icinga\Module\Director\Web\Controller\ActionController;
|
use Icinga\Module\Director\Web\Controller\ActionController;
|
||||||
use Icinga\Data\Filter\Filter;
|
use Icinga\Data\Filter\Filter;
|
||||||
use ipl\Html\Util;
|
use ipl\Html\Util;
|
||||||
|
use Icinga\Module\Director\Objects\HostApplyMatches;
|
||||||
|
|
||||||
class SuggestController extends ActionController
|
class SuggestController extends ActionController
|
||||||
{
|
{
|
||||||
|
@ -91,6 +92,48 @@ class SuggestController extends ActionController
|
||||||
return $db->fetchCol($query);
|
return $db->fetchCol($query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function suggestServicenames()
|
||||||
|
{
|
||||||
|
$r=array();
|
||||||
|
$this->assertPermission('director/services');
|
||||||
|
$db = $this->db()->getDbAdapter();
|
||||||
|
$for_host = $this->getRequest()->getPost('for_host');
|
||||||
|
if (!empty($for_host)) {
|
||||||
|
$tmp_host = IcingaHost::load($for_host,$this->db());
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = $db->select()->distinct()
|
||||||
|
->from('icinga_service', 'object_name')
|
||||||
|
->order('object_name')
|
||||||
|
->where("object_type IN ('object','apply')");
|
||||||
|
if (!empty($tmp_host)) {
|
||||||
|
$query->where('host_id = ?',$tmp_host->id);
|
||||||
|
}
|
||||||
|
$r = array_merge($r,$db->fetchCol($query));
|
||||||
|
if (!empty($tmp_host)) {
|
||||||
|
$resolver = $tmp_host->templateResolver();
|
||||||
|
foreach ($resolver->fetchResolvedParents() as $template_obj) {
|
||||||
|
$query = $db->select()->distinct()
|
||||||
|
->from('icinga_service', 'object_name')
|
||||||
|
->order('object_name')
|
||||||
|
->where("object_type IN ('object','apply')")
|
||||||
|
->where('host_id = ?', $template_obj->id);
|
||||||
|
$r = array_merge($r,$db->fetchCol($query));
|
||||||
|
}
|
||||||
|
|
||||||
|
$matcher = HostApplyMatches::prepare($tmp_host);
|
||||||
|
foreach ($this->getAllApplyRules() as $rule) {
|
||||||
|
if ($matcher->matchesFilter($rule->filter)) { //TODO
|
||||||
|
$r[]=$rule->name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
natcasesort($r);
|
||||||
|
return $r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
protected function suggestHosttemplates()
|
protected function suggestHosttemplates()
|
||||||
{
|
{
|
||||||
$this->assertPermission('director/hosts');
|
$this->assertPermission('director/hosts');
|
||||||
|
@ -199,6 +242,17 @@ class SuggestController extends ActionController
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function suggestDependencytemplates()
|
||||||
|
{
|
||||||
|
$this->assertPermission('director/hosts');
|
||||||
|
$db = $this->db()->getDbAdapter();
|
||||||
|
$query = $db->select()
|
||||||
|
->from('icinga_dependency', 'object_name')
|
||||||
|
->order('object_name')
|
||||||
|
->where("object_type = 'template'");
|
||||||
|
return $db->fetchCol($query);
|
||||||
|
}
|
||||||
|
|
||||||
protected function highlight($val, $search)
|
protected function highlight($val, $search)
|
||||||
{
|
{
|
||||||
$search = ($search);
|
$search = ($search);
|
||||||
|
@ -209,4 +263,33 @@ class SuggestController extends ActionController
|
||||||
$val
|
$val
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function getAllApplyRules()
|
||||||
|
{
|
||||||
|
$allApplyRules=$this->fetchAllApplyRules();
|
||||||
|
foreach ($allApplyRules as $rule) {
|
||||||
|
$rule->filter = Filter::fromQueryString($rule->assign_filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $allApplyRules;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function fetchAllApplyRules()
|
||||||
|
{
|
||||||
|
$db = $this->db()->getDbAdapter();
|
||||||
|
$query = $db->select()->from(
|
||||||
|
array('s' => 'icinga_service'),
|
||||||
|
array(
|
||||||
|
'id' => 's.id',
|
||||||
|
'name' => 's.object_name',
|
||||||
|
'assign_filter' => 's.assign_filter',
|
||||||
|
)
|
||||||
|
)->where('object_type = ? AND assign_filter IS NOT NULL', 'apply');
|
||||||
|
|
||||||
|
return $db->fetchAll($query);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,252 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Icinga\Module\Director\Forms;
|
||||||
|
|
||||||
|
use Icinga\Module\Director\Web\Form\DirectorObjectForm;
|
||||||
|
use Icinga\Module\Director\Objects\IcingaHost;
|
||||||
|
use Icinga\Module\Director\Objects\IcingaService;
|
||||||
|
use Icinga\Module\Director\Objects\IcingaDependency;
|
||||||
|
|
||||||
|
class IcingaDependencyForm extends DirectorObjectForm
|
||||||
|
{
|
||||||
|
public function setup()
|
||||||
|
{
|
||||||
|
$this->setupDependencyElements();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function setupDependencyElements() {
|
||||||
|
|
||||||
|
$this->addObjectTypeElement();
|
||||||
|
if (! $this->hasObjectType()) {
|
||||||
|
$this->groupMainProperties();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->addNameElement()
|
||||||
|
->addDisabledElement()
|
||||||
|
->addImportsElement()
|
||||||
|
->addObjectsElement()
|
||||||
|
->addBooleanElements()
|
||||||
|
->addPeriodElement()
|
||||||
|
->addAssignmentElements()
|
||||||
|
->addEventFilterElements(array('states'))
|
||||||
|
->groupMainProperties()
|
||||||
|
->setButtons();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function addNameElement()
|
||||||
|
{
|
||||||
|
$this->addElement('text', 'object_name', array(
|
||||||
|
'label' => $this->translate('Name'),
|
||||||
|
'required' => true,
|
||||||
|
'description' => $this->translate('Name for the Icinga dependency you are going to create')
|
||||||
|
));
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected function addAssignmentElements()
|
||||||
|
{
|
||||||
|
if (!$this->object || !$this->object->isApplyRule()) {
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->addElement('select', 'apply_to', array(
|
||||||
|
'label' => $this->translate('Apply to'),
|
||||||
|
'description' => $this->translate(
|
||||||
|
'Whether this dependency should affect hosts or services'
|
||||||
|
),
|
||||||
|
'required' => true,
|
||||||
|
'class' => 'autosubmit',
|
||||||
|
'multiOptions' => $this->optionalEnum(
|
||||||
|
array(
|
||||||
|
'host' => $this->translate('Hosts'),
|
||||||
|
'service' => $this->translate('Services'),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
));
|
||||||
|
|
||||||
|
$applyTo = $this->getSentOrObjectValue('apply_to');
|
||||||
|
|
||||||
|
if ($applyTo === 'host') {
|
||||||
|
$columns = IcingaHost::enumProperties($this->db, 'host.');
|
||||||
|
} elseif ($applyTo === 'service') {
|
||||||
|
// TODO: Also add host properties
|
||||||
|
$columns = IcingaService::enumProperties($this->db, 'service.');
|
||||||
|
} else {
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->addAssignFilter(array(
|
||||||
|
'columns' => $columns,
|
||||||
|
'required' => true,
|
||||||
|
'description' => $this->translate(
|
||||||
|
'This allows you to configure an assignment filter. Please feel'
|
||||||
|
. ' free to combine as many nested operators as you want'
|
||||||
|
)
|
||||||
|
));
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function addPeriodElement()
|
||||||
|
{
|
||||||
|
$periods = $this->db->enumTimeperiods();
|
||||||
|
if (empty($periods)) {
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->addElement(
|
||||||
|
'select',
|
||||||
|
'period_id',
|
||||||
|
array(
|
||||||
|
'label' => $this->translate('Time period'),
|
||||||
|
'description' => $this->translate(
|
||||||
|
'The name of a time period which determines when this'
|
||||||
|
. ' notification should be triggered. Not set by default.'
|
||||||
|
),
|
||||||
|
'multiOptions' => $this->optionalEnum($periods),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function addBooleanElements() {
|
||||||
|
|
||||||
|
$this->addBoolean(
|
||||||
|
'disable_checks',
|
||||||
|
array(
|
||||||
|
'label' => $this->translate('Disable Checks'),
|
||||||
|
'description' => $this->translate('Whether to disable checks when this dependency fails. Defaults to false.')
|
||||||
|
),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->addBoolean(
|
||||||
|
'disable_notifications',
|
||||||
|
array(
|
||||||
|
'label' => $this->translate('Disable Notificiations'),
|
||||||
|
'description' => $this->translate('Whether to disable notifications when this dependency fails. Defaults to true.')
|
||||||
|
),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->addBoolean(
|
||||||
|
'ignore_soft_states',
|
||||||
|
array(
|
||||||
|
'label' => $this->translate('Ignore Soft States'),
|
||||||
|
'description' => $this->translate('Whether to ignore soft states for the reachability calculation. Defaults to true.')
|
||||||
|
),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function addObjectsElement()
|
||||||
|
{
|
||||||
|
$this->addElement(
|
||||||
|
'text',
|
||||||
|
'parent_host',
|
||||||
|
array(
|
||||||
|
'label' => $this->translate('Parent Host'),
|
||||||
|
'description' => $this->translate(
|
||||||
|
'The parent host.'
|
||||||
|
),
|
||||||
|
'class' => "autosubmit director-suggest",
|
||||||
|
'data-suggestion-context' => 'hostnames',
|
||||||
|
'order' => 10,
|
||||||
|
'value' => $this->getObject()->get('parent_host')
|
||||||
|
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$sent_parent=$this->getSentOrObjectValue("parent_host");
|
||||||
|
|
||||||
|
if (!empty($sent_parent) || $this->object->isApplyRule()) {
|
||||||
|
$this->addElement(
|
||||||
|
'text',
|
||||||
|
'parent_service',
|
||||||
|
array(
|
||||||
|
'label' => $this->translate('Parent Service'),
|
||||||
|
'description' => $this->translate(
|
||||||
|
'Optional. The parent service. If omitted this dependency object is treated as host dependency.'
|
||||||
|
),
|
||||||
|
'class' => "autosubmit director-suggest",
|
||||||
|
'data-suggestion-context' => 'servicenames',
|
||||||
|
'data-suggestion-for-host' => $sent_parent,
|
||||||
|
'order' => 20,
|
||||||
|
'value' => $this->getObject()->get('parent_service')
|
||||||
|
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// If configuring Object, allow selection of child host and/or service, otherwise apply rules will determine child object.
|
||||||
|
if ($this->isObject()) {
|
||||||
|
$this->addElement(
|
||||||
|
'text',
|
||||||
|
'child_host',
|
||||||
|
array(
|
||||||
|
'label' => $this->translate('Child Host'),
|
||||||
|
'description' => $this->translate(
|
||||||
|
'The child host.'
|
||||||
|
),
|
||||||
|
'class' => "autosubmit director-suggest",
|
||||||
|
'data-suggestion-context' => 'hostnames',
|
||||||
|
'order' => 30,
|
||||||
|
'value' => $this->getObject()->get('child_host')
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$sent_child=$this->getSentOrObjectValue("child_host");
|
||||||
|
|
||||||
|
if (!empty($sent_child)) {
|
||||||
|
$this->addElement(
|
||||||
|
'text',
|
||||||
|
'child_service',
|
||||||
|
array(
|
||||||
|
'label' => $this->translate('Child Service'),
|
||||||
|
'description' => $this->translate(
|
||||||
|
'Optional. The child service. If omitted this dependency object is treated as host dependency.'
|
||||||
|
),
|
||||||
|
'class' => "autosubmit director-suggest",
|
||||||
|
'data-suggestion-context' => 'servicenames',
|
||||||
|
'data-suggestion-for-host' => $sent_child,
|
||||||
|
'order' => 40,
|
||||||
|
'value' => $this->getObject()->get('child_service')
|
||||||
|
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$elements=array('parent_host','child_host','parent_service','child_service');
|
||||||
|
$this->addDisplayGroup($elements, 'related_objects', array(
|
||||||
|
'decorators' => array(
|
||||||
|
'FormElements',
|
||||||
|
array('HtmlTag', array('tag' => 'dl')),
|
||||||
|
'Fieldset',
|
||||||
|
),
|
||||||
|
'order' => 25,
|
||||||
|
'legend' => $this->translate('Related Objects')
|
||||||
|
));
|
||||||
|
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createApplyRuleFor(IcingaDependency $dependency)
|
||||||
|
{
|
||||||
|
$object = $this->object();
|
||||||
|
$object->imports = $dependency->object_name;
|
||||||
|
$object->object_type = 'apply';
|
||||||
|
$object->object_name = $dependency->object_name;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,105 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Icinga\Module\Director\Tables;
|
||||||
|
|
||||||
|
use Icinga\Module\Director\Web\Table\IcingaObjectTable;
|
||||||
|
|
||||||
|
class IcingaDependencyTable extends IcingaObjectTable
|
||||||
|
{
|
||||||
|
protected $searchColumns = array(
|
||||||
|
'dependency',
|
||||||
|
);
|
||||||
|
|
||||||
|
public function getColumns()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
'id' => 'd.id',
|
||||||
|
'object_type' => 'd.object_type',
|
||||||
|
'dependency' => 'd.object_name',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function listTableClasses()
|
||||||
|
{
|
||||||
|
return array_merge(array('assignment-table'), parent::listTableClasses());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getActionUrl($row)
|
||||||
|
{
|
||||||
|
return $this->url('director/dependency', array('id' => $row->id));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTitles()
|
||||||
|
{
|
||||||
|
$view = $this->view();
|
||||||
|
return array(
|
||||||
|
'dependency' => $view->translate('Dependency'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function renderRow($row)
|
||||||
|
{
|
||||||
|
$v = $this->view();
|
||||||
|
$extra = $this->appliedOnes($row->id);
|
||||||
|
$htm = " <tr" . $this->getRowClassesString($row) . ">\n";
|
||||||
|
$htm .= '<td>' . $v->qlink($row->dependency, $this->getActionUrl($row));
|
||||||
|
if (empty($extra)) {
|
||||||
|
$htm .= ' ' . $v->qlink(
|
||||||
|
'Create apply-rule',
|
||||||
|
'director/dependency/add',
|
||||||
|
array('apply' => $row->dependency, 'type' => 'apply'),
|
||||||
|
array('class' => 'icon-plus')
|
||||||
|
);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$htm .= '. Related apply rules: <ul class="apply-rules">';
|
||||||
|
foreach ($extra as $id => $dependency) {
|
||||||
|
$htm .= '<li>'
|
||||||
|
. $v->qlink($dependency, 'director/dependency', array('id' => $id))
|
||||||
|
. '</li>';
|
||||||
|
}
|
||||||
|
$htm .= '</ul>';
|
||||||
|
$htm .= $v->qlink(
|
||||||
|
'Add more',
|
||||||
|
'director/dependency/add',
|
||||||
|
array('apply' => $row->dependency),
|
||||||
|
array('class' => 'icon-plus')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
$htm .= '</td>';
|
||||||
|
return $htm . " </tr>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function appliedOnes($id)
|
||||||
|
{
|
||||||
|
$db = $this->db();
|
||||||
|
$query = $db->select()->from(
|
||||||
|
array('s' => 'icinga_dependency'),
|
||||||
|
array(
|
||||||
|
'id' => 's.id',
|
||||||
|
'objectname' => 's.object_name',
|
||||||
|
)
|
||||||
|
)->join(
|
||||||
|
array('i' => 'icinga_dependency_inheritance'),
|
||||||
|
'i.dependency_id = s.id',
|
||||||
|
array()
|
||||||
|
)->where('i.parent_dependency_id = ?', $id)
|
||||||
|
->where('s.object_type = ?', 'apply');
|
||||||
|
|
||||||
|
|
||||||
|
return $db->fetchPairs($query);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUnfilteredQuery()
|
||||||
|
{
|
||||||
|
return $this->db()->select()->from(
|
||||||
|
array('d' => 'icinga_dependency'),
|
||||||
|
array()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getBaseQuery()
|
||||||
|
{
|
||||||
|
return $this->getUnfilteredQuery()->order('d.object_name');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Icinga\Module\Director\Tables;
|
||||||
|
|
||||||
|
use Icinga\Module\Director\Tables\IcingaDependencyTable;
|
||||||
|
|
||||||
|
class IcingaDependencyTemplateTable extends IcingaDependencyTable
|
||||||
|
{
|
||||||
|
public function getBaseQuery()
|
||||||
|
{
|
||||||
|
return $this->getUnfilteredQuery()->where('d.object_type = ?', 'template');
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Icinga\Module\Director\Dashboard\Dashlet;
|
||||||
|
|
||||||
|
class DependencyObjectDashlet extends Dashlet
|
||||||
|
{
|
||||||
|
protected $icon = '';
|
||||||
|
|
||||||
|
protected $requiredStats = array('dependency');
|
||||||
|
|
||||||
|
public function getTitle()
|
||||||
|
{
|
||||||
|
return $this->translate('Dependencies.');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSummary()
|
||||||
|
{
|
||||||
|
return $this->translate('Define object dependency relationships.')
|
||||||
|
. ' ' . parent::getSummary();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUrl()
|
||||||
|
{
|
||||||
|
return 'director/dependencies';
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,6 +9,7 @@ class ObjectsDashboard extends Dashboard
|
||||||
'ServiceObject',
|
'ServiceObject',
|
||||||
'CommandObject',
|
'CommandObject',
|
||||||
// 'Notifications',
|
// 'Notifications',
|
||||||
|
'DependencyObject',
|
||||||
);
|
);
|
||||||
|
|
||||||
public function getTitle()
|
public function getTitle()
|
||||||
|
|
|
@ -389,6 +389,7 @@ class Db extends DbConnection
|
||||||
'apiuser',
|
'apiuser',
|
||||||
'endpoint',
|
'endpoint',
|
||||||
'zone',
|
'zone',
|
||||||
|
'dependency',
|
||||||
);
|
);
|
||||||
|
|
||||||
$queries = array();
|
$queries = array();
|
||||||
|
|
|
@ -477,6 +477,7 @@ class IcingaConfig
|
||||||
->createFileFromDb('userGroup')
|
->createFileFromDb('userGroup')
|
||||||
->createFileFromDb('user')
|
->createFileFromDb('user')
|
||||||
->createFileFromDb('notification')
|
->createFileFromDb('notification')
|
||||||
|
->createFileFromDb('dependency')
|
||||||
;
|
;
|
||||||
|
|
||||||
if (! $this->isLegacy()) {
|
if (! $this->isLegacy()) {
|
||||||
|
@ -719,7 +720,8 @@ apply Service for (title => params in host.vars["%s"]) {
|
||||||
'user',
|
'user',
|
||||||
'userGroup',
|
'userGroup',
|
||||||
'timePeriod',
|
'timePeriod',
|
||||||
'notification'
|
'notification',
|
||||||
|
'dependency'
|
||||||
);
|
);
|
||||||
|
|
||||||
return in_array($type, $types);
|
return in_array($type, $types);
|
||||||
|
|
|
@ -0,0 +1,421 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Icinga\Module\Director\Objects;
|
||||||
|
|
||||||
|
use Icinga\Exception\ConfigurationError;
|
||||||
|
use Icinga\Module\Director\IcingaConfig\IcingaConfigHelper as c;
|
||||||
|
use Icinga\Exception\NotFoundError;
|
||||||
|
use Icinga\Data\Filter\Filter;
|
||||||
|
use Icinga\Module\Director\Objects\HostApplyMatches;
|
||||||
|
|
||||||
|
|
||||||
|
class IcingaDependency extends IcingaObject
|
||||||
|
{
|
||||||
|
protected $table = 'icinga_dependency';
|
||||||
|
|
||||||
|
protected $defaultProperties = array(
|
||||||
|
'id' => null,
|
||||||
|
'object_name' => null,
|
||||||
|
'object_type' => null,
|
||||||
|
'disabled' => 'n',
|
||||||
|
'apply_to' => null,
|
||||||
|
'parent_host_id' => null,
|
||||||
|
'parent_service_id' => null,
|
||||||
|
'child_host_id' => null,
|
||||||
|
'child_service_id' => null,
|
||||||
|
'disable_checks' => null,
|
||||||
|
'disable_notifications' => null,
|
||||||
|
'ignore_soft_states' => null,
|
||||||
|
'period_id' => null,
|
||||||
|
'zone_id' => null,
|
||||||
|
'assign_filter' => null,
|
||||||
|
'parent_service_s' => null,
|
||||||
|
);
|
||||||
|
|
||||||
|
protected $supportsCustomVars = false;
|
||||||
|
|
||||||
|
protected $supportsImports = true;
|
||||||
|
|
||||||
|
protected $supportsApplyRules = true;
|
||||||
|
|
||||||
|
protected $relatedSets = array(
|
||||||
|
'states' => 'StateFilterSet',
|
||||||
|
);
|
||||||
|
|
||||||
|
protected $relations = array(
|
||||||
|
'zone' => 'IcingaZone',
|
||||||
|
'parent_host' => 'IcingaHost',
|
||||||
|
'parent_service' => 'IcingaService',
|
||||||
|
'child_host' => 'IcingaHost',
|
||||||
|
'child_service' => 'IcingaService',
|
||||||
|
'period' => 'IcingaTimePeriod',
|
||||||
|
);
|
||||||
|
|
||||||
|
protected $booleans = array(
|
||||||
|
'disable_checks' => 'disable_checks',
|
||||||
|
'disable_notifications' => 'disable_notifications',
|
||||||
|
'ignore_soft_states' => 'ignore_soft_states'
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do not render internal property apply_to
|
||||||
|
*
|
||||||
|
* Avoid complaints for method names with underscore:
|
||||||
|
* @codingStandardsIgnoreStart
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function renderApply_to()
|
||||||
|
{
|
||||||
|
// @codingStandardsIgnoreEnd
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function renderObjectHeader()
|
||||||
|
{
|
||||||
|
if ($this->isApplyRule()) {
|
||||||
|
if (($to = $this->get('apply_to')) === null) {
|
||||||
|
throw new ConfigurationError(
|
||||||
|
'Applied dependency "%s" has no valid object type',
|
||||||
|
$this->getObjectName()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sprintf(
|
||||||
|
"%s %s %s to %s {\n",
|
||||||
|
$this->getObjectTypeName(),
|
||||||
|
$this->getType(),
|
||||||
|
c::renderString($this->getObjectName()),
|
||||||
|
ucfirst($to)
|
||||||
|
);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return parent::renderObjectHeader();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function setKey($key)
|
||||||
|
{
|
||||||
|
if (is_int($key)) {
|
||||||
|
$this->id = $key;
|
||||||
|
} elseif (is_array($key)) {
|
||||||
|
foreach (array('id', 'parent_host_id', 'parent_service_id', 'child_host_id', 'child_service_id', 'object_name') as $k) {
|
||||||
|
if (array_key_exists($k, $key)) {
|
||||||
|
$this->set($k, $key[$k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return parent::setKey($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function renderAssignments()
|
||||||
|
{
|
||||||
|
if ($this->hasBeenAssignedToServiceApply()) {
|
||||||
|
|
||||||
|
$tmpService= $this->getRelatedObject('child_service', $this->child_service_id);
|
||||||
|
$assigns = $tmpService->assignments()->toConfigString();
|
||||||
|
|
||||||
|
$filter = sprintf(
|
||||||
|
'%s && service.name == "%s"',
|
||||||
|
trim($assigns), $this->child_service
|
||||||
|
);
|
||||||
|
return "\n " . $filter . "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->hasBeenAssignedToHostTemplateService()) {
|
||||||
|
$filter = sprintf(
|
||||||
|
'assign where "%s" in host.templates && service.name == "%s"',
|
||||||
|
$this->child_host, $this->child_service
|
||||||
|
);
|
||||||
|
return "\n " . $filter . "\n";
|
||||||
|
}
|
||||||
|
if ($this->hasBeenAssignedToHostTemplate()) {
|
||||||
|
$filter = sprintf(
|
||||||
|
'assign where "%s" in host.templates',
|
||||||
|
$this->child_host
|
||||||
|
);
|
||||||
|
return "\n " . $filter . "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->hasBeenAssignedToServiceTemplate()) {
|
||||||
|
$filter = sprintf(
|
||||||
|
'assign where "%s" in service.templates',
|
||||||
|
$this->child_service
|
||||||
|
);
|
||||||
|
return "\n " . $filter . "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::renderAssignments();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function hasBeenAssignedToHostTemplate()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return $this->child_host_id && $this->getRelatedObject(
|
||||||
|
'child_host',
|
||||||
|
$this->child_host_id
|
||||||
|
)->object_type === 'template';
|
||||||
|
} catch (NotFoundError $e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function hasBeenAssignedToServiceTemplate()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return $this->child_service_id && $this->getRelatedObject(
|
||||||
|
'child_service',
|
||||||
|
$this->child_service_id
|
||||||
|
)->object_type === 'template';
|
||||||
|
} catch (NotFoundError $e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function hasBeenAssignedToHostTemplateService()
|
||||||
|
{
|
||||||
|
if (!$this->hasBeenAssignedToHostTemplate()) return false;
|
||||||
|
try {
|
||||||
|
return $this->child_service_id && $this->getRelatedObject(
|
||||||
|
'child_service',
|
||||||
|
$this->child_service_id
|
||||||
|
)->object_type === 'object';
|
||||||
|
} catch (NotFoundError $e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function hasBeenAssignedToServiceApply()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return $this->child_service_id && $this->getRelatedObject(
|
||||||
|
'child_service',
|
||||||
|
$this->child_service_id
|
||||||
|
)->object_type === 'apply';
|
||||||
|
} catch (NotFoundError $e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render child_host_id as host_name
|
||||||
|
*
|
||||||
|
* Avoid complaints for method names with underscore:
|
||||||
|
* @codingStandardsIgnoreStart
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function renderChild_host_id()
|
||||||
|
{
|
||||||
|
// @codingStandardsIgnoreEnd
|
||||||
|
|
||||||
|
if ($this->hasBeenAssignedToHostTemplate()) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->renderRelationProperty('child_host', $this->child_host_id, 'child_host_name');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render parent_host_id as parent_host_name
|
||||||
|
*
|
||||||
|
* Avoid complaints for method names with underscore:
|
||||||
|
* @codingStandardsIgnoreStart
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function renderParent_host_id()
|
||||||
|
{
|
||||||
|
// @codingStandardsIgnoreEnd
|
||||||
|
|
||||||
|
return $this->renderRelationProperty('parent_host', $this->parent_host_id, 'parent_host_name');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render child_service_id as host_name
|
||||||
|
*
|
||||||
|
* Avoid complaints for method names with underscore:
|
||||||
|
* @codingStandardsIgnoreStart
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function renderChild_service_id()
|
||||||
|
{
|
||||||
|
// @codingStandardsIgnoreEnd
|
||||||
|
if ($this->hasBeenAssignedToServiceTemplate()) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->hasBeenAssignedToHostTemplateService()) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->hasBeenAssignedToServiceApply()) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->renderRelationProperty('child_service', $this->child_service_id, 'child_service_name');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render parent_service_id as parent_service_name
|
||||||
|
*
|
||||||
|
* Avoid complaints for method names with underscore:
|
||||||
|
* @codingStandardsIgnoreStart
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function renderParent_service_id()
|
||||||
|
{
|
||||||
|
return $this->renderRelationProperty('parent_service', $this->parent_service_id, 'parent_service_name');
|
||||||
|
}
|
||||||
|
|
||||||
|
//special case for parent service set as plain string for Apply rules
|
||||||
|
public function renderParent_service_s()
|
||||||
|
{
|
||||||
|
return "\n parent_service_name = \"" . $this->parent_service_s ."\"\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isApplyRule()
|
||||||
|
{
|
||||||
|
if ($this->hasBeenAssignedToHostTemplate()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->hasBeenAssignedToServiceTemplate()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->hasBeenAssignedToServiceApply()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->hasProperty('object_type')
|
||||||
|
&& $this->object_type === 'apply';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function resolveUnresolvedRelatedProperty($name)
|
||||||
|
{
|
||||||
|
|
||||||
|
$short = substr($name, 0, -3);
|
||||||
|
/** @var IcingaObject $class */
|
||||||
|
$class = $this->getRelationClass($short);
|
||||||
|
$obj_key = $this->unresolvedRelatedProperties[$name];
|
||||||
|
|
||||||
|
# related services need array key
|
||||||
|
if ($class == "Icinga\Module\Director\Objects\IcingaService" ) {
|
||||||
|
if ($name == "parent_service_id" && $this->object_type == 'apply' ) { //special case , parent service can be set as simple string for Apply
|
||||||
|
if ($this->properties['parent_host_id']==null) {
|
||||||
|
$this->reallySet('parent_service_s', $this->unresolvedRelatedProperties[$name]);
|
||||||
|
$this->reallySet('parent_service_id',null);
|
||||||
|
unset($this->unresolvedRelatedProperties[$name]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->reallySet('parent_service_s',null);
|
||||||
|
$host_id_prop=str_replace("service","host",$name);
|
||||||
|
if (isset($this->properties[$host_id_prop])) {
|
||||||
|
$obj_key=array("host_id" => $this->properties[$host_id_prop], "object_name" => $this->unresolvedRelatedProperties[$name]);
|
||||||
|
} else {
|
||||||
|
$obj_key=array("host_id" => null, "object_name" => $this->unresolvedRelatedProperties[$name]);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$object = $class::load( $obj_key, $this->connection);
|
||||||
|
} catch (NotFoundError $e) {
|
||||||
|
// Not a simple service on host
|
||||||
|
// Hunt through inherited services, use service assigned to template if found
|
||||||
|
$tmp_host=IcingaHost::loadWithAutoIncId($this->properties[$host_id_prop], $this->connection);
|
||||||
|
|
||||||
|
//services for applicable templates
|
||||||
|
$resolver = $tmp_host->templateResolver();
|
||||||
|
foreach ($resolver->fetchResolvedParents() as $template_obj) {
|
||||||
|
$obj_key=array("host_id" => $template_obj->id, "object_name" => $this->unresolvedRelatedProperties[$name]);
|
||||||
|
try {
|
||||||
|
$object = $class::load( $obj_key, $this->connection);
|
||||||
|
} catch (NotFoundError $e) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!isset($object)) { //Not an inherited service, now try apply rules
|
||||||
|
$matcher = HostApplyMatches::prepare($tmp_host);
|
||||||
|
foreach ($this->getAllApplyRules() as $rule) {
|
||||||
|
if ($matcher->matchesFilter($rule->filter)) {
|
||||||
|
if ($rule->name == $this->unresolvedRelatedProperties[$name]) {
|
||||||
|
$object=IcingaService::loadWithAutoIncId($rule->id, $this->connection);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$object = $class::load(
|
||||||
|
$obj_key,
|
||||||
|
$this->connection
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($object)) {
|
||||||
|
$this->reallySet($name, $object->get('id'));
|
||||||
|
unset($this->unresolvedRelatedProperties[$name]);
|
||||||
|
} else {
|
||||||
|
throw new NotFoundError('Unable to resolve related property: "%s"', $name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getAllApplyRules()
|
||||||
|
{
|
||||||
|
$allApplyRules=$this->fetchAllApplyRules();
|
||||||
|
foreach ($allApplyRules as $rule) {
|
||||||
|
$rule->filter = Filter::fromQueryString($rule->assign_filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $allApplyRules;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function fetchAllApplyRules()
|
||||||
|
{
|
||||||
|
$db = $this->connection->getDbAdapter();
|
||||||
|
$query = $db->select()->from(
|
||||||
|
array('s' => 'icinga_service'),
|
||||||
|
array(
|
||||||
|
'id' => 's.id',
|
||||||
|
'name' => 's.object_name',
|
||||||
|
'assign_filter' => 's.assign_filter',
|
||||||
|
)
|
||||||
|
)->where('object_type = ? AND assign_filter IS NOT NULL', 'apply');
|
||||||
|
|
||||||
|
return $db->fetchAll($query);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getRelatedProperty($key)
|
||||||
|
{
|
||||||
|
$idKey = $key . '_id';
|
||||||
|
if ($this->hasUnresolvedRelatedProperty($idKey)) {
|
||||||
|
return $this->unresolvedRelatedProperties[$idKey];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($id = $this->get($idKey)) {
|
||||||
|
/** @var IcingaObject $class */
|
||||||
|
$class = $this->getRelationClass($key);
|
||||||
|
$object = $class::loadWithAutoIncId($id, $this->connection);
|
||||||
|
return $object->get('object_name');
|
||||||
|
} else {
|
||||||
|
// handle special case for plain string parent service on Dependency Apply rules
|
||||||
|
if ($key == 'parent_service' && $this->get('parent_service_s') != null) {
|
||||||
|
return $this->get('parent_service_s');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -2699,7 +2699,8 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
||||||
|
|
||||||
public function getOnDeleteUrl()
|
public function getOnDeleteUrl()
|
||||||
{
|
{
|
||||||
return 'director/' . strtolower($this->getShortTableName()) . 's';
|
$plural= preg_replace('/cys$/','cies', strtolower($this->getShortTableName()) . 's');
|
||||||
|
return 'director/' . $plural;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function toJson(
|
public function toJson(
|
||||||
|
|
|
@ -9,6 +9,7 @@ class TemplateActionBar extends DirectorBaseActionBar
|
||||||
protected function assemble()
|
protected function assemble()
|
||||||
{
|
{
|
||||||
$type = $this->type;
|
$type = $this->type;
|
||||||
|
$pltype = preg_replace('/cys$/','cies', $type . 's');
|
||||||
$renderTree = $this->url->getParam('render') === 'tree';
|
$renderTree = $this->url->getParam('render') === 'tree';
|
||||||
$renderParams = $renderTree ? null : ['render' => 'tree'];
|
$renderParams = $renderTree ? null : ['render' => 'tree'];
|
||||||
$this->add(
|
$this->add(
|
||||||
|
@ -27,7 +28,7 @@ class TemplateActionBar extends DirectorBaseActionBar
|
||||||
)->add(
|
)->add(
|
||||||
Link::create(
|
Link::create(
|
||||||
$renderTree ? $this->translate('Table') : $this->translate('Tree'),
|
$renderTree ? $this->translate('Table') : $this->translate('Tree'),
|
||||||
"director/${type}s/templates",
|
"director/$pltype/templates",
|
||||||
$renderParams,
|
$renderParams,
|
||||||
[
|
[
|
||||||
'class' => 'icon-' . ($renderTree ? 'doc-text' : 'sitemap'),
|
'class' => 'icon-' . ($renderTree ? 'doc-text' : 'sitemap'),
|
||||||
|
|
|
@ -80,7 +80,7 @@ abstract class ObjectsController extends ActionController
|
||||||
$this
|
$this
|
||||||
->addObjectsTabs()
|
->addObjectsTabs()
|
||||||
->setAutorefreshInterval(10)
|
->setAutorefreshInterval(10)
|
||||||
->addTitle($this->translate(ucfirst(strtolower($type)) . 's'))
|
->addTitle($this->translate(ucfirst($this->getPluralType())))
|
||||||
->actions(new ObjectsActionBar($type, $this->url()));
|
->actions(new ObjectsActionBar($type, $this->url()));
|
||||||
|
|
||||||
if ($type === 'command' && $this->params->get('type') === 'external_object') {
|
if ($type === 'command' && $this->params->get('type') === 'external_object') {
|
||||||
|
@ -127,6 +127,7 @@ abstract class ObjectsController extends ActionController
|
||||||
)->content()->add($form);
|
)->content()->add($form);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the TemplatesTable or the TemplateTreeRenderer
|
* Loads the TemplatesTable or the TemplateTreeRenderer
|
||||||
*
|
*
|
||||||
|
@ -139,7 +140,6 @@ abstract class ObjectsController extends ActionController
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$type = $this->getType();
|
$type = $this->getType();
|
||||||
|
|
||||||
$shortType = IcingaObject::createByType($type)->getShortTableName();
|
$shortType = IcingaObject::createByType($type)->getShortTableName();
|
||||||
$this
|
$this
|
||||||
->assertPermission('director/admin')
|
->assertPermission('director/admin')
|
||||||
|
@ -294,8 +294,8 @@ abstract class ObjectsController extends ActionController
|
||||||
{
|
{
|
||||||
// Strip final 's' and upcase an eventual 'group'
|
// Strip final 's' and upcase an eventual 'group'
|
||||||
return preg_replace(
|
return preg_replace(
|
||||||
array('/group$/', '/period$/', '/argument$/', '/apiuser$/'),
|
array('/group$/', '/period$/', '/argument$/', '/apiuser$/', '/dependencie$/'),
|
||||||
array('Group', 'Period', 'Argument', 'ApiUser'),
|
array('Group', 'Period', 'Argument', 'ApiUser', 'dependency'),
|
||||||
str_replace(
|
str_replace(
|
||||||
'template',
|
'template',
|
||||||
'',
|
'',
|
||||||
|
@ -306,11 +306,11 @@ abstract class ObjectsController extends ActionController
|
||||||
|
|
||||||
protected function getPluralType()
|
protected function getPluralType()
|
||||||
{
|
{
|
||||||
return $this->getType() . 's';
|
return preg_replace("/cys$/","cies",$this->getType() . 's');
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getPluralBaseType()
|
protected function getPluralBaseType()
|
||||||
{
|
{
|
||||||
return $this->getBaseType() . 's';
|
return preg_replace("/cys$/","cies",$this->getBaseType() . 's');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -177,7 +177,7 @@ abstract class TemplateController extends CompatController
|
||||||
|
|
||||||
protected function getPluralType()
|
protected function getPluralType()
|
||||||
{
|
{
|
||||||
return $this->template()->getShortTableName() . 's';
|
return preg_replace('/cys$/','cies',$this->template()->getShortTableName() . 's');
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getTranslatedType()
|
protected function getTranslatedType()
|
||||||
|
|
|
@ -523,6 +523,9 @@ abstract class DirectorObjectForm extends DirectorForm
|
||||||
'email',
|
'email',
|
||||||
'pager',
|
'pager',
|
||||||
'enable_notifications',
|
'enable_notifications',
|
||||||
|
'disable_checks', //Dependencies
|
||||||
|
'disable_notifications',
|
||||||
|
'ignore_soft_states',
|
||||||
'apply_for',
|
'apply_for',
|
||||||
'create_live',
|
'create_live',
|
||||||
'disabled',
|
'disabled',
|
||||||
|
@ -1508,28 +1511,28 @@ abstract class DirectorObjectForm extends DirectorForm
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function addEventFilterElements()
|
protected function addEventFilterElements($elements = array('states','types'))
|
||||||
{
|
{
|
||||||
$this->addElement('extensibleSet', 'states', array(
|
if (in_array('states', $elements)) {
|
||||||
'label' => $this->translate('States'),
|
$this->addElement('extensibleSet', 'states', array(
|
||||||
'multiOptions' => $this->optionallyAddFromEnum($this->enumStates()),
|
'label' => $this->translate('States'),
|
||||||
'description' => $this->translate(
|
'multiOptions' => $this->optionallyAddFromEnum($this->enumStates()),
|
||||||
'The host/service states you want to get notifications for'
|
'description' => $this->translate(
|
||||||
),
|
'The host/service states you want to get notifications for'
|
||||||
));
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
$this->addElement('extensibleSet', 'types', array(
|
if (in_array('types', $elements)) {
|
||||||
'label' => $this->translate('Transition types'),
|
$this->addElement('extensibleSet', 'types', array(
|
||||||
'multiOptions' => $this->optionallyAddFromEnum($this->enumTypes()),
|
'label' => $this->translate('Transition types'),
|
||||||
'description' => $this->translate(
|
'multiOptions' => $this->optionallyAddFromEnum($this->enumTypes()),
|
||||||
'The state transition types you want to get notifications for'
|
'description' => $this->translate(
|
||||||
),
|
'The state transition types you want to get notifications for'
|
||||||
));
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
$elements = array(
|
|
||||||
'states',
|
|
||||||
'types',
|
|
||||||
);
|
|
||||||
$this->addDisplayGroup($elements, 'event_filters', array(
|
$this->addDisplayGroup($elements, 'event_filters', array(
|
||||||
'decorators' => array(
|
'decorators' => array(
|
||||||
'FormElements',
|
'FormElements',
|
||||||
|
|
|
@ -18,17 +18,17 @@ class ObjectsTabs extends Tabs
|
||||||
$object = IcingaObject::createByType(substr($type, 0, -5));
|
$object = IcingaObject::createByType(substr($type, 0, -5));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: plural?
|
$pltype=strtolower(preg_replace('/cys$/','cies',$type . 's'));
|
||||||
if ($auth->hasPermission("director/${type}s")) {
|
if ($auth->hasPermission("director/${pltype}")) {
|
||||||
$this->add('index', array(
|
$this->add('index', array(
|
||||||
'url' => sprintf('director/%ss', strtolower($type)),
|
'url' => sprintf('director/%s', $pltype),
|
||||||
'label' => $this->translate(ucfirst($type) . 's'),
|
'label' => $this->translate(ucfirst($pltype)),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($object->getShortTableName() === 'command') {
|
if ($object->getShortTableName() === 'command') {
|
||||||
$this->add('external', array(
|
$this->add('external', array(
|
||||||
'url' => sprintf('director/%ss', strtolower($type)),
|
'url' => sprintf('director/%s', strtolower($pltype)),
|
||||||
'urlParams' => ['type' => 'external_object'],
|
'urlParams' => ['type' => 'external_object'],
|
||||||
'label' => $this->translate('External'),
|
'label' => $this->translate('External'),
|
||||||
));
|
));
|
||||||
|
@ -39,7 +39,7 @@ class ObjectsTabs extends Tabs
|
||||||
)) {
|
)) {
|
||||||
if ($object->supportsApplyRules()) {
|
if ($object->supportsApplyRules()) {
|
||||||
$this->add('applyrules', array(
|
$this->add('applyrules', array(
|
||||||
'url' => sprintf('director/%ss/applyrules', $type),
|
'url' => sprintf('director/%s/applyrules', $pltype),
|
||||||
'label' => $this->translate('Apply')
|
'label' => $this->translate('Apply')
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ class ObjectsTabs extends Tabs
|
||||||
if ($auth->hasPermission('director/admin') && $type !== 'zone') {
|
if ($auth->hasPermission('director/admin') && $type !== 'zone') {
|
||||||
if ($object->supportsImports()) {
|
if ($object->supportsImports()) {
|
||||||
$this->add('templates', array(
|
$this->add('templates', array(
|
||||||
'url' => sprintf('director/%ss/templates', strtolower($type)),
|
'url' => sprintf('director/%s/templates', $pltype),
|
||||||
'label' => $this->translate('Templates'),
|
'label' => $this->translate('Templates'),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ class ObjectsTabs extends Tabs
|
||||||
}
|
}
|
||||||
if ($object->supportsSets() && $auth->hasPermission("director/${type}_sets")) {
|
if ($object->supportsSets() && $auth->hasPermission("director/${type}_sets")) {
|
||||||
$this->add('sets', array(
|
$this->add('sets', array(
|
||||||
'url' => sprintf('director/%ss/sets', $type),
|
'url' => sprintf('director/%s/sets', $pltype),
|
||||||
'label' => $this->translate('Sets')
|
'label' => $this->translate('Sets')
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
|
@ -275,7 +275,8 @@
|
||||||
{
|
{
|
||||||
$suggestions.load(this.module.icinga.config.baseUrl + '/director/suggest', {
|
$suggestions.load(this.module.icinga.config.baseUrl + '/director/suggest', {
|
||||||
value: $el.val(),
|
value: $el.val(),
|
||||||
context: $el.data('suggestion-context')
|
context: $el.data('suggestion-context'),
|
||||||
|
for_host: $el.data('suggestion-for-host')
|
||||||
}, function (responseText, textStatus, jqXHR) {
|
}, function (responseText, textStatus, jqXHR) {
|
||||||
var $li = $suggestions.find('li');
|
var $li = $suggestions.find('li');
|
||||||
if ($li.length) {
|
if ($li.length) {
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
|
||||||
|
CREATE TABLE icinga_dependency (
|
||||||
|
id INT(10) UNSIGNED AUTO_INCREMENT NOT NULL,
|
||||||
|
object_name VARCHAR(255) DEFAULT NULL,
|
||||||
|
object_type ENUM('object', 'template', 'apply') NOT NULL,
|
||||||
|
disabled ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||||
|
apply_to ENUM('host', 'service') DEFAULT NULL,
|
||||||
|
parent_host_id INT(10) UNSIGNED DEFAULT NULL,
|
||||||
|
parent_service_id INT(10) UNSIGNED DEFAULT NULL,
|
||||||
|
child_host_id INT(10) UNSIGNED DEFAULT NULL,
|
||||||
|
child_service_id INT(10) UNSIGNED DEFAULT NULL,
|
||||||
|
disable_checks ENUM('y', 'n'),
|
||||||
|
disable_notifications ENUM('y', 'n'),
|
||||||
|
ignore_soft_states ENUM('y', 'n'),
|
||||||
|
period_id INT(10) UNSIGNED DEFAULT NULL,
|
||||||
|
zone_id INT(10) UNSIGNED DEFAULT NULL,
|
||||||
|
assign_filter TEXT DEFAULT NULL,
|
||||||
|
PRIMARY KEY (id),
|
||||||
|
CONSTRAINT icinga_dependency_parent_host
|
||||||
|
FOREIGN KEY parent_host (parent_host_id)
|
||||||
|
REFERENCES icinga_host (id)
|
||||||
|
ON DELETE CASCADE
|
||||||
|
ON UPDATE CASCADE,
|
||||||
|
CONSTRAINT icinga_dependency_parent_service
|
||||||
|
FOREIGN KEY parent_service (parent_service_id)
|
||||||
|
REFERENCES icinga_service (id)
|
||||||
|
ON DELETE CASCADE
|
||||||
|
ON UPDATE CASCADE,
|
||||||
|
CONSTRAINT icinga_dependency_child_host
|
||||||
|
FOREIGN KEY child_host (child_host_id)
|
||||||
|
REFERENCES icinga_host (id)
|
||||||
|
ON DELETE CASCADE
|
||||||
|
ON UPDATE CASCADE,
|
||||||
|
CONSTRAINT icinga_dependency_child_service
|
||||||
|
FOREIGN KEY child_service (child_service_id)
|
||||||
|
REFERENCES icinga_service (id)
|
||||||
|
ON DELETE CASCADE
|
||||||
|
ON UPDATE CASCADE,
|
||||||
|
CONSTRAINT icinga_dependency_period
|
||||||
|
FOREIGN KEY period (period_id)
|
||||||
|
REFERENCES icinga_timeperiod (id)
|
||||||
|
ON DELETE RESTRICT
|
||||||
|
ON UPDATE CASCADE,
|
||||||
|
CONSTRAINT icinga_dependency_zone
|
||||||
|
FOREIGN KEY zone (zone_id)
|
||||||
|
REFERENCES icinga_zone (id)
|
||||||
|
ON DELETE RESTRICT
|
||||||
|
ON UPDATE CASCADE
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
CREATE TABLE icinga_dependency_inheritance (
|
||||||
|
dependency_id INT(10) UNSIGNED NOT NULL,
|
||||||
|
parent_dependency_id INT(10) UNSIGNED NOT NULL,
|
||||||
|
weight MEDIUMINT UNSIGNED DEFAULT NULL,
|
||||||
|
PRIMARY KEY (dependency_id, parent_dependency_id),
|
||||||
|
UNIQUE KEY unique_order (dependency_id, weight),
|
||||||
|
CONSTRAINT icinga_dependency_inheritance_dependency
|
||||||
|
FOREIGN KEY dependency (dependency_id)
|
||||||
|
REFERENCES icinga_dependency (id)
|
||||||
|
ON DELETE CASCADE
|
||||||
|
ON UPDATE CASCADE,
|
||||||
|
CONSTRAINT icinga_dependency_inheritance_parent_dependency
|
||||||
|
FOREIGN KEY parent_dependency (parent_dependency_id)
|
||||||
|
REFERENCES icinga_dependency (id)
|
||||||
|
ON DELETE RESTRICT
|
||||||
|
ON UPDATE CASCADE
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
CREATE TABLE icinga_dependency_states_set (
|
||||||
|
dependency_id INT(10) UNSIGNED NOT NULL,
|
||||||
|
property ENUM(
|
||||||
|
'OK',
|
||||||
|
'Warning',
|
||||||
|
'Critical',
|
||||||
|
'Unknown',
|
||||||
|
'Up',
|
||||||
|
'Down'
|
||||||
|
) NOT NULL,
|
||||||
|
merge_behaviour ENUM('override', 'extend', 'blacklist') NOT NULL DEFAULT 'override'
|
||||||
|
COMMENT 'override: = [], extend: += [], blacklist: -= []',
|
||||||
|
PRIMARY KEY (dependency_id, property, merge_behaviour),
|
||||||
|
CONSTRAINT icinga_dependency_states_set_dependency
|
||||||
|
FOREIGN KEY icinga_dependency (dependency_id)
|
||||||
|
REFERENCES icinga_dependency (id)
|
||||||
|
ON DELETE CASCADE
|
||||||
|
ON UPDATE CASCADE
|
||||||
|
) ENGINE=InnoDB;
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
|
||||||
|
ALTER TABLE icinga_dependency ADD COLUMN parent_service_s VARCHAR(255);
|
|
@ -1575,6 +1575,94 @@ CREATE TABLE icinga_user_resolved_var (
|
||||||
ON UPDATE RESTRICT
|
ON UPDATE RESTRICT
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
CREATE TABLE icinga_dependency (
|
||||||
|
id INT(10) UNSIGNED AUTO_INCREMENT NOT NULL,
|
||||||
|
object_name VARCHAR(255) DEFAULT NULL,
|
||||||
|
object_type ENUM('object', 'template', 'apply') NOT NULL,
|
||||||
|
disabled ENUM('y', 'n') NOT NULL DEFAULT 'n',
|
||||||
|
apply_to ENUM('host', 'service') DEFAULT NULL,
|
||||||
|
parent_host_id INT(10) UNSIGNED DEFAULT NULL,
|
||||||
|
parent_service_id INT(10) UNSIGNED DEFAULT NULL,
|
||||||
|
child_host_id INT(10) UNSIGNED DEFAULT NULL,
|
||||||
|
child_service_id INT(10) UNSIGNED DEFAULT NULL,
|
||||||
|
disable_checks ENUM('y', 'n'),
|
||||||
|
disable_notifications ENUM('y', 'n'),
|
||||||
|
ignore_soft_states ENUM('y', 'n'),
|
||||||
|
period_id INT(10) UNSIGNED DEFAULT NULL,
|
||||||
|
zone_id INT(10) UNSIGNED DEFAULT NULL,
|
||||||
|
assign_filter TEXT DEFAULT NULL,
|
||||||
|
parent_service_s VARCHAR(255) DEFAULT NULL,
|
||||||
|
PRIMARY KEY (id),
|
||||||
|
CONSTRAINT icinga_dependency_parent_host
|
||||||
|
FOREIGN KEY parent_host (parent_host_id)
|
||||||
|
REFERENCES icinga_host (id)
|
||||||
|
ON DELETE CASCADE
|
||||||
|
ON UPDATE CASCADE,
|
||||||
|
CONSTRAINT icinga_dependency_parent_service
|
||||||
|
FOREIGN KEY parent_service (parent_service_id)
|
||||||
|
REFERENCES icinga_service (id)
|
||||||
|
ON DELETE CASCADE
|
||||||
|
ON UPDATE CASCADE,
|
||||||
|
CONSTRAINT icinga_dependency_child_host
|
||||||
|
FOREIGN KEY child_host (child_host_id)
|
||||||
|
REFERENCES icinga_host (id)
|
||||||
|
ON DELETE CASCADE
|
||||||
|
ON UPDATE CASCADE,
|
||||||
|
CONSTRAINT icinga_dependency_child_service
|
||||||
|
FOREIGN KEY child_service (child_service_id)
|
||||||
|
REFERENCES icinga_service (id)
|
||||||
|
ON DELETE CASCADE
|
||||||
|
ON UPDATE CASCADE,
|
||||||
|
CONSTRAINT icinga_dependency_period
|
||||||
|
FOREIGN KEY period (period_id)
|
||||||
|
REFERENCES icinga_timeperiod (id)
|
||||||
|
ON DELETE RESTRICT
|
||||||
|
ON UPDATE CASCADE,
|
||||||
|
CONSTRAINT icinga_dependency_zone
|
||||||
|
FOREIGN KEY zone (zone_id)
|
||||||
|
REFERENCES icinga_zone (id)
|
||||||
|
ON DELETE RESTRICT
|
||||||
|
ON UPDATE CASCADE
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
CREATE TABLE icinga_dependency_inheritance (
|
||||||
|
dependency_id INT(10) UNSIGNED NOT NULL,
|
||||||
|
parent_dependency_id INT(10) UNSIGNED NOT NULL,
|
||||||
|
weight MEDIUMINT UNSIGNED DEFAULT NULL,
|
||||||
|
PRIMARY KEY (dependency_id, parent_dependency_id),
|
||||||
|
UNIQUE KEY unique_order (dependency_id, weight),
|
||||||
|
CONSTRAINT icinga_dependency_inheritance_dependency
|
||||||
|
FOREIGN KEY dependency (dependency_id)
|
||||||
|
REFERENCES icinga_dependency (id)
|
||||||
|
ON DELETE CASCADE
|
||||||
|
ON UPDATE CASCADE,
|
||||||
|
CONSTRAINT icinga_dependency_inheritance_parent_dependency
|
||||||
|
FOREIGN KEY parent_dependency (parent_dependency_id)
|
||||||
|
REFERENCES icinga_dependency (id)
|
||||||
|
ON DELETE RESTRICT
|
||||||
|
ON UPDATE CASCADE
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
CREATE TABLE icinga_dependency_states_set (
|
||||||
|
dependency_id INT(10) UNSIGNED NOT NULL,
|
||||||
|
property ENUM(
|
||||||
|
'OK',
|
||||||
|
'Warning',
|
||||||
|
'Critical',
|
||||||
|
'Unknown',
|
||||||
|
'Up',
|
||||||
|
'Down'
|
||||||
|
) NOT NULL,
|
||||||
|
merge_behaviour ENUM('override', 'extend', 'blacklist') NOT NULL DEFAULT 'override'
|
||||||
|
COMMENT 'override: = [], extend: += [], blacklist: -= []',
|
||||||
|
PRIMARY KEY (dependency_id, property, merge_behaviour),
|
||||||
|
CONSTRAINT icinga_dependency_states_set_dependency
|
||||||
|
FOREIGN KEY icinga_dependency (dependency_id)
|
||||||
|
REFERENCES icinga_dependency (id)
|
||||||
|
ON DELETE CASCADE
|
||||||
|
ON UPDATE CASCADE
|
||||||
|
) ENGINE=InnoDB;
|
||||||
|
|
||||||
INSERT INTO director_schema_migration
|
INSERT INTO director_schema_migration
|
||||||
(schema_version, migration_time)
|
(schema_version, migration_time)
|
||||||
VALUES (143, NOW());
|
VALUES (143, NOW());
|
||||||
|
|
Loading…
Reference in New Issue