Code

Updated opsi module
[gosa.git] / gosa-si / server / events / opsi_com.pm
1 ## @file
2 # @details A GOsa-SI-server event module containing all functions for message handling.
3 # @brief Implementation of an event module for GOsa-SI-server. 
6 package opsi_com;
7 use Exporter;
8 @ISA = qw(Exporter);
9 my @events = (
10     "get_events",
11     "opsi_install_client",
12     "opsi_get_netboot_products",  
13     "opsi_get_local_products",
14     "opsi_get_client_hardware",
15     "opsi_get_client_software",
16     "opsi_get_product_properties",
17     "opsi_set_product_properties",
18     "opsi_list_clients",
19     "opsi_del_client",
20     "opsi_add_client",
21     "opsi_modify_client",
22     "opsi_add_product_to_client",
23     "opsi_del_product_from_client",
24    );
25 @EXPORT = @events;
27 use strict;
28 use warnings;
29 use GOSA::GosaSupportDaemon;
30 use Data::Dumper;
31 use XML::Quote qw(:all);
34 BEGIN {}
36 END {}
38 ## @method get_events()
39 # A brief function returning a list of functions which are exported by importing the module.
40 # @return List of all provided functions
41 sub get_events {
42     return \@events;
43 }
46 sub opsi_add_product_to_client {
47   my ($msg, $msg_hash, $session_id) = @_;
48   my $header = @{$msg_hash->{'header'}}[0];
49   my $source = @{$msg_hash->{'source'}}[0];
50   my $target = @{$msg_hash->{'target'}}[0];
51   my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
52   my ($hostId, $productId);
54   # TODO: check dependencies later on?
56   # build return message with twisted target and source
57   my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
58   if (defined $forward_to_gosa) {
59     &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
60   }
62   # Get hostID
63   $hostId = @{$msg_hash->{'hostId'}}[0];
64   &add_content2xml_hash($out_hash, "hostId", $hostId);
66   # Get productID
67   $productId = @{$msg_hash->{'productId'}}[0];
68   &add_content2xml_hash($out_hash, "productId", $productId);
70   # Do an action request for all these -> "setup".
71   my $callobj = {
72     method  => 'setProductActionRequest',
73     params  => [ $productId, $hostId, "setup" ],
74     id  => 1, }; 
76   my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
77   if (&main::check_opsi_res($sres)){
78     &main::daemon_log("ERROR: cannot add product: ".$sres->error_message, 1);
79     &add_content2xml_hash($out_hash, "error", $sres->error_message);
80   }
81   
82   # return message
83   return ( &create_xml_string($out_hash) );
84 }
87 sub opsi_del_product_from_client {
88   my ($msg, $msg_hash, $session_id) = @_;
89   my $header = @{$msg_hash->{'header'}}[0];
90   my $source = @{$msg_hash->{'source'}}[0];
91   my $target = @{$msg_hash->{'target'}}[0];
92   my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
93   my ($hostId, $productId);
95   # build return message with twisted target and source
96   my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
97   if (defined $forward_to_gosa) {
98     &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
99   }
101   # Get hostID
102   $hostId = @{$msg_hash->{'hostId'}}[0];
103   &add_content2xml_hash($out_hash, "hostId", $hostId);
105   # Get productID
106   $productId = @{$msg_hash->{'productId'}}[0];
107   &add_content2xml_hash($out_hash, "productId", $productId);
110   #TODO: check the results for more than one entry which is currently installed
111   #$callobj = {
112   #    method  => 'getProductDependencies_listOfHashes',
113   #    params  => [ $productId ],
114   #    id  => 1, };
115   #
116   #my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
117   #if (&main::check_opsi_res($sres)){
118   #  &main::daemon_log("ERROR: cannot perform dependency check: ".$res->error_message, 1);
119   #  &add_content2xml_hash($out_hash, "error", $res->error_message);
120   #  return ( &create_xml_string($out_hash) );
121   #}
124   # Check for uninstall method
125   my $callobj = {
126       method  => 'getPossibleProductActions_list',
127       params  => [ $productId ],
128       id  => 1, };
129   
130   my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
131   if (&main::check_opsi_res($sres)){
132     &main::daemon_log("ERROR: cannot get product action list: ".$sres->error_message, 1);
133     &add_content2xml_hash($out_hash, "error", $sres->error_message);
134     return ( &create_xml_string($out_hash) );
135   }
136   my $uninst_possible= 0;
137   foreach my $r (@{$sres->result}) {
138     if ($r eq 'uninstall') {
139       $uninst_possible= 1;
140     }
141   }
142   if (!$uninst_possible){
143     &main::daemon_log("ERROR: cannot uninstall product", 1);
144     &add_content2xml_hash($out_hash, "error", "product is not uninstallable");
145     return ( &create_xml_string($out_hash) );
146   }
148   # Set product state to "none"
149   # Do an action request for all these -> "setup".
150   $callobj = {
151       method  => 'setProductActionRequest',
152       params  => [ $productId, $hostId, "none" ],
153       id  => 1, }; 
155   $sres = $main::opsi_client->call($main::opsi_url, $callobj);
156   if (&main::check_opsi_res($sres)){
157       &main::daemon_log("ERROR: cannot delete product: ".$sres->error_message, 1);
158       &add_content2xml_hash($out_hash, "error", $sres->error_message);
159       return ( &create_xml_string($out_hash) );
160   }
161   
162   # return message
163   return ( &create_xml_string($out_hash) );
167 sub opsi_add_client {
168   my ($msg, $msg_hash, $session_id) = @_;
169   my $header = @{$msg_hash->{'header'}}[0];
170   my $source = @{$msg_hash->{'source'}}[0];
171   my $target = @{$msg_hash->{'target'}}[0];
172   my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
173   my $hostId;
175   # build return message with twisted target and source
176   my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
177   if (defined $forward_to_gosa) {
178     &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
179   }
181   # Get hostID
182   $hostId = @{$msg_hash->{'hostId'}}[0];
183   &add_content2xml_hash($out_hash, "hostId", $hostId);
184   my $name= $hostId;
185   $name=~ s/^([^.]+).*$/$1/;
186   my $domain= $hostId;
187   $domain=~ s/^[^.]+(.*)$/$1/;
188   my ($description, $notes, $ip, $mac);
190   if (defined @{$msg_hash->{'description'}}[0]){
191     $description = @{$msg_hash->{'description'}}[0];
192   }
193   if (defined @{$msg_hash->{'notes'}}[0]){
194     $notes = @{$msg_hash->{'notes'}}[0];
195   }
196   if (defined @{$msg_hash->{'ip'}}[0]){
197     $ip = @{$msg_hash->{'ip'}}[0];
198   }
199   if (defined @{$msg_hash->{'mac'}}[0]){
200     $mac = @{$msg_hash->{'mac'}}[0];
201   }
202   
203   my $callobj;
204   $callobj = {
205     method  => 'createclient',
206     params  => [ $name, $domain, $description, $notes, $ip, $mac ],
207     id  => 1,
208   };
210   my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
211   if (&main::check_opsi_res($sres)){
212     &main::daemon_log("ERROR: cannot create client: ".$sres->error_message, 1);
213     &add_content2xml_hash($out_hash, "error", $sres->error_message);
214   }
216   # return message
217   return ( &create_xml_string($out_hash) );
220     
221 sub opsi_modify_client {
222   my ($msg, $msg_hash, $session_id) = @_;
223   my $header = @{$msg_hash->{'header'}}[0];
224   my $source = @{$msg_hash->{'source'}}[0];
225   my $target = @{$msg_hash->{'target'}}[0];
226   my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
227   my $hostId;
229   # build return message with twisted target and source
230   my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
231   if (defined $forward_to_gosa) {
232     &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
233   }
235   # Get hostID
236   $hostId = @{$msg_hash->{'hostId'}}[0];
237   &add_content2xml_hash($out_hash, "hostId", $hostId);
238   my $name= $hostId;
239   $name=~ s/^([^.]+).*$/$1/;
240   my $domain= $hostId;
241   $domain=~ s/^[^.]+(.*)$/$1/;
242   my ($description, $notes, $ip, $mac);
244   my $callobj;
246   if (defined @{$msg_hash->{'description'}}[0]){
247     $description = @{$msg_hash->{'description'}}[0];
248     $callobj = {
249       method  => 'setHostDescription',
250       params  => [ $hostId, $description ],
251       id  => 1,
252     };
253     my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
254     if (&main::check_opsi_res($sres)){
255       &main::daemon_log("ERROR: cannot set description: ".$sres->error_message, 1);
256       &add_content2xml_hash($out_hash, "error", $sres->error_message);
257       return ( &create_xml_string($out_hash) );
258     }
259   }
260   if (defined @{$msg_hash->{'notes'}}[0]){
261     $notes = @{$msg_hash->{'notes'}}[0];
262     $callobj = {
263       method  => 'setHostNotes',
264       params  => [ $hostId, $notes ],
265       id  => 1,
266     };
267     my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
268     if (&main::check_opsi_res($sres)){
269       &main::daemon_log("ERROR: cannot set notes: ".$sres->error_message, 1);
270       &add_content2xml_hash($out_hash, "error", $sres->error_message);
271       return ( &create_xml_string($out_hash) );
272     }
273   }
274   if (defined @{$msg_hash->{'mac'}}[0]){
275     $mac = @{$msg_hash->{'mac'}}[0];
276     $callobj = {
277       method  => 'setMacAddress',
278       params  => [ $hostId, $mac ],
279       id  => 1,
280     };
281     my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
282     if (&main::check_opsi_res($sres)){
283       &main::daemon_log("ERROR: cannot set mac address: ".$sres->error_message, 1);
284       &add_content2xml_hash($out_hash, "error", $sres->error_message);
285       return ( &create_xml_string($out_hash) );
286     }
287   }
288   
289   # return message
290   return ( &create_xml_string($out_hash) );
293     
294 ## @method opsi_get_netboot_products
295 # ???
296 # @param msg - STRING - xml message with tag hostId
297 # @param msg_hash - HASHREF - message information parsed into a hash
298 # @param session_id - INTEGER - POE session id of the processing of this message
299 sub opsi_get_netboot_products {
300   my ($msg, $msg_hash, $session_id) = @_;
301   my $header = @{$msg_hash->{'header'}}[0];
302   my $source = @{$msg_hash->{'source'}}[0];
303   my $target = @{$msg_hash->{'target'}}[0];
304   my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
305   my $hostId;
307   # build return message with twisted target and source
308   my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
309   if (defined $forward_to_gosa) {
310     &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
311   }
313   # Get hostID if defined
314   if (defined @{$msg_hash->{'hostId'}}[0]){
315     $hostId = @{$msg_hash->{'hostId'}}[0];
316     &add_content2xml_hash($out_hash, "hostId", $hostId);
317   }
319   &add_content2xml_hash($out_hash, "xxx", "");
320   my $xml_msg= &create_xml_string($out_hash);
322   # For hosts, only return the products that are or get installed
323   my $callobj;
324   $callobj = {
325     method  => 'getNetBootProductIds_list',
326     params  => [ ],
327     id  => 1,
328   };
330   my $res = $main::opsi_client->call($main::opsi_url, $callobj);
331   my %r = ();
332   for (@{$res->result}) { $r{$_} = 1 }
334   if (&main::check_opsi_res($res)){
336     if (defined $hostId){
337       $callobj = {
338         method  => 'getProductStates_hash',
339         params  => [ $hostId ],
340         id  => 1,
341       };
343       my $hres = $main::opsi_client->call($main::opsi_url, $callobj);
344       if (&main::check_opsi_res($hres)){
345         my $htmp= $hres->result->{$hostId};
347         # check state != not_installed or action == setup -> load and add
348         foreach my $product (@{$htmp}){
350           if (!defined ($r{$product->{'productId'}})){
351             next;
352           }
354           # Now we've a couple of hashes...
355           if ($product->{'installationStatus'} ne "not_installed" or
356               $product->{'actionRequest'} eq "setup"){
357             my $state= "<state>".$product->{'installationStatus'}."</state><action>".$product->{'actionRequest'}."</action>";
359             $callobj = {
360               method  => 'getProduct_hash',
361               params  => [ $product->{'productId'} ],
362               id  => 1,
363             };
365             my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
366             if (&main::check_opsi_res($sres)){
367               my $tres= $sres->result;
369               my $name= xml_quote($tres->{'name'});
370               my $r= $product->{'productId'};
371               my $description= xml_quote($tres->{'description'});
372               $name=~ s/\//\\\//;
373               $description=~ s/\//\\\//;
374               $xml_msg=~ s/<xxx><\/xxx>/<item><ProductId>$r<\/ProductId><name><\/name><description>$description<\/description><\/item>$state<xxx><\/xxx>/;
375             }
377           }
378         }
380       }
382     } else {
383       foreach my $r (@{$res->result}) {
384         $callobj = {
385           method  => 'getProduct_hash',
386           params  => [ $r ],
387           id  => 1,
388         };
390         my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
391         if (&main::check_opsi_res($sres)){
392           my $tres= $sres->result;
394           my $name= xml_quote($tres->{'name'});
395           my $description= xml_quote($tres->{'description'});
396           $name=~ s/\//\\\//;
397           $description=~ s/\//\\\//;
398           $xml_msg=~ s/<xxx><\/xxx>/<item><ProductId>$r<\/ProductId><name><\/name><description>$description<\/description><\/item><xxx><\/xxx>/;
399         }
401       }
403     }
404   }
406   $xml_msg=~ s/<xxx><\/xxx>//;
408   return ($xml_msg);
412 ## @method opsi_get_product_properties
413 # ???
414 # @param msg - STRING - xml message with tags ProductId and hostId
415 # @param msg_hash - HASHREF - message information parsed into a hash
416 # @param session_id - INTEGER - POE session id of the processing of this message
417 sub opsi_get_product_properties {
418     my ($msg, $msg_hash, $session_id) = @_;
419     my $header = @{$msg_hash->{'header'}}[0];
420     my $source = @{$msg_hash->{'source'}}[0];
421     my $target = @{$msg_hash->{'target'}}[0];
422     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
423     my $productId = @{$msg_hash->{'ProductId'}}[0];
424     my $hostId;
426     # build return message with twisted target and source
427     my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
429     # Get hostID if defined
430     if (defined @{$msg_hash->{'hostId'}}[0]){
431       $hostId = @{$msg_hash->{'hostId'}}[0];
432       &add_content2xml_hash($out_hash, "hostId", $hostId);
433     }
435     if (defined $forward_to_gosa) {
436       &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
437     }
438     &add_content2xml_hash($out_hash, "ProducId", "$productId");
440     # Load actions
441     my $callobj = {
442       method  => 'getPossibleProductActions_list',
443       params  => [ $productId ],
444       id  => 1,
445     };
446     my $res = $main::opsi_client->call($main::opsi_url, $callobj);
447     if (&main::check_opsi_res($res)){
448       foreach my $action (@{$res->result}){
449         &add_content2xml_hash($out_hash, "action", $action);
450       }
451     }
453     # Add place holder
454     &add_content2xml_hash($out_hash, "xxx", "");
456     # Move to XML string
457     my $xml_msg= &create_xml_string($out_hash);
459     # JSON Query
460     $callobj = {
461       method  => 'getProductProperties_hash',
462       params  => [ $productId ],
463       id  => 1,
464     };
466     $res = $main::opsi_client->call($main::opsi_url, $callobj);
468     if (&main::check_opsi_res($res)){
469         my $r= $res->result;
470         foreach my $key (keys %{$r}) {
471           my $item= "<item>";
472           my $value= $r->{$key};
473           if (UNIVERSAL::isa( $value, "ARRAY" )){
474             foreach my $subval (@{$value}){
475               $item.= "<$key>".xml_quote($subval)."</$key>";
476             }
477           } else {
478             $item.= "<$key>".xml_quote($value)."</$key>";
479           }
480           $item.= "</item>";
481           $xml_msg=~ s/<xxx><\/xxx>/$item<xxx><\/xxx>/;
482         }
483     }
486   $xml_msg=~ s/<xxx><\/xxx>//;
488   return ($xml_msg);
492 ## @method opsi_set_product_properties
493 # ???
494 # @param msg - STRING - xml message with tags ProductId, hostId, action and state
495 # @param msg_hash - HASHREF - message information parsed into a hash
496 # @param session_id - INTEGER - POE session id of the processing of this message
497 sub opsi_set_product_properties {
498     my ($msg, $msg_hash, $session_id) = @_;
499     my $header = @{$msg_hash->{'header'}}[0];
500     my $source = @{$msg_hash->{'source'}}[0];
501     my $target = @{$msg_hash->{'target'}}[0];
502     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
503     my $productId = @{$msg_hash->{'ProductId'}}[0];
504     my $hostId;
506     # build return message with twisted target and source
507     my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
508     &add_content2xml_hash($out_hash, "ProductId", $productId);
510     # Get hostID if defined
511     if (defined @{$msg_hash->{'hostId'}}[0]){
512       $hostId = @{$msg_hash->{'hostId'}}[0];
513       &add_content2xml_hash($out_hash, "hostId", $hostId);
514     }
516     # Set product states if requested
517     if (defined @{$msg_hash->{'action'}}[0]){
518       &_set_action($productId, @{$msg_hash->{'action'}}[0], $hostId);
519     }
520     if (defined @{$msg_hash->{'state'}}[0]){
521       &_set_state($productId, @{$msg_hash->{'state'}}[0], $hostId);
522     }
524     if (defined $forward_to_gosa) {
525         &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
526     }
528     # Find properties
529     foreach my $item (@{$msg_hash->{'item'}}){
530       # JSON Query
531       my $callobj;
533       if (defined $hostId){
534         $callobj = {
535           method  => 'setProductProperty',
536           params  => [ $productId, $item->{'name'}[0], $item->{'value'}[0], $hostId ],
537           id  => 1,
538         };
539       } else {
540         $callobj = {
541           method  => 'setProductProperty',
542           params  => [ $productId, $item->{'name'}[0], $item->{'value'}[0] ],
543           id  => 1,
544         };
545       }
547       my $res = $main::opsi_client->call($main::opsi_url, $callobj);
549       if (!&main::check_opsi_res($res)){
550         &main::daemon_log("ERROR: no communication failed while setting '".$item->{'name'}[0]."': ".$res->error_message, 1);
551         &add_content2xml_hash($out_hash, "error", $res->error_message);
552       }
554     }
556     # return message
557     return ( &create_xml_string($out_hash) );
561 ## @method opsi_get_client_hardware
562 # ???
563 # @param msg - STRING - xml message with tag hostId
564 # @param msg_hash - HASHREF - message information parsed into a hash
565 # @param session_id - INTEGER - POE session id of the processing of this message
566 sub opsi_get_client_hardware {
567     my ($msg, $msg_hash, $session_id) = @_;
568     my $header = @{$msg_hash->{'header'}}[0];
569     my $source = @{$msg_hash->{'source'}}[0];
570     my $target = @{$msg_hash->{'target'}}[0];
571     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
572     my $hostId = @{$msg_hash->{'hostId'}}[0];
574     # build return message with twisted target and source
575     my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
577     if (defined $forward_to_gosa) {
578       &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
579     }
580     &add_content2xml_hash($out_hash, "hostId", "$hostId");
581     &add_content2xml_hash($out_hash, "xxx", "");
582     my $xml_msg= &create_xml_string($out_hash);
584     # JSON Query
585     my $callobj = {
586       method  => 'getHardwareInformation_hash',
587       params  => [ $hostId ],
588       id  => 1,
589     };
591     my $res = $main::opsi_client->call($main::opsi_url, $callobj);
592     if (&main::check_opsi_res($res)){
593       my $result= $res->result;
594       foreach my $r (keys %{$result}){
595         my $item= "<item><id>".xml_quote($r)."</id>";
596         my $value= $result->{$r};
597         foreach my $sres (@{$value}){
599           foreach my $dres (keys %{$sres}){
600             if (defined $sres->{$dres}){
601               $item.= "<$dres>".xml_quote($sres->{$dres})."</$dres>";
602             }
603           }
605         }
606           $item.= "</item>";
607           $xml_msg=~ s%<xxx></xxx>%$item<xxx></xxx>%;
609       }
610     }
612     $xml_msg=~ s/<xxx><\/xxx>//;
614     return ( $xml_msg );
618 ## @method opsi_list_clients
619 # ???
620 # @param msg - STRING - xml message 
621 # @param msg_hash - HASHREF - message information parsed into a hash
622 # @param session_id - INTEGER - POE session id of the processing of this message
623 sub opsi_list_clients {
624     my ($msg, $msg_hash, $session_id) = @_;
625     my $header = @{$msg_hash->{'header'}}[0];
626     my $source = @{$msg_hash->{'source'}}[0];
627     my $target = @{$msg_hash->{'target'}}[0];
628     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
630     # build return message with twisted target and source
631     my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
633     if (defined $forward_to_gosa) {
634       &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
635     }
637     &add_content2xml_hash($out_hash, "xxx", "");
638     my $xml_msg= &create_xml_string($out_hash);
640     # JSON Query
641     my $callobj = {
642       method  => 'getClients_listOfHashes',
643       params  => [ ],
644       id  => 1,
645     };
647     my $res = $main::opsi_client->call($main::opsi_url, $callobj);
648     if (&main::check_opsi_res($res)){
650       foreach my $host (@{$res->result}){
651         my $item= "<item><name>".$host->{'hostId'}."</name>";
652         if (defined($host->{'description'})){
653           $item.= "<description>".xml_quote($host->{'description'})."</description>";
654         }
655         $item.= "</item>";
656         $xml_msg=~ s%<xxx></xxx>%$item<xxx></xxx>%;
657       }
659     }
661     $xml_msg=~ s/<xxx><\/xxx>//;
662     return ( $xml_msg );
666 ## @method opsi_get_client_software
667 # ???
668 # @param msg - STRING - xml message with tag hostId
669 # @param msg_hash - HASHREF - message information parsed into a hash
670 # @param session_id - INTEGER - POE session id of the processing of this message
671 sub opsi_get_client_software {
672     my ($msg, $msg_hash, $session_id) = @_;
673     my $header = @{$msg_hash->{'header'}}[0];
674     my $source = @{$msg_hash->{'source'}}[0];
675     my $target = @{$msg_hash->{'target'}}[0];
676     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
677     my $hostId = @{$msg_hash->{'hostId'}}[0];
679     # build return message with twisted target and source
680     my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
682     if (defined $forward_to_gosa) {
683       &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
684     }
685     &add_content2xml_hash($out_hash, "hostId", "$hostId");
686     &add_content2xml_hash($out_hash, "xxx", "");
687     my $xml_msg= &create_xml_string($out_hash);
689     # JSON Query
690     my $callobj = {
691       method  => 'getSoftwareInformation_hash',
692       params  => [ $hostId ],
693       id  => 1,
694     };
696     my $res = $main::opsi_client->call($main::opsi_url, $callobj);
697     if (&main::check_opsi_res($res)){
698       my $result= $res->result;
699     }
701     $xml_msg=~ s/<xxx><\/xxx>//;
703     return ( $xml_msg );
707 ## @method opsi_get_local_products
708 # ???
709 # @param msg - STRING - xml message with tag hostId
710 # @param msg_hash - HASHREF - message information parsed into a hash
711 # @param session_id - INTEGER - POE session id of the processing of this message
712 sub opsi_get_local_products {
713   my ($msg, $msg_hash, $session_id) = @_;
714   my $header = @{$msg_hash->{'header'}}[0];
715   my $source = @{$msg_hash->{'source'}}[0];
716   my $target = @{$msg_hash->{'target'}}[0];
717   my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
718   my $hostId;
720   # build return message with twisted target and source
721   my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
723   # Get hostID if defined
724   if (defined @{$msg_hash->{'hostId'}}[0]){
725     $hostId = @{$msg_hash->{'hostId'}}[0];
726     &add_content2xml_hash($out_hash, "hostId", $hostId);
727   }
729   if (defined $forward_to_gosa) {
730     &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
731   }
732   &add_content2xml_hash($out_hash, "xxx", "");
733   my $xml_msg= &create_xml_string($out_hash);
735   # For hosts, only return the products that are or get installed
736   my $callobj;
737   $callobj = {
738     method  => 'getLocalBootProductIds_list',
739     params  => [ ],
740     id  => 1,
741   };
743   my $res = $main::opsi_client->call($main::opsi_url, $callobj);
744   my %r = ();
745   for (@{$res->result}) { $r{$_} = 1 }
747   if (&main::check_opsi_res($res)){
749     if (defined $hostId){
750       $callobj = {
751         method  => 'getProductStates_hash',
752         params  => [ $hostId ],
753         id  => 1,
754       };
756       my $hres = $main::opsi_client->call($main::opsi_url, $callobj);
757       if (&main::check_opsi_res($hres)){
758         my $htmp= $hres->result->{$hostId};
760         # check state != not_installed or action == setup -> load and add
761         foreach my $product (@{$htmp}){
763           if (!defined ($r{$product->{'productId'}})){
764             next;
765           }
767           # Now we've a couple of hashes...
768           if ($product->{'installationStatus'} ne "not_installed" or
769               $product->{'actionRequest'} eq "setup"){
770             my $state= "<state>".$product->{'installationStatus'}."</state><action>".$product->{'actionRequest'}."</action>";
772             $callobj = {
773               method  => 'getProduct_hash',
774               params  => [ $product->{'productId'} ],
775               id  => 1,
776             };
778             my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
779             if (&main::check_opsi_res($sres)){
780               my $tres= $sres->result;
782               my $name= xml_quote($tres->{'name'});
783               my $r= $product->{'productId'};
784               my $description= xml_quote($tres->{'description'});
785               $name=~ s/\//\\\//;
786               $description=~ s/\//\\\//;
787               $xml_msg=~ s/<xxx><\/xxx>/<item><ProductId>$r<\/ProductId><name><\/name><description>$description<\/description><\/item>$state<xxx><\/xxx>/;
788             }
790           }
791         }
793       }
795     } else {
796       foreach my $r (@{$res->result}) {
797         $callobj = {
798           method  => 'getProduct_hash',
799           params  => [ $r ],
800           id  => 1,
801         };
803         my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
804         if (&main::check_opsi_res($sres)){
805           my $tres= $sres->result;
807           my $name= xml_quote($tres->{'name'});
808           my $description= xml_quote($tres->{'description'});
809           $name=~ s/\//\\\//;
810           $description=~ s/\//\\\//;
811           $xml_msg=~ s/<xxx><\/xxx>/<item><ProductId>$r<\/ProductId><name><\/name><description>$description<\/description><\/item><xxx><\/xxx>/;
812         }
814       }
816     }
817   }
819   $xml_msg=~ s/<xxx><\/xxx>//;
821   return ( $xml_msg );
825 ## @method opsi_del_client
826 # ???
827 # @param msg - STRING - xml message with tag hostId
828 # @param msg_hash - HASHREF - message information parsed into a hash
829 # @param session_id - INTEGER - POE session id of the processing of this message
830 sub opsi_del_client {
831     my ($msg, $msg_hash, $session_id) = @_;
832     my $header = @{$msg_hash->{'header'}}[0];
833     my $source = @{$msg_hash->{'source'}}[0];
834     my $target = @{$msg_hash->{'target'}}[0];
835     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
836     my $hostId = @{$msg_hash->{'hostId'}}[0];
838     # build return message with twisted target and source
839     my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
841     if (defined $forward_to_gosa) {
842       &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
843     }
844     &add_content2xml_hash($out_hash, "hostId", "$hostId");
846     # JSON Query
847     my $callobj = {
848       method  => 'deleteClient',
849       params  => [ $hostId ],
850       id  => 1,
851     };
853     my $res = $main::opsi_client->call($main::opsi_url, $callobj);
855     my $xml_msg= &create_xml_string($out_hash);
856     return ( $xml_msg );
860 ## @method opsi_install_client
861 # ???
862 # @param msg - STRING - xml message with tags hostId, macaddress
863 # @param msg_hash - HASHREF - message information parsed into a hash
864 # @param session_id - INTEGER - POE session id of the processing of this message
865 sub opsi_install_client {
866     my ($msg, $msg_hash, $session_id) = @_;
867     my $header = @{$msg_hash->{'header'}}[0];
868     my $source = @{$msg_hash->{'source'}}[0];
869     my $target = @{$msg_hash->{'target'}}[0];
870     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
871     my $hostId = @{$msg_hash->{'hostId'}}[0];
872     my $error = 0;
873     my @out_msg_l;
875     # If no macaddress is specified, raise error  
876     my $macaddress; 
877     if ((exists $msg_hash->{'macaddress'}) && 
878             ($msg_hash->{'macaddress'}[0] =~ /^([0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2})$/i)) {  
879         $macaddress = $1; 
880     } else { 
881         $error ++; 
882         my $out_msg = "<xml>". 
883             "<header>answer</header>". 
884             "<source>$main::server_address</source>". 
885             "<target>GOSA</target>". 
886             "<answer1>1</answer1>". 
887             "<error_string>no mac address specified in macaddres-tag</error_string>". 
888             "</xml>"; 
889         push(@out_msg_l, $out_msg);
890     } 
892     # Set parameters in opsi
893     if (not $error) {
894         # build return message with twisted target and source
895         my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
897         if (defined $forward_to_gosa) {
898             &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
899         }
900         &add_content2xml_hash($out_hash, "hostId", "$hostId");
902         # Load all products for this host with status != "not_installed" or actionRequest != "none"
903         if (defined $hostId){
904             my $callobj = {
905                 method  => 'getProductStates_hash',
906                 params  => [ $hostId ],
907                 id  => 1,
908             };
910             my $hres = $main::opsi_client->call($main::opsi_url, $callobj);
911             if (&main::check_opsi_res($hres)){
912                 my $htmp= $hres->result->{$hostId};
914                 # check state != not_installed or action == setup -> load and add
915                 foreach my $product (@{$htmp}){
916                     # Now we've a couple of hashes...
917                     if ($product->{'installationStatus'} ne "not_installed" or
918                             $product->{'actionRequest'} ne "none"){
920                         # Do an action request for all these -> "setup".
921                         $callobj = {
922                             method  => 'setProductActionRequest',
923                             params  => [ $product->{'productId'}, $hostId, "setup" ],
924                             id  => 1,
925                         };
926                         my $res = $main::opsi_client->call($main::opsi_url, $callobj);
927                         if (!&main::check_opsi_res($res)){
928                             &main::daemon_log("ERROR: cannot set product action request for $hostId!", 1);
929                         } else {
930                             &main::daemon_log("INFO: requesting 'setup' for '".$product->{'productId'}."' on $hostId", 1);
931                         }
933                     }
934                 }
935             }
936         }
938         push(@out_msg_l, &create_xml_string($out_hash));
939     }
941     # Build wakeup message for client
942     if (not $error) {
943         my $wakeup_hash = &create_xml_hash("trigger_wake", "GOSA", "KNOWN_SERVER");
944         &add_content2xml_hash($wakeup_hash, 'macAddress', $macaddress);
945         my $wakeup_msg = &create_xml_string($wakeup_hash);
946         push(@out_msg_l, $wakeup_msg);
948         # invoke trigger wake for this gosa-si-server
949         &main::server_server_com::trigger_wake($wakeup_msg, $wakeup_hash, $session_id);
950     }
953     return @out_msg_l;
957 ## @method _set_action
958 # ???
959 # @param product - STRING - ???
960 # @param action - STRING - ???
961 # @param hostId - STRING - ???
962 sub _set_action {
963   my $product= shift;
964   my $action = shift;
965   my $hostId = shift;
966   my $callobj;
968   $callobj = {
969     method  => 'setProductActionRequest',
970     params  => [ $product, $hostId, $action],
971     id  => 1,
972   };
974   $main::opsi_client->call($main::opsi_url, $callobj);
977 ## @method _set_state
978 # ???
979 # @param product - STRING - ???
980 # @param action - STRING - ???
981 # @param hostId - STRING - ???
982 sub _set_state {
983   my $product = shift;
984   my $hostId = shift;
985   my $action = shift;
986   my $callobj;
988   $callobj = {
989     method  => 'setProductState',
990     params  => [ $product, $hostId, $action ],
991     id  => 1,
992   };
994   $main::opsi_client->call($main::opsi_url, $callobj);
997 1;