2cb851deaee4246c63bb3567c42dae032481599f
1 <?php
3 define("DEBUG_FAI_FUNC",FALSE);
5 /* TEST PHASE .... */
7 /* Returns all object for the given release.
8 This function resolves the releases
9 from base up to the given dn.
10 */
11 function get_all_objects_for_given_base($Current_DN,$filter,$detailed = false)
12 {
13 global $config;
14 $ldap = $config->get_ldap_link();
15 $ldap->cd($config->current['BASE']);
17 /* Collect some basic informations and initialize some variables */
18 $base_release = get_release_dn($Current_DN);
19 $previous_releases = array_reverse(get_previous_releases_of_this_release($base_release,true));
20 $res = array();
21 $tmp = array();
23 /* We must also include the given release dn */
24 $previous_releases[] = $base_release;
26 /* Walk through all releases */
27 foreach($previous_releases as $release){
29 /* Get fai departments */
30 $deps_to_search = get_FAI_departments($release);
32 /* For every single department (ou=hoos,ou ..) */
33 foreach($deps_to_search as $fai_base){
35 /* Ldap search for fai classes specified in this release */
36 $ldap->cd($fai_base);
37 $ldap->search($filter,array("dn","objectClass","FAIstate"));
39 /* check the returned objects, and add/replace them in our return variable */
40 while($attr = $ldap->fetch()){
42 $buffer = array();
43 $name = str_ireplace($release,"",$attr['dn']);
45 if(isset($attr['FAIstate'][0])){
46 if(preg_match("/removed$/",$attr['FAIstate'][0])){
47 if(isset($res[$name])){
48 unset($res[$name]);
49 }
50 continue;
51 }
52 }
55 /* In detailed mode are some additonal informations visible */
56 if($detailed){
58 /* Create list of parents */
59 if(isset($res[$name])){
60 $buffer = $res[$name];
61 $buffer['parents'][] = $res[$name]['dn'];
62 }else{
63 $buffer['parents'] = array();
64 }
66 /* Append objectClass to resulsts */
67 $buffer['objectClass'] = $attr['objectClass'];
68 unset($buffer['objectClass'][0]);
69 }
71 /* Add this object to our list */
72 $buffer['dn'] = $attr['dn'];
73 $res[$name] = $buffer;
74 }
75 }
76 }
77 return($res);
78 }
82 /* Return the object defining ObjectClass e.g. FAIscriptEntry */
83 function get_FAI_type($attr)
84 {
85 $arr = array( "FAIprofile","FAIpartitionTable", "FAIpartitionDisk","FAIpartitionEntry","FAIhook","FAIhookEntry",
86 "FAIscriptEntry","FAIscript","FAIvariable","FAIvariableEntry","FAIpackageList","FAItemplate",
87 "FAItemplateEntry","FAIdebconfInfo","FAIrepository","FAIrepositoryServer","FAIbranch","FAIreleaseTag");
88 foreach($arr as $name){
89 if(in_array($name,$attr['objectClass'])){
90 preg_match("");
91 return($name);
92 }
93 }
94 if(DEBUG_FAI_FUNC) { echo "Not found"; }
95 return("");
96 }
99 /* Return all relevant FAI departments */
100 function get_FAI_departments($suffix = "")
101 {
102 $arr = array("hooks","scripts","disk","packages","profiles","templates","variables");
103 $tmp = array();
104 if(preg_match("/^,/",$suffix)){
105 $suffix = preg_replace("/^,/","",$suffix);
106 }
107 foreach($arr as $name){
108 if(empty($suffix)){
109 $tmp[$name] = "ou=".$name;
110 }else{
111 $tmp[$name] = "ou=".$name.",".$suffix;
112 }
113 }
114 return($tmp);
115 }
118 /* Return all releases within the given base */
119 function get_all_releases_from_base($dn)
120 {
121 global $config;
122 $base = "ou=fai,ou=configs,ou=systems,".$dn;
123 $res = array();
125 $ldap = $config->get_ldap_link();
126 $ldap->cd($base);
127 $ldap->search("(objectClass=FAIbranch)",array("ou","dn"));
128 while($attrs = $ldap->fetch()){
129 $res[$attrs['dn']] = $attrs['ou'][0];
130 }
131 return($res);
132 }
135 /* This function does everything to be able to save the given dn. */
136 function prepare_to_save_FAI_object($Current_DN,$objectAttrs,$removed = false)
137 {
138 /* Get ldap object */
139 global $config;
140 $ldap = $config->get_ldap_link();
141 $ldap->cd($config->current['BASE']);
143 /* Get some basic informations */
144 $base_release = get_release_dn($Current_DN);
145 $sub_releases = get_sub_releases_of_this_release($base_release,true);
146 $parent_obj = get_parent_release_object($Current_DN);
147 $following_releases = get_sub_releases_of_this_release($base_release,true);
149 /* Check if given dn exists or if is a new entry */
150 $ldap->cat($Current_DN);
151 if(!$ldap->count()){
152 $is_new = true;
153 }else{
154 $is_new = false;
155 }
157 /* if parameter removed is true, we have to add FAIstate to the current attrs
158 FAIstate should end with ...|removed after this operation */
159 if($removed ){
160 $ldap->cat($Current_DN);
162 /* Get current object, because we must add the FAIstate ...|removed */
163 if((!$ldap->count()) && !empty($parent_obj)){
164 $ldap->cat($parent_obj);
165 }
167 /* Check if we have found a suiteable object */
168 if(!$ldap->count()){
169 echo "Error can't remove this object ".$Current_DN;
170 return;
171 }else{
173 /* Set FAIstate to current objectAttrs */
174 $objectAttrs = prepare_ldap_fetch_to_be_saved($ldap->fetch());
175 if(isset($objectAttrs['FAIstate'][0])){
176 if(!preg_match("/removed$/",$objectAttrs['FAIstate'][0])){
177 $objectAttrs['FAIstate'][0] .= "|removed";
178 }
179 }else{
180 $objectAttrs['FAIstate'][0] = "|removed";
181 }
182 }
183 }
186 /* Check if this a leaf release or not */
187 if(count($following_releases) == 0 ){
189 /* This is a leaf object. It isn't unherited by any other object */
190 if(DEBUG_FAI_FUNC) {
191 echo "<b>Saving directly, is a leaf object</b><br> ".$Current_DN;
192 print_a($objectAttrs);
193 }
194 save_FAI_object($Current_DN,$objectAttrs);
195 }else{
197 /* This object is inherited by some sub releases */
199 /* Get all releases, that inherit this object */
200 $r = get_following_releases_that_inherit_this_object($Current_DN);
202 /* Get parent object */
203 $ldap->cat($parent_obj);
204 $parent_attrs = prepare_ldap_fetch_to_be_saved($ldap->fetch());
206 /* New objects require special handling */
207 if($is_new){
209 /* check if there is already an entry named like this,
210 in one of our parent releases */
211 if(!empty($parent_obj)){
212 if(DEBUG_FAI_FUNC) {
213 echo "There is already an entry named like this.</b><br>";
215 echo "<b>Saving main object</b>".$Current_DN;
216 print_a($objectAttrs);
217 }
218 save_FAI_object($Current_DN,$objectAttrs);
220 foreach($r as $key){
221 if(DEBUG_FAI_FUNC) {
222 echo "<b>Saving parent to following release</b> ".$key;
223 print_a($parent_attrs);
224 }
225 save_FAI_object($key,$parent_attrs);
226 }
227 }else{
229 if(DEBUG_FAI_FUNC) {
230 echo "<b>Saving main object</b>".$Current_DN;
231 print_a($objectAttrs);
232 }
233 save_FAI_object($Current_DN,$objectAttrs);
235 if(isset($objectAttrs['FAIstate'])){
236 $objectAttrs['FAIstate'] .= "|removed";
237 }else{
238 $objectAttrs['FAIstate'] = "|removed";
239 }
241 foreach($r as $key ){
242 if(DEBUG_FAI_FUNC) {
243 echo "<b>Create an empty placeholder in follwing release</b> ".$key;
244 print_a($objectAttrs);
245 }
246 save_FAI_object($key,$objectAttrs);
247 }
248 }
249 }else{
251 /* check if we must patch the follwing release */
252 if(!empty($r)){
253 foreach($r as $key ){
254 if(DEBUG_FAI_FUNC) {
255 echo "<b>Copy current objects original attributes to next release</b> ".$key;
256 print_a($parent_attrs);
257 }
258 save_FAI_object($key,$parent_attrs);
259 }
260 }
262 if(DEBUG_FAI_FUNC) {
263 echo "<b>Saving current object</b>".$parent_obj;
264 print_a($objectAttrs);
265 }
266 save_FAI_object($parent_obj,$objectAttrs);
268 if(($parent_obj != $Current_DN)){
269 print_red(sprintf(_("Error, following objects should be equal '%s' and '%s'"),$parent_obj,$Current_DN));
270 }
271 }
272 }
273 }
276 /* this function will remove all unused (deleted) objects,
277 that have no parent object */
278 function clean_up_releases($Current_DN)
279 {
280 global $config;
281 $ldap = $config->get_ldap_link();
282 $ldap->cd($config->current['BASE']);
284 /* Collect some basic informations and initialize some variables */
285 $base_release = get_release_dn($Current_DN);
286 $previous_releases = array_reverse(get_previous_releases_of_this_release($base_release,true));
287 $Kill = array();
288 $Skip = array();
290 /* We must also include the given release dn */
291 $previous_releases[] = $base_release;
293 /* Walk through all releases */
294 foreach($previous_releases as $release){
296 /* Get fai departments */
297 $deps_to_search = get_FAI_departments($release);
299 /* For every single department (ou=hoos,ou ..) */
300 foreach($deps_to_search as $fai_base){
302 /* Ldap search for fai classes specified in this release */
303 $ldap->cd($fai_base);
304 $ldap->search("(objectClass=FAIclass)",array("dn","objectClass","FAIstate"));
306 /* check the returned objects, and add/replace them in our return variable */
307 while($attr = $ldap->fetch()){
309 $buffer = array();
310 $name = str_ireplace($release,"",$attr['dn']);
312 if(isset($attr['FAIstate'][0])&&(preg_match("/removed$/",$attr['FAIstate'][0]))){
314 /* Check if this object is required somehow */
315 if(!isset($Skip[$name])){
316 $Kill[$attr['dn']] = $attr['dn'];
317 }
318 }else{
320 /* This object is required (not removed), so do not
321 delete any following sub releases of this object */
322 $Skip[$name] = $attr['dn'];
323 }
324 }
325 }
326 }
327 return($Kill);
328 }
331 function prepare_ldap_fetch_to_be_saved($attrs)
332 {
333 foreach($attrs as $key => $value){
334 if(is_numeric($key) || ($key == "count") || ($key == "dn")){
335 unset($attrs[$key]);
336 }
337 if(is_array($value) && isset($value['count'])){
338 unset($attrs[$key]['count']);
339 }
340 }
341 return($attrs);
342 }
345 function save_FAI_object($dn,$attrs)
346 {
347 global $config;
348 $ldap = $config->get_ldap_link();
349 $ldap->cd($config->current['BASE']);
350 $ldap->create_missing_trees(preg_replace('/^[^,]+,/', '', $dn));
351 $ldap->cd($dn);
353 $ldap->cat($dn,array("dn"));
354 if($ldap->count()){
355 $ldap->modify($attrs);
356 }else{
357 $ldap->add($attrs);
358 }
359 show_ldap_error($ldap->get_error(),sprintf(_("Release management failed, can't save '%s'"),$dn));
360 }
363 function get_following_releases_that_inherit_this_object($dn)
364 {
365 global $config;
366 $ldap = $config->get_ldap_link();
367 $ldap->cd($config->current['BASE']);
369 $ret = array();
371 /* Get base release */
372 $base_release = get_release_dn($dn);
374 /* Get previous release dns */
375 $sub_releases = get_sub_releases_of_this_release($base_release);
377 /* Get dn suffix. Example "FAIvairableEntry=keksdose,FAIvariable=Keksregal," */
378 $dn_suffix = str_ireplace($base_release,"",$dn);
380 /* Check if given object also exists whitin one of these releases */
381 foreach($sub_releases as $p_release => $name){
383 $check_dn = $dn_suffix.$p_release;
385 $ldap->cat($check_dn,array("dn","objectClass"));
387 if($ldap->count()){
388 //return($ret);
389 }else{
390 $ret[$check_dn]=$check_dn;
391 }
392 }
393 return($ret);
394 }
397 /* Get previous version of the object dn */
398 function get_parent_release_object($dn,$include_myself=true)
399 {
400 global $config;
401 $ldap = $config->get_ldap_link();
402 $ldap->cd($config->current['BASE']);
403 $previous_releases= array();
405 /* Get base release */
406 $base_release = get_release_dn($dn);
407 if($include_myself){
408 $previous_releases[] = $base_release;
409 }
411 /* Get previous release dns */
412 $tmp = get_previous_releases_of_this_release($base_release,true);
413 foreach($tmp as $release){
414 $previous_releases[] = $release;
415 }
417 /* Get dn suffix. Example "FAIvairableEntry=keksdose,FAIvariable=Keksregal," */
418 $dn_suffix = str_ireplace($base_release,"",$dn);
420 /* Check if given object also exists whitin one of these releases */
421 foreach($previous_releases as $p_release){
422 $check_dn = $dn_suffix.$p_release;
423 $ldap->cat($check_dn,array("dn","objectClass"));
425 if($ldap->count()){
426 return($check_dn);
427 }
428 }
429 return("");
430 }
433 /* return release names of all parent releases */
434 function get_previous_releases_of_this_release($dn,$flat)
435 {
436 global $config;
437 $ldap = $config->get_ldap_link();
438 $ldap->cd($config->current['BASE']);
439 $ret = array();
441 /* Explode dns into pieces, to be able to build parent dns */
442 $dns_to_check = ldap_explode_dn(str_ireplace(",".$config->current['BASE'],"",$dn),0);
443 if(!is_array($dns_to_check)){
444 return;
445 }
447 /* Unset first entry which represents the given dn */
448 unset($dns_to_check['count']);
449 unset($dns_to_check[key($dns_to_check)]);
451 /* Create dns addresses and check if this dn is a release dn */
452 $id = 0;
453 while(count($dns_to_check)){
455 /* build parent dn */
456 $new_dn = "";
457 foreach($dns_to_check as $part){
458 $new_dn .= $part.",";
459 }
460 $new_dn .= $config->current['BASE'];
462 /* check if this dn is a release */
463 if(is_release_department($new_dn)){
464 if($flat){
465 $ret[$id] = $new_dn;
466 }else{
467 $ret = array($new_dn=>$ret);
468 }
469 $id ++;
470 }else{
471 return($ret);
472 }
473 reset($dns_to_check);
474 unset($dns_to_check[key($dns_to_check)]);
475 }
476 return($ret);
477 }
480 /* This function returns all sub release names, recursivly */
481 function get_sub_releases_of_this_release($dn,$flat = false)
482 {
483 global $config;
484 $res = array();
485 $ldap = $config->get_ldap_link();
486 $ldap->cd($config->current['BASE']);
487 $ldap->ls("(objectClass=FAIbranch)",$dn,array("objectClass","dn","ou"));
488 while($attr = $ldap->fetch()){
490 /* Append department name */
491 if($flat){
492 $res[$attr['dn']] = $attr['ou'][0];
493 }else{
494 $res[$attr['dn']] = array();
495 }
497 /* Get sub release departments of this department */
498 if(in_array("FAIbranch",$attr['objectClass'])) {
499 if($flat){
500 $tmp = get_sub_releases_of_this_release($attr['dn'],$flat);
501 foreach($tmp as $dn => $value){
502 $res[$dn]=$value;
503 }
504 }else{
505 $res[$attr['dn']] = get_sub_releases_of_this_release($attr['dn']);
506 }
507 }
508 }
509 return($res);
510 }
513 /* Check if the given department is a release department */
514 function is_release_department($dn)
515 {
516 global $config;
517 $ldap = $config->get_ldap_link();
518 $ldap->cd($config->current['BASE']);
519 $ldap->cat($dn,array("objectClass","ou"));
521 /* Check objectClasses and name to check if this is a release department */
522 if($ldap->count()){
523 $attrs = $ldap->fetch();
525 $ou = "";
526 if(isset($attrs['ou'][0])){
527 $ou = $attrs['ou'][0];
528 }
530 if((in_array("FAIbranch",$attrs['objectClass'])) || ($ou == "fai")){
531 return($attrs['dn']);
532 }
533 }
534 return(false);
535 }
538 /* This function returns the dn of the object release */
539 function get_release_dn($Current_DN)
540 {
541 global $config;
542 $ldap = $config->get_ldap_link();
543 $ldap->cd($config->current['BASE']);
545 /* Split dn into pices */
546 $dns_to_check = ldap_explode_dn(str_ireplace(",".$config->current['BASE'],"",$Current_DN),0);
547 if(!is_array($dns_to_check)){
548 return;
549 }
551 /* Use dn pieces, to create sub dns like
552 ou=test,ou=1,ou=0...
553 ou=1,ou=0...
554 ou=0...
555 To check which dn is our release container.
556 */
557 unset($dns_to_check['count']);
558 while(count($dns_to_check)){
560 /* Create dn */
561 $new_dn = "";
562 foreach($dns_to_check as $part){
563 $new_dn .= $part.",";
564 }
565 $new_dn .= $config->current['BASE'];
567 /* Check if this dn is a release dn */
568 if(is_release_department($new_dn)){
569 return($new_dn);
570 }
572 /* Remove first element of dn pieces */
573 reset($dns_to_check);
574 unset($dns_to_check[key($dns_to_check)]);
575 }
576 return("");
577 }
579 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
580 ?>