diff --git a/gosa-plugins/goto-ng/admin/newConfigManagement/class_newConfigManagement.inc b/gosa-plugins/goto-ng/admin/newConfigManagement/class_newConfigManagement.inc
index 2633eda4004eec32ca3188d126358120b76e99ab..2b92346270e932a952ff6b6fead2b49751747f86 100644 (file)
var $dataModel = NULL;
var $listing = NULL;
- var $cfgTypeMap = NULL;
+ var $cfgItemMap = NULL;
+
+ var $addableContainerItems = array();
+ var $currentObject = NULL;
+ var $itemsPerMethod = NULL;
/*! \brief Initialize the plugin and finally update the data model.
*/
// to use for the HTML it produces.
$this->TemplateEngine = new TemplateEngine($config);
+ // Preset item config - with Distribution and Release objects.
+ $items = array();
+ $items['root']['container'] = array('Distribution');
+ $items['root']['name'] = '/';
+ $items['root']['description'] = _('Root');
+
+ // Define distribution paramters.
+ $dOpt1 = array('description' => _('Name'), 'default' => '', 'value' => '', 'required' => true,
+ 'type' => 'string', 'display' => _('Name'));
+ $dOpt2 = array('description' => _('Distribution type'), 'default' => 'deb', 'value' => 'deb', 'required' => true,
+ 'type' => 'combobox', 'display' => _('Distribution type'), 'values' => array("deb" => 'deb', "rpm" => 'rpm'));
+ $dOpt3 = array('description' => _('Mirror Url'), 'default' => '', 'value' => '', 'required' => false,
+ 'type' => 'string', 'display' => _('Mirror Url'));
+ $dOpt4 = array('description' => _('Method'), 'default' => 'puppet', 'value' => 'puppet', 'required' => false,
+ 'type' => 'combobox', 'display' => _('Installation method'), 'values'=>array('puppet'=>_('Puppet')));
+
+ // Define release parameters
+ $rOpt1 = array('description' => _('Name'), 'default' => '', 'value' => '', 'required' => true,
+ 'type' => 'string', 'display' => _('Name'));
+
+ $items['Distribution']['container'] = array('Release');
+ $items['Distribution']['name'] = 'Distribution';
+ $items['Distribution']['description'] = _('Distribution');
+ $items['Distribution']['options']['name'] = $dOpt1;
+ $items['Distribution']['options']['mirror'] = $dOpt3;
+ $items['Distribution']['options']['installation_type'] = $dOpt2;
+ $items['Distribution']['options']['installation_method'] = $dOpt4;
+
+ $items['Release']['container'] = array('Release', '__CFG_ITEMS__');
+ $items['Release']['name'] = 'Release';
+ $items['Release']['description'] = _('Release');
+ $items['Release']['options']['name'] = $rOpt1;
+
+ $this->installationMethods = array();
+ $this->installationMethods['root']['description'] = _('root');
+ $this->installationMethods['root']['name'] = 'root';
+ $this->installationMethods['root']['title'] = _('root');
+ $this->installationMethods['root']['items']['Distribution'] = &$items['Distribution'];
+ $this->installationMethods['root']['items']['Release'] = &$items['Release'];
+ $this->installationMethods['root']['items']['root'] = &$items['root'];
+
// Request an update of the data model
- $this->cfgTypeMap = array();
$this->loadInstallationMethods();
$this->updateDataModel();
$this->listing->setListingTypes($this->getListingTypes());
}
- /*! \brief Sets the installation method to the given method.
- * Updates the template engine and adds the initial root
- * object for the selected method.
- * @param The method to use.
- * @return TRUE on success else FALSE.
+ /*! \brief Intializes this plugin
+ * All available installation methods will be loaded
*/
- function setInstallMethod($str)
+ function loadInstallationMethods()
{
- if(!isset($this->installationMethods[$str])){
- $this->itemConfig = array();
- $this->invalidInstallMethod =TRUE;
- $this->errorMessage = sprintf(_("Invalid installation method %s selected!"), bold($str));
- msg_dialog::display(_("Setup"), $this->errorMessage, ERROR_DIALOG);
- return(FALSE);
+ // Reset erros
+ $this->rpcError = $this->initFailed = FALSE;
+
+ // Load configuration via rpc.
+ $rpc = $this->config->getRpcHandle();
+ $res = $rpc->getSupportedInstallMethods();
+ if(!$rpc->success()){
+ $this->rpcError = TRUE;
+ $this->errorMessage = $rpc->get_error();;
+ return;
+ }
+
+ // Populate install methods on success.
+ if(!count($res)){
+ $this->errorMessage = _("No selectable install methods returned!");
+ msg_dialog::display(_("Setup"), $this->errorMessage , ERROR_DIALOG);
+ $this->initFailed = TRUE;
+ return;
}else{
-
- $this->TemplateEngine->setTemplate($str.".tpl");
- $this->itemConfig = $this->installationMethods[$str]['items'];
- $this->invalidInstallMethod =FALSE;
- $this->TemplateEngine->load($this->itemConfig);
-
- // Detect root item, its name is /
- $root = NULL;
- foreach($this->itemConfig as $key => $item){
- if($item['name'] == '/') {
- $root = $key;
- break;
+
+ // Merge result with hard coded methods
+ $this->installationMethods = array_merge($this->installationMethods, $res);
+
+ // Walk through entries and create useful mappings.
+ $this->cfgItemMap = array();
+ $this->itemConfig = array();
+ $this->itemsPerMethod = array();
+ $rootElements = array();
+ foreach($this->installationMethods as $method => $items){
+ foreach($items['items'] as $itemName => $item){
+ $this->itemsPerMethod[$method][] = $itemName;
+ $this->cfgItemMap[$itemName] = $method;
+ $this->itemConfig[$itemName] = &$this->installationMethods[$method]['items'][$itemName];
+
+ // This enables us to create the first level of config items when
+ // a release is selected.
+ if($item['name'] == "/" && $itemName != 'root'){
+ $rootElements = array_merge($rootElements, $item['container']);
+ }
}
}
- if(!$root){
- $this->errorMessage = sprintf(_("Installation method %s is invalid: no root object found!"), bold($str));
- msg_dialog::display(_("Setup"), $this->errorMessage , ERROR_DIALOG);
- $this->initFailed = TRUE;
- $this->itemConfig = array();
- return(FALSE);
+
+ // Merge in root elements to releases.
+ foreach($this->itemConfig as $item => $data){
+ if(in_array('__CFG_ITEMS__', $data['container'])){
+ $this->itemConfig[$item]['container'] = array_merge($this->itemConfig[$item]['container'], $rootElements );
+ }
}
}
}
// Load distributions
$rpc = $this->config->getRpcHandle();
$res = $rpc->getDistributions();
-
if(!$rpc->success()){
msg_dialog::display(_("Error"), sprintf(_("Failed to load distributions: %s"), $rpc->get_error()),ERROR_DIALOG);
return(NULL);
}else{
foreach($res as $dist){
$this->dataModel->addItem('Distribution','/root', $dist['name'], $dist);
- $this->cfgTypeMap['/root/'.$dist['name']] = $dist['installation_method'];
- foreach($dist['releases'] as $release){
- $distPath = "/root/{$dist['name']}";
- $this->dataModel->addItem('Release',$distPath, $release['name'], $release);
+
+ if(isset($dist['releases'])){
+
+ // Sort releases by name length
+ $sort = array();
+ foreach($dist['releases'] as $id => $release){
+ $sort[strlen($release['name']) . $release['name']] = $id;
+ }
+ uksort($sort, "strnatcasecmp");
+
+ // Append release tags
+ foreach($sort as $id){
+ $release = $dist['releases'][$id];
+ $names = preg_split("/\//", $release['name']);
+
+ $rPath = "";
+ $distPath = "/root/{$dist['name']}";
+ foreach($names as $rName){
+ $rPath .= '/'.$rName;
+ $this->dataModel->addItem('Release',$distPath, $rName, $release);
+ $distPath .= $rPath;
+ }
+ }
}
}
}
if(isset($_POST['ROOT'])){
$this->setCurrentContainer('/root');
}elseif(isset($_POST['BACK'])){
-
$path = $this->selectedContainer;
if($this->dataModel->itemExistsByPath($path)){
$data = $this->dataModel->getItemByPath($path);
// Only releases can contain config-items.
if($data['type'] == 'Release' && $data['status'] != "fetched"){
+
+ // Request all config items for the selected release via rpc.
$rpc = $this->config->getRpcHandle();
- $res = $rpc->listConfigItems($data['name']);
+ $releasePath = $this->getReleasePart($path);
+ $res = $rpc->listConfigItems($releasePath);
if(!$rpc->success()){
- msg_dialog::display(_("Error"),
- sprintf(_("Failed to load distributions: %s"),
- $rpc->get_error()),ERROR_DIALOG);
+ msg_dialog::display(_("Error"),sprintf(_("Failed to load distributions: %s"),$rpc->get_error()),ERROR_DIALOG);
}else{
+
+ if(!$res) return;
// Sort entries by path length
$sLen = array();
// Walk through each entry and then try to add it to the model
foreach($sLen as $unused => $itemPath){
+ // Do not add the root element '/'
+ if($itemPath == "/") continue;
+
$type = $res[$itemPath];
- // Root installation objects do not have a name, so we use 'root' here.
- $targetPath = trim($path."/root/".$itemPath);
+ // Append the items-path to the current path to create the
+ // effective item path in the data model.
+ $targetPath = trim($path."/".$itemPath);
// Remove trailing and duplicated slashes
$targetPath = rtrim($targetPath, '/');
// Cleanup the path and then add the item.
$targetPath = preg_replace("/[^\/]*$/","", $targetPath);
$targetPath = rtrim($targetPath,'/');
- $this->dataModel->addItem($type, $targetPath, $name,
- array(
- '__path' => $itemPath,
- '__release' => $path
- ),'-' );
+ $this->dataModel->addItem($type, $targetPath, $name,array(),'-' );
}
$this->dataModel->setItemStatus($path, 'fetched');
}
$this->listing->setContainers($this->getContainerList());
$this->listing->setContainer($cont);
- // Set the correct installation method for the selected item
- if(isset($this->cfgTypeMap[$cont])){
- $method = $this->cfgTypeMap[$cont];
- $this->setInstallMethod($method);
+ // Update the list of addable sub objects
+ $this->addableContainerItems = $this->getAddableContainersPerPath($cont);
+ }
+
+
+ function getAddableContainersPerPath($path)
+ {
+ $currentItem = $this->dataModel->getItemByPath($path);
+ $method = $this->getInstallationMethodPerPath($path);
+
+ // Get allowed items for the currently selected method
+ // merge in root elements, they are allowed everywhere.
+ $allowedItems = $this->itemsPerMethod[$method];
+ $allowedItems = array_merge($allowedItems, $this->itemsPerMethod['root']);
+
+ // Get addable items
+ $possibleItems = $this->itemConfig[$currentItem['type']]['container'];
+ return(array_unique(array_intersect($allowedItems, $possibleItems)));
+ }
+
+
+ function getInstallationMethodPerPath($path)
+ {
+ $path .= '/';
+ while(preg_match("/\//", $path)){
+ $path = preg_replace("/\/[^\/]*$/","",$path);
+ $item = $this->dataModel->getItemByPath($path);
+ if(isset($item['values']['installation_method'])){
+ return($item['values']['installation_method']);
+ }
}
+ return('root');
}
*/
function getItemsToBeDisplayed()
{
-
$path = $this->selectedContainer;
$item = $this->dataModel->getItemByPath($path);
return($item);
$data = $this->dataModel->getItemByPath('/root');
$res = array();
$res["/root"] = array("name" => "/", "desc" => "");
- $res = array_merge($res,$this->__recurseItem($data, array('Distribution','Release')));
+ $res = array_merge($res,$this->__recurseItem($data));
return($res);
}
- /*! \brief Recursivly walks through an item and collects all path and name info.
+ /*! \brief Recursivly wlks through an item and collects all path and name info.
* The reult can then be used to fill the ItemSelector.
* @param Array The Item to recurse.
* @param Array The type of of objects to collect.
* @param String The parent path prefix which should be removed.
* @return Array An array containing Array[path] = name
*/
- function __recurseItem($item, $types, $parent = "")
+ function __recurseItem($item, $parent = "")
{
$res = array();
- if(1 || in_array($item['type'], $types)){
- $path = preg_replace("/".preg_quote($parent,'/')."/","",$item['path']);
- $res[$path] = array('name' => $item['name'],'desc'=>$item['type']);
- }
+ $path = preg_replace("/".preg_quote($parent,'/')."/","",$item['path']);
+ $res[$path] = array('name' => $item['name'],'desc'=>$item['type']);
if(count($item['children'])){
foreach($item['children'] as $child){
- $res = array_merge($res, $this->__recurseItem($child, $types, $parent));
+ $res = array_merge($res, $this->__recurseItem($child, $parent));
}
}
return($res);
}
- /*! \brief Intializes this plugin
- * All available installation methods will be loaded
- */
- function loadInstallationMethods()
- {
- // Reset erros
- $this->rpcError = $this->initFailed = FALSE;
-
- // Load configuration via rpc.
- $rpc = $this->config->getRpcHandle();
-
- // Populate install methods on success.
- $res = $rpc->getSupportedInstallMethods();
- if(!$rpc->success()){
- $this->rpcError = TRUE;
- $this->errorMessage = $rpc->get_error();;
- return;
- }
- $this->installationMethods = $res;
- if(!count($this->installationMethods)){
- $this->errorMessage = _("No selectable install methods returned!");
- msg_dialog::display(_("Setup"), $this->errorMessage , ERROR_DIALOG);
- $this->initFailed = TRUE;
- return;
- }else{
- foreach($this->installationMethods as $method => $items){
- foreach($items['items'] as $itemName => $item){
- $this->cfgTypeMap[$itemName] = $method;
- }
- }
- }
- }
-
-
/*! \brief Returns a info list about all items we can manage,
* this used to fill the listings <objectType> settings.
* @return Array An array with item info.
- /*! \brief
- * @param
- * @return
+ /*! \brief Removes an entry from the listing.
*/
- function remove_lock()
+ function removeEntry($ids)
+ {
+ foreach($ids as $id){
+ $item = $this->dataModel->getItemById($id);
+
+ // Is an config item.
+ if($this->cfgItemMap[$item['type']] != 'root'){
+ $release = preg_replace("/^.*\//","", $this->getReleasePath($item['path']));
+ $path = $this->getItemPath($item['path']);
+
+ $rpc = $this->config->getRpcHandle();
+ $rpc->removeConfigItem($release, $path);
+ if(!$rpc->success()){
+ msg_dialog::display(_("Error"), sprintf(_("Failed to remove: %s"), $rpc->get_error()),ERROR_DIALOG);
+ return(NULL);
+ }else{
+ $this->dataModel->removeItem($item['path']);
+ }
+ }else{
+ echo $item['type']." - are not handled yet!";
+ }
+ }
+ }
+
+ function getUsedNamesForPath($path)
{
+ $item = $this->dataModel->getItemByPath($path);
+ $names = array();
+ foreach($item['children'] as $path => $data){
+ $names[] = $data['name'];
+ }
+ return($names);
}
+ /*! \brief Edits a selected list item.
+ */
function editEntry($ids)
{
- // Update the template engine to use another type of item and
- // some other values.
$item = $this->dataModel->getItemById($ids[0]);
- $release = preg_replace("/^.*\//","",$item['values']['__release']);
- $path = $item['values']['__path'];
+ $release = preg_replace("/^.*\//","", $this->getReleasePath($item['path']));
+ $path = $this->getItemPath($item['path']);
+ $method = $this->cfgItemMap[$item['type']];
// Load item values on demand
- if($item['status'] == '-'){
- $rpc = $this->config->getRpcHandle();
- $item['values']['itemValues'] = $rpc->getConfigItem($release, $path);
- $this->dataModel->setItemStatus($item['path'], 'fetched');
- $this->dataModel->setItemValues($item['path'], $item['values']);
+ if($this->cfgItemMap[$item['type']] != 'root'){
+ if($item['status'] == '-'){
+ $rpc = $this->config->getRpcHandle();
+ $item['values'] = $rpc->getConfigItem($release, $path);
+ $this->dataModel->setItemStatus($item['path'], 'fetched');
+ $this->dataModel->setItemValues($item['path'], $item['values']);
+ }
}
- $method = $this->cfgTypeMap[$item['type']];
- $this->setInstallMethod($method);
- echo $method;
- $this->TemplateEngine->setValues($item['type'],$item['values']['itemValues']);
+ $this->TemplateEngine->load($this->itemConfig);
+ $this->TemplateEngine->setTemplate($method.".tpl");
+ $this->TemplateEngine->setValues($item['type'],$item['values']);
$this->listing->setDialogObject($this->TemplateEngine);
+ $this->currentObject = $item;
}
+ /*! \brief Initiates the creation of a new item
+ */
+ function newEntry($type)
+ {
+ // We've to add a config item
+ $this->TemplateEngine->load($this->itemConfig);
+ if($this->cfgItemMap[$type] != 'root'){
+ $method = $this->cfgItemMap[$type];
+ $this->TemplateEngine->setTemplate($method.".tpl");
+ $this->TemplateEngine->setValues($type,array());
+ $this->listing->setDialogObject($this->TemplateEngine);
+ $this->currentObject = NULL;
+ }else{
+ $this->TemplateEngine->setTemplate("root.tpl");
+ $this->TemplateEngine->setValues($type,array());
+ $this->listing->setDialogObject($this->TemplateEngine);
+ $this->currentObject = NULL;
+ }
+ }
+
+
+ /*! \brief Extracts the item-path out of a path.
+ * e.g. /debian/squeeze/test/module -> /test/module
+ */
+ function getItemPath($fullPath)
+ {
+ $fPath = $fullPath.'/';
+ while(preg_match("/\//", $fPath)){
+ $fPath = preg_replace("/\/[^\/]*$/","", $fPath);
+ $item = $this->dataModel->getItemByPath($fPath);
+ if(in_array($item['type'], array('Release', 'Distribution', 'root'))){
+ return(preg_replace("/".preg_quote($item['path'],'/')."/", "", $fullPath));
+ }
+ }
+ return(NULL);
+ }
+
+
+ /*! \brief Extracts the releaes path out of a path.
+ * e.g. /debian/squeeze/test/module -> /debian/squeeze
+ */
+ function getReleasePath($fullPath)
+ {
+ $fullPath.='/';
+ while(preg_match("/\//", $fullPath)){
+ $fullPath = preg_replace("/\/[^\/]*$/","", $fullPath);
+ $item = $this->dataModel->getItemByPath($fullPath);
+ if($item['type'] == 'Release'){
+ return($fullPath);
+ }
+ }
+ return(NULL);
+ }
+
+
+ /*! \brief Extracts the distribution path out of a path.
+ * e.g. /root/debian/squeeze/test/module -> /root/debian
+ */
+ function getDistributionPath($fullPath)
+ {
+ $fullPath.='/';
+ while(preg_match("/\//", $fullPath)){
+ $fullPath = preg_replace("/\/[^\/]*$/","", $fullPath);
+ $item = $this->dataModel->getItemByPath($fullPath);
+ if($item['type'] == 'Distribution'){
+ return($fullPath);
+ }
+ }
+ return(NULL);
+ }
+
+
+ /*! \brief Extracts the release-part out of a path.
+ * e.g. /root/debian/squeeze/test/module -> squeeze/test
+ */
+ function getReleasePart($path)
+ {
+ $rPath = $this->getReleasePath($path);
+ $dPath = $this->getDistributionPath($path);
+ return(preg_replace("/^".preg_quote($dPath, '/')."\/?/", "", $rPath));
+ }
+
+
+ function saveItemChanges()
+ {
+ // Save template engine modifications and validate values.
+ $this->TemplateEngine->save_object();
+ $msgs = $this->TemplateEngine->check();
+
+ // Get values to be saved
+ $values = array();
+ foreach($this->TemplateEngine->getWidgets() as $w){
+ $values[$w->getName()] = $w->getValue();
+ }
+
+ // No input error were found, now check that we do not use the same name twice.
+ if(!count($msgs)){
+ $usedNames = $this->getUsedNamesForPath($this->selectedContainer);
+
+ // Allow the item to keep its name.
+ if($this->currentObject != NULL && isset($this->currentObject['values']['name'])){
+ $usedNames = array_remove_entries(array($this->currentObject['values']['name']), $usedNames);
+ }
+ if(in_array($values['name'],$usedNames)){
+ $msgs[] = msgPool::duplicated(_("Name"));
+ }
+ }
+
+ // Display errors
+ if(count($msgs)){
+ msg_dialog::displayChecks($msgs);
+ return;
+ }
+
+ // Get the item type to be saved
+ $item = $this->currentObject;
+ $type = $this->TemplateEngine->getItemType();
+ if($this->cfgItemMap[$type] == 'root'){
+
+ // We've to create a new distribution
+ if($type == 'Distribution'){
+ $name = $values['name'];
+ $itype = $values['installation_type'];
+ $imethod = $values['installation_method'];
+ $mirror = $values['mirror'];
+
+ // Initiate the rpc request.
+ $rpc = $this->config->getRpcHandle();
+ $res = $rpc->createDistribution($name, $itype, array('mirror'=>$mirror, 'install_method' => $imethod));
+ if(!$rpc->success()){
+ msg_dialog::display(_("Error"), sprintf(_("Failed to save distributions: %s"), $rpc->get_error()),ERROR_DIALOG);
+ return(NULL);
+ }else{
+
+ // We've successfully added the item, now add it to the tree.
+ $this->dataModel->addItem($type, $this->selectedContainer, $values['name'],array(), '-' );
+
+ // Finally - close the dialog.
+ $this->listing->clearDialogObject();
+ }
+
+
+ $this->listing->clearDialogObject();
+
+ }else{
+
+ echo "{$type} Cannot be saved yet";
+ $this->listing->clearDialogObject();
+ return;
+ }
+ }
+
+ // Save a CONFIG-ITEM object.
+ if($this->cfgItemMap[$type] != 'root'){
+
+ // Get paths
+ $release = preg_replace("/^.*\//","", $this->getReleasePath($this->selectedContainer));
+ $newPath = $this->selectedContainer."/".$values['name'];
+ $newItemPath = $this->getItemPath($this->selectedContainer)."/".$values['name'];
+ if($item){
+ $oldPath = $item['path'];
+ $oldItemPath = $this->getItemPath($item['path']);
+ }
+
+ // If this is a new item, then create it now.
+ if($item == NULL){
+
+ // Add the new item
+ $rpc = $this->config->getRpcHandle();
+ $res = $rpc->setConfigItem($release, $newItemPath, $type, $values);
+ if(!$rpc->success()){
+ msg_dialog::display(_("Error"), sprintf(_("Failed to load distributions: %s"), $rpc->get_error()),ERROR_DIALOG);
+ return(NULL);
+ }else{
+
+ // We've successfully added the item, now add it to the tree.
+ $this->dataModel->addItem($type, $this->selectedContainer, $values['name'],array(), '-' );
+
+ // Finally - close the dialog.
+ $this->listing->clearDialogObject();
+ }
+ }else{
+
+ // Write the modifications back to the server.
+ $rpc = $this->config->getRpcHandle();
+ $res = $rpc->setConfigItem($release, $oldItemPath, $type, $values);
+ if(!$rpc->success()){
+ msg_dialog::display(_("Error"), sprintf(_("Failed to load distributions: %s"), $rpc->get_error()),ERROR_DIALOG);
+ return(NULL);
+ }else{
+
+ // Update the data model
+ $this->dataModel->setItemValues($oldPath, $values);
+ if($oldPath != $newPath){
+ $this->dataModel->moveItem($oldPath, $newPath);
+ }
+ $this->listing->clearDialogObject();
+ }
+ }
+ }
+ }
+ function remove_lock() {}
}
+
+
?>