summaryrefslogtreecommitdiffstats
path: root/modules/monitoring/application/forms/Config/TransportConfigForm.php
diff options
context:
space:
mode:
Diffstat (limited to 'modules/monitoring/application/forms/Config/TransportConfigForm.php')
-rw-r--r--modules/monitoring/application/forms/Config/TransportConfigForm.php392
1 files changed, 392 insertions, 0 deletions
diff --git a/modules/monitoring/application/forms/Config/TransportConfigForm.php b/modules/monitoring/application/forms/Config/TransportConfigForm.php
new file mode 100644
index 0000000..c68e63d
--- /dev/null
+++ b/modules/monitoring/application/forms/Config/TransportConfigForm.php
@@ -0,0 +1,392 @@
+<?php
+/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */
+
+namespace Icinga\Module\Monitoring\Forms\Config;
+
+use Icinga\Data\ConfigObject;
+use Icinga\Module\Monitoring\Command\Transport\CommandTransport;
+use Icinga\Module\Monitoring\Exception\CommandTransportException;
+use InvalidArgumentException;
+use Icinga\Application\Platform;
+use Icinga\Exception\IcingaException;
+use Icinga\Exception\NotFoundError;
+use Icinga\Forms\ConfigForm;
+use Icinga\Module\Monitoring\Command\Transport\ApiCommandTransport;
+use Icinga\Module\Monitoring\Command\Transport\LocalCommandFile;
+use Icinga\Module\Monitoring\Command\Transport\RemoteCommandFile;
+use Icinga\Module\Monitoring\Forms\Config\Transport\ApiTransportForm;
+use Icinga\Module\Monitoring\Forms\Config\Transport\LocalTransportForm;
+use Icinga\Module\Monitoring\Forms\Config\Transport\RemoteTransportForm;
+
+/**
+ * Form for managing command transports
+ */
+class TransportConfigForm extends ConfigForm
+{
+ /**
+ * The transport to load when displaying the form for the first time
+ *
+ * @var string
+ */
+ protected $transportToLoad;
+
+ /**
+ * The names of all available Icinga instances
+ *
+ * @var array
+ */
+ protected $instanceNames;
+
+ /**
+ * @var bool
+ */
+ protected $validatePartial = true;
+
+ /**
+ * Initialize this form
+ */
+ public function init()
+ {
+ $this->setName('form_config_command_transports');
+ $this->setSubmitLabel($this->translate('Save Changes'));
+ }
+
+ /**
+ * Set the names of all available Icinga instances
+ *
+ * @param array $names
+ *
+ * @return $this
+ */
+ public function setInstanceNames(array $names)
+ {
+ $this->instanceNames = $names;
+ return $this;
+ }
+
+ /**
+ * Return the names of all available Icinga instances
+ *
+ * @return array
+ */
+ public function getInstanceNames()
+ {
+ return $this->instanceNames ?: array();
+ }
+
+ /**
+ * Return a form object for the given transport type
+ *
+ * @param string $type The transport type for which to return a form
+ *
+ * @return \Icinga\Web\Form
+ *
+ * @throws InvalidArgumentException In case the given transport type is invalid
+ */
+ public function getTransportForm($type)
+ {
+ switch (strtolower($type)) {
+ case LocalCommandFile::TRANSPORT:
+ return new LocalTransportForm();
+ case RemoteCommandFile::TRANSPORT:
+ return new RemoteTransportForm();
+ case ApiCommandTransport::TRANSPORT:
+ return new ApiTransportForm();
+ default:
+ throw new InvalidArgumentException(
+ sprintf($this->translate('Invalid command transport type "%s" given'), $type)
+ );
+ }
+ }
+
+ /**
+ * Populate the form with the given transport's config
+ *
+ * @param string $name
+ *
+ * @return $this
+ *
+ * @throws NotFoundError In case no transport with the given name is found
+ */
+ public function load($name)
+ {
+ if (! $this->config->hasSection($name)) {
+ throw new NotFoundError('No command transport called "%s" found', $name);
+ }
+
+ $this->transportToLoad = $name;
+ return $this;
+ }
+
+ /**
+ * Add a new command transport
+ *
+ * The transport to add is identified by the array-key `name'.
+ *
+ * @param array $data
+ *
+ * @return $this
+ *
+ * @throws InvalidArgumentException In case $data does not contain a transport name
+ * @throws IcingaException In case a transport with the same name already exists
+ */
+ public function add(array $data)
+ {
+ if (! isset($data['name'])) {
+ throw new InvalidArgumentException('Key \'name\' missing');
+ }
+
+ $transportName = $data['name'];
+ if ($this->config->hasSection($transportName)) {
+ throw new IcingaException(
+ $this->translate('A command transport with the name "%s" does already exist'),
+ $transportName
+ );
+ }
+
+ unset($data['name']);
+ $this->config->setSection($transportName, $data);
+ return $this;
+ }
+
+ /**
+ * Edit an existing command transport
+ *
+ * @param string $name
+ * @param array $data
+ *
+ * @return $this
+ *
+ * @throws NotFoundError In case no transport with the given name is found
+ */
+ public function edit($name, array $data)
+ {
+ if (! $this->config->hasSection($name)) {
+ throw new NotFoundError('No command transport called "%s" found', $name);
+ }
+
+ $transportConfig = $this->config->getSection($name);
+ if (isset($data['name'])) {
+ if ($data['name'] !== $name) {
+ $this->config->removeSection($name);
+ $name = $data['name'];
+ }
+
+ unset($data['name']);
+ }
+
+ $transportConfig->merge($data);
+ $this->config->setSection($name, $transportConfig);
+ return $this;
+ }
+
+ /**
+ * Remove a command transport
+ *
+ * @param string $name
+ *
+ * @return $this
+ */
+ public function delete($name)
+ {
+ $this->config->removeSection($name);
+ return $this;
+ }
+
+ /**
+ * Create and add elements to this form
+ *
+ * @param array $formData
+ */
+ public function createElements(array $formData)
+ {
+ $instanceNames = $this->getInstanceNames();
+ if (count($instanceNames) > 1) {
+ $options = array('none' => $this->translate('None', 'command transport instance association'));
+ $this->addElement(
+ 'select',
+ 'instance',
+ array(
+ 'label' => $this->translate('Instance Link'),
+ 'description' => $this->translate(
+ 'The name of the Icinga instance this transport should exclusively transfer commands to.'
+ ),
+ 'multiOptions' => array_merge($options, array_combine($instanceNames, $instanceNames))
+ )
+ );
+ }
+
+ $this->addElement(
+ 'text',
+ 'name',
+ array(
+ 'required' => true,
+ 'label' => $this->translate('Transport Name'),
+ 'description' => $this->translate(
+ 'The name of this command transport that is used to differentiate it from others'
+ )
+ )
+ );
+
+ $transportTypes = array(
+ ApiCommandTransport::TRANSPORT => $this->translate('Icinga 2 API'),
+ LocalCommandFile::TRANSPORT => $this->translate('Local Command File'),
+ RemoteCommandFile::TRANSPORT => $this->translate('Remote Command File')
+ );
+ if (! Platform::extensionLoaded('curl')) {
+ unset($transportTypes[ApiCommandTransport::TRANSPORT]);
+ }
+
+ $transportType = isset($formData['transport']) ? $formData['transport'] : null;
+ if ($transportType === null) {
+ $transportType = key($transportTypes);
+ }
+
+ $this->addElements(array(
+ array(
+ 'select',
+ 'transport',
+ array(
+ 'required' => true,
+ 'autosubmit' => true,
+ 'label' => $this->translate('Transport Type'),
+ 'multiOptions' => $transportTypes
+ )
+ )
+ ));
+
+ $this->addSubForm($this->getTransportForm($transportType)->create($formData), 'transport_form');
+ }
+
+ /**
+ * Add a submit button to this form and one to manually validate the configuration
+ *
+ * Calls parent::addSubmitButton() to add the submit button.
+ *
+ * @return $this
+ */
+ public function addSubmitButton()
+ {
+ parent::addSubmitButton();
+
+ if ($this->getSubForm('transport_form') instanceof ApiTransportForm) {
+ $btnSubmit = $this->getElement('btn_submit');
+
+ if ($btnSubmit !== null) {
+ // In the setup wizard $this is being used as a subform which doesn't have a submit button.
+ $this->addElement(
+ 'submit',
+ 'transport_validation',
+ array(
+ 'ignore' => true,
+ 'label' => $this->translate('Validate Configuration'),
+ 'data-progress-label' => $this->translate('Validation In Progress'),
+ 'decorators' => array('ViewHelper')
+ )
+ );
+
+ $this->setAttrib('data-progress-element', 'transport-progress');
+ $this->addElement(
+ 'note',
+ 'transport-progress',
+ array(
+ 'decorators' => array(
+ 'ViewHelper',
+ array('Spinner', array('id' => 'transport-progress'))
+ )
+ )
+ );
+
+ $elements = array('transport_validation', 'transport-progress');
+
+ $btnSubmit->setDecorators(array('ViewHelper'));
+ array_unshift($elements, 'btn_submit');
+
+ $this->addDisplayGroup(
+ $elements,
+ 'submit_validation',
+ array(
+ 'decorators' => array(
+ 'FormElements',
+ array('HtmlTag', array('tag' => 'div', 'class' => 'control-group form-controls'))
+ )
+ )
+ );
+ }
+ }
+
+ return $this;
+ }
+
+ /**
+ * Populate the configuration of the transport to load
+ */
+ public function onRequest()
+ {
+ if ($this->transportToLoad) {
+ $data = $this->config->getSection($this->transportToLoad)->toArray();
+ $data['name'] = $this->transportToLoad;
+ $this->populate($data);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isValidPartial(array $formData)
+ {
+ $isValidPartial = parent::isValidPartial($formData);
+
+ $transportValidation = $this->getElement('transport_validation');
+ if ($transportValidation !== null && $transportValidation->isChecked() && $this->isValid($formData)) {
+ $this->info($this->translate('The configuration has been successfully validated.'));
+ }
+
+ return $isValidPartial;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isValid($formData)
+ {
+ if (! parent::isValid($formData)) {
+ return false;
+ }
+
+ if ($this->getSubForm('transport_form') instanceof ApiTransportForm) {
+ if (! isset($formData['transport_validation'])
+ && isset($formData['force_creation']) && $formData['force_creation']
+ ) {
+ // ignore any validation result
+ return true;
+ }
+
+ try {
+ CommandTransport::createTransport(new ConfigObject($this->getValues()))->probe();
+ } catch (CommandTransportException $e) {
+ $this->error(sprintf(
+ $this->translate('Failed to successfully validate the configuration: %s'),
+ $e->getMessage()
+ ));
+
+ $this->addElement(
+ 'checkbox',
+ 'force_creation',
+ array(
+ 'order' => 0,
+ 'ignore' => true,
+ 'label' => $this->translate('Force Changes'),
+ 'description' => $this->translate(
+ 'Check this box to enforce changes without connectivity validation'
+ )
+ )
+ );
+
+ return false;
+ }
+ }
+
+ return true;
+ }
+}