summaryrefslogtreecommitdiffstats
path: root/library/Director/DataType
diff options
context:
space:
mode:
Diffstat (limited to 'library/Director/DataType')
-rw-r--r--library/Director/DataType/DataTypeArray.php14
-rw-r--r--library/Director/DataType/DataTypeBoolean.php30
-rw-r--r--library/Director/DataType/DataTypeDatalist.php159
-rw-r--r--library/Director/DataType/DataTypeDictionary.php107
-rw-r--r--library/Director/DataType/DataTypeDirectorObject.php87
-rw-r--r--library/Director/DataType/DataTypeNumber.php19
-rw-r--r--library/Director/DataType/DataTypeSqlQuery.php96
-rw-r--r--library/Director/DataType/DataTypeString.php35
-rw-r--r--library/Director/DataType/DataTypeTime.php16
9 files changed, 563 insertions, 0 deletions
diff --git a/library/Director/DataType/DataTypeArray.php b/library/Director/DataType/DataTypeArray.php
new file mode 100644
index 0000000..a7667d9
--- /dev/null
+++ b/library/Director/DataType/DataTypeArray.php
@@ -0,0 +1,14 @@
+<?php
+
+namespace Icinga\Module\Director\DataType;
+
+use Icinga\Module\Director\Hook\DataTypeHook;
+use Icinga\Module\Director\Web\Form\QuickForm;
+
+class DataTypeArray extends DataTypeHook
+{
+ public function getFormElement($name, QuickForm $form)
+ {
+ return $form->createElement('extensibleSet', $name);
+ }
+}
diff --git a/library/Director/DataType/DataTypeBoolean.php b/library/Director/DataType/DataTypeBoolean.php
new file mode 100644
index 0000000..d9edc60
--- /dev/null
+++ b/library/Director/DataType/DataTypeBoolean.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace Icinga\Module\Director\DataType;
+
+use Icinga\Module\Director\Hook\DataTypeHook;
+use Icinga\Module\Director\Web\Form\Decorator\ViewHelperRaw;
+use Icinga\Module\Director\Web\Form\QuickForm;
+use Zend_Form_Element as ZfElement;
+
+class DataTypeBoolean extends DataTypeHook
+{
+ public function getFormElement($name, QuickForm $form)
+ {
+ return $this->applyRawViewHelper(
+ $form->createElement('boolean', $name)
+ );
+ }
+
+ protected function applyRawViewHelper(ZfElement $element)
+ {
+ $vhClass = 'Zend_Form_Decorator_ViewHelper';
+ $decorators = $element->getDecorators();
+ if (array_key_exists($vhClass, $decorators)) {
+ $decorators[$vhClass] = new ViewHelperRaw;
+ $element->setDecorators($decorators);
+ }
+
+ return $element;
+ }
+}
diff --git a/library/Director/DataType/DataTypeDatalist.php b/library/Director/DataType/DataTypeDatalist.php
new file mode 100644
index 0000000..354c7c3
--- /dev/null
+++ b/library/Director/DataType/DataTypeDatalist.php
@@ -0,0 +1,159 @@
+<?php
+
+namespace Icinga\Module\Director\DataType;
+
+use Icinga\Module\Director\Acl;
+use Icinga\Module\Director\Db;
+use Icinga\Module\Director\Hook\DataTypeHook;
+use Icinga\Module\Director\Objects\DirectorDatalistEntry;
+use Icinga\Module\Director\Web\Form\DirectorForm;
+use Icinga\Module\Director\Web\Form\QuickForm;
+use Icinga\Module\Director\Web\Form\DirectorObjectForm;
+use Icinga\Module\Director\Web\Form\Validate\IsDataListEntry;
+
+class DataTypeDatalist extends DataTypeHook
+{
+ /**
+ * @param $name
+ * @param QuickForm $form
+ * @return \Zend_Form_Element
+ * @throws \Zend_Form_Exception
+ */
+ public function getFormElement($name, QuickForm $form)
+ {
+ $params = [];
+ $behavior = $this->getSetting('behavior', 'strict');
+ $targetDataType = $this->getSetting('data_type', 'string');
+ $listId = $this->getSetting('datalist_id');
+
+ if ($behavior === 'strict') {
+ $enum = $this->getEntries($form);
+ if ($targetDataType === 'string') {
+ $params['sorted'] = true;
+ $params = ['multiOptions' => $form->optionalEnum($enum)];
+ $type = 'select';
+ } else {
+ $params = ['multiOptions' => $form->optionalEnum($enum)];
+ $type = 'extensibleSet';
+ }
+ } else {
+ if ($targetDataType === 'string') {
+ $type = 'text';
+ } else {
+ $type = 'extensibleSet';
+ }
+ $params['class'] = 'director-suggest';
+ $params['data-suggestion-context'] = "dataListValuesForListId!$listId";
+ }
+ $element = $form->createElement($type, $name, $params);
+ if ($behavior === 'suggest_strict') {
+ $element->addValidator(new IsDataListEntry($listId, $form->getDb()));
+ }
+
+ if ($behavior === 'suggest_extend') {
+ $form->callOnSuccess(function (DirectorForm $form) use ($name, $listId) {
+ $value = (array) $form->getValue($name);
+ if ($value === null) {
+ return;
+ }
+
+ $db = $form->getDb();
+ foreach ($value as $entry) {
+ if ($entry !== '') {
+ $this->createEntryIfNotExists($db, $listId, $entry);
+ }
+ }
+ });
+ }
+
+ return $element;
+ }
+
+ /**
+ * @param Db $db
+ * @param $listId
+ * @param $entry
+ */
+ protected function createEntryIfNotExists(Db $db, $listId, $entry)
+ {
+ if (! DirectorDatalistEntry::exists([
+ 'list_id' => $listId,
+ 'entry_name' => $entry,
+ ], $db)) {
+ DirectorDatalistEntry::create([
+ 'list_id' => $listId,
+ 'entry_name' => $entry,
+ 'entry_value' => $entry,
+ ])->store($db);
+ }
+ }
+
+ protected function getEntries(QuickForm $form)
+ {
+ /** @var DirectorObjectForm $form */
+ $db = $form->getDb()->getDbAdapter();
+ $roles = Acl::instance()->listRoleNames();
+ $select = $db->select()
+ ->from('director_datalist_entry', ['entry_name', 'entry_value'])
+ ->where('list_id = ?', $this->getSetting('datalist_id'))
+ ->order('entry_value ASC');
+
+ if (empty($roles)) {
+ $select->where('allowed_roles IS NULL');
+ } else {
+ $parts = ['allowed_roles IS NULL'];
+ foreach ($roles as $role) {
+ $parts[] = $db->quoteInto("allowed_roles LIKE ?", '%' . \json_encode($role) . '%');
+ }
+ $select->where('(' . \implode(' OR ', $parts) . ')');
+ }
+
+ return $db->fetchPairs($select);
+ }
+
+ /**
+ * @param QuickForm $form
+ * @throws \Zend_Form_Exception
+ */
+ public static function addSettingsFormFields(QuickForm $form)
+ {
+ /** @var DirectorObjectForm $form */
+ $db = $form->getDb();
+
+ $form->addElement('select', 'datalist_id', [
+ 'label' => 'List name',
+ 'required' => true,
+ 'multiOptions' => $form->optionalEnum($db->enumDatalist()),
+ ]);
+
+ $form->addElement('select', 'data_type', [
+ 'label' => $form->translate('Target data type'),
+ 'multiOptions' => $form->optionalEnum([
+ 'string' => $form->translate('String'),
+ 'array' => $form->translate('Array'),
+ ]),
+ 'description' => $form->translate(
+ 'Whether this should be a String or an Array in the generated'
+ . ' Icinga configuration. In case you opt for Array, Director'
+ . ' users will be able to select multiple elements from the list'
+ ),
+ 'required' => true,
+ ]);
+
+ $form->addElement('select', 'behavior', [
+ 'label' => $form->translate('Element behavior'),
+ 'value' => 'strict',
+ 'description' => $form->translate(
+ 'This allows to show either a drop-down list or an auto-completion'
+ ),
+ 'multiOptions' => [
+ 'strict' => $form->translate('Dropdown (list values only)'),
+ $form->translate('Autocomplete') => [
+ 'suggest_strict' => $form->translate('Strict, list values only'),
+ 'suggest_optional' => $form->translate('Allow for values not on the list'),
+ 'suggest_extend' => $form->translate('Extend the list with new values'),
+ ]
+ ]
+ ]);
+ }
+}
diff --git a/library/Director/DataType/DataTypeDictionary.php b/library/Director/DataType/DataTypeDictionary.php
new file mode 100644
index 0000000..7880698
--- /dev/null
+++ b/library/Director/DataType/DataTypeDictionary.php
@@ -0,0 +1,107 @@
+<?php
+
+namespace Icinga\Module\Director\DataType;
+
+use Icinga\Module\Director\Hook\DataTypeHook;
+use Icinga\Module\Director\Objects\IcingaHost;
+use Icinga\Module\Director\Objects\IcingaService;
+use Icinga\Module\Director\Web\Form\DirectorObjectForm;
+use Icinga\Module\Director\Web\Form\QuickForm;
+use InvalidArgumentException;
+use ipl\Html\Html;
+use RuntimeException;
+
+class DataTypeDictionary extends DataTypeHook
+{
+ public function getFormElement($name, QuickForm $form)
+ {
+ if (strpos($name, 'var_') !== 0) {
+ throw new InvalidArgumentException(
+ "'$name' is not a valid candidate for a Nested Dictionary, 'var_*' expected"
+ );
+ }
+ /** @var DirectorObjectForm $form */
+ $object = $form->getObject();
+ if ($form->isTemplate()) {
+ return $form->createElement('simpleNote', $name, [
+ 'ignore' => true,
+ 'value' => Html::tag('span', $form->translate('To be managed on objects only')),
+ ]);
+ }
+ if (! $object->hasBeenLoadedFromDb()) {
+ return $form->createElement('simpleNote', $name, [
+ 'ignore' => true,
+ 'value' => Html::tag(
+ 'span',
+ $form->translate('Can be managed once this object has been created')
+ ),
+ ]);
+ }
+ $params = [
+ 'varname' => substr($name, 4),
+ ];
+ if ($object instanceof IcingaHost) {
+ $params['host'] = $object->getObjectName();
+ } elseif ($object instanceof IcingaService) {
+ $params['host'] = $object->get('host');
+ $params['service'] = $object->getObjectName();
+ }
+ return $form->createElement('InstanceSummary', $name, [
+ 'linkParams' => $params
+ ]);
+ }
+
+ public static function addSettingsFormFields(QuickForm $form)
+ {
+ /** @var DirectorObjectForm $form */
+ $db = $form->getDb()->getDbAdapter();
+ $enum = [
+ 'host' => $form->translate('Hosts'),
+ 'service' => $form->translate('Services'),
+ ];
+
+ $form->addElement('select', 'template_object_type', [
+ 'label' => $form->translate('Template (Object) Type'),
+ 'description' => $form->translate(
+ 'Please choose a specific Icinga object type'
+ ),
+ 'class' => 'autosubmit',
+ 'required' => true,
+ 'multiOptions' => $form->optionalEnum($enum),
+ 'sorted' => true,
+ ]);
+
+ // There should be a helper method for this
+ if ($form->hasBeenSent()) {
+ $type = $form->getSentOrObjectValue('template_object_type');
+ } else {
+ $type = $form->getObject()->getSetting('template_object_type');
+ }
+ if (empty($type)) {
+ return $form;
+ }
+
+ if (array_key_exists($type, $enum)) {
+ $form->addElement('select', 'template_name', [
+ 'label' => $form->translate('Template'),
+ 'multiOptions' => $form->optionalEnum(self::fetchTemplateNames($db, $type)),
+ 'required' => true,
+ ]);
+ } else {
+ throw new RuntimeException("$type is not a valid Dictionary object type");
+ }
+
+ return $form;
+ }
+
+ protected static function fetchTemplateNames($db, $type)
+ {
+ $query = $db->select()
+ ->from("icinga_$type", ['a' => 'object_name', 'b' => 'object_name'])
+ ->where('object_type = ?', 'template')
+ ->where('template_choice_id IS NULL')
+ ->order('object_name');
+
+ return $db->fetchPairs($query);
+ }
+}
diff --git a/library/Director/DataType/DataTypeDirectorObject.php b/library/Director/DataType/DataTypeDirectorObject.php
new file mode 100644
index 0000000..7f313e0
--- /dev/null
+++ b/library/Director/DataType/DataTypeDirectorObject.php
@@ -0,0 +1,87 @@
+<?php
+
+namespace Icinga\Module\Director\DataType;
+
+use Icinga\Module\Director\Hook\DataTypeHook;
+use Icinga\Module\Director\Objects\IcingaObject;
+use Icinga\Module\Director\Web\Form\DirectorObjectForm;
+use Icinga\Module\Director\Web\Form\QuickForm;
+
+class DataTypeDirectorObject extends DataTypeHook
+{
+ public function getFormElement($name, QuickForm $form)
+ {
+ /** @var DirectorObjectForm $form */
+ $db = $form->getDb()->getDbAdapter();
+
+ $type = $this->getSetting('icinga_object_type');
+ $dummy = IcingaObject::createByType($type);
+
+ $display = in_array($type, ['service_set', 'notification'])
+ ? 'object_name'
+ : 'COALESCE(display_name, object_name)';
+ $query = $db->select()->from($dummy->getTableName(), [
+ 'object_name' => 'object_name',
+ 'display_name' => $display
+ ])->order($display);
+
+ if ($type === 'service_set') {
+ $query->where('host_id IS NULL');
+ } elseif ($type === 'notification') {
+ $query->where('object_type = ?', 'apply');
+ } else {
+ $query->where('object_type = ?', 'object');
+ }
+
+ $enum = $db->fetchPairs($query);
+
+ $params = [];
+ if ($this->getSetting('data_type') === 'array') {
+ $elementType = $type === 'notification' ? 'select' : 'extensibleSet';
+ $params['sorted'] = true;
+ $params = ['multiOptions' => $enum];
+ } else {
+ $params = ['multiOptions' => [
+ null => $form->translate('- please choose -'),
+ ] + $enum];
+ $elementType = 'select';
+ }
+
+ return $form->createElement($elementType, $name, $params);
+ }
+
+ public static function addSettingsFormFields(QuickForm $form)
+ {
+ $enum = [
+ 'host' => $form->translate('Hosts'),
+ 'hostgroup' => $form->translate('Host groups'),
+ 'notification' => $form->translate('Notification Apply Rules'),
+ 'service' => $form->translate('Services'),
+ 'servicegroup' => $form->translate('Service groups'),
+ 'service_set' => $form->translate('Service Set'),
+ 'user' => $form->translate('Users'),
+ 'usergroup' => $form->translate('User groups'),
+ ];
+
+ $form->addElement('select', 'icinga_object_type', [
+ 'label' => $form->translate('Object'),
+ 'description' => $form->translate(
+ 'Please choose a specific Icinga object type'
+ ),
+ 'required' => true,
+ 'multiOptions' => $form->optionalEnum($enum),
+ 'sorted' => true,
+ ]);
+
+ $form->addElement('select', 'data_type', [
+ 'label' => $form->translate('Target data type'),
+ 'multiOptions' => $form->optionalEnum([
+ 'string' => $form->translate('String'),
+ 'array' => $form->translate('Array'),
+ ]),
+ 'required' => true,
+ ]);
+
+ return $form;
+ }
+}
diff --git a/library/Director/DataType/DataTypeNumber.php b/library/Director/DataType/DataTypeNumber.php
new file mode 100644
index 0000000..cd47f88
--- /dev/null
+++ b/library/Director/DataType/DataTypeNumber.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace Icinga\Module\Director\DataType;
+
+use Icinga\Module\Director\Hook\DataTypeHook;
+use Icinga\Module\Director\Web\Form\QuickForm;
+use Icinga\Module\Director\Data\ValueFilter\FilterInt;
+
+class DataTypeNumber extends DataTypeHook
+{
+ public function getFormElement($name, QuickForm $form)
+ {
+ $element = $form->createElement('text', $name)
+ ->addValidator('int')
+ ->addFilter(new FilterInt);
+
+ return $element;
+ }
+}
diff --git a/library/Director/DataType/DataTypeSqlQuery.php b/library/Director/DataType/DataTypeSqlQuery.php
new file mode 100644
index 0000000..07e7418
--- /dev/null
+++ b/library/Director/DataType/DataTypeSqlQuery.php
@@ -0,0 +1,96 @@
+<?php
+
+namespace Icinga\Module\Director\DataType;
+
+use Exception;
+use Icinga\Data\Db\DbConnection;
+use Icinga\Module\Director\Hook\DataTypeHook;
+use Icinga\Module\Director\Web\Form\QuickForm;
+use Icinga\Module\Director\Util;
+
+class DataTypeSqlQuery extends DataTypeHook
+{
+ /** @var \Zend_Db_Adapter_Pdo_Abstract */
+ protected $db;
+
+ protected static $cachedResult;
+
+ protected static $cacheTime = 0;
+
+ public function getFormElement($name, QuickForm $form)
+ {
+ try {
+ $data = $this->fetchData();
+ $error = false;
+ } catch (Exception $e) {
+ $data = array();
+ $error = sprintf($form->translate('Unable to fetch data: %s'), $e->getMessage());
+ }
+
+ $params = [];
+ if ($this->getSetting('data_type') === 'array') {
+ $type = 'extensibleSet';
+ $params['sorted'] = true;
+ $params = ['multiOptions' => $data];
+ } else {
+ $params = ['multiOptions' => [
+ null => $form->translate('- please choose -'),
+ ] + $data];
+ $type = 'select';
+ }
+
+ $element = $form->createElement($type, $name, $params);
+
+ if ($error) {
+ $element->addError($error);
+ }
+
+ return $element;
+ }
+
+ protected function fetchData()
+ {
+ // TODO: Hash _:)
+ //if (self::$cachedResult === null || (time() - self::$cacheTime > 3)) {
+ self::$cachedResult = $this->db()->fetchPairs($this->settings['query']);
+ self::$cacheTime = time();
+ // }
+
+ return self::$cachedResult;
+ }
+
+ public static function addSettingsFormFields(QuickForm $form)
+ {
+ Util::addDbResourceFormElement($form, 'resource');
+
+ $form->addElement('textarea', 'query', array(
+ 'label' => 'DB Query',
+ 'description' => 'This query should return exactly two columns, value and label',
+ 'required' => true,
+ 'rows' => 10,
+ ));
+
+ $form->addElement('select', 'data_type', [
+ 'label' => $form->translate('Target data type'),
+ 'multiOptions' => $form->optionalEnum([
+ 'string' => $form->translate('String'),
+ 'array' => $form->translate('Array'),
+ ]),
+ 'value' => 'string',
+ 'required' => true,
+ ]);
+
+ return $form;
+ }
+
+ protected function db()
+ {
+ if ($this->db === null) {
+ $this->db = DbConnection::fromResourceName($this->settings['resource'])->getDbAdapter();
+ // TODO: should be handled by resources:
+ $this->db->exec("SET NAMES 'utf8'");
+ }
+
+ return $this->db;
+ }
+}
diff --git a/library/Director/DataType/DataTypeString.php b/library/Director/DataType/DataTypeString.php
new file mode 100644
index 0000000..a2dc196
--- /dev/null
+++ b/library/Director/DataType/DataTypeString.php
@@ -0,0 +1,35 @@
+<?php
+
+namespace Icinga\Module\Director\DataType;
+
+use Icinga\Module\Director\Hook\DataTypeHook;
+use Icinga\Module\Director\Web\Form\QuickForm;
+
+class DataTypeString extends DataTypeHook
+{
+ public function getFormElement($name, QuickForm $form)
+ {
+ if ($this->getSetting('visibility', 'visible') === 'visible') {
+ $element = $form->createElement('text', $name);
+ } else {
+ $element = $form->createElement('storedPassword', $name);
+ }
+
+ return $element;
+ }
+
+ public static function addSettingsFormFields(QuickForm $form)
+ {
+ $form->addElement('select', 'visibility', [
+ 'label' => $form->translate('Visibility'),
+ 'multiOptions' => $form->optionalEnum([
+ 'visible' => $form->translate('Visible'),
+ 'hidden' => $form->translate('Hidden'),
+ ]),
+ 'value' => 'visible',
+ 'required' => true,
+ ]);
+
+ return $form;
+ }
+}
diff --git a/library/Director/DataType/DataTypeTime.php b/library/Director/DataType/DataTypeTime.php
new file mode 100644
index 0000000..13b9635
--- /dev/null
+++ b/library/Director/DataType/DataTypeTime.php
@@ -0,0 +1,16 @@
+<?php
+
+namespace Icinga\Module\Director\DataType;
+
+use Icinga\Module\Director\Hook\DataTypeHook;
+use Icinga\Module\Director\Web\Form\QuickForm;
+
+class DataTypeTime extends DataTypeHook
+{
+ public function getFormElement($name, QuickForm $form)
+ {
+ $element = $form->createElement('text', $name);
+
+ return $element;
+ }
+}