From 086e0812682c4fac167784712733f7bdebf6e52c Mon Sep 17 00:00:00 2001 From: Thomas Gelf Date: Thu, 6 Jul 2017 11:41:29 +0200 Subject: [PATCH] SelfServiceSettings: settings for the new Self... ...Service API feature refs #486 --- .../controllers/SettingsController.php | 24 ++ application/forms/SelfServiceSettingsForm.php | 207 ++++++++++++++++++ .../Dashlet/ApiUserObjectDashlet.php | 2 +- .../Dashboard/InfrastructureDashboard.php | 1 + library/Director/Settings.php | 32 ++- 5 files changed, 255 insertions(+), 11 deletions(-) create mode 100644 application/forms/SelfServiceSettingsForm.php diff --git a/application/controllers/SettingsController.php b/application/controllers/SettingsController.php index 5ba05e9b..c7cc4af6 100644 --- a/application/controllers/SettingsController.php +++ b/application/controllers/SettingsController.php @@ -2,7 +2,10 @@ namespace Icinga\Module\Director\Controllers; +use Icinga\Module\Director\Forms\SelfServiceSettingsForm; +use Icinga\Module\Director\Settings; use Icinga\Module\Director\Web\Controller\ActionController; +use ipl\Html\Html; class SettingsController extends ActionController { @@ -16,4 +19,25 @@ class SettingsController extends ActionController ->setModuleConfig($this->Config()) ->handleRequest(); } + + public function selfServiceAction() + { + $form = SelfServiceSettingsForm::create($this->db(), new Settings($this->db())); + + $form->handleRequest(); + if ($this->getRequest()->isApiRequest()) { + return; + } + + $hint = $this->translate( + 'The Icinga Director Self Service API allows your Hosts to register' + . ' themselves. This allows them to get their Icinga Agent configured,' + . ' installed and upgraded in an automated way.' + ); + + $this->addSingleTab($this->translate('Self Service')) + ->addTitle($this->translate('Self Service API - Settings')) + ->content()->add(Html::p($hint)) + ->add($form); + } } diff --git a/application/forms/SelfServiceSettingsForm.php b/application/forms/SelfServiceSettingsForm.php new file mode 100644 index 00000000..ae0ec983 --- /dev/null +++ b/application/forms/SelfServiceSettingsForm.php @@ -0,0 +1,207 @@ +settings; + $this->addElement('select', 'agent_name', [ + 'label' => $this->translate('Host Name'), + 'description' => $this->translate( + 'What to use as your Icinga 2 Agent\'s Host Name' + ), + 'multiOptions' => [ + 'fqdn' => $this->translate('Fully qualified domain name (FQDN)'), + 'hostname' => $this->translate('Host name (local part, without domain)'), + ], + 'value' => $settings->getStoredOrDefaultValue('self-service/agent_name') + ]); + + $this->addElement('select', 'transform_hostname', [ + 'label' => $this->translate('Transform Host Name'), + 'description' => $this->translate( + 'Whether to adjust your host name' + ), + 'multiOptions' => [ + '0' => $this->translate('Do not transform at all'), + '1' => $this->translate('Transform to lowercase'), + '2' => $this->translate('Transform to uppercase'), + ], + 'value' => $settings->getStoredOrDefaultValue('self-service/transform_hostname') + ]); + + $this->addElement('select', 'download_type', [ + 'label' => $this->translate('Installation Source'), + 'description' => $this->translate( + 'You might want to let the generated Powershell script install' + . ' the Icinga 2 Agent in an automated way. If so, please choose' + . ' where your Windows nodes should fetch the Agent installer' + ), + 'multiOptions' => [ + null => $this->translate('- no automatic installation -'), + 'director' => $this->translate('Download via the Icinga Director'), + 'icinga' => $this->translate('Download from packages.icinga.com'), + 'url' => $this->translate('Download from a custom url'), + 'file' => $this->translate('Use a local file or network share'), + ], + 'value' => $settings->getStoredOrDefaultValue('self-service/download_type'), + 'class' => 'autosubmit' + ]); + + $downloadType = $this->getSentValue( + 'download_type', + $settings->getStoredOrDefaultValue('self-service/download_type') + ); + + if ($downloadType) { + $this->addElement('text', 'download_url', [ + 'label' => $this->translate('Source Path'), + 'description' => $this->translate( + 'Define a download Url or local directory from which the a specific' + . ' Icinga 2 Agent MSI Installer package should be fetched. Please' + . ' ensure to only define the base download Url or Directory. The' + . ' Module will generate the MSI file name based on your operating' + . ' system architecture and the version to install. The Icinga 2 MSI' + . ' Installer name is internally build as follows:' + . ' Icinga2-v[InstallAgentVersion]-[OSArchitecture].msi (full example:' + . ' Icinga2-v2.6.3-x86_64.msi)' + ), + 'value' => $settings->getStoredOrDefaultValue('self-service/download_url'), + ]); + + // TODO: offer to check for available versions + if ($downloadType === 'icinga') { + $el = $this->getElement('download_url'); + $el->setAttrib('disabled', 'disabled'); + $value = 'https://packages.icinga.com/windows/'; + $el->setValue($value); + $this->setSentValue('download_url', $value); + } + if ($downloadType === 'director') { + $el = $this->getElement('download_url'); + $el->setAttrib('disabled', 'disabled'); + + $r = $this->getRequest(); + $scheme = $r->getServer('HTTP_X_FORWARDED_PROTO', $r->getScheme()); + + $value = sprintf( + '%s://%s%s/director/download/windows/', + $scheme, + $r->getHttpHost(), + $this->getRequest()->getBaseUrl() + ); + $el->setValue($value); + $this->setSentValue('download_url', $value); + } + + $this->addElement('text', 'agent_version', [ + 'label' => $this->translate('Agent Version'), + 'description' => $this->translate( + 'In case the Icinga 2 Agent should be automatically installed,' + . ' this has to be a string value like: 2.6.3' + ), + 'value' => $settings->getStoredOrDefaultValue('self-service/agent_version'), + 'required' => true, + ]); + + $this->addElement('extensibleSet', 'installer_hashes', [ + 'label' => $this->translate('Installer Hashes'), + 'description' => $this->translate( + 'To ensure downloaded packages are build by the Icinga Team' + . ' and not compromised by third parties, you will be able' + . ' to provide an array of SHA1 hashes here. In case you have' + . ' defined any hashses, the module will not continue with' + . ' updating / installing the Agent in case the SHA1 hash of' + . ' the downloaded MSI package is not matching one of the' + . ' provided hashes of this setting' + ), + 'value' => $settings->getStoredOrDefaultValue('self-service/installer_hashes'), + ]); + + $this->addBoolean('allow_updates', [ + 'label' => $this->translate('Allow Updates'), + 'description' => $this->translate( + 'In case the Icinga 2 Agent is already installed on the system,' + . ' this parameter will allow you to configure if you wish to' + . ' upgrade / downgrade to a specified version with the as well.' + ), + 'value' => $settings->getStoredOrDefaultValue('self-service/allow_updates'), + 'required' => true, + ], true); + } + + /* + // This is managed through the template + $this->addBoolean('accept_config', [ + 'label' => $this->translate('Accept Config'), + 'description' => $this->translate( + 'Whether this Agent should accept configuration from it\'s Icinga' + . ' parent Zone' + ), + 'required' => true, + ], true); + */ + + $this->addBoolean('flush_api_dir', [ + 'label' => $this->translate('Flush API directory'), + 'description' => $this->translate( + 'In case the Icinga Agent will accept configuration from the parent' + . ' Icinga 2 system, it will possibly write data to /var/lib/icinga2/api/*.' + . ' By setting this parameter to true, all content inside the api directory' + . ' will be flushed before an eventual restart of the Icinga 2 Agent' + ), + 'required' => true, + ], true); + } + + public static function create(Db $db, Settings $settings) + { + return static::load()->setDb($db)->setSettings($settings); + } + + protected function setSentValue($key, $value) + { + $this->getRequest()->setPost($key, $value); + return $this; + } + + public function setSettings(Settings $settings) + { + $this->settings = $settings; + return $this; + } + + public function onSuccess() + { + try { + foreach ($this->getValues() as $key => $value) { + if ($value === '') { + $value = null; + } + + if (is_array($value)) { + $value = json_encode($value); + } + $this->settings->set("self-service/$key", $value); + } + + $this->setSuccessMessage($this->translate( + 'Self Service Sttings have been stored' + )); + + parent::onSuccess(); + } catch (Exception $e) { + $this->addException($e); + } + } +} diff --git a/library/Director/Dashboard/Dashlet/ApiUserObjectDashlet.php b/library/Director/Dashboard/Dashlet/ApiUserObjectDashlet.php index f348d5f0..419859d5 100644 --- a/library/Director/Dashboard/Dashlet/ApiUserObjectDashlet.php +++ b/library/Director/Dashboard/Dashlet/ApiUserObjectDashlet.php @@ -10,7 +10,7 @@ class ApiUserObjectDashlet extends Dashlet public function getTitle() { - return $this->translate('Api users'); + return $this->translate('Icinga Api users'); } public function getUrl() diff --git a/library/Director/Dashboard/InfrastructureDashboard.php b/library/Director/Dashboard/InfrastructureDashboard.php index e9876e55..dfcd016b 100644 --- a/library/Director/Dashboard/InfrastructureDashboard.php +++ b/library/Director/Dashboard/InfrastructureDashboard.php @@ -6,6 +6,7 @@ class InfrastructureDashboard extends Dashboard { protected $dashletNames = array( 'Kickstart', + 'SelfService', 'ApiUserObject', 'EndpointObject', 'ZoneObject', diff --git a/library/Director/Settings.php b/library/Director/Settings.php index 8987b9df..99b5ae54 100644 --- a/library/Director/Settings.php +++ b/library/Director/Settings.php @@ -11,16 +11,18 @@ class Settings protected $cache; protected $defaults = array( - 'default_global_zone' => 'director-global', - 'magic_apply_for' => '_director_apply_for', - 'config_format' => 'v2', - 'override_services_varname' => '_override_servicevars', - 'override_services_templatename' => 'host var overrides (Director)', - 'disable_all_jobs' => 'n', // 'y' - 'enable_audit_log' => 'n', - 'deployment_mode_v1' => 'active-passive', - 'deployment_path_v1' => null, - 'activation_script_v1' => null, + 'default_global_zone' => 'director-global', + 'magic_apply_for' => '_director_apply_for', + 'config_format' => 'v2', + 'override_services_varname' => '_override_servicevars', + 'override_services_templatename' => 'host var overrides (Director)', + 'disable_all_jobs' => 'n', // 'y' + 'enable_audit_log' => 'n', + 'deployment_mode_v1' => 'active-passive', + 'deployment_path_v1' => null, + 'activation_script_v1' => null, + 'self-service/agent_name' => 'fqdn', + 'self-service/transform_hostname' => '0' // 'experimental_features' => null, // 'allow' // 'master_zone' => null, ); @@ -58,6 +60,16 @@ class Settings } } + public function getStoredOrDefaultValue($key) + { + $value = $this->getStoredValue($key); + if ($value === null) { + return $this->getDefaultValue($key); + } else { + return $value; + } + } + public function set($name, $value) { $db = $this->db;