1 <?php
3 class gotomasses extends plugin
4 {
5 /* Definitions */
6 var $plHeadline = "System deployment";
7 var $plDescription = "This does something";
9 /* attribute list for save action */
10 var $attributes= array();
11 var $objectclasses= array();
13 /* Source file that contains the gotomasses data */
14 var $data_file = "Undefined"; #Set in constructor
16 /* Queue tasks */
17 var $tasks = array();
18 var $current =false;
19 var $dialog = FALSE;
20 var $ids_to_remove = array();
23 function gotomasses(&$config, $dn= NULL)
24 {
25 /* Include config object */
26 $this->config= &$config;
28 /* Define source file */
29 $this->data_file = CONFIG_DIR."/gotomasses_machines";
30 $file = $this->config->search("gotomasses", "STORAGE_FILE",array('menu'));
31 if(!empty($file)){
32 $this->data_file = $file;
33 }
35 $this->load_gotomasses_data();
36 }
39 function execute()
40 {
41 $smarty = get_smarty();
42 /************
43 * Handle posts
44 ************/
46 $s_entry = $s_action = "";
47 $arr = array( "/^edit_task_/"=>"edit","/^remove_task_/"=>"remove",
48 "/^new_task_/"=>"new_task","/^remove_multiple_task_/" => "remove_multiple");
49 foreach($arr as $regex => $action){
50 foreach($_POST as $name => $value){
51 if(preg_match($regex,$name)){
52 $s_action = $action;
53 $s_entry = preg_replace($regex,"",$name);
54 $s_entry = preg_replace("/_(x|y)$/","",$s_entry);
55 }
56 }
57 }
59 /* Edit posted from list link */
60 if(isset($_GET['act']) && $_GET['act'] == "edit" && isset($_GET['id']) && isset($this->tasks[$_GET['id']])){
61 $s_action = "edit";
62 $s_entry = $_GET['id'];
63 }
65 /************
66 * List posts
67 ************/
69 /* Remove multiple */
70 if($s_action == "remove_multiple"){
71 if(!$this->acl_is_removeable()){
72 print_red(_("You are not allowed to remove a task."));
73 }else{
74 $this->ids_to_remove = $this->list_get_selected_items();
75 $tmp = "";
76 foreach($this->ids_to_remove as $key => $id){
77 if(isset($this->tasks[$id])){
78 $task = $this->tasks[$id];
79 $tmp.= "\n".$this->target_to_string($task);
80 }else{
81 unset($this->ids_to_remove[$key]);
82 }
83 }
84 $smarty->assign("multiple", TRUE);
85 $smarty->assign("info",sprintf(_("Your are about to delete the following tasks: %s"),"<pre>".$tmp."</pre>"));
86 $this->current = $s_entry;
87 return($smarty->fetch(get_template_path('remove.tpl', TRUE)));
88 }
89 }
91 /* Remove specified tasks */
92 if(count($this->ids_to_remove) && isset($_POST['delete_multiple_confirm'])){
93 foreach($this->ids_to_remove as $id){
94 if(isset($this->tasks[$id])){
95 unset($this->tasks[$id]);
96 }
97 }
98 $this->save();
99 }
101 /* Remove entry from list */
102 if($s_action == "remove" && isset($this->tasks[$s_entry])){
103 if(!$this->acl_is_removeable()){
104 print_red(_("You are not allowed to remove a task."));
105 }else{
106 $entry = $this->tasks[$s_entry];
107 $this->current = $s_entry;
108 $smarty->assign("info",sprintf(_("Your are about to delete the following tasks: %s"),
109 "<pre>".$this->target_to_string($entry)."</pre>"));
110 $smarty->assign("multiple", FALSE);
111 return($smarty->fetch(get_template_path('remove.tpl', TRUE)));
112 }
113 }
115 /* Remove entry, remove is confirmed */
116 if($this->current != -1 && isset($_POST['delete_confirm'])){
117 unset($this->tasks[$this->current]);
118 $this->current = -1;
119 $this->save();
120 }
122 /* Remove aborted */
123 if(isset($_POST['delete_cancel'])){
124 $this->ids_to_remove = array();;
125 }
127 /* Edit selected entry */
128 if($s_action == "edit" && isset($this->tasks[$s_entry])){
129 $entry = $this->tasks[$s_entry];
130 $this->dialog = new goto_task($this->config,$this,$entry);
131 $this->current = $s_entry;
132 }
134 /* New entry */
135 if($s_action== "new_task" && $this->acl_is_createable()){
136 $this->dialog = new goto_task($this->config,$this);
137 $this->current = -1;
138 }
140 /* Close dialog */
141 if(isset($_POST['close_goto_task'])){
142 $this->dialog = FALSE;
143 $this->current = -1;
144 }
146 /* Close dialog */
147 if((isset($_POST['save_goto_task']) || isset($_POST['apply_goto_task'])) && is_object($this->dialog) ){
148 $this->dialog->save_object();
149 $msgs = $this->dialog->check();
150 if(count($msgs)){
151 foreach($msgs as $msg){
152 print_red($msg);
153 }
154 }else{
155 if(isset($this->tasks[$this->current]) && $this->current != -1){
156 $this->tasks[$this->current] = $this->dialog->save();
157 }else{
158 $this->tasks[] = $this->dialog->save();
159 }
160 if(!isset($_POST['apply_goto_task'])){
161 $this->dialog = FALSE;
162 $this->current = -1;
163 }
164 $this->save();
165 }
166 }
168 /* Display dialogs if currently opened */
169 if(is_object($this->dialog)){
170 $this->dialog->save_object();
171 return($this->dialog->execute());
172 }
175 /************
176 * Handle Divlist
177 ************/
179 $plug = $_GET['plug'];
180 $divlist = new MultiSelectWindow($this->config,"GotoMasses","gotomassses");
181 $divlist->SetSummary(_("List of system deployment tasks"));
182 $divlist->SetHeadpageMode();
183 $divlist->EnableCloseButton(FALSE);
184 $divlist->EnableSaveButton(FALSE);
185 $divlist->SetInformation(_("This menu allows you to add, remove and change the properties of system deployment tasks."));
187 /* Display add button if allowed */
188 $header = "<div style='padding:5px'>";
189 if($this->acl_is_createable()){
190 $header .= "<input type='image' src='images/gotomasses_new_task.png' name='new_task' class='center'> ";
191 }
193 /* Display add button if allowed */
194 if($this->acl_is_removeable()){
195 $header .= "<input type='image' src='images/edittrash.png' name='remove_multiple_task' class='center'> ";
196 }
197 $header .= "</div>";
199 /* Get Permissions */
200 $ui = get_userinfo();
201 $acls = $this->getacl("");
202 foreach($ui->get_module_departments("gotomasses") as $dep){
203 $acls .= $ui->get_category_permissions($dep,"gotomasses");
204 }
206 /* Create divlist */
207 $divlist->SetListHeader($header);
208 /* Toggle all selected / deselected */
209 $chk = "<input type='checkbox' id='select_all' name='select_all'
210 onClick='toggle_all_(\"^item_selected_[0-9]*$\",\"select_all\");' >";
212 /* set Page header */
213 $divlist->AddHeader(array("string"=> $chk, "attach"=>"style='width:20px;'"));
215 $divlist->AddHeader(array("string"=>"<a href='?plug=".$plug."&sort=object'>"._("Target")."</a>"));
216 $divlist->AddHeader(array("string"=>"<a href='?plug=".$plug."&sort=schedule'>"._("Schedule")."</a>",
217 "attach"=>"style='width:100px;'"));
218 $divlist->AddHeader(array("string"=>"<a href='?plug=".$plug."&sort=action'>"._("Type")."</a>",
219 "attach"=>"style='width:80px;'"));
220 $divlist->AddHeader(array("string"=>_("Action"),
221 "attach"=>"style='border-right:0px;width:40px;'"));
223 /* Create edit link */
224 $edit_link = "<div style='width:100%;overflow:hidden;'><nobr><a href='?plug=".$_GET['plug']."&act=edit&id=%key%'>%str%</nobr></div>";
226 if(!empty($acls)){
227 foreach($this->tasks as $key => $task){
228 $action = "<input type='image' src='images/edit.png' name='edit_task_".$key."' class='center' alt='"._("Edit")."'>";
229 if($this->acl_is_removeable()){
230 $action.= "<input type='image' src='images/edittrash.png' name='remove_task_".$key."' class='center' alt='"._("Reomve")."'>";
231 }
232 /* Create each field */
233 $field0 = array("string" => "<input type='checkbox' id='item_selected_".$key."' name='item_selected_".$key."'>" ,
234 "attach" => "style='width:20px;'");
236 $field1 = array("string" => preg_replace(array("/%key%/","/%str%/"),array($key,$this->target_to_string($task)),$edit_link));
237 $field2 = array("string" => $this->time_to_string($task),"attach" => "style='width:100px;'");
238 $field3 = array("string" => $this->action_to_string($task),"attach" => "style='width:80px;'");
239 $field4 = array("string" => $action,"attach" => "style='text-align:right;width:40px;border-right:0px;'");
240 $divlist->AddElement(array($field0,$field1,$field2,$field3,$field4));
241 }
242 }
244 return($divlist->Draw());
245 }
248 function target_to_string($data)
249 {
250 $ret = "";
251 if($data['Action'] == "initial_install"){
252 foreach($data['Initial_Target'] as $target){
253 $ret .= $target['MAC'].", ";
254 }
255 }else{
256 foreach($data['Target'] as $target){
257 $ret .= $target.", ";
258 }
259 }
260 return(preg_replace("/, $/","",$ret));
261 }
264 function time_to_string($data)
265 {
266 return($data['Minute']." ".$data['Hour']." ".$data['Day']." ".$data['Month']." ".$data['Weekday']);
267 }
270 function action_to_string($data)
271 {
272 $tmp = $this->get_actions();
273 if(isset($tmp[$data['Action']])){
274 return($tmp[$data['Action']]);
275 }else{
276 return(_("Unknown"));
277 }
278 }
281 function load_gotomasses_data()
282 {
283 $ui = get_userinfo();
285 /* Check file existence */
286 if(!file_exists($this->data_file) || !is_readable($this->data_file)){
287 print_red(sprintf(_("Can't locate or read gotomasses storage file '%s'."),$this->data_file));
288 return(FALSE);
289 }
291 /* check if file is readable */
292 $fp = @fopen($this->data_file,"r");
293 if(!$fp){
294 print_red(sprintf(_("Can't read gotomasses storage file '%s'."),$this->data_file));
295 return(FALSE);
296 }
298 /* Get file contents */
299 $data ="";
300 while(!feof($fp)){
301 $data.= fread($fp,512);
302 }
304 /* Get lines from file */
305 $this->tasks = array();
306 $comment = "";
307 $rows = split("\n",$data);
309 /* Walk trough rows and parse data */
310 foreach($rows as $row){
312 /* Skip empty lines */
313 $row = trim($row);
314 if(empty($row)){
315 continue;
316 }
318 /* Get comment, if available */
319 if(preg_match("/^#/",$row)){
320 $comment = preg_replace("/^#/","",$row);
321 continue;
322 }
324 /* Split row into minutes/ hours ...*/
325 $row = preg_replace('/[\t ]/umi'," ",$row);
326 $row = preg_replace('/ */umi'," ",$row);
327 $parts = split(" ",$row);
329 if(count($parts) != 10){
330 print_red(_("Entry broken, skipped."));
331 }else{
333 $entry = array();
334 $entry['Minute'] = $parts[0];
335 $entry['Hour'] = $parts[1];
336 $entry['Day'] = $parts[2];
337 $entry['Month'] = $parts[3];
338 $entry['Weekday'] = $parts[4];
339 $entry['Action'] = $parts[5];
340 $entry['OGroup'] = $parts[6];
341 $entry['Zone'] = $parts[7];
342 $entry['Section'] = $parts[8];
343 if($entry['Action'] == "initial_install"){
344 $tmp2 = split(";",$parts[9]);
345 foreach($tmp2 as $target){
346 $tmp = split(",",$target);
347 $entry['Initial_Target'][] = array(
348 "MAC" => $tmp[0],
349 "IP" => $tmp[1],
350 "NAME" => $tmp[2]);
351 }
352 $entry['Target'] = array();
353 }else{
354 $entry['Initial_Target'] = array();
355 $entry['Target'] = split(";",$parts[7]);
356 }
357 $entry['Comment'] = $comment;
358 $this->tasks [] = $entry;
359 }
360 }
361 }
364 function save_gotomasses_data()
365 {
366 $str = "#GOsa generated file, please just modify if you realy know what you do.";
367 foreach($this->tasks as $task){
368 $str .= "\n#".trim($task['Comment']);
369 $str .= "\n";
370 if($task['Action'] == "initial_install"){
371 $str .= "* * * * * ";
372 }else{
373 $str .= str_pad($task['Minute'] ,5," ")." ";
374 $str .= str_pad($task['Hour'] ,5," ")." ";
375 $str .= str_pad($task['Day'] ,5," ")." ";
376 $str .= str_pad($task['Month'] ,5," ")." ";
377 $str .= str_pad($task['Weekday'],5," ")." ";
378 }
379 $str .= str_pad($task['Action'] ,5," ")." ";
380 $str .= str_pad($task['OGroup'] ,5," ")." ";
381 $str .= str_pad($task['Zone'] ,5," ")." ";
382 $str .= str_pad($task['Section'],5," ")." ";
383 if($task['Action'] == "initial_install"){
384 foreach($task['Initial_Target'] as $target){
385 $str .= trim($target['MAC']).",".trim($target['IP']).",".trim($target['NAME']).";";
386 }
387 }else{
388 foreach($task['Target'] as $target){
389 $str .= $target.";";
390 }
391 }
392 $str = preg_replace("/;$/","",$str);
393 }
395 /* check file existence*/
396 $ui = get_userinfo();
397 if(!file_exists($this->data_file) || !is_writeable($this->data_file)){
398 print_red(sprintf(_("Can't locate or write gotomasses storage file '%s'."),$this->data_file));
399 return(FALSE);
400 }
402 /* check permissions */
403 $fp = @fopen($this->data_file,"w");
404 if(!$fp){
405 print_red(sprintf(_("Can't read gotomasses storage file '%s'."),$this->data_file));
406 return(FALSE);
407 }
409 /* Write contents */
410 $str .= "\n";
411 fwrite($fp,$str);
412 fclose($fp);
413 }
416 function save_object()
417 {
418 }
421 /* Return list of object groups */
422 function get_object_groups()
423 {
424 $ret = array();
425 $ldap = $this->config->get_ldap_link();
426 $ldap->cd($this->config->current['BASE']);
427 $ldap->search("(&(objectClass=gosaGroupOfNames)(cn=*))",array("cn"));
428 while($attrs = $ldap->fetch()){
429 $ret[$attrs['cn'][0]] = $attrs['cn'][0];
430 }
431 return($ret);
432 }
435 function save()
436 {
437 $this->save_gotomasses_data();
438 }
441 function list_get_selected_items()
442 {
443 $ids = array();
444 foreach($_POST as $name => $value){
445 if(preg_match("/^item_selected_[0-9]*$/",$name)){
446 $id = preg_replace("/^item_selected_/","",$name);
447 $ids[$id] = $id;
448 }
449 }
450 return($ids);
451 }
454 function get_actions()
455 {
456 /* Prepare list of available actions */
457 $actions = array( "reboot" => _("Reboot"),
458 "localboot" => _("Localboot"),
459 "halt" => _("Halt system"),
460 "initial_install" => _("Initial installation"),
461 "update" => _("Update"),
462 "reinstall" => _("(Re)Install"),
463 "rescan" => _("Rescan"),
464 "wake" => _("Wake"),
465 "memcheck" => _("Memory check"));
466 return($actions);
467 }
470 function plInfo()
471 {
472 return (array(
473 "plShortName" => _("System mass deployment"),
474 "plDescription" => _("Provide a mechanism to automatically activate a set of systems"),
475 "plSelfModify" => FALSE,
476 "plDepends" => array(),
477 "plPriority" => 0,
478 "plSection" => array("addon"),
479 "plCategory" => array("gotomasses" => array("objectClass" => "none", "description" => _("System mass deployment"))),
480 "plProvidedAcls" => array("Comment" => _("Description"),
481 "Action" => _("Action"),
482 "Day" => _("Day"),
483 "Minute" => _("Minute"),
484 "Hour" => _("Hour"),
485 "Month" => _("Month"),
486 "Weekday" => _("Week day"),
487 "Target" => _("Target"))
488 ));
489 }
490 }
491 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
492 ?>