Code

bugfix: opsi_add_product_to_client, callobj with correct param sequence
[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   
132   my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
133   my ($sres_err, $sres_err_string) = &check_opsi_res($sres);
134   if ($sres_err){
135     &main::daemon_log("$session_id ERROR: cannot get product action list: ".$sres_err_string, 1);
136     &add_content2xml_hash($out_hash, "error", $sres_err_string);
137     return ( &create_xml_string($out_hash) );
138   }
139   my $uninst_possible= 0;
140   foreach my $r (@{$sres->result}) {
141     if ($r eq 'uninstall') {
142       $uninst_possible= 1;
143     }
144   }
145   if (!$uninst_possible){
146     &main::daemon_log("$session_id ERROR: cannot uninstall product", 1);
147     &add_content2xml_hash($out_hash, "error", "product is not uninstallable");
148     return ( &create_xml_string($out_hash) );
149   }
151   # Set product state to "none"
152   # Do an action request for all these -> "setup".
153   $callobj = {
154       method  => 'setProductActionRequest',
155       params  => [ $productId, $hostId, "none" ],
156       id  => 1, }; 
158   $sres = $main::opsi_client->call($main::opsi_url, $callobj);
159   my ($sres_err, $sres_err_string) = &check_opsi_res($sres);
160   if ($sres_err){
161       &main::daemon_log("$session_id ERROR: cannot delete product: ".$sres_err_string, 1);
162       &add_content2xml_hash($out_hash, "error", $sres_err_string);
163       return ( &create_xml_string($out_hash) );
164   }
165   
166   # return message
167   return ( &create_xml_string($out_hash) );
171 sub opsi_add_client {
172   my ($msg, $msg_hash, $session_id) = @_;
173   my $header = @{$msg_hash->{'header'}}[0];
174   my $source = @{$msg_hash->{'source'}}[0];
175   my $target = @{$msg_hash->{'target'}}[0];
176   my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
177   my $hostId;
179   # build return message with twisted target and source
180   my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
181   if (defined $forward_to_gosa) {
182     &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
183   }
185   # Get hostID
186   $hostId = @{$msg_hash->{'hostId'}}[0];
187   &add_content2xml_hash($out_hash, "hostId", $hostId);
188   my $name= $hostId;
189   $name=~ s/^([^.]+).*$/$1/;
190   my $domain= $hostId;
191   $domain=~ s/^[^.]+\.(.*)$/$1/;
192   my ($description, $notes, $ip, $mac);
194   if (defined @{$msg_hash->{'description'}}[0]){
195     $description = @{$msg_hash->{'description'}}[0];
196   }
197   if (defined @{$msg_hash->{'notes'}}[0]){
198     $notes = @{$msg_hash->{'notes'}}[0];
199   }
200   if (defined @{$msg_hash->{'ip'}}[0]){
201     $ip = @{$msg_hash->{'ip'}}[0];
202   }
203   if (defined @{$msg_hash->{'macaddress'}}[0]){
204     $mac = @{$msg_hash->{'macaddress'}}[0];
205   }
206   
207   my $callobj;
208   $callobj = {
209     method  => 'createClient',
210     params  => [ $name, $domain, $description, $notes, $ip, $mac ],
211     id  => 1,
212   };
214   my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
215   my ($sres_err, $sres_err_string) = &check_opsi_res($sres);
216   if ($sres_err){
217     &main::daemon_log("$session_id ERROR: cannot create client: ".$sres_err_string, 1);
218     &add_content2xml_hash($out_hash, "error", $sres_err_string);
219   }
221   # return message
222   return ( &create_xml_string($out_hash) );
225     
226 sub opsi_modify_client {
227   my ($msg, $msg_hash, $session_id) = @_;
228   my $header = @{$msg_hash->{'header'}}[0];
229   my $source = @{$msg_hash->{'source'}}[0];
230   my $target = @{$msg_hash->{'target'}}[0];
231   my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
232   my $hostId;
234   # build return message with twisted target and source
235   my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
236   if (defined $forward_to_gosa) {
237     &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
238   }
240   # Get hostID
241   $hostId = @{$msg_hash->{'hostId'}}[0];
242   &add_content2xml_hash($out_hash, "hostId", $hostId);
243   my $name= $hostId;
244   $name=~ s/^([^.]+).*$/$1/;
245   my $domain= $hostId;
246   $domain=~ s/^[^.]+(.*)$/$1/;
247   my ($description, $notes, $ip, $mac);
249   my $callobj;
251   if (defined @{$msg_hash->{'description'}}[0]){
252     $description = @{$msg_hash->{'description'}}[0];
253     $callobj = {
254       method  => 'setHostDescription',
255       params  => [ $hostId, $description ],
256       id  => 1,
257     };
258     my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
259     my ($sres_err, $sres_err_string) = &check_opsi_res($sres);
260     if ($sres_err){
261       &main::daemon_log("ERROR: cannot set description: ".$sres_err_string, 1);
262       &add_content2xml_hash($out_hash, "error", $sres_err_string);
263       return ( &create_xml_string($out_hash) );
264     }
265   }
266   if (defined @{$msg_hash->{'notes'}}[0]){
267     $notes = @{$msg_hash->{'notes'}}[0];
268     $callobj = {
269       method  => 'setHostNotes',
270       params  => [ $hostId, $notes ],
271       id  => 1,
272     };
273     my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
274     my ($sres_err, $sres_err_string) = &check_opsi_res($sres);
275     if ($sres_err){
276       &main::daemon_log("ERROR: cannot set notes: ".$sres_err_string, 1);
277       &add_content2xml_hash($out_hash, "error", $sres_err_string);
278       return ( &create_xml_string($out_hash) );
279     }
280   }
281   if (defined @{$msg_hash->{'mac'}}[0]){
282     $mac = @{$msg_hash->{'mac'}}[0];
283     $callobj = {
284       method  => 'setMacAddress',
285       params  => [ $hostId, $mac ],
286       id  => 1,
287     };
288     my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
289     my ($sres_err, $sres_err_string) = &check_opsi_res($sres);
290     if ($sres_err){
291       &main::daemon_log("ERROR: cannot set mac address: ".$sres_err_string, 1);
292       &add_content2xml_hash($out_hash, "error", $sres_err_string);
293       return ( &create_xml_string($out_hash) );
294     }
295   }
296   
297   # return message
298   return ( &create_xml_string($out_hash) );
301     
302 ## @method opsi_get_netboot_products
303 # ???
304 # @param msg - STRING - xml message with tag hostId
305 # @param msg_hash - HASHREF - message information parsed into a hash
306 # @param session_id - INTEGER - POE session id of the processing of this message
307 sub opsi_get_netboot_products {
308   my ($msg, $msg_hash, $session_id) = @_;
309   my $header = @{$msg_hash->{'header'}}[0];
310   my $source = @{$msg_hash->{'source'}}[0];
311   my $target = @{$msg_hash->{'target'}}[0];
312   my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
313   my $hostId;
315   # build return message with twisted target and source
316   my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
317   if (defined $forward_to_gosa) {
318     &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
319   }
321   # Get hostID if defined
322   if (defined @{$msg_hash->{'hostId'}}[0]){
323     $hostId = @{$msg_hash->{'hostId'}}[0];
324     &add_content2xml_hash($out_hash, "hostId", $hostId);
325   }
327   &add_content2xml_hash($out_hash, "xxx", "");
328   my $xml_msg= &create_xml_string($out_hash);
330   # For hosts, only return the products that are or get installed
331   my $callobj;
332   $callobj = {
333     method  => 'getNetBootProductIds_list',
334     params  => [ ],
335     id  => 1,
336   };
338   my $res = $main::opsi_client->call($main::opsi_url, $callobj);
339   my %r = ();
340   for (@{$res->result}) { $r{$_} = 1 }
342   if (&check_opsi_res($res)){
344     if (defined $hostId){
345       $callobj = {
346         method  => 'getProductStates_hash',
347         params  => [ $hostId ],
348         id  => 1,
349       };
351       my $hres = $main::opsi_client->call($main::opsi_url, $callobj);
352       if (&check_opsi_res($hres)){
353         my $htmp= $hres->result->{$hostId};
355         # check state != not_installed or action == setup -> load and add
356         foreach my $product (@{$htmp}){
358           if (!defined ($r{$product->{'productId'}})){
359             next;
360           }
362           # Now we've a couple of hashes...
363           if ($product->{'installationStatus'} ne "not_installed" or
364               $product->{'actionRequest'} eq "setup"){
365             my $state= "<state>".$product->{'installationStatus'}."</state><action>".$product->{'actionRequest'}."</action>";
367             $callobj = {
368               method  => 'getProduct_hash',
369               params  => [ $product->{'productId'} ],
370               id  => 1,
371             };
373             my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
374             if (&check_opsi_res($sres)){
375               my $tres= $sres->result;
377               my $name= xml_quote($tres->{'name'});
378               my $r= $product->{'productId'};
379               my $description= xml_quote($tres->{'description'});
380               $name=~ s/\//\\\//;
381               $description=~ s/\//\\\//;
382               $xml_msg=~ s/<xxx><\/xxx>/<item><productId>$r<\/productId><name><\/name><description>$description<\/description><\/item>$state<xxx><\/xxx>/;
383             }
385           }
386         }
388       }
390     } else {
391       foreach my $r (@{$res->result}) {
392         $callobj = {
393           method  => 'getProduct_hash',
394           params  => [ $r ],
395           id  => 1,
396         };
398         my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
399         if (&check_opsi_res($sres)){
400           my $tres= $sres->result;
402           my $name= xml_quote($tres->{'name'});
403           my $description= xml_quote($tres->{'description'});
404           $name=~ s/\//\\\//;
405           $description=~ s/\//\\\//;
406           $xml_msg=~ s/<xxx><\/xxx>/<item><productId>$r<\/productId><name><\/name><description>$description<\/description><\/item><xxx><\/xxx>/;
407         }
409       }
411     }
412   }
414   $xml_msg=~ s/<xxx><\/xxx>//;
416   return ($xml_msg);
420 ## @method opsi_get_product_properties
421 # ???
422 # @param msg - STRING - xml message with tags ProductId and hostId
423 # @param msg_hash - HASHREF - message information parsed into a hash
424 # @param session_id - INTEGER - POE session id of the processing of this message
425 sub opsi_get_product_properties {
426     my ($msg, $msg_hash, $session_id) = @_;
427     my $header = @{$msg_hash->{'header'}}[0];
428     my $source = @{$msg_hash->{'source'}}[0];
429     my $target = @{$msg_hash->{'target'}}[0];
430     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
431     my $productId = @{$msg_hash->{'productId'}}[0];
432     my $hostId;
434     # build return message with twisted target and source
435     my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
437     # Get hostID if defined
438     if (defined @{$msg_hash->{'hostId'}}[0]){
439       $hostId = @{$msg_hash->{'hostId'}}[0];
440       &add_content2xml_hash($out_hash, "hostId", $hostId);
441     }
443     if (defined $forward_to_gosa) {
444       &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
445     }
446     &add_content2xml_hash($out_hash, "ProducId", "$productId");
448     # Load actions
449     my $callobj = {
450       method  => 'getPossibleProductActions_list',
451       params  => [ $productId ],
452       id  => 1,
453     };
454     my $res = $main::opsi_client->call($main::opsi_url, $callobj);
455     if (&check_opsi_res($res)){
456       foreach my $action (@{$res->result}){
457         &add_content2xml_hash($out_hash, "action", $action);
458       }
459     }
461     # Add place holder
462     &add_content2xml_hash($out_hash, "xxx", "");
464     # Move to XML string
465     my $xml_msg= &create_xml_string($out_hash);
467     # JSON Query
468     $callobj = {
469       method  => 'getProductProperties_hash',
470       params  => [ $productId ],
471       id  => 1,
472     };
474     $res = $main::opsi_client->call($main::opsi_url, $callobj);
476     if (&check_opsi_res($res)){
477         my $r= $res->result;
478         foreach my $key (keys %{$r}) {
479           my $item= "<item>";
480           my $value= $r->{$key};
481           if (UNIVERSAL::isa( $value, "ARRAY" )){
482             foreach my $subval (@{$value}){
483               $item.= "<$key>".xml_quote($subval)."</$key>";
484             }
485           } else {
486             $item.= "<$key>".xml_quote($value)."</$key>";
487           }
488           $item.= "</item>";
489           $xml_msg=~ s/<xxx><\/xxx>/$item<xxx><\/xxx>/;
490         }
491     }
494   $xml_msg=~ s/<xxx><\/xxx>//;
496   return ($xml_msg);
500 ## @method opsi_set_product_properties
501 # ???
502 # @param msg - STRING - xml message with tags ProductId, hostId, action and state
503 # @param msg_hash - HASHREF - message information parsed into a hash
504 # @param session_id - INTEGER - POE session id of the processing of this message
505 sub opsi_set_product_properties {
506     my ($msg, $msg_hash, $session_id) = @_;
507     my $header = @{$msg_hash->{'header'}}[0];
508     my $source = @{$msg_hash->{'source'}}[0];
509     my $target = @{$msg_hash->{'target'}}[0];
510     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
511     my $productId = @{$msg_hash->{'productId'}}[0];
512     my $hostId;
514     # build return message with twisted target and source
515     my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
516     &add_content2xml_hash($out_hash, "productId", $productId);
518     # Get hostID if defined
519     if (defined @{$msg_hash->{'hostId'}}[0]){
520       $hostId = @{$msg_hash->{'hostId'}}[0];
521       &add_content2xml_hash($out_hash, "hostId", $hostId);
522     }
524     # Set product states if requested
525     if (defined @{$msg_hash->{'action'}}[0]){
526       &_set_action($productId, @{$msg_hash->{'action'}}[0], $hostId);
527     }
528     if (defined @{$msg_hash->{'state'}}[0]){
529       &_set_state($productId, @{$msg_hash->{'state'}}[0], $hostId);
530     }
532     if (defined $forward_to_gosa) {
533         &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
534     }
536     # Find properties
537     foreach my $item (@{$msg_hash->{'item'}}){
538       # JSON Query
539       my $callobj;
541       if (defined $hostId){
542         $callobj = {
543           method  => 'setProductProperty',
544           params  => [ $productId, $item->{'name'}[0], $item->{'value'}[0], $hostId ],
545           id  => 1,
546         };
547       } else {
548         $callobj = {
549           method  => 'setProductProperty',
550           params  => [ $productId, $item->{'name'}[0], $item->{'value'}[0] ],
551           id  => 1,
552         };
553       }
555       my $res = $main::opsi_client->call($main::opsi_url, $callobj);
556       my ($res_err, $res_err_string) = &check_opsi_res($res);
557 # TODO : This error message sounds strange
558       if ($res_err){
559         &man::daemon_log("$session_id ERROR: no communication failed while setting '".$item->{'name'}[0]."': ".$res_err_string, 1);
560         &add_content2xml_hash($out_hash, "error", $res_err_string);
561       }
563     }
565     # return message
566     return ( &create_xml_string($out_hash) );
570 ## @method opsi_get_client_hardware
571 # ???
572 # @param msg - STRING - xml message with tag hostId
573 # @param msg_hash - HASHREF - message information parsed into a hash
574 # @param session_id - INTEGER - POE session id of the processing of this message
575 sub opsi_get_client_hardware {
576     my ($msg, $msg_hash, $session_id) = @_;
577     my $header = @{$msg_hash->{'header'}}[0];
578     my $source = @{$msg_hash->{'source'}}[0];
579     my $target = @{$msg_hash->{'target'}}[0];
580     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
581     my $hostId = @{$msg_hash->{'hostId'}}[0];
583     # build return message with twisted target and source
584     my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
586     if (defined $forward_to_gosa) {
587       &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
588     }
589     &add_content2xml_hash($out_hash, "hostId", "$hostId");
590     &add_content2xml_hash($out_hash, "xxx", "");
591     my $xml_msg= &create_xml_string($out_hash);
593     # JSON Query
594     my $callobj = {
595       method  => 'getHardwareInformation_hash',
596       params  => [ $hostId ],
597       id  => 1,
598     };
600     my $res = $main::opsi_client->call($main::opsi_url, $callobj);
601     if (&check_opsi_res($res)){
602       my $result= $res->result;
603       foreach my $r (keys %{$result}){
604         my $item= "<item><id>".xml_quote($r)."</id>";
605         my $value= $result->{$r};
606         foreach my $sres (@{$value}){
608           foreach my $dres (keys %{$sres}){
609             if (defined $sres->{$dres}){
610               $item.= "<$dres>".xml_quote($sres->{$dres})."</$dres>";
611             }
612           }
614         }
615           $item.= "</item>";
616           $xml_msg=~ s%<xxx></xxx>%$item<xxx></xxx>%;
618       }
619     }
621     $xml_msg=~ s/<xxx><\/xxx>//;
623     return ( $xml_msg );
627 ## @method opsi_list_clients
628 # ???
629 # @param msg - STRING - xml message 
630 # @param msg_hash - HASHREF - message information parsed into a hash
631 # @param session_id - INTEGER - POE session id of the processing of this message
632 sub opsi_list_clients {
633     my ($msg, $msg_hash, $session_id) = @_;
634     my $header = @{$msg_hash->{'header'}}[0];
635     my $source = @{$msg_hash->{'source'}}[0];
636     my $target = @{$msg_hash->{'target'}}[0];
637     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
639     # build return message with twisted target and source
640     my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
642     if (defined $forward_to_gosa) {
643       &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
644     }
646     &add_content2xml_hash($out_hash, "xxx", "");
647     my $xml_msg= &create_xml_string($out_hash);
649     # JSON Query
650     my $callobj = {
651       method  => 'getClients_listOfHashes',
652       params  => [ ],
653       id  => 1,
654     };
656     my $res = $main::opsi_client->call($main::opsi_url, $callobj);
657     if (&check_opsi_res($res)){
659       foreach my $host (@{$res->result}){
660         my $item= "<item><name>".$host->{'hostId'}."</name>";
661         if (defined($host->{'description'})){
662           $item.= "<description>".xml_quote($host->{'description'})."</description>";
663         }
664         $item.= "</item>";
665         $xml_msg=~ s%<xxx></xxx>%$item<xxx></xxx>%;
666       }
668     }
670     $xml_msg=~ s/<xxx><\/xxx>//;
671     return ( $xml_msg );
675 ## @method opsi_get_client_software
676 # ???
677 # @param msg - STRING - xml message with tag hostId
678 # @param msg_hash - HASHREF - message information parsed into a hash
679 # @param session_id - INTEGER - POE session id of the processing of this message
680 sub opsi_get_client_software {
681     my ($msg, $msg_hash, $session_id) = @_;
682     my $header = @{$msg_hash->{'header'}}[0];
683     my $source = @{$msg_hash->{'source'}}[0];
684     my $target = @{$msg_hash->{'target'}}[0];
685     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
686     my $hostId = @{$msg_hash->{'hostId'}}[0];
688     # build return message with twisted target and source
689     my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
691     if (defined $forward_to_gosa) {
692       &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
693     }
694     &add_content2xml_hash($out_hash, "hostId", "$hostId");
695     &add_content2xml_hash($out_hash, "xxx", "");
696     my $xml_msg= &create_xml_string($out_hash);
698     # JSON Query
699     my $callobj = {
700       method  => 'getSoftwareInformation_hash',
701       params  => [ $hostId ],
702       id  => 1,
703     };
705     my $res = $main::opsi_client->call($main::opsi_url, $callobj);
706     if (&check_opsi_res($res)){
707       my $result= $res->result;
708     }
710     $xml_msg=~ s/<xxx><\/xxx>//;
712     return ( $xml_msg );
716 ## @method opsi_get_local_products
717 # ???
718 # @param msg - STRING - xml message with tag hostId
719 # @param msg_hash - HASHREF - message information parsed into a hash
720 # @param session_id - INTEGER - POE session id of the processing of this message
721 sub opsi_get_local_products {
722   my ($msg, $msg_hash, $session_id) = @_;
723   my $header = @{$msg_hash->{'header'}}[0];
724   my $source = @{$msg_hash->{'source'}}[0];
725   my $target = @{$msg_hash->{'target'}}[0];
726   my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
727   my $hostId;
729   # build return message with twisted target and source
730   my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
732   # Get hostID if defined
733   if (defined @{$msg_hash->{'hostId'}}[0]){
734     $hostId = @{$msg_hash->{'hostId'}}[0];
735     &add_content2xml_hash($out_hash, "hostId", $hostId);
736   }
738   if (defined $forward_to_gosa) {
739     &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
740   }
741   &add_content2xml_hash($out_hash, "xxx", "");
742   my $xml_msg= &create_xml_string($out_hash);
744   # For hosts, only return the products that are or get installed
745   my $callobj;
746   $callobj = {
747     method  => 'getLocalBootProductIds_list',
748     params  => [ ],
749     id  => 1,
750   };
752   my $res = $main::opsi_client->call($main::opsi_url, $callobj);
753   my %r = ();
754   for (@{$res->result}) { $r{$_} = 1 }
756   if (&check_opsi_res($res)){
758     if (defined $hostId){
759       $callobj = {
760         method  => 'getProductStates_hash',
761         params  => [ $hostId ],
762         id  => 1,
763       };
765       my $hres = $main::opsi_client->call($main::opsi_url, $callobj);
766       if (&check_opsi_res($hres)){
767         my $htmp= $hres->result->{$hostId};
769         # check state != not_installed or action == setup -> load and add
770         foreach my $product (@{$htmp}){
772           if (!defined ($r{$product->{'productId'}})){
773             next;
774           }
776           # Now we've a couple of hashes...
777           if ($product->{'installationStatus'} ne "not_installed" or
778               $product->{'actionRequest'} eq "setup"){
779             my $state= "<state>".$product->{'installationStatus'}."</state><action>".$product->{'actionRequest'}."</action>";
781             $callobj = {
782               method  => 'getProduct_hash',
783               params  => [ $product->{'productId'} ],
784               id  => 1,
785             };
787             my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
788             if (&check_opsi_res($sres)){
789               my $tres= $sres->result;
791               my $name= xml_quote($tres->{'name'});
792               my $r= $product->{'productId'};
793               my $description= xml_quote($tres->{'description'});
794               $name=~ s/\//\\\//;
795               $description=~ s/\//\\\//;
796               $xml_msg=~ s/<xxx><\/xxx>/<item><productId>$r<\/productId><name><\/name><description>$description<\/description><\/item>$state<xxx><\/xxx>/;
797             }
799           }
800         }
802       }
804     } else {
805       foreach my $r (@{$res->result}) {
806         $callobj = {
807           method  => 'getProduct_hash',
808           params  => [ $r ],
809           id  => 1,
810         };
812         my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
813         if (&check_opsi_res($sres)){
814           my $tres= $sres->result;
816           my $name= xml_quote($tres->{'name'});
817           my $description= xml_quote($tres->{'description'});
818           $name=~ s/\//\\\//;
819           $description=~ s/\//\\\//;
820           $xml_msg=~ s/<xxx><\/xxx>/<item><productId>$r<\/productId><name><\/name><description>$description<\/description><\/item><xxx><\/xxx>/;
821         }
823       }
825     }
826   }
828   $xml_msg=~ s/<xxx><\/xxx>//;
830   return ( $xml_msg );
834 ## @method opsi_del_client
835 # ???
836 # @param msg - STRING - xml message with tag hostId
837 # @param msg_hash - HASHREF - message information parsed into a hash
838 # @param session_id - INTEGER - POE session id of the processing of this message
839 sub opsi_del_client {
840     my ($msg, $msg_hash, $session_id) = @_;
841     my $header = @{$msg_hash->{'header'}}[0];
842     my $source = @{$msg_hash->{'source'}}[0];
843     my $target = @{$msg_hash->{'target'}}[0];
844     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
845     my $hostId = @{$msg_hash->{'hostId'}}[0];
847     # build return message with twisted target and source
848     my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
850     if (defined $forward_to_gosa) {
851       &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
852     }
853     &add_content2xml_hash($out_hash, "hostId", "$hostId");
855     # JSON Query
856     my $callobj = {
857       method  => 'deleteClient',
858       params  => [ $hostId ],
859       id  => 1,
860     };
862     my $res = $main::opsi_client->call($main::opsi_url, $callobj);
864     my $xml_msg= &create_xml_string($out_hash);
865     return ( $xml_msg );
869 ## @method opsi_install_client
870 # ???
871 # @param msg - STRING - xml message with tags hostId, macaddress
872 # @param msg_hash - HASHREF - message information parsed into a hash
873 # @param session_id - INTEGER - POE session id of the processing of this message
874 sub opsi_install_client {
875     my ($msg, $msg_hash, $session_id) = @_;
876     my $header = @{$msg_hash->{'header'}}[0];
877     my $source = @{$msg_hash->{'source'}}[0];
878     my $target = @{$msg_hash->{'target'}}[0];
879     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
880     my $hostId = @{$msg_hash->{'hostId'}}[0];
881     my $error = 0;
882     my @out_msg_l;
884     # If no macaddress is specified, raise error  
885     my $macaddress; 
886     if ((exists $msg_hash->{'macaddress'}) && 
887             ($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)) {  
888         $macaddress = $1; 
889     } else { 
890         $error ++; 
891         my $out_msg = "<xml>". 
892             "<header>answer</header>". 
893             "<source>$main::server_address</source>". 
894             "<target>GOSA</target>". 
895             "<answer1>1</answer1>". 
896             "<error_string>no mac address specified in macaddres-tag</error_string>". 
897             "</xml>"; 
898         push(@out_msg_l, $out_msg);
899     } 
901     # Set parameters in opsi
902     if (not $error) {
903         # build return message with twisted target and source
904         my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
906         if (defined $forward_to_gosa) {
907             &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
908         }
909         &add_content2xml_hash($out_hash, "hostId", "$hostId");
911         # Load all products for this host with status != "not_installed" or actionRequest != "none"
912         if (defined $hostId){
913             my $callobj = {
914                 method  => 'getProductStates_hash',
915                 params  => [ $hostId ],
916                 id  => 1,
917             };
919             my $hres = $main::opsi_client->call($main::opsi_url, $callobj);
920             if (&check_opsi_res($hres)){
921                 my $htmp= $hres->result->{$hostId};
923                 # check state != not_installed or action == setup -> load and add
924                 foreach my $product (@{$htmp}){
925                     # Now we've a couple of hashes...
926                     if ($product->{'installationStatus'} ne "not_installed" or
927                             $product->{'actionRequest'} ne "none"){
929                         # Do an action request for all these -> "setup".
930                         $callobj = {
931                             method  => 'setProductActionRequest',
932                             params  => [ $product->{'productId'}, $hostId, "setup" ],
933                             id  => 1,
934                         };
935                         my $res = $main::opsi_client->call($main::opsi_url, $callobj);
936                         if (!&check_opsi_res($res)){
937                             &main::daemon_log("ERROR: cannot set product action request for $hostId!", 1);
938                         } else {
939                             &main::daemon_log("INFO: requesting 'setup' for '".$product->{'productId'}."' on $hostId", 1);
940                         }
942                     }
943                 }
944             }
945         }
947         push(@out_msg_l, &create_xml_string($out_hash));
948     }
950     # Build wakeup message for client
951     if (not $error) {
952         my $wakeup_hash = &create_xml_hash("trigger_wake", "GOSA", "KNOWN_SERVER");
953         &add_content2xml_hash($wakeup_hash, 'macAddress', $macaddress);
954         my $wakeup_msg = &create_xml_string($wakeup_hash);
955         push(@out_msg_l, $wakeup_msg);
957         # invoke trigger wake for this gosa-si-server
958         &main::server_server_com::trigger_wake($wakeup_msg, $wakeup_hash, $session_id);
959     }
962     return @out_msg_l;
966 ## @method _set_action
967 # ???
968 # @param product - STRING - ???
969 # @param action - STRING - ???
970 # @param hostId - STRING - ???
971 sub _set_action {
972   my $product= shift;
973   my $action = shift;
974   my $hostId = shift;
975   my $callobj;
977   $callobj = {
978     method  => 'setProductActionRequest',
979     params  => [ $product, $hostId, $action],
980     id  => 1,
981   };
983   $main::opsi_client->call($main::opsi_url, $callobj);
986 ## @method _set_state
987 # ???
988 # @param product - STRING - ???
989 # @param action - STRING - ???
990 # @param hostId - STRING - ???
991 sub _set_state {
992   my $product = shift;
993   my $hostId = shift;
994   my $action = shift;
995   my $callobj;
997   $callobj = {
998     method  => 'setProductState',
999     params  => [ $product, $hostId, $action ],
1000     id  => 1,
1001   };
1003   $main::opsi_client->call($main::opsi_url, $callobj);
1006 1;