Code

bugfix: opsi_del_product_from_client, correct and more detailed debug infos
[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", $main::server_address, $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   my ($sres_err, $sres_err_string) = &check_opsi_res($sres);
78   if ($sres_err){
79     &main::daemon_log("$session_id ERROR: cannot add product: ".$sres_err_string, 1);
80     &add_content2xml_hash($out_hash, "error", $sres_err_string);
81   }
82   
83   # return message
84   return ( &create_xml_string($out_hash) );
85 }
88 sub opsi_del_product_from_client {
89   my ($msg, $msg_hash, $session_id) = @_;
90   my $header = @{$msg_hash->{'header'}}[0];
91   my $source = @{$msg_hash->{'source'}}[0];
92   my $target = @{$msg_hash->{'target'}}[0];
93   my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
94   my ($hostId, $productId);
96   # build return message with twisted target and source
97   my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
98   if (defined $forward_to_gosa) {
99     &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
100   }
102   # Get hostID
103   $hostId = @{$msg_hash->{'hostId'}}[0];
104   &add_content2xml_hash($out_hash, "hostId", $hostId);
106   # Get productID
107   $productId = @{$msg_hash->{'productId'}}[0];
108   &add_content2xml_hash($out_hash, "productId", $productId);
111   #TODO: check the results for more than one entry which is currently installed
112   #$callobj = {
113   #    method  => 'getProductDependencies_listOfHashes',
114   #    params  => [ $productId ],
115   #    id  => 1, };
116   #
117   #my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
118   #my ($sres_err, $sres_err_string) = &check_opsi_res($sres);
119   #if ($sres_err){
120   #  &main::daemon_log("ERROR: cannot perform dependency check: ".$sres_err_string, 1);
121   #  &add_content2xml_hash($out_hash, "error", $sres_err_string);
122   #  return ( &create_xml_string($out_hash) );
123   #}
126   # Check for uninstall method
127   my $callobj = {
128       method  => 'getPossibleProductActions_list',
129       params  => [ $productId ],
130       id  => 1, };
131   my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
132   my ($sres_err, $sres_err_string) = &check_opsi_res($sres);
133   if ($sres_err){
134     &main::daemon_log("$session_id ERROR: cannot get product action list: ".$sres_err_string, 1);
135     &add_content2xml_hash($out_hash, "error", $sres_err_string);
136     return ( &create_xml_string($out_hash) );
137   }
138   my $uninst_possible= 0;
139   foreach my $r (@{$sres->result}) {
140     if ($r eq 'uninstall') {
141       $uninst_possible= 1;
142     }
143   }
144   if (!$uninst_possible){
145     &main::daemon_log("$session_id ERROR: cannot uninstall product '$productId', product do not has the action 'uninstall'", 1);
146     &add_content2xml_hash($out_hash, "error", "cannot uninstall product '$productId', product do not has the action 'uninstall'");
147     return ( &create_xml_string($out_hash) );
148   }
150   # Set product state to "none"
151   # Do an action request for all these -> "setup".
152   $callobj = {
153       method  => 'setProductActionRequest',
154       params  => [ $productId, $hostId, "none" ],
155       id  => 1, }; 
157 print STDERR Dumper($callobj);
159   my $res = $main::opsi_client->call($main::opsi_url, $callobj);
160   my ($res_err, $res_err_string) = &check_opsi_res($res);
161   if ($res_err){
162       &main::daemon_log("$session_id ERROR: cannot delete product: ".$res_err_string, 1);
163       &add_content2xml_hash($out_hash, "error", $res_err_string);
164       return ( &create_xml_string($out_hash) );
165   }
166   
167   # return message
168   return ( &create_xml_string($out_hash) );
172 sub opsi_add_client {
173   my ($msg, $msg_hash, $session_id) = @_;
174   my $header = @{$msg_hash->{'header'}}[0];
175   my $source = @{$msg_hash->{'source'}}[0];
176   my $target = @{$msg_hash->{'target'}}[0];
177   my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
178   my $hostId;
180   # build return message with twisted target and source
181   my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
182   if (defined $forward_to_gosa) {
183     &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
184   }
186   # Get hostID
187   $hostId = @{$msg_hash->{'hostId'}}[0];
188   &add_content2xml_hash($out_hash, "hostId", $hostId);
189   my $name= $hostId;
190   $name=~ s/^([^.]+).*$/$1/;
191   my $domain= $hostId;
192   $domain=~ s/^[^.]+\.(.*)$/$1/;
193   my ($description, $notes, $ip, $mac);
195   if (defined @{$msg_hash->{'description'}}[0]){
196     $description = @{$msg_hash->{'description'}}[0];
197   }
198   if (defined @{$msg_hash->{'notes'}}[0]){
199     $notes = @{$msg_hash->{'notes'}}[0];
200   }
201   if (defined @{$msg_hash->{'ip'}}[0]){
202     $ip = @{$msg_hash->{'ip'}}[0];
203   }
204   if (defined @{$msg_hash->{'macaddress'}}[0]){
205     $mac = @{$msg_hash->{'macaddress'}}[0];
206   }
207   
208   my $callobj;
209   $callobj = {
210     method  => 'createClient',
211     params  => [ $name, $domain, $description, $notes, $ip, $mac ],
212     id  => 1,
213   };
215   my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
216   my ($sres_err, $sres_err_string) = &check_opsi_res($sres);
217   if ($sres_err){
218     &main::daemon_log("$session_id ERROR: cannot create client: ".$sres_err_string, 1);
219     &add_content2xml_hash($out_hash, "error", $sres_err_string);
220   }
222   # return message
223   return ( &create_xml_string($out_hash) );
226     
227 sub opsi_modify_client {
228   my ($msg, $msg_hash, $session_id) = @_;
229   my $header = @{$msg_hash->{'header'}}[0];
230   my $source = @{$msg_hash->{'source'}}[0];
231   my $target = @{$msg_hash->{'target'}}[0];
232   my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
233   my $hostId;
235   # build return message with twisted target and source
236   my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
237   if (defined $forward_to_gosa) {
238     &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
239   }
241   # Get hostID
242   $hostId = @{$msg_hash->{'hostId'}}[0];
243   &add_content2xml_hash($out_hash, "hostId", $hostId);
244   my $name= $hostId;
245   $name=~ s/^([^.]+).*$/$1/;
246   my $domain= $hostId;
247   $domain=~ s/^[^.]+(.*)$/$1/;
248   my ($description, $notes, $ip, $mac);
250   my $callobj;
252   if (defined @{$msg_hash->{'description'}}[0]){
253     $description = @{$msg_hash->{'description'}}[0];
254     $callobj = {
255       method  => 'setHostDescription',
256       params  => [ $hostId, $description ],
257       id  => 1,
258     };
259     my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
260     my ($sres_err, $sres_err_string) = &check_opsi_res($sres);
261     if ($sres_err){
262       &main::daemon_log("ERROR: cannot set description: ".$sres_err_string, 1);
263       &add_content2xml_hash($out_hash, "error", $sres_err_string);
264       return ( &create_xml_string($out_hash) );
265     }
266   }
267   if (defined @{$msg_hash->{'notes'}}[0]){
268     $notes = @{$msg_hash->{'notes'}}[0];
269     $callobj = {
270       method  => 'setHostNotes',
271       params  => [ $hostId, $notes ],
272       id  => 1,
273     };
274     my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
275     my ($sres_err, $sres_err_string) = &check_opsi_res($sres);
276     if ($sres_err){
277       &main::daemon_log("ERROR: cannot set notes: ".$sres_err_string, 1);
278       &add_content2xml_hash($out_hash, "error", $sres_err_string);
279       return ( &create_xml_string($out_hash) );
280     }
281   }
282   if (defined @{$msg_hash->{'mac'}}[0]){
283     $mac = @{$msg_hash->{'mac'}}[0];
284     $callobj = {
285       method  => 'setMacAddress',
286       params  => [ $hostId, $mac ],
287       id  => 1,
288     };
289     my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
290     my ($sres_err, $sres_err_string) = &check_opsi_res($sres);
291     if ($sres_err){
292       &main::daemon_log("ERROR: cannot set mac address: ".$sres_err_string, 1);
293       &add_content2xml_hash($out_hash, "error", $sres_err_string);
294       return ( &create_xml_string($out_hash) );
295     }
296   }
297   
298   # return message
299   return ( &create_xml_string($out_hash) );
302     
303 ## @method opsi_get_netboot_products
304 # ???
305 # @param msg - STRING - xml message with tag hostId
306 # @param msg_hash - HASHREF - message information parsed into a hash
307 # @param session_id - INTEGER - POE session id of the processing of this message
308 sub opsi_get_netboot_products {
309   my ($msg, $msg_hash, $session_id) = @_;
310   my $header = @{$msg_hash->{'header'}}[0];
311   my $source = @{$msg_hash->{'source'}}[0];
312   my $target = @{$msg_hash->{'target'}}[0];
313   my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
314   my $hostId;
316   # build return message with twisted target and source
317   my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
318   if (defined $forward_to_gosa) {
319     &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
320   }
322   # Get hostID if defined
323   if (defined @{$msg_hash->{'hostId'}}[0]){
324     $hostId = @{$msg_hash->{'hostId'}}[0];
325     &add_content2xml_hash($out_hash, "hostId", $hostId);
326   }
328   &add_content2xml_hash($out_hash, "xxx", "");
329   my $xml_msg= &create_xml_string($out_hash);
331   # For hosts, only return the products that are or get installed
332   my $callobj;
333   $callobj = {
334     method  => 'getNetBootProductIds_list',
335     params  => [ ],
336     id  => 1,
337   };
339   my $res = $main::opsi_client->call($main::opsi_url, $callobj);
340   my %r = ();
341   for (@{$res->result}) { $r{$_} = 1 }
343   if (&check_opsi_res($res)){
345     if (defined $hostId){
346       $callobj = {
347         method  => 'getProductStates_hash',
348         params  => [ $hostId ],
349         id  => 1,
350       };
352       my $hres = $main::opsi_client->call($main::opsi_url, $callobj);
353       if (&check_opsi_res($hres)){
354         my $htmp= $hres->result->{$hostId};
356         # check state != not_installed or action == setup -> load and add
357         foreach my $product (@{$htmp}){
359           if (!defined ($r{$product->{'productId'}})){
360             next;
361           }
363           # Now we've a couple of hashes...
364           if ($product->{'installationStatus'} ne "not_installed" or
365               $product->{'actionRequest'} eq "setup"){
366             my $state= "<state>".$product->{'installationStatus'}."</state><action>".$product->{'actionRequest'}."</action>";
368             $callobj = {
369               method  => 'getProduct_hash',
370               params  => [ $product->{'productId'} ],
371               id  => 1,
372             };
374             my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
375             if (&check_opsi_res($sres)){
376               my $tres= $sres->result;
378               my $name= xml_quote($tres->{'name'});
379               my $r= $product->{'productId'};
380               my $description= xml_quote($tres->{'description'});
381               $name=~ s/\//\\\//;
382               $description=~ s/\//\\\//;
383               $xml_msg=~ s/<xxx><\/xxx>/<item><productId>$r<\/productId><name><\/name><description>$description<\/description><\/item>$state<xxx><\/xxx>/;
384             }
386           }
387         }
389       }
391     } else {
392       foreach my $r (@{$res->result}) {
393         $callobj = {
394           method  => 'getProduct_hash',
395           params  => [ $r ],
396           id  => 1,
397         };
399         my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
400         if (&check_opsi_res($sres)){
401           my $tres= $sres->result;
403           my $name= xml_quote($tres->{'name'});
404           my $description= xml_quote($tres->{'description'});
405           $name=~ s/\//\\\//;
406           $description=~ s/\//\\\//;
407           $xml_msg=~ s/<xxx><\/xxx>/<item><productId>$r<\/productId><name><\/name><description>$description<\/description><\/item><xxx><\/xxx>/;
408         }
410       }
412     }
413   }
415   $xml_msg=~ s/<xxx><\/xxx>//;
417   return ($xml_msg);
421 ## @method opsi_get_product_properties
422 # ???
423 # @param msg - STRING - xml message with tags ProductId and hostId
424 # @param msg_hash - HASHREF - message information parsed into a hash
425 # @param session_id - INTEGER - POE session id of the processing of this message
426 sub opsi_get_product_properties {
427     my ($msg, $msg_hash, $session_id) = @_;
428     my $header = @{$msg_hash->{'header'}}[0];
429     my $source = @{$msg_hash->{'source'}}[0];
430     my $target = @{$msg_hash->{'target'}}[0];
431     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
432     my $productId = @{$msg_hash->{'productId'}}[0];
433     my $hostId;
435     # build return message with twisted target and source
436     my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
438     # Get hostID if defined
439     if (defined @{$msg_hash->{'hostId'}}[0]){
440       $hostId = @{$msg_hash->{'hostId'}}[0];
441       &add_content2xml_hash($out_hash, "hostId", $hostId);
442     }
444     if (defined $forward_to_gosa) {
445       &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
446     }
447     &add_content2xml_hash($out_hash, "ProducId", "$productId");
449     # Load actions
450     my $callobj = {
451       method  => 'getPossibleProductActions_list',
452       params  => [ $productId ],
453       id  => 1,
454     };
455     my $res = $main::opsi_client->call($main::opsi_url, $callobj);
456     if (&check_opsi_res($res)){
457       foreach my $action (@{$res->result}){
458         &add_content2xml_hash($out_hash, "action", $action);
459       }
460     }
462     # Add place holder
463     &add_content2xml_hash($out_hash, "xxx", "");
465     # Move to XML string
466     my $xml_msg= &create_xml_string($out_hash);
468     # JSON Query
469     $callobj = {
470       method  => 'getProductProperties_hash',
471       params  => [ $productId ],
472       id  => 1,
473     };
475     $res = $main::opsi_client->call($main::opsi_url, $callobj);
477     if (&check_opsi_res($res)){
478         my $r= $res->result;
479         foreach my $key (keys %{$r}) {
480           my $item= "<item>";
481           my $value= $r->{$key};
482           if (UNIVERSAL::isa( $value, "ARRAY" )){
483             foreach my $subval (@{$value}){
484               $item.= "<$key>".xml_quote($subval)."</$key>";
485             }
486           } else {
487             $item.= "<$key>".xml_quote($value)."</$key>";
488           }
489           $item.= "</item>";
490           $xml_msg=~ s/<xxx><\/xxx>/$item<xxx><\/xxx>/;
491         }
492     }
495   $xml_msg=~ s/<xxx><\/xxx>//;
497   return ($xml_msg);
501 ## @method opsi_set_product_properties
502 # ???
503 # @param msg - STRING - xml message with tags ProductId, hostId, action and state
504 # @param msg_hash - HASHREF - message information parsed into a hash
505 # @param session_id - INTEGER - POE session id of the processing of this message
506 sub opsi_set_product_properties {
507     my ($msg, $msg_hash, $session_id) = @_;
508     my $header = @{$msg_hash->{'header'}}[0];
509     my $source = @{$msg_hash->{'source'}}[0];
510     my $target = @{$msg_hash->{'target'}}[0];
511     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
512     my $productId = @{$msg_hash->{'productId'}}[0];
513     my $hostId;
515     # build return message with twisted target and source
516     my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
517     &add_content2xml_hash($out_hash, "productId", $productId);
519     # Get hostID if defined
520     if (defined @{$msg_hash->{'hostId'}}[0]){
521       $hostId = @{$msg_hash->{'hostId'}}[0];
522       &add_content2xml_hash($out_hash, "hostId", $hostId);
523     }
525     # Set product states if requested
526     if (defined @{$msg_hash->{'action'}}[0]){
527       &_set_action($productId, @{$msg_hash->{'action'}}[0], $hostId);
528     }
529     if (defined @{$msg_hash->{'state'}}[0]){
530       &_set_state($productId, @{$msg_hash->{'state'}}[0], $hostId);
531     }
533     if (defined $forward_to_gosa) {
534         &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
535     }
537     # Find properties
538     foreach my $item (@{$msg_hash->{'item'}}){
539       # JSON Query
540       my $callobj;
542       if (defined $hostId){
543         $callobj = {
544           method  => 'setProductProperty',
545           params  => [ $productId, $item->{'name'}[0], $item->{'value'}[0], $hostId ],
546           id  => 1,
547         };
548       } else {
549         $callobj = {
550           method  => 'setProductProperty',
551           params  => [ $productId, $item->{'name'}[0], $item->{'value'}[0] ],
552           id  => 1,
553         };
554       }
556       my $res = $main::opsi_client->call($main::opsi_url, $callobj);
557       my ($res_err, $res_err_string) = &check_opsi_res($res);
558 # TODO : This error message sounds strange
559       if ($res_err){
560         &man::daemon_log("$session_id ERROR: no communication failed while setting '".$item->{'name'}[0]."': ".$res_err_string, 1);
561         &add_content2xml_hash($out_hash, "error", $res_err_string);
562       }
564     }
566     # return message
567     return ( &create_xml_string($out_hash) );
571 ## @method opsi_get_client_hardware
572 # ???
573 # @param msg - STRING - xml message with tag hostId
574 # @param msg_hash - HASHREF - message information parsed into a hash
575 # @param session_id - INTEGER - POE session id of the processing of this message
576 sub opsi_get_client_hardware {
577     my ($msg, $msg_hash, $session_id) = @_;
578     my $header = @{$msg_hash->{'header'}}[0];
579     my $source = @{$msg_hash->{'source'}}[0];
580     my $target = @{$msg_hash->{'target'}}[0];
581     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
582     my $hostId = @{$msg_hash->{'hostId'}}[0];
584     # build return message with twisted target and source
585     my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
587     if (defined $forward_to_gosa) {
588       &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
589     }
590     &add_content2xml_hash($out_hash, "hostId", "$hostId");
591     &add_content2xml_hash($out_hash, "xxx", "");
592     my $xml_msg= &create_xml_string($out_hash);
594     # JSON Query
595     my $callobj = {
596       method  => 'getHardwareInformation_hash',
597       params  => [ $hostId ],
598       id  => 1,
599     };
601     my $res = $main::opsi_client->call($main::opsi_url, $callobj);
602     if (&check_opsi_res($res)){
603       my $result= $res->result;
604       foreach my $r (keys %{$result}){
605         my $item= "<item><id>".xml_quote($r)."</id>";
606         my $value= $result->{$r};
607         foreach my $sres (@{$value}){
609           foreach my $dres (keys %{$sres}){
610             if (defined $sres->{$dres}){
611               $item.= "<$dres>".xml_quote($sres->{$dres})."</$dres>";
612             }
613           }
615         }
616           $item.= "</item>";
617           $xml_msg=~ s%<xxx></xxx>%$item<xxx></xxx>%;
619       }
620     }
622     $xml_msg=~ s/<xxx><\/xxx>//;
624     return ( $xml_msg );
628 ## @method opsi_list_clients
629 # ???
630 # @param msg - STRING - xml message 
631 # @param msg_hash - HASHREF - message information parsed into a hash
632 # @param session_id - INTEGER - POE session id of the processing of this message
633 sub opsi_list_clients {
634     my ($msg, $msg_hash, $session_id) = @_;
635     my $header = @{$msg_hash->{'header'}}[0];
636     my $source = @{$msg_hash->{'source'}}[0];
637     my $target = @{$msg_hash->{'target'}}[0];
638     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
640     # build return message with twisted target and source
641     my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
643     if (defined $forward_to_gosa) {
644       &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
645     }
647     &add_content2xml_hash($out_hash, "xxx", "");
648     my $xml_msg= &create_xml_string($out_hash);
650     # JSON Query
651     my $callobj = {
652       method  => 'getClients_listOfHashes',
653       params  => [ ],
654       id  => 1,
655     };
657     my $res = $main::opsi_client->call($main::opsi_url, $callobj);
658     if (&check_opsi_res($res)){
660       foreach my $host (@{$res->result}){
661         my $item= "<item><name>".$host->{'hostId'}."</name>";
662         if (defined($host->{'description'})){
663           $item.= "<description>".xml_quote($host->{'description'})."</description>";
664         }
665         $item.= "</item>";
666         $xml_msg=~ s%<xxx></xxx>%$item<xxx></xxx>%;
667       }
669     }
671     $xml_msg=~ s/<xxx><\/xxx>//;
672     return ( $xml_msg );
676 ## @method opsi_get_client_software
677 # ???
678 # @param msg - STRING - xml message with tag hostId
679 # @param msg_hash - HASHREF - message information parsed into a hash
680 # @param session_id - INTEGER - POE session id of the processing of this message
681 sub opsi_get_client_software {
682     my ($msg, $msg_hash, $session_id) = @_;
683     my $header = @{$msg_hash->{'header'}}[0];
684     my $source = @{$msg_hash->{'source'}}[0];
685     my $target = @{$msg_hash->{'target'}}[0];
686     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
687     my $hostId = @{$msg_hash->{'hostId'}}[0];
689     # build return message with twisted target and source
690     my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
692     if (defined $forward_to_gosa) {
693       &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
694     }
695     &add_content2xml_hash($out_hash, "hostId", "$hostId");
696     &add_content2xml_hash($out_hash, "xxx", "");
697     my $xml_msg= &create_xml_string($out_hash);
699     # JSON Query
700     my $callobj = {
701       method  => 'getSoftwareInformation_hash',
702       params  => [ $hostId ],
703       id  => 1,
704     };
706     my $res = $main::opsi_client->call($main::opsi_url, $callobj);
707     if (&check_opsi_res($res)){
708       my $result= $res->result;
709     }
711     $xml_msg=~ s/<xxx><\/xxx>//;
713     return ( $xml_msg );
717 ## @method opsi_get_local_products
718 # ???
719 # @param msg - STRING - xml message with tag hostId
720 # @param msg_hash - HASHREF - message information parsed into a hash
721 # @param session_id - INTEGER - POE session id of the processing of this message
722 sub opsi_get_local_products {
723   my ($msg, $msg_hash, $session_id) = @_;
724   my $header = @{$msg_hash->{'header'}}[0];
725   my $source = @{$msg_hash->{'source'}}[0];
726   my $target = @{$msg_hash->{'target'}}[0];
727   my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
728   my $hostId;
730   # build return message with twisted target and source
731   my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
733   # Get hostID if defined
734   if (defined @{$msg_hash->{'hostId'}}[0]){
735     $hostId = @{$msg_hash->{'hostId'}}[0];
736     &add_content2xml_hash($out_hash, "hostId", $hostId);
737   }
739   if (defined $forward_to_gosa) {
740     &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
741   }
742   &add_content2xml_hash($out_hash, "xxx", "");
743   my $xml_msg= &create_xml_string($out_hash);
745   # For hosts, only return the products that are or get installed
746   my $callobj;
747   $callobj = {
748     method  => 'getLocalBootProductIds_list',
749     params  => [ ],
750     id  => 1,
751   };
753   my $res = $main::opsi_client->call($main::opsi_url, $callobj);
754   my %r = ();
755   for (@{$res->result}) { $r{$_} = 1 }
757   if (&check_opsi_res($res)){
759     if (defined $hostId){
760       $callobj = {
761         method  => 'getProductStates_hash',
762         params  => [ $hostId ],
763         id  => 1,
764       };
766       my $hres = $main::opsi_client->call($main::opsi_url, $callobj);
767       if (&check_opsi_res($hres)){
768         my $htmp= $hres->result->{$hostId};
770         # check state != not_installed or action == setup -> load and add
771         foreach my $product (@{$htmp}){
773           if (!defined ($r{$product->{'productId'}})){
774             next;
775           }
777           # Now we've a couple of hashes...
778           if ($product->{'installationStatus'} ne "not_installed" or
779               $product->{'actionRequest'} eq "setup"){
780             my $state= "<state>".$product->{'installationStatus'}."</state><action>".$product->{'actionRequest'}."</action>";
782             $callobj = {
783               method  => 'getProduct_hash',
784               params  => [ $product->{'productId'} ],
785               id  => 1,
786             };
788             my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
789             if (&check_opsi_res($sres)){
790               my $tres= $sres->result;
792               my $name= xml_quote($tres->{'name'});
793               my $r= $product->{'productId'};
794               my $description= xml_quote($tres->{'description'});
795               $name=~ s/\//\\\//;
796               $description=~ s/\//\\\//;
797               $xml_msg=~ s/<xxx><\/xxx>/<item><productId>$r<\/productId><name><\/name><description>$description<\/description><\/item>$state<xxx><\/xxx>/;
798             }
800           }
801         }
803       }
805     } else {
806       foreach my $r (@{$res->result}) {
807         $callobj = {
808           method  => 'getProduct_hash',
809           params  => [ $r ],
810           id  => 1,
811         };
813         my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
814         if (&check_opsi_res($sres)){
815           my $tres= $sres->result;
817           my $name= xml_quote($tres->{'name'});
818           my $description= xml_quote($tres->{'description'});
819           $name=~ s/\//\\\//;
820           $description=~ s/\//\\\//;
821           $xml_msg=~ s/<xxx><\/xxx>/<item><productId>$r<\/productId><name><\/name><description>$description<\/description><\/item><xxx><\/xxx>/;
822         }
824       }
826     }
827   }
829   $xml_msg=~ s/<xxx><\/xxx>//;
831   return ( $xml_msg );
835 ## @method opsi_del_client
836 # ???
837 # @param msg - STRING - xml message with tag hostId
838 # @param msg_hash - HASHREF - message information parsed into a hash
839 # @param session_id - INTEGER - POE session id of the processing of this message
840 sub opsi_del_client {
841     my ($msg, $msg_hash, $session_id) = @_;
842     my $header = @{$msg_hash->{'header'}}[0];
843     my $source = @{$msg_hash->{'source'}}[0];
844     my $target = @{$msg_hash->{'target'}}[0];
845     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
846     my $hostId = @{$msg_hash->{'hostId'}}[0];
848     # build return message with twisted target and source
849     my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
851     if (defined $forward_to_gosa) {
852       &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
853     }
854     &add_content2xml_hash($out_hash, "hostId", "$hostId");
856     # JSON Query
857     my $callobj = {
858       method  => 'deleteClient',
859       params  => [ $hostId ],
860       id  => 1,
861     };
863     my $res = $main::opsi_client->call($main::opsi_url, $callobj);
865     my $xml_msg= &create_xml_string($out_hash);
866     return ( $xml_msg );
870 ## @method opsi_install_client
871 # ???
872 # @param msg - STRING - xml message with tags hostId, macaddress
873 # @param msg_hash - HASHREF - message information parsed into a hash
874 # @param session_id - INTEGER - POE session id of the processing of this message
875 sub opsi_install_client {
876     my ($msg, $msg_hash, $session_id) = @_;
877     my $header = @{$msg_hash->{'header'}}[0];
878     my $source = @{$msg_hash->{'source'}}[0];
879     my $target = @{$msg_hash->{'target'}}[0];
880     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
881     my $hostId = @{$msg_hash->{'hostId'}}[0];
882     my $error = 0;
883     my @out_msg_l;
885     # If no macaddress is specified, raise error  
886     my $macaddress; 
887     if ((exists $msg_hash->{'macaddress'}) && 
888             ($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)) {  
889         $macaddress = $1; 
890     } else { 
891         $error ++; 
892         my $out_msg = "<xml>". 
893             "<header>answer</header>". 
894             "<source>$main::server_address</source>". 
895             "<target>GOSA</target>". 
896             "<answer1>1</answer1>". 
897             "<error_string>no mac address specified in macaddres-tag</error_string>". 
898             "</xml>"; 
899         push(@out_msg_l, $out_msg);
900     } 
902     # Set parameters in opsi
903     if (not $error) {
904         # build return message with twisted target and source
905         my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
907         if (defined $forward_to_gosa) {
908             &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
909         }
910         &add_content2xml_hash($out_hash, "hostId", "$hostId");
912         # Load all products for this host with status != "not_installed" or actionRequest != "none"
913         if (defined $hostId){
914             my $callobj = {
915                 method  => 'getProductStates_hash',
916                 params  => [ $hostId ],
917                 id  => 1,
918             };
920             my $hres = $main::opsi_client->call($main::opsi_url, $callobj);
921             if (&check_opsi_res($hres)){
922                 my $htmp= $hres->result->{$hostId};
924                 # check state != not_installed or action == setup -> load and add
925                 foreach my $product (@{$htmp}){
926                     # Now we've a couple of hashes...
927                     if ($product->{'installationStatus'} ne "not_installed" or
928                             $product->{'actionRequest'} ne "none"){
930                         # Do an action request for all these -> "setup".
931                         $callobj = {
932                             method  => 'setProductActionRequest',
933                             params  => [ $product->{'productId'}, $hostId, "setup" ],
934                             id  => 1,
935                         };
936                         my $res = $main::opsi_client->call($main::opsi_url, $callobj);
937                         if (!&check_opsi_res($res)){
938                             &main::daemon_log("ERROR: cannot set product action request for $hostId!", 1);
939                         } else {
940                             &main::daemon_log("INFO: requesting 'setup' for '".$product->{'productId'}."' on $hostId", 1);
941                         }
943                     }
944                 }
945             }
946         }
948         push(@out_msg_l, &create_xml_string($out_hash));
949     }
951     # Build wakeup message for client
952     if (not $error) {
953         my $wakeup_hash = &create_xml_hash("trigger_wake", "GOSA", "KNOWN_SERVER");
954         &add_content2xml_hash($wakeup_hash, 'macAddress', $macaddress);
955         my $wakeup_msg = &create_xml_string($wakeup_hash);
956         push(@out_msg_l, $wakeup_msg);
958         # invoke trigger wake for this gosa-si-server
959         &main::server_server_com::trigger_wake($wakeup_msg, $wakeup_hash, $session_id);
960     }
963     return @out_msg_l;
967 ## @method _set_action
968 # ???
969 # @param product - STRING - ???
970 # @param action - STRING - ???
971 # @param hostId - STRING - ???
972 sub _set_action {
973   my $product= shift;
974   my $action = shift;
975   my $hostId = shift;
976   my $callobj;
978   $callobj = {
979     method  => 'setProductActionRequest',
980     params  => [ $product, $hostId, $action],
981     id  => 1,
982   };
984   $main::opsi_client->call($main::opsi_url, $callobj);
987 ## @method _set_state
988 # ???
989 # @param product - STRING - ???
990 # @param action - STRING - ???
991 # @param hostId - STRING - ???
992 sub _set_state {
993   my $product = shift;
994   my $hostId = shift;
995   my $action = shift;
996   my $callobj;
998   $callobj = {
999     method  => 'setProductState',
1000     params  => [ $product, $hostId, $action ],
1001     id  => 1,
1002   };
1004   $main::opsi_client->call($main::opsi_url, $callobj);
1007 1;