X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=include%2Ffunctions_FAI.inc;h=26c0a572659f10287d156965b74bdb68579e2095;hb=c4924928dc7abdf5caaf67d8d614fe014483a0c5;hp=b1f702ea692d6619e738310f52b834ac222346dd;hpb=f147ecff6f7fe1daeaeff11bbf816e5a002dd784;p=gosa.git diff --git a/include/functions_FAI.inc b/include/functions_FAI.inc index b1f702ea6..26c0a5726 100644 --- a/include/functions_FAI.inc +++ b/include/functions_FAI.inc @@ -1,22 +1,28 @@ get_ldap_link(); $ldap->cd($config->current['BASE']); + $res = array(); + $tmp = array(); + + if(!is_release_department($Current_DN)) { + return($res); + } /* Collect some basic informations and initialize some variables */ $base_release = get_release_dn($Current_DN); $previous_releases = array_reverse(get_previous_releases_of_this_release($base_release,true)); - $res = array(); - $tmp = array(); /* We must also include the given release dn */ $previous_releases[] = $base_release; @@ -31,14 +37,23 @@ function get_all_objects_for_given_base($Current_DN,$filter,$detailed = false) foreach($deps_to_search as $fai_base){ /* Ldap search for fai classes specified in this release */ - $ldap->cd($fai_base); - $ldap->search($filter,array("dn","objectClass")); - - /* check the returned objects, and add/replace them in our return vareable */ - while($attr = $ldap->fetch()){ - + $res_tmp = get_list($filter,"fai",$fai_base,array("dn","objectClass","FAIstate"),GL_SUBSEARCH | GL_SIZELIMIT); + + /* check the returned objects, and add/replace them in our return variable */ + foreach($res_tmp as $attr){ + $buffer = array(); - $name = str_ireplace($release,"",$attr['dn']); + $name = preg_replace("/".normalizePreg($release)."/i","",$attr['dn']); + + if(isset($attr['FAIstate'][0])){ + if(preg_match("/removed$/",$attr['FAIstate'][0])){ + if(isset($res[$name])){ + unset($res[$name]); + } + continue; + } + } + /* In detailed mode are some additonal informations visible */ if($detailed){ @@ -66,24 +81,6 @@ function get_all_objects_for_given_base($Current_DN,$filter,$detailed = false) } - -/* Return the object defining ObjectClass e.g. FAIscriptEntry */ -function get_FAI_type($attr) -{ - $arr = array( "FAIprofile","FAIpartitionTable", "FAIpartitionDisk","FAIpartitionEntry","FAIhook","FAIhookEntry", - "FAIscriptEntry","FAIscript","FAIvariable","FAIvariableEntry","FAIpackageList","FAItemplate", - "FAItemplateEntry","FAIdebconfInfo","FAIrepository","FAIrepositoryServer","FAIbranch","FAIreleaseTag"); - foreach($arr as $name){ - if(in_array($name,$attr['objectClass'])){ - preg_match(""); - return($name); - } - } - echo "Not found"; - return(""); -} - - /* Return all relevant FAI departments */ function get_FAI_departments($suffix = "") { @@ -103,70 +100,410 @@ function get_FAI_departments($suffix = "") } -function get_all_releases_from_base($dn) +/* Return all releases within the given base */ +function get_all_releases_from_base($dn,$appendedName=false) { global $config; - $base = "ou=fai,ou=configs,ou=systems,".$dn; + + if(!preg_match("/ou=fai,ou=configs,ou=systems,/",$dn)){ + $base = "ou=fai,ou=configs,ou=systems,".$dn; + }else{ + $base = $dn; + } $res = array(); $ldap = $config->get_ldap_link(); $ldap->cd($base); $ldap->search("(objectClass=FAIbranch)",array("ou","dn")); while($attrs = $ldap->fetch()){ - $res[$attrs['dn']] = $attrs['ou'][0]; - } + if($appendedName){ + $res[$attrs['dn']] = convert_department_dn(preg_replace("/,ou=fai,ou=configs,ou=system.*$/","",$attrs['dn'])); + }else{ + $res[$attrs['dn']] = $attrs['ou'][0]; + } + } return($res); } -/* This function does everything to be able to save the given dn. +/* Add this object to list of objects, that must be checked for release saving */ +function prepare_to_save_FAI_object($Current_DN,$objectAttrs,$removed = false) +{ + /* Get ldap object */ + global $config; + $addObj['Current_DN'] = $Current_DN; + $addObj['objectAttrs']= $objectAttrs; + $addObj['removed'] = $removed; + $addObj['diff'] = TRUE; + + if(!$removed){ + $ldap = $config->get_ldap_link(); + $ldap->cd($config->current['BASE']); + + /* Get some basic informations */ + $parent_obj = get_parent_release_object($Current_DN); + if(!empty($parent_obj)){ + $ldap->cat($parent_obj,array("*")); + $attrs = prepare_ldap_fetch_to_be_saved($ldap->fetch()); + + if(!array_diff_FAI( $attrs,$objectAttrs)){ + $addObj['diff'] = FALSE; + } + } + } + + $_SESSION['FAI_objects_to_save'][$Current_DN] = $addObj; +} + - !!!!!!! No functionality just output - - */ -function prepare_to_save_FAI_object($Current_DN) +/* Detect differences in attribute arrays */ +function array_diff_FAI($ar1,$ar2) +{ + + if((!isset($ar1['description'])) || (isset($ar1['description']) && (count($ar1['description']) == 0))){ + $ar1['description'] = ""; + } + if((!isset($ar2['description'])) || (isset($ar2['description']) && (count($ar2['description']) == 0))){ + $ar2['description'] = ""; + } + + if(count($ar1) != count($ar2)) { + return (true); + } + + foreach($ar1 as $key1 => $val1){ + + if((is_array($val1)) && (count($val1)==1)){ + $ar1[$key1] = $val1[0]; + } + + if((is_array($ar2[$key1])) && (count($ar2[$key1])==1)){ + $val1 = $val1[0]; + $ar2[$key1] = $ar2[$key1][0]; + } + } + ksort($ar1); + ksort($ar2); + if(count( array_diff($ar1,$ar2)) || arr_diff($ar1,$ar2)){ + return(true); + }else{ + return(false); + } +} + + +function arr_diff($ar1,$ar2) +{ + foreach($ar1 as $ak1 => $av1){ + if(!isset($ar2[$ak1]) || (!($av1 === $ar2[$ak1]))){ + return(true); + }elseif(is_array($av1)){ + return(arr_diff($av1,$ar2[$ak1])); + } + } + return(FALSE); +} + + + + +/* check which objects must be saved, and save them */ +function save_release_changes_now() +{ + /* Variable init*/ + $to_save = array(); + + /* check which objects must be saved */ + foreach($_SESSION['FAI_objects_to_save'] as $Current_DN => $object){ + if($object['diff']){ + $sub_name = $Current_DN; + while(isset($_SESSION['FAI_objects_to_save'][$sub_name])){ + $to_save[strlen($sub_name)][$sub_name] = $_SESSION['FAI_objects_to_save'][$sub_name]; + unset($_SESSION['FAI_objects_to_save'][$sub_name]); + $sub_name = preg_replace('/^[^,]+,/', '', $sub_name); + } + } + } + + /* Sort list of objects that must be saved, and ensure that + container objects are safed, before their childs are saved */ + ksort($to_save); + $tmp = array(); + foreach($to_save as $SubObjects){ + foreach($SubObjects as $object){ + $tmp[] = $object; + } + } + $to_save = $tmp; + + /* Save objects and manage the correct release behavior*/ + foreach($to_save as $save){ + + $Current_DN = $save['Current_DN']; + $removed = $save['removed']; + $objectAttrs= $save['objectAttrs']; + + /* Get ldap object */ + global $config; + $ldap = $config->get_ldap_link(); + $ldap->cd($config->current['BASE']); + + /* Get some basic informations */ + $base_release = get_release_dn($Current_DN); + $sub_releases = get_sub_releases_of_this_release($base_release,true); + $parent_obj = get_parent_release_object($Current_DN); + $following_releases = get_sub_releases_of_this_release($base_release,true); + + /* Check if given dn exists or if is a new entry */ + $ldap->cat($Current_DN); + if(!$ldap->count()){ + $is_new = true; + }else{ + $is_new = false; + } + + /* if parameter removed is true, we have to add FAIstate to the current attrs + FAIstate should end with ...|removed after this operation */ + if($removed ){ + $ldap->cat($Current_DN); + + /* Get current object, because we must add the FAIstate ...|removed */ + if((!$ldap->count()) && !empty($parent_obj)){ + $ldap->cat($parent_obj); + } + + /* Check if we have found a suiteable object */ + if(!$ldap->count()){ + echo "Error can't remove this object ".$Current_DN; + return; + }else{ + + /* Set FAIstate to current objectAttrs */ + $objectAttrs = prepare_ldap_fetch_to_be_saved($ldap->fetch()); + if(isset($objectAttrs['FAIstate'][0])){ + if(!preg_match("/removed$/",$objectAttrs['FAIstate'][0])){ + $objectAttrs['FAIstate'][0] .= "|removed"; + } + }else{ + $objectAttrs['FAIstate'][0] = "|removed"; + } + } + } + + /* Check if this a leaf release or not */ + if(count($following_releases) == 0 ){ + + /* This is a leaf object. It isn't inherited by any other object */ + if(DEBUG_FAI_FUNC) { + echo "Saving directly, is a leaf object
".$Current_DN; + print_a($objectAttrs); + } + save_FAI_object($Current_DN,$objectAttrs); + }else{ + + /* This object is inherited by some sub releases */ + + /* Get all releases, that inherit this object */ + $r = get_following_releases_that_inherit_this_object($Current_DN); + + /* Get parent object */ + $ldap->cat($parent_obj); + $parent_attrs = prepare_ldap_fetch_to_be_saved($ldap->fetch()); + + /* New objects require special handling */ + if($is_new){ + + /* check if there is already an entry named like this, + in one of our parent releases */ + if(!empty($parent_obj)){ + if(DEBUG_FAI_FUNC) { + echo "There is already an entry named like this.
"; + + echo "Saving main object".$Current_DN; + print_a($objectAttrs); + } + save_FAI_object($Current_DN,$objectAttrs); + + foreach($r as $key){ + if(DEBUG_FAI_FUNC) { + echo "Saving parent to following release ".$key; + print_a($parent_attrs); + } + save_FAI_object($key,$parent_attrs); + } + }else{ + + if(DEBUG_FAI_FUNC) { + echo "Saving main object".$Current_DN; + print_a($objectAttrs); + } + save_FAI_object($Current_DN,$objectAttrs); + + if(isset($objectAttrs['FAIstate'])){ + $objectAttrs['FAIstate'] .= "|removed"; + }else{ + $objectAttrs['FAIstate'] = "|removed"; + } + + foreach($r as $key ){ + if(DEBUG_FAI_FUNC) { + echo "Create an empty placeholder in follwing release ".$key; + print_a($objectAttrs); + } + save_FAI_object($key,$objectAttrs); + } + } + }else{ + + /* check if we must patch the follwing release */ + if(!empty($r)){ + foreach($r as $key ){ + if(DEBUG_FAI_FUNC) { + echo "Copy current objects original attributes to next release ".$key; + print_a($parent_attrs); + } + save_FAI_object($key,$parent_attrs); + } + } + + if(DEBUG_FAI_FUNC) { + echo "Saving current object".$parent_obj; + print_a($objectAttrs); + } + save_FAI_object($parent_obj,$objectAttrs); + + if(($parent_obj != $Current_DN)){ + print_red(sprintf(_("Error, following objects should be equal '%s' and '%s'"),$parent_obj,$Current_DN)); + } + } + } + } + $_SESSION['FAI_objects_to_save'] = array(); +} + + +/* this function will remove all unused (deleted) objects, + that have no parent object */ +function clean_up_releases($Current_DN) { - /* Get some basic informations */ - $base_release = get_release_dn($Current_DN); - $sub_releases = get_sub_releases_of_this_release($base_release,true); - $parent_obj = get_parent_release_object($Current_DN); - - $previous_releases = get_previous_releases_of_this_release($base_release,true); - $following_releases= get_sub_releases_of_this_release($base_release,true); - global $config; $ldap = $config->get_ldap_link(); $ldap->cd($config->current['BASE']); - $ldap->cat($Current_DN); - if(!$ldap->count()){ - $is_new = true; - }else{ - $is_new = false; + + /* Collect some basic informations and initialize some variables */ + $base_release = get_release_dn($Current_DN); + $previous_releases = array_reverse(get_previous_releases_of_this_release($base_release,true)); + $Kill = array(); + $Skip = array(); + + /* We must also include the given release dn */ + $previous_releases[] = $base_release; + + /* Walk through all releases */ + foreach($previous_releases as $release){ + + /* Get fai departments */ + $deps_to_search = get_FAI_departments($release); + + /* For every single department (ou=hoos,ou ..) */ + foreach($deps_to_search as $fai_base){ + + /* Ldap search for fai classes specified in this release */ + $ldap->cd($fai_base); + $ldap->search("(objectClass=FAIclass)",array("dn","objectClass","FAIstate")); + + /* check the returned objects, and add/replace them in our return variable */ + while($attr = $ldap->fetch()){ + + $buffer = array(); +# $name = str_ireplace($release,"",$attr['dn']); + $name = preg_replace("/".normalizePreg($release)."/i","",$attr['dn']); + + if(isset($attr['FAIstate'][0])&&(preg_match("/removed$/",$attr['FAIstate'][0]))){ + + /* Check if this object is required somehow */ + if(!isset($Skip[$name])){ + $Kill[$attr['dn']] = $attr['dn']; + } + }else{ + + /* This object is required (not removed), so do not + delete any following sub releases of this object */ + $Skip[$name] = $attr['dn']; + } + } + } } + return($Kill); +} + + +/* Remove numeric index and 'count' from ldap->fetch result */ +function prepare_ldap_fetch_to_be_saved($attrs) +{ + foreach($attrs as $key => $value){ + if(is_numeric($key) || ($key == "count") || ($key == "dn")){ + unset($attrs[$key]); + } + if(is_array($value) && isset($value['count'])){ + unset($attrs[$key]['count']); + } + } + return($attrs); +} + + +/* Save given attrs to specified dn*/ +function save_FAI_object($dn,$attrs) +{ + global $config; + $ldap = $config->get_ldap_link(); + $ldap->cd($config->current['BASE']); + $ldap->create_missing_trees(preg_replace('/^[^,]+,/', '', $dn)); + $ldap->cd($dn); - echo "

".$Current_DN."

"; - - /* If we are a leaf object */ - if(count($following_releases) == 0 ){ - echo "Saving dircetly, is a leaf object
"; - }else{ - - $r = get_following_releases_that_inherit_this_object($Current_DN); + $ldap->cat($dn,array("dn")); + if($ldap->count()){ - if($is_new){ - echo "Creating an empty entry for ".$r[key($r)]."
"; - echo "By setting 'FAIstate' to '*|removed'
"; - }else{ - echo "This object has sub releases:
This object must be updated "; - echo $r[key($r)]."
with ".$parent_obj."
"; + /* Remove FAIstate*/ + if(!isset($attrs['FAIstate'])){ + $attrs['FAIstate'] = array(); } - unset($r[key($r)]); - echo "
the result will be inherited by ."; - foreach($r as $release => $value){ - echo "
  : ".$release.""; + + $ldap->modify($attrs); + }else{ + + /* Unset description if empty */ + if(empty($attrs['description'])){ + unset($attrs['description']); + } + + $ldap->add($attrs); + } + show_ldap_error($ldap->get_error(),sprintf(_("Release management failed, can't save '%s'"),$dn)); +} + + +/* Return FAIstate freeze branch or "" for specified release department */ +function get_release_tag($dn) +{ + global $config; + $ldap = $config->get_ldap_link(); + $ldap->cd($dn); + $ldap->cat($dn,array("FAIstate")); + + if($ldap->count()){ + + $attr = $ldap->fetch(); + if(isset($attr['FAIstate'][0])){ + if(preg_match("/freeze/",$attr['FAIstate'][0])){ + return("freeze"); + }elseif(preg_match("/branch/",$attr['FAIstate'][0])){ + return("branch"); + } } - } - echo "
.--------------------------------------------------------------------.
"; + } + return(""); } @@ -182,11 +519,12 @@ function get_following_releases_that_inherit_this_object($dn) $base_release = get_release_dn($dn); /* Get previous release dns */ - $sub_releases = get_sub_releases_of_this_release($base_release,true); + $sub_releases = get_sub_releases_of_this_release($base_release); /* Get dn suffix. Example "FAIvairableEntry=keksdose,FAIvariable=Keksregal," */ - $dn_suffix = str_ireplace($base_release,"",$dn); - +# $dn_suffix = str_ireplace($base_release,"",$dn); + $dn_suffix = preg_replace("/".normalizePreg($base_release)."/i","",$dn); + /* Check if given object also exists whitin one of these releases */ foreach($sub_releases as $p_release => $name){ @@ -195,7 +533,7 @@ function get_following_releases_that_inherit_this_object($dn) $ldap->cat($check_dn,array("dn","objectClass")); if($ldap->count()){ - return($ret); + //return($ret); }else{ $ret[$check_dn]=$check_dn; } @@ -205,7 +543,7 @@ function get_following_releases_that_inherit_this_object($dn) /* Get previous version of the object dn */ -function get_parent_release_object($dn) +function get_parent_release_object($dn,$include_myself=true) { global $config; $ldap = $config->get_ldap_link(); @@ -214,7 +552,9 @@ function get_parent_release_object($dn) /* Get base release */ $base_release = get_release_dn($dn); - $previous_releases[] = $base_release; + if($include_myself){ + $previous_releases[] = $base_release; + } /* Get previous release dns */ $tmp = get_previous_releases_of_this_release($base_release,true); @@ -223,7 +563,8 @@ function get_parent_release_object($dn) } /* Get dn suffix. Example "FAIvairableEntry=keksdose,FAIvariable=Keksregal," */ - $dn_suffix = str_ireplace($base_release,"",$dn); +# $dn_suffix = str_ireplace($base_release,"",$dn); + $dn_suffix = preg_replace("/".normalizePreg($base_release)."/i","",$dn); /* Check if given object also exists whitin one of these releases */ foreach($previous_releases as $p_release){ @@ -247,7 +588,8 @@ function get_previous_releases_of_this_release($dn,$flat) $ret = array(); /* Explode dns into pieces, to be able to build parent dns */ - $dns_to_check = ldap_explode_dn(str_ireplace(",".$config->current['BASE'],"",$dn),0); + $dns_to_check = gosa_ldap_explode_dn(preg_replace("/".normalizePreg(",".$config->current['BASE'])."/i","",$dn)); + if(!is_array($dns_to_check)){ return; } @@ -351,7 +693,8 @@ function get_release_dn($Current_DN) $ldap->cd($config->current['BASE']); /* Split dn into pices */ - $dns_to_check = ldap_explode_dn(str_ireplace(",".$config->current['BASE'],"",$Current_DN),0); + $dns_to_check = gosa_ldap_explode_dn(preg_replace("/".normalizePreg(",".$config->current['BASE'])."/i","",$Current_DN)); + if(!is_array($dns_to_check)){ return; }