From 1e60d37775f1ca611258acf5311711aff9d63e5a Mon Sep 17 00:00:00 2001 From: Roland Gruber Date: Sun, 26 Aug 2012 14:10:33 +0000 Subject: [PATCH] Puppet support --- lam/HISTORY | 1 + lam/docs/manual-sources/howto.xml | 49 ++ .../manual-sources/images/mod_puppet1.png | Bin 0 -> 27718 bytes .../manual-sources/images/mod_puppet2.png | Bin 0 -> 22317 bytes .../manual-sources/images/mod_puppet3.png | Bin 0 -> 16377 bytes lam/graphics/puppet.png | Bin 0 -> 2515 bytes lam/lib/modules/puppetClient.inc | 519 ++++++++++++++++++ 7 files changed, 569 insertions(+) create mode 100644 lam/docs/manual-sources/images/mod_puppet1.png create mode 100644 lam/docs/manual-sources/images/mod_puppet2.png create mode 100644 lam/docs/manual-sources/images/mod_puppet3.png create mode 100644 lam/graphics/puppet.png create mode 100644 lam/lib/modules/puppetClient.inc diff --git a/lam/HISTORY b/lam/HISTORY index 9a8b547d..7c7be33e 100644 --- a/lam/HISTORY +++ b/lam/HISTORY @@ -1,5 +1,6 @@ September 2012 3.9 - Kolab 2.4 support + - Puppet support - LAM Pro -> support RFC2307bis automount entries -> read-only fields in self service diff --git a/lam/docs/manual-sources/howto.xml b/lam/docs/manual-sources/howto.xml index 29691eef..fc7200be 100644 --- a/lam/docs/manual-sources/howto.xml +++ b/lam/docs/manual-sources/howto.xml @@ -2477,6 +2477,55 @@ Have fun! + +
+ Puppet + + LAM supports to manage your Puppet configuration. You can + edit all attributes like environment, classes, variables and parent + node. + + Configuration + + To activate this feature please edit your LAM server profile and + add the host module "Puppet (puppetClient)" on tab "Modules". This + will add the Puppet tab to your host pages. + + + + + + + + + + On tab "Module settings" in your LAM server profile you may also + setup some common environment names. LAM will use them to provide + autocompletion hints when editing the environment for a node. + + + + + + + + + + Editing nodes + + When you edit a host entry then you will see the tab "Puppet". + Here you can add/remove the Puppet extension and edit all + attributes. + + + + + + + + +
diff --git a/lam/docs/manual-sources/images/mod_puppet1.png b/lam/docs/manual-sources/images/mod_puppet1.png new file mode 100644 index 0000000000000000000000000000000000000000..a1415990741296240b5b8204a2b6b14e40c07c4b GIT binary patch literal 27718 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 bZ4=K-`-bE#VU)mmA<7Tb?-$EId;Q-4d~4!? literal 0 HcmV?d00001 diff --git a/lam/docs/manual-sources/images/mod_puppet2.png b/lam/docs/manual-sources/images/mod_puppet2.png new file mode 100644 index 0000000000000000000000000000000000000000..a77113fcc1cfd9d417f00011f0577aa2f698bb24 GIT binary patch literal 22317 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 V$AFTw@%evixNR5t58Zts{{f-|LrVYv literal 0 HcmV?d00001 diff --git a/lam/docs/manual-sources/images/mod_puppet3.png b/lam/docs/manual-sources/images/mod_puppet3.png new file mode 100644 index 0000000000000000000000000000000000000000..5176d07cf252b0965def5edc0de1620a33698d3c GIT binary patch literal 16377 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 literal 0 HcmV?d00001 diff --git a/lam/lib/modules/puppetClient.inc b/lam/lib/modules/puppetClient.inc new file mode 100644 index 00000000..33c51d1c --- /dev/null +++ b/lam/lib/modules/puppetClient.inc @@ -0,0 +1,519 @@ +autoAddObjectClasses = false; + } + + + /** + * Returns meta data that is interpreted by parent class + * + * @return array array with meta data + */ + function get_metaData() { + $return = array(); + // icon + $return['icon'] = 'puppet.png'; + // manages user accounts + $return["account_types"] = array("host"); + // alias name + $return["alias"] = _("Puppet"); + // module dependencies + $return['dependencies'] = array('depends' => array(), 'conflicts' => array()); + // managed object classes + $return['objectClasses'] = array('puppetClient'); + // managed attributes + $return['attributes'] = array('environment', 'parentnode', 'puppetclass', 'puppetvar'); + // help Entries + $return['help'] = array ( + 'environment' => array ( + "Headline" => _('Environment'), 'attr' => 'environment', + "Text" => _('Please enter the environment name for this node (e.g. production).') + ), + 'environmentList' => array ( + "Headline" => _('Environment'), 'attr' => 'environment', + "Text" => _('Please enter the environment name for this node (e.g. production).') . ' ' . _('Multiple values are separated by semicolon.') + ), + 'parentnode' => array ( + "Headline" => _('Parent node'), 'attr' => 'parentnode', + "Text" => _('This is this node\'s parent. All classes and variables are inherited from this node.') + ), + 'puppetclass' => array ( + "Headline" => _('Classes'), 'attr' => 'puppetclass', + "Text" => _('The list of configured Puppet classes for this node (e.g. ntp).') + ), + 'puppetclassList' => array ( + "Headline" => _('Classes'), 'attr' => 'puppetclass', + "Text" => _('The list of configured Puppet classes for this node (e.g. ntp).') . ' ' . _('Multiple values are separated by semicolon.') + ), + 'puppetvar' => array ( + "Headline" => _('Variables'), 'attr' => 'puppetvar', + "Text" => _('Please enter your Puppet variables for this node (e.g. config_exim=true).') + ), + 'puppetvarList' => array ( + "Headline" => _('Variables'), 'attr' => 'puppetvar', + "Text" => _('Please enter your Puppet variables for this node (e.g. config_exim=true).') . ' ' . _('Multiple values are separated by semicolon.') + ), + 'autoAdd' => array( + "Headline" => _('Automatically add this extension'), + "Text" => _('This will enable the extension automatically if this profile is loaded.') + ), + 'predefinedClasses' => array( + "Headline" => _('Predefined classes'), + "Text" => _('These classes will be available as autocompletion hints when adding new classes.') + ), + 'predefinedEnvironments' => array( + "Headline" => _('Predefined environments'), + "Text" => _('These environments will be available as autocompletion hints when setting the environment.') + ), + ); + // config options + $configContainer = new htmlTable(); + $configContainer->addElement(new htmlTableExtendedInputTextarea('puppetClient_environments', "production\r\ntesting", 30, 5, _('Predefined environments'), 'predefinedEnvironments'), true); + $return['config_options']['all'] = $configContainer; + // upload fields + $return['upload_columns'] = array( + array( + 'name' => 'puppetClient_environment', + 'description' => _('Environment'), + 'help' => 'environmentList', + 'example' => 'production' + ), + array( + 'name' => 'puppetClient_parentnode', + 'description' => _('Parent node'), + 'help' => 'parentnode', + 'example' => 'basenode' + ), + array( + 'name' => 'puppetClient_puppetclass', + 'description' => _('Classes'), + 'help' => 'puppetclassList', + 'example' => 'ntp;exim' + ), + array( + 'name' => 'puppetClient_puppetvar', + 'description' => _('Variables'), + 'help' => 'puppetvarList', + 'example' => 'config_exim=true;config_exim_trusted_users=root' + ), + ); + // available PDF fields + $return['PDF_fields'] = array( + 'environment' => _('Environment'), + 'parentnode' => _('Parent node'), + 'puppetclass' => _('Classes'), + 'puppetvar' => _('Variables'), + ); + // profile options + $profileContainer = new htmlTable(); + $profileContainer->addElement(new htmlTableExtendedInputCheckbox('puppetClient_addExt', false, _('Automatically add this extension'), 'autoAdd'), true); + $profileEnvironment = new htmlTableExtendedInputField(_('Environment'), 'puppetClient_environment', null, 'environment'); + $autocompleteEnvironment = array(); + if (isset($this->moduleSettings['puppetClient_environments'])) { + $autocompleteEnvironment = $this->moduleSettings['puppetClient_environments']; + } + $profileEnvironment->enableAutocompletion($autocompleteEnvironment); + $profileContainer->addElement($profileEnvironment, true); + $profileContainer->addElement(new htmlTableExtendedInputTextarea('puppetClient_puppetclass', '', 60, 5, _('Classes'), 'puppetclass'), true); + $profileContainer->addElement(new htmlTableExtendedInputTextarea('puppetClient_puppetvar', '', 60, 5, _('Variables'), 'puppetvar'), true); + $return['profile_options'] = $profileContainer; + // profile checks + $return['profile_checks']['puppetClient_environment'] = array('type' => 'ext_preg', 'regex' => 'ascii', 'error_message' => $this->messages['environment'][0]); + // profile mappings + $return['profile_mappings'] = array( + 'puppetClient_environment' => 'environment', + ); + return $return; + } + + /** + * This function fills the error message array with messages + */ + function load_Messages() { + $this->messages['environment'][0] = array('ERROR', _('The environment name may only contain ASCII characters.')); + $this->messages['environment'][1] = array('ERROR', _('Account %s:') . ' puppetClient_environment', _('The environment name may only contain ASCII characters.')); + $this->messages['puppetclass'][0] = array('ERROR', _('The class names may only contain ASCII characters.')); + $this->messages['puppetclass'][1] = array('ERROR', _('Account %s:') . ' puppetClient_puppetclass', _('The class names may only contain ASCII characters.')); + $this->messages['puppetvar'][0] = array('ERROR', _('The variables may only contain ASCII characters.')); + $this->messages['puppetvar'][1] = array('ERROR', _('Account %s:') . ' puppetClient_puppetvar', _('The variables may only contain ASCII characters.')); + $this->messages['parentnode'][0] = array('ERROR', _('Account %s:') . ' puppetClient_parentnode', _('Parent node not found.')); + } + + /** + * Returns a list of modifications which have to be made to the LDAP account. + * + * @return array list of modifications + *
This function returns an array with 3 entries: + *
array( DN1 ('add' => array($attr), 'remove' => array($attr), 'modify' => array($attr)), DN2 .... ) + *
DN is the DN to change. It may be possible to change several DNs (e.g. create a new user and add him to some groups via attribute memberUid) + *
"add" are attributes which have to be added to LDAP entry + *
"remove" are attributes which have to be removed from LDAP entry + *
"modify" are attributes which have to been modified in LDAP entry + *
"info" are values with informational value (e.g. to be used later by pre/postModify actions) + */ + function save_attributes() { + if (!in_array('puppetClient', $this->attributes['objectClass']) && !in_array('puppetClient', $this->orig['objectClass'])) { + // skip saving if the extension was not added/modified + return array(); + } + return parent::save_attributes(); + } + + /** + * Returns the HTML meta data for the main account page. + * + * @return htmlElement HTML meta data + */ + function display_html_attributes() { + if (isset($_POST['form_subpage_puppetClient_attributes_addObjectClass'])) { + $this->attributes['objectClass'][] = 'puppetClient'; + } + $return = new htmlTable(); + if (!in_array('puppetClient', $this->attributes['objectClass'])) { + $return->addElement(new htmlAccountPageButton('puppetClient', 'attributes', 'addObjectClass', _('Add Puppet extension'))); + return $return; + } + // environment + $autocompleteEnvironment = array(); + if (isset($this->moduleSettings['puppetClient_environments'])) { + $autocompleteEnvironment = $this->moduleSettings['puppetClient_environments']; + } + $environments = array(); + if (isset($this->attributes['environment'][0])) { + $environments = $this->attributes['environment']; + } + if (sizeof($environments) == 0) { + $environments[] = ''; + } + $environmentLabel = new htmlOutputText(_('Environment')); + $environmentLabel->alignment = htmlElement::ALIGN_TOP; + $return->addElement($environmentLabel); + $environmentContainer = new htmlGroup(); + for ($i = 0; $i < sizeof($environments); $i++) { + $environmentField = new htmlInputField('environment' . $i, $environments[$i]); + $environmentField->enableAutocompletion($autocompleteEnvironment); + $environmentContainer->addElement($environmentField); + if ($i < (sizeof($environments) - 1)) { + $environmentContainer->addElement(new htmlOutputText('
', false)); + } + else { + $environmentContainer->addElement(new htmlButton('addEnvironment', 'add.png', true)); + } + } + $return->addElement($environmentContainer); + $environmentHelp = new htmlHelpLink('environment'); + $environmentHelp->alignment = htmlElement::ALIGN_TOP; + $return->addElement($environmentHelp, true); + // parent node + $possibleParentNodes = $this->getPossibleParentNodes(); + array_unshift($possibleParentNodes, '-'); + $parentnode = '-'; + if (isset($this->attributes['parentnode'][0])) { + $parentnode = $this->attributes['parentnode'][0]; + } + $return->addElement(new htmlTableExtendedSelect('parentnode', $possibleParentNodes, array($parentnode), _('Parent node'), 'parentnode'), true); + // classes + $puppetclass = ''; + if (isset($this->attributes['puppetclass'])) { + $puppetclass = implode("\r\n", $this->attributes['puppetclass']); + } + $return->addElement(new htmlTableExtendedInputTextarea('puppetclass', $puppetclass, 60, 5, _('Classes'), 'puppetclass'), true); + // variables + $puppetvar = ''; + if (isset($this->attributes['puppetvar'])) { + $puppetvar = implode("\r\n", $this->attributes['puppetvar']); + } + $return->addElement(new htmlTableExtendedInputTextarea('puppetvar', $puppetvar, 60, 5, _('Variables'), 'puppetvar'), true); + + $return->addElement(new htmlSpacer(null, '10px'),true); + $remButton = new htmlAccountPageButton('puppetClient', 'attributes', 'remObjectClass', _('Remove Puppet extension')); + $remButton->colspan = 4; + $return->addElement($remButton); + return $return; + } + + /** + * Processes user input of the primary module page. + * It checks if all input values are correct and updates the associated LDAP attributes. + * + * @return array list of info/error messages + */ + function process_attributes() { + if (isset($_POST['form_subpage_puppetClient_attributes_remObjectClass'])) { + $this->attributes['objectClass'] = array_delete(array('puppetClient'), $this->attributes['objectClass']); + for ($i = 0; $i < sizeof($this->meta['attributes']); $i++) { + if (isset($this->attributes[$this->meta['attributes'][$i]])) { + unset($this->attributes[$this->meta['attributes'][$i]]); + } + } + return array(); + } + if (!in_array('puppetClient', $this->attributes['objectClass'])) { + return array(); + } + + $errors = array(); + // environment + $environmentCounter = 0; + while (isset($_POST['environment' . $environmentCounter])) { + $this->attributes['environment'][$environmentCounter] = $_POST['environment' . $environmentCounter]; + if (!get_preg($this->attributes['environment'][$environmentCounter], 'ascii')) $errors[] = $this->messages['environment'][0]; + if ($this->attributes['environment'][$environmentCounter] == '') { + unset($this->attributes['environment'][$environmentCounter]); + } + $environmentCounter++; + } + if (isset($_POST['addEnvironment'])) { + $this->attributes['environment'][] = ''; + } + $this->attributes['environment'] = array_values($this->attributes['environment']); + // parent node + if (isset($this->attributes['parentnode'][0]) && ($_POST['parentnode'] == '-')) { + unset($this->attributes['parentnode'][0]); + } + elseif ($_POST['parentnode'] != '-') { + $this->attributes['parentnode'][0] = $_POST['parentnode']; + } + // classes + $puppetclass = explode("\r\n", $_POST['puppetclass']); + for ($i = 0; $i < sizeof($puppetclass); $i++) { + if (trim($puppetclass[$i]) == '') { + unset($puppetclass[$i]); + continue; + } + if (!get_preg($puppetclass[$i], 'ascii')) { + $error = $this->messages['puppetclass'][0]; + $error[] = htmlspecialchars($puppetclass[$i]); + $errors[] = $error; + } + } + $this->attributes['puppetclass'] = array_values(array_unique($puppetclass)); + // variables + $puppetvar = explode("\r\n", $_POST['puppetvar']); + for ($i = 0; $i < sizeof($puppetvar); $i++) { + if (trim($puppetvar[$i]) == '') { + unset($puppetvar[$i]); + continue; + } + if (!get_preg($puppetvar[$i], 'ascii')) { + $error = $this->messages['puppetvar'][0]; + $error[] = htmlspecialchars($puppetvar[$i]); + $errors[] = $error; + } + } + $this->attributes['puppetvar'] = array_values(array_unique($puppetvar)); + + return $errors; + } + + /** + * In this function the LDAP account is built up. + * + * @param array $rawAccounts list of hash arrays (name => value) from user input + * @param array $ids list of IDs for column position (e.g. "posixAccount_uid" => 5) + * @param array $partialAccounts list of hash arrays (name => value) which are later added to LDAP + * @param array $selectedModules list of selected account modules + * @return array list of error messages if any + */ + function build_uploadAccounts($rawAccounts, $ids, &$partialAccounts, $selectedModules) { + $messages = array(); + for ($i = 0; $i < sizeof($rawAccounts); $i++) { + // add object class + if (!in_array("puppetClient", $partialAccounts[$i]['objectClass'])) $partialAccounts[$i]['objectClass'][] = "puppetClient"; + // parent node + if ($rawAccounts[$i][$ids['puppetClient_parentnode']] != "") { + if (!in_array($rawAccounts[$i][$ids['puppetClient_parentnode']], $this->getPossibleParentNodes())) { + $messages[] = $this->messages['parentnode'][0]; + } + else { + $partialAccounts[$i]['parentnode'][0] = $rawAccounts[$i][$ids['puppetClient_parentnode']]; + } + } + // environment + if ($rawAccounts[$i][$ids['puppetClient_environment']] != "") { + if (get_preg($rawAccounts[$i][$ids['puppetClient_environment']], 'ascii')) { + $partialAccounts[$i]['environment'] = explode(';', $rawAccounts[$i][$ids['puppetClient_environment']]); + } + else { + $errMsg = $this->messages['environment'][1]; + array_push($errMsg, array($i)); + $messages[] = $errMsg; + } + } + // classes + if ($rawAccounts[$i][$ids['puppetClient_puppetclass']] != "") { + if (get_preg($rawAccounts[$i][$ids['puppetClient_puppetclass']], 'ascii')) { + $partialAccounts[$i]['puppetclass'] = explode(';', $rawAccounts[$i][$ids['puppetClient_puppetclass']]); + } + else { + $errMsg = $this->messages['puppetclass'][1]; + array_push($errMsg, array($i)); + $messages[] = $errMsg; + } + } + // variables + if ($rawAccounts[$i][$ids['puppetClient_puppetvar']] != "") { + if (get_preg($rawAccounts[$i][$ids['puppetClient_puppetvar']], 'ascii')) { + $partialAccounts[$i]['puppetvar'] = explode(';', $rawAccounts[$i][$ids['puppetClient_puppetvar']]); + } + else { + $errMsg = $this->messages['puppetvar'][1]; + array_push($errMsg, array($i)); + $messages[] = $errMsg; + } + } + } + return $messages; + } + + /** + * Returns the PDF entries for this module. + * + * @return array list of possible PDF entries + */ + function get_pdfEntries() { + $return = array(); + if (in_array('puppetClient', $this->attributes['objectClass'])) { + if (isset($this->attributes['environment'][0])) { + $return['puppetClient_environment'][0] = '' . _('Environment') . '' . implode(', ', $this->attributes['environment']) . ''; + } + if (isset($this->attributes['parentnode'][0])) { + $return['puppetClient_parentnode'][0] = '' . _('Parent node') . '' . $this->attributes['parentnode'][0] . ''; + } + if (isset($this->attributes['puppetclass'][0])) { + $return['puppetClient_puppetclass'][0] = '' . _('Classes') . '' . $this->attributes['puppetclass'][0] . ''; + for ($i = 1; $i < sizeof($this->attributes['puppetclass']); $i++) { + $return['puppetClient_puppetclass'][] = '' . $this->attributes['puppetclass'][$i] . ''; + } + } + if (isset($this->attributes['puppetvar'][0])) { + $return['puppetClient_puppetvar'][0] = '' . _('Variables') . '' . $this->attributes['puppetvar'][0] . ''; + for ($i = 1; $i < sizeof($this->attributes['puppetvar']); $i++) { + $return['puppetClient_puppetvar'][] = '' . $this->attributes['puppetvar'][$i] . ''; + } + } + } + return $return; + } + + /** + * This function defines what attributes will be used in the account profiles and their appearance in the profile editor. + * + * Calling this method does not require the existence of an enclosing {@link accountContainer}.
+ *
+ * The return value is an object implementing htmlElement.
+ * The field name are used as keywords to load + * and save profiles. We recommend to use the module name as prefix for them + * (e.g. posixAccount_homeDirectory) to avoid naming conflicts. + * + * @return htmlElement meta HTML object + * + * @see baseModule::get_metaData() + * @see htmlElement + */ + public function get_profileOptions() { + $return = parent::get_profileOptions(); + $possibleParentNodes = $this->getPossibleParentNodes(); + if (sizeof($possibleParentNodes) > 0) { + $return->addElement(new htmlTableExtendedSelect('puppetClient_parentnode', $possibleParentNodes, array(), _('Parent node'), 'parentnode'), true); + } + return $return; + } + + /** + * Loads the values of an account profile into internal variables. + * + * @param array $profile hash array with profile values (identifier => value) + */ + function load_profile($profile) { + // profile mappings in meta data + parent::load_profile($profile); + // add extension + if (isset($profile['puppetClient_addExt'][0]) && ($profile['puppetClient_addExt'][0] == "true")) { + if (!in_array('puppetClient', $this->attributes['objectClass'])) { + $this->attributes['objectClass'][] = 'puppetClient'; + } + } + // parent node + if (isset($profile['puppetClient_parentnode'][0]) && ($profile['puppetClient_parentnode'][0] != "-")) { + $this->attributes['parentnode'][0] = $profile['puppetClient_parentnode'][0]; + } + // classes + if (isset($profile['puppetClient_puppetclass'][0]) && ($profile['puppetClient_puppetclass'][0] != '')) { + $this->attributes['puppetclass'] = $profile['puppetClient_puppetclass']; + } + // variables + if (isset($profile['puppetClient_puppetvar'][0]) && ($profile['puppetClient_puppetvar'][0] != '')) { + $this->attributes['puppetvar'] = $profile['puppetClient_puppetvar']; + } + } + + /** + * Reurns a list of valid parent nodes for this node. + * + * @return array parent nodes (e.g. array('node1', 'node2')) + */ + private function getPossibleParentNodes() { + $possibleParentNodes = array(); + $searchResult = searchLDAPByAttribute('cn', '*', 'puppetClient', array('cn'), array('host')); + $possibleParentNodes = array(); + for ($i = 0; $i < sizeof($searchResult); $i++) { + if (!get_preg($searchResult[$i]['cn'][0], 'ascii')) { + continue; + } + if (($this->getAccountContainer() == null) || $this->getAccountContainer()->isNewAccount + || (!isset($this->getAccountContainer()->attributes_orig['cn'][0]) + || ($this->getAccountContainer()->attributes_orig['cn'][0] != $searchResult[$i]['cn'][0]))) { + $possibleParentNodes[] = $searchResult[$i]['cn'][0]; + } + } + return $possibleParentNodes; + } + +} + +?>