mirror of
https://github.com/Icinga/icingaweb2-module-director.git
synced 2025-07-31 01:34:12 +02:00
parent
e9e9f91fee
commit
616892984d
@ -85,6 +85,11 @@ class IcingaHostForm extends DirectorObjectForm
|
|||||||
$this->translate('Whether this check is volatile.')
|
$this->translate('Whether this check is volatile.')
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$this->addElement('text', 'groups', array(
|
||||||
|
'label' => $this->translate('Hostgroups'),
|
||||||
|
'description' => $this->translate('One or more comma separated hostgroup names')
|
||||||
|
));
|
||||||
|
|
||||||
$this->addElement('select', 'zone_id', array(
|
$this->addElement('select', 'zone_id', array(
|
||||||
'label' => $this->translate('Cluster Zone'),
|
'label' => $this->translate('Cluster Zone'),
|
||||||
'description' => $this->translate('Check this host in this specific Icinga cluster zone')
|
'description' => $this->translate('Check this host in this specific Icinga cluster zone')
|
||||||
@ -92,4 +97,11 @@ class IcingaHostForm extends DirectorObjectForm
|
|||||||
|
|
||||||
$this->addElement('submit', $this->translate('Store'));
|
$this->addElement('submit', $this->translate('Store'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function loadObject($id)
|
||||||
|
{
|
||||||
|
parent::loadObject($id);
|
||||||
|
$this->getElement('groups')->setValue(implode(', ', $this->object->groups()->listGroupNames()));
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,11 +3,12 @@
|
|||||||
namespace Icinga\Module\Director\CustomVariable;
|
namespace Icinga\Module\Director\CustomVariable;
|
||||||
|
|
||||||
use Icinga\Module\Director\IcingaConfig\IcingaConfigHelper as c;
|
use Icinga\Module\Director\IcingaConfig\IcingaConfigHelper as c;
|
||||||
|
use Icinga\Module\Director\IcingaConfig\IcingaConfigRenderer;
|
||||||
use Icinga\Module\Director\Objects\IcingaObject;
|
use Icinga\Module\Director\Objects\IcingaObject;
|
||||||
use Iterator;
|
use Iterator;
|
||||||
use Countable;
|
use Countable;
|
||||||
|
|
||||||
class CustomVariables implements Iterator, Countable
|
class CustomVariables implements Iterator, Countable, IcingaConfigRenderer
|
||||||
{
|
{
|
||||||
protected $storedVars = array();
|
protected $storedVars = array();
|
||||||
|
|
||||||
@ -164,7 +165,7 @@ class CustomVariables implements Iterator, Countable
|
|||||||
$this->modified = false;
|
$this->modified = false;
|
||||||
$this->storedVars = $this->vars;
|
$this->storedVars = $this->vars;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function toConfigString()
|
public function toConfigString()
|
||||||
{
|
{
|
||||||
|
@ -468,6 +468,10 @@ abstract class DbObject
|
|||||||
return $this->db;
|
return $this->db;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getConnection()
|
||||||
|
{
|
||||||
|
return $this->connection;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Lädt einen Datensatz aus der Datenbank und setzt die entsprechenden
|
* Lädt einen Datensatz aus der Datenbank und setzt die entsprechenden
|
||||||
* Eigenschaften dieses Objekts
|
* Eigenschaften dieses Objekts
|
||||||
@ -738,21 +742,29 @@ abstract class DbObject
|
|||||||
return $obj;
|
return $obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function loadAll(DbConnection $connection)
|
public static function loadAll(DbConnection $connection, $query = null, $keyColumn = null)
|
||||||
{
|
{
|
||||||
$objects = array();
|
$objects = array();
|
||||||
$class = get_called_class();
|
$class = get_called_class();
|
||||||
$db = $connection->getConnection();
|
$db = $connection->getDbAdapter();
|
||||||
|
|
||||||
$dummy = new $class();
|
if ($query === null) {
|
||||||
$select = $db->select()->from($dummy->table);
|
$dummy = new $class();
|
||||||
|
$select = $db->select()->from($dummy->table);
|
||||||
|
} else {
|
||||||
|
$select = $query;
|
||||||
|
}
|
||||||
$rows = $db->fetchAll($select);
|
$rows = $db->fetchAll($select);
|
||||||
|
|
||||||
foreach ($rows as $row) {
|
foreach ($rows as $row) {
|
||||||
$obj = new $class();
|
$obj = new $class();
|
||||||
$obj->connection = $connection;
|
$obj->connection = $connection;
|
||||||
$obj->setDb($db)->setDbProperties($row);
|
$obj->setDb($db)->setDbProperties($row);
|
||||||
$objects[] = $obj;
|
if ($keyColumn === null) {
|
||||||
|
$objects[] = $obj;
|
||||||
|
} else {
|
||||||
|
$objects[$row->$keyColumn] = $obj;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $objects;
|
return $objects;
|
||||||
|
@ -4,11 +4,12 @@ namespace Icinga\Module\Director\Objects;
|
|||||||
|
|
||||||
use Icinga\Module\Director\CustomVariable\CustomVariables;
|
use Icinga\Module\Director\CustomVariable\CustomVariables;
|
||||||
use Icinga\Module\Director\Data\Db\DbObject;
|
use Icinga\Module\Director\Data\Db\DbObject;
|
||||||
|
use Icinga\Module\Director\IcingaConfig\IcingaConfigRenderer;
|
||||||
use Icinga\Module\Director\IcingaConfig\IcingaConfigHelper as c;
|
use Icinga\Module\Director\IcingaConfig\IcingaConfigHelper as c;
|
||||||
use Icinga\Exception\ProgrammingError;
|
use Icinga\Exception\ProgrammingError;
|
||||||
use Exception;
|
use Exception;
|
||||||
|
|
||||||
abstract class IcingaObject extends DbObject
|
abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
|
||||||
{
|
{
|
||||||
protected $keyName = 'id';
|
protected $keyName = 'id';
|
||||||
|
|
||||||
@ -16,15 +17,38 @@ abstract class IcingaObject extends DbObject
|
|||||||
|
|
||||||
protected $supportsCustomVars = false;
|
protected $supportsCustomVars = false;
|
||||||
|
|
||||||
|
protected $supportsGroups = false;
|
||||||
|
|
||||||
private $type;
|
private $type;
|
||||||
|
|
||||||
private $vars;
|
private $vars;
|
||||||
|
|
||||||
|
private $groups;
|
||||||
|
|
||||||
public function supportsCustomVars()
|
public function supportsCustomVars()
|
||||||
{
|
{
|
||||||
return $this->supportsCustomVars;
|
return $this->supportsCustomVars;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function supportsGroups()
|
||||||
|
{
|
||||||
|
return $this->supportsGroups;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function groups()
|
||||||
|
{
|
||||||
|
$this->assertGroupsSupport();
|
||||||
|
if ($this->groups === null) {
|
||||||
|
if ($this->hasBeenLoadedFromDb()) {
|
||||||
|
$this->groups = IcingaObjectGroups::loadForStoredObject($this);
|
||||||
|
} else {
|
||||||
|
$this->groups = new IcingaObjectGroups($this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->groups;
|
||||||
|
}
|
||||||
|
|
||||||
protected function assertCustomVarsSupport()
|
protected function assertCustomVarsSupport()
|
||||||
{
|
{
|
||||||
if (! $this->supportsCustomVars()) {
|
if (! $this->supportsCustomVars()) {
|
||||||
@ -37,6 +61,18 @@ abstract class IcingaObject extends DbObject
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function assertGroupsSupport()
|
||||||
|
{
|
||||||
|
if (! $this->supportsGroups()) {
|
||||||
|
throw new ProgrammingError(
|
||||||
|
'Objects of type "%s" have no groups',
|
||||||
|
$this->getType()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function vars()
|
public function vars()
|
||||||
{
|
{
|
||||||
$this->assertCustomVarsSupport();
|
$this->assertCustomVarsSupport();
|
||||||
@ -56,10 +92,15 @@ abstract class IcingaObject extends DbObject
|
|||||||
return $this->getTableName() . '_var';
|
return $this->getTableName() . '_var';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getVarsIdColumn()
|
public function getShortTableName()
|
||||||
{
|
{
|
||||||
// strlen('icinga_') = 7
|
// strlen('icinga_') = 7
|
||||||
return substr($this->getTableName(), 7) . '_id';
|
return substr($this->getTableName(), 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getVarsIdColumn()
|
||||||
|
{
|
||||||
|
return $this->getShortTableName() . '_id';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isTemplate()
|
public function isTemplate()
|
||||||
@ -142,6 +183,18 @@ abstract class IcingaObject extends DbObject
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function renderGroups()
|
||||||
|
{
|
||||||
|
if ($this->supportsGroups()) {
|
||||||
|
return $this->groups()->toConfigString();
|
||||||
|
} else {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected function renderCommandProperty($commandId, $propertyName = 'check_command')
|
protected function renderCommandProperty($commandId, $propertyName = 'check_command')
|
||||||
{
|
{
|
||||||
return c::renderKeyValue(
|
return c::renderKeyValue(
|
||||||
@ -179,6 +232,7 @@ abstract class IcingaObject extends DbObject
|
|||||||
$this->renderObjectHeader(),
|
$this->renderObjectHeader(),
|
||||||
$this->renderImports(),
|
$this->renderImports(),
|
||||||
$this->renderProperties(),
|
$this->renderProperties(),
|
||||||
|
$this->renderGroups(),
|
||||||
$this->renderCustomVars(),
|
$this->renderCustomVars(),
|
||||||
$this->renderSuffix()
|
$this->renderSuffix()
|
||||||
));
|
));
|
||||||
|
267
library/Director/Objects/IcingaObjectGroups.php
Normal file
267
library/Director/Objects/IcingaObjectGroups.php
Normal file
@ -0,0 +1,267 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Icinga\Module\Director\Objects;
|
||||||
|
|
||||||
|
use Icinga\Exception\ProgrammingError;
|
||||||
|
use Iterator;
|
||||||
|
use Countable;
|
||||||
|
use Icinga\Module\Director\IcingaConfig\IcingaConfigRenderer;
|
||||||
|
use Icinga\Module\Director\IcingaConfig\IcingaConfigHelper as c;
|
||||||
|
|
||||||
|
class IcingaObjectGroups implements Iterator, Countable, IcingaConfigRenderer
|
||||||
|
{
|
||||||
|
protected $storedGroups = array();
|
||||||
|
|
||||||
|
protected $groups = array();
|
||||||
|
|
||||||
|
protected $modified = false;
|
||||||
|
|
||||||
|
protected $object;
|
||||||
|
|
||||||
|
private $position = 0;
|
||||||
|
|
||||||
|
protected $idx = array();
|
||||||
|
|
||||||
|
public function __construct(IcingaObject $object)
|
||||||
|
{
|
||||||
|
$this->object = $object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function count()
|
||||||
|
{
|
||||||
|
return count($this->groups);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function rewind()
|
||||||
|
{
|
||||||
|
$this->position = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function current()
|
||||||
|
{
|
||||||
|
if (! $this->valid()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->groups[$this->idx[$this->position]];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function key()
|
||||||
|
{
|
||||||
|
return $this->idx[$this->position];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function next()
|
||||||
|
{
|
||||||
|
++$this->position;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function valid()
|
||||||
|
{
|
||||||
|
return array_key_exists($this->position, $this->idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get($key)
|
||||||
|
{
|
||||||
|
if (array_key_exists($key, $this->groups)) {
|
||||||
|
return $this->groups[$key];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set($group)
|
||||||
|
{
|
||||||
|
$this->groups = array();
|
||||||
|
|
||||||
|
return $this->add($group);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Magic isset check
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function __isset($group)
|
||||||
|
{
|
||||||
|
return array_key_exists($group, $this->groups);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function remove($group)
|
||||||
|
{
|
||||||
|
if (array_key_exists($group, $this->groups)) {
|
||||||
|
unset($this->groups[$group]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->refreshIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function refreshIndex()
|
||||||
|
{
|
||||||
|
ksort($this->groups);
|
||||||
|
$this->idx = array_keys($this->groups);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function add($group)
|
||||||
|
{
|
||||||
|
// TODO: only one query when adding array
|
||||||
|
if (is_array($group)) {
|
||||||
|
foreach ($group as $g) {
|
||||||
|
$this->add($g);
|
||||||
|
}
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (array_key_exists($group, $this->groups)) {
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
$class = $this->getGroupClass();
|
||||||
|
$connection = $this->object->getConnection();
|
||||||
|
|
||||||
|
if ($group instanceof $class) {
|
||||||
|
$this->groups[$group->object_name] = $group;
|
||||||
|
} elseif (is_string($group)) {
|
||||||
|
$query = $this->object->getDb()->select()->from(
|
||||||
|
$this->getGroupTableName()
|
||||||
|
)->where('object_name = ?', $group);
|
||||||
|
$groups = $class::loadAll($connection, $query, 'object_name');
|
||||||
|
}
|
||||||
|
if (! array_key_exists($group, $groups)) {
|
||||||
|
throw new ProgrammingError(
|
||||||
|
'The group "%s" doesn\'t exists.',
|
||||||
|
$group
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->groups[$group] = $groups[$group];
|
||||||
|
|
||||||
|
$this->modified = true;
|
||||||
|
$this->refreshIndex();
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getGroupTableName()
|
||||||
|
{
|
||||||
|
return $this->object->getTableName() . 'group';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected function getGroupMemberTableName()
|
||||||
|
{
|
||||||
|
return $this->object->getTableName() . 'group_' . $this->getType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function listGroupNames()
|
||||||
|
{
|
||||||
|
return array_keys($this->groups);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getType()
|
||||||
|
{
|
||||||
|
return $this->object->getShortTableName();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function loadFromDb()
|
||||||
|
{
|
||||||
|
$db = $this->object->getDb();
|
||||||
|
$connection = $this->object->getConnection();
|
||||||
|
|
||||||
|
$type = $this->getType();
|
||||||
|
|
||||||
|
$table = $this->object->getTableName();
|
||||||
|
$query = $db->select()->from(
|
||||||
|
array('o' => $table),
|
||||||
|
array()
|
||||||
|
)->join(
|
||||||
|
array('go' => $table . 'group_' . $type),
|
||||||
|
'go.' . $type . '_id = o.id',
|
||||||
|
array()
|
||||||
|
)->join(
|
||||||
|
array('g' => $table . 'group'),
|
||||||
|
'go.' . $type . 'group_id = g.id',
|
||||||
|
'*'
|
||||||
|
)->where('o.object_name = ?', $this->object->object_name)
|
||||||
|
->order('g.object_name');
|
||||||
|
|
||||||
|
$class = $this->getGroupClass();
|
||||||
|
$this->groups = $class::loadAll($connection, $query, 'object_name');
|
||||||
|
$this->storedGroups = $this->groups;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function store()
|
||||||
|
{
|
||||||
|
$storedGroups = array_keys($this->storedGroups);
|
||||||
|
$groups = array_keys($this->groups);
|
||||||
|
|
||||||
|
$objectId = $this->object->id;
|
||||||
|
$type = $this->getType();
|
||||||
|
|
||||||
|
$objectCol = $type . '_id';
|
||||||
|
$groupCol = $type . 'group_id';
|
||||||
|
|
||||||
|
$toDelete = array_diff($storedGroups, $groups);
|
||||||
|
foreach ($toDelete as $group) {
|
||||||
|
$where = sprintf(
|
||||||
|
$objectCol . ' = %d AND ' . $groupCol . ' = %d',
|
||||||
|
$objectId,
|
||||||
|
$this->storedGroups[$group]->id
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->object->db->delete(
|
||||||
|
$this->getGroupMemberTableName(),
|
||||||
|
$where
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$toAdd = array_diff($groups, $storedGroups);
|
||||||
|
foreach ($toAdd as $group) {
|
||||||
|
$this->object->db->insert(
|
||||||
|
$this->getGroupMemberTableName(),
|
||||||
|
array(
|
||||||
|
$objectCol => $objectId,
|
||||||
|
$groupCol => $this->groups[$group]->id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
$this->storedGroups = $this->groups;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getGroupClass()
|
||||||
|
{
|
||||||
|
return __NAMESPACE__ . '\\Icinga' .ucfirst($this->object->getShortTableName()) . 'Group';
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function loadForStoredObject(IcingaObject $object)
|
||||||
|
{
|
||||||
|
$groups = new static($object);
|
||||||
|
return $groups->loadFromDb();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toConfigString()
|
||||||
|
{
|
||||||
|
return c::renderKeyValue('groups', c::renderArray(array_keys($this->groups)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __toString()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return $this->toConfigString();
|
||||||
|
} catch (Exception $e) {
|
||||||
|
trigger_error($e);
|
||||||
|
$previousHandler = set_exception_handler(function () {});
|
||||||
|
restore_error_handler();
|
||||||
|
if ($previousHandler !== null) {
|
||||||
|
call_user_func($previousHandler, $e);
|
||||||
|
die();
|
||||||
|
} else {
|
||||||
|
die($e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -14,8 +14,15 @@ abstract class DirectorObjectForm extends QuickForm
|
|||||||
|
|
||||||
public function onSuccess()
|
public function onSuccess()
|
||||||
{
|
{
|
||||||
|
$values = $this->getValues();
|
||||||
|
|
||||||
|
if ($this->object->supportsGroups()) {
|
||||||
|
unset($values['groups']);
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->object) {
|
if ($this->object) {
|
||||||
$this->object->setProperties($this->getValues())->store();
|
$this->object->setProperties($values)->store();
|
||||||
|
$this->storeGroupMembership();
|
||||||
$this->redirectOnSuccess(
|
$this->redirectOnSuccess(
|
||||||
sprintf(
|
sprintf(
|
||||||
$this->translate('The Icinga %s has successfully been stored'),
|
$this->translate('The Icinga %s has successfully been stored'),
|
||||||
@ -24,7 +31,8 @@ abstract class DirectorObjectForm extends QuickForm
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
$class = $this->getObjectClassname();
|
$class = $this->getObjectClassname();
|
||||||
$class::create($this->getValues())->store($this->db);
|
$this->object = $class::create($values)->store($this->db);
|
||||||
|
$this->storeGroupMembership();
|
||||||
$this->redirectOnSuccess(
|
$this->redirectOnSuccess(
|
||||||
sprintf(
|
sprintf(
|
||||||
$this->translate('A new Icinga %s has successfully been created'),
|
$this->translate('A new Icinga %s has successfully been created'),
|
||||||
@ -34,6 +42,17 @@ abstract class DirectorObjectForm extends QuickForm
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function storeGroupMembership()
|
||||||
|
{
|
||||||
|
if (! $this->object->supportsGroups()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->object->groups()->set(
|
||||||
|
preg_split('/\s*,\s*/', $this->getValue('groups'), -1, PREG_SPLIT_NO_EMPTY)
|
||||||
|
)->store();
|
||||||
|
}
|
||||||
|
|
||||||
protected function optionalEnum($enum)
|
protected function optionalEnum($enum)
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user