diff options
Diffstat (limited to 'library/Director/DataType')
-rw-r--r-- | library/Director/DataType/DataTypeArray.php | 14 | ||||
-rw-r--r-- | library/Director/DataType/DataTypeBoolean.php | 30 | ||||
-rw-r--r-- | library/Director/DataType/DataTypeDatalist.php | 159 | ||||
-rw-r--r-- | library/Director/DataType/DataTypeDictionary.php | 107 | ||||
-rw-r--r-- | library/Director/DataType/DataTypeDirectorObject.php | 87 | ||||
-rw-r--r-- | library/Director/DataType/DataTypeNumber.php | 19 | ||||
-rw-r--r-- | library/Director/DataType/DataTypeSqlQuery.php | 96 | ||||
-rw-r--r-- | library/Director/DataType/DataTypeString.php | 35 | ||||
-rw-r--r-- | library/Director/DataType/DataTypeTime.php | 16 |
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; + } +} |