Code

e42107ba9a1f61f3352164374ce06ca5a1c6f8f9
[gosa.git] / branches / old / 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 }
45 ## @method opsi_add_product_to_client
46 # Adds an Opsi product to an Opsi client.
47 # @param msg - STRING - xml message with tags hostId and productId
48 # @param msg_hash - HASHREF - message information parsed into a hash
49 # @param session_id - INTEGER - POE session id of the processing of this message
50 # @return out_msg - STRING - feedback to GOsa in success and error case
51 sub opsi_add_product_to_client {
52     my ($msg, $msg_hash, $session_id) = @_;
53     my $header = @{$msg_hash->{'header'}}[0];
54     my $source = @{$msg_hash->{'source'}}[0];
55     my $target = @{$msg_hash->{'target'}}[0];
56     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
57     my ($hostId, $productId);
58     my $error = 0;
60     # Build return message
61     my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
62     if (defined $forward_to_gosa) {
63         &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
64     }
66     # Sanity check of needed parameter
67     if ((not exists $msg_hash->{'hostId'}) || (@{$msg_hash->{'hostId'}} != 1))  {
68         $error++;
69         &add_content2xml_hash($out_hash, "error_string", "no hostId specified or hostId tag invalid");
70         &add_content2xml_hash($out_hash, "error", "hostId");
71         &main::daemon_log("$session_id ERROR: no hostId specified or hostId tag invalid: $msg", 1); 
73     }
74     if ((not exists $msg_hash->{'productId'}) || (@{$msg_hash->{'productId'}} != 1)) {
75         $error++;
76         &add_content2xml_hash($out_hash, "error_string", "no productId specified or productId tag invalid");
77         &add_content2xml_hash($out_hash, "error", "productId");
78         &main::daemon_log("$session_id ERROR: no productId specified or procutId tag invalid: $msg", 1); 
79     }
81     if (not $error) {
82         # Get hostID
83         $hostId = @{$msg_hash->{'hostId'}}[0];
84         &add_content2xml_hash($out_hash, "hostId", $hostId);
86         # Get productID
87         $productId = @{$msg_hash->{'productId'}}[0];
88         &add_content2xml_hash($out_hash, "productId", $productId);
90         # Do an action request for all these -> "setup".
91         my $callobj = {
92             method  => 'setProductActionRequest',
93             params  => [ $productId, $hostId, "setup" ],
94             id  => 1, }; 
96         my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
97         my ($sres_err, $sres_err_string) = &check_opsi_res($sres);
98         if ($sres_err){
99             &main::daemon_log("$session_id ERROR: cannot add product: ".$sres_err_string, 1);
100             &add_content2xml_hash($out_hash, "error", $sres_err_string);
101         }
102     } 
104     # return message
105     return ( &create_xml_string($out_hash) );
108 ## @method opsi_del_product_from_client
109 # Deletes an Opsi-product from an Opsi-client. 
110 # @param msg - STRING - xml message with tags hostId and productId
111 # @param msg_hash - HASHREF - message information parsed into a hash
112 # @param session_id - INTEGER - POE session id of the processing of this message
113 # @return out_msg - STRING - feedback to GOsa in success and error case
114 sub opsi_del_product_from_client {
115     my ($msg, $msg_hash, $session_id) = @_;
116     my $header = @{$msg_hash->{'header'}}[0];
117     my $source = @{$msg_hash->{'source'}}[0];
118     my $target = @{$msg_hash->{'target'}}[0];
119     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
120     my ($hostId, $productId);
121     my $error = 0;
122     my ($sres, $sres_err, $sres_err_string);
124     # Build return message
125     my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
126     if (defined $forward_to_gosa) {
127         &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
128     }
130     # Sanity check of needed parameter
131     if ((not exists $msg_hash->{'hostId'}) || (@{$msg_hash->{'hostId'}} != 1))  {
132         $error++;
133         &add_content2xml_hash($out_hash, "error_string", "no hostId specified or hostId tag invalid");
134         &add_content2xml_hash($out_hash, "error", "hostId");
135         &main::daemon_log("$session_id ERROR: no hostId specified or hostId tag invalid: $msg", 1); 
137     }
138     if ((not exists $msg_hash->{'productId'}) || (@{$msg_hash->{'productId'}} != 1)) {
139         $error++;
140         &add_content2xml_hash($out_hash, "error_string", "no productId specified or productId tag invalid");
141         &add_content2xml_hash($out_hash, "error", "productId");
142         &main::daemon_log("$session_id ERROR: no productId specified or procutId tag invalid: $msg", 1); 
143     }
145     # All parameter available
146     if (not $error) {
147         # Get hostID
148         $hostId = @{$msg_hash->{'hostId'}}[0];
149         &add_content2xml_hash($out_hash, "hostId", $hostId);
151         # Get productID
152         $productId = @{$msg_hash->{'productId'}}[0];
153         &add_content2xml_hash($out_hash, "productId", $productId);
156 #TODO : check the results for more than one entry which is currently installed
157         #$callobj = {
158         #    method  => 'getProductDependencies_listOfHashes',
159         #    params  => [ $productId ],
160         #    id  => 1, };
161         #
162         #my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
163         #my ($sres_err, $sres_err_string) = &check_opsi_res($sres);
164         #if ($sres_err){
165         #  &main::daemon_log("ERROR: cannot perform dependency check: ".$sres_err_string, 1);
166         #  &add_content2xml_hash($out_hash, "error", $sres_err_string);
167         #  return ( &create_xml_string($out_hash) );
168         #}
171         # Check to get product action list 
172         my $callobj = {
173             method  => 'getPossibleProductActions_list',
174             params  => [ $productId ],
175             id  => 1, };
176         $sres = $main::opsi_client->call($main::opsi_url, $callobj);
177         ($sres_err, $sres_err_string) = &check_opsi_res($sres);
178         if ($sres_err){
179             &main::daemon_log("$session_id ERROR: cannot get product action list: ".$sres_err_string, 1);
180             &add_content2xml_hash($out_hash, "error", $sres_err_string);
181             $error++;
182         }
183     }
185     # Check action uninstall of product
186     if (not $error) {
187         my $uninst_possible= 0;
188         foreach my $r (@{$sres->result}) {
189             if ($r eq 'uninstall') {
190                 $uninst_possible= 1;
191             }
192         }
193         if (!$uninst_possible){
194             &main::daemon_log("$session_id ERROR: cannot uninstall product '$productId', product do not has the action 'uninstall'", 1);
195             &add_content2xml_hash($out_hash, "error", "cannot uninstall product '$productId', product do not has the action 'uninstall'");
196             $error++;
197         }
198     }
200     # Set product state to "none"
201     # Do an action request for all these -> "setup".
202     if (not $error) {
203         my $callobj = {
204             method  => 'setProductActionRequest',
205             params  => [ $productId, $hostId, "none" ],
206             id  => 1, 
207         }; 
208         $sres = $main::opsi_client->call($main::opsi_url, $callobj);
209         ($sres_err, $sres_err_string) = &check_opsi_res($sres);
210         if ($sres_err){
211             &main::daemon_log("$session_id ERROR: cannot delete product: ".$sres_err_string, 1);
212             &add_content2xml_hash($out_hash, "error", $sres_err_string);
213         }
214     }
216     # Return message
217     return ( &create_xml_string($out_hash) );
220 ## @method opsi_add_client
221 # Adds an Opsi client to Opsi.
222 # @param msg - STRING - xml message with tags hostId and macaddress
223 # @param msg_hash - HASHREF - message information parsed into a hash
224 # @param session_id - INTEGER - POE session id of the processing of this message
225 # @return out_msg - STRING - feedback to GOsa in success and error case
226 sub opsi_add_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, $mac);
233     my $error = 0;
234     my ($sres, $sres_err, $sres_err_string);
236     # Build return message with twisted target and source
237     my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
238     if (defined $forward_to_gosa) {
239         &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
240     }
242     # Sanity check of needed parameter
243     if ((not exists $msg_hash->{'hostId'}) || (@{$msg_hash->{'hostId'}} != 1))  {
244         $error++;
245         &add_content2xml_hash($out_hash, "error_string", "no hostId specified or hostId tag invalid");
246         &add_content2xml_hash($out_hash, "error", "hostId");
247         &main::daemon_log("$session_id ERROR: no hostId specified or hostId tag invalid: $msg", 1); 
248     }
249     if ((not exists $msg_hash->{'macaddress'}) || (@{$msg_hash->{'macaddress'}} != 1))  {
250         $error++;
251         &add_content2xml_hash($out_hash, "error_string", "no macaddress specified or macaddress tag invalid");
252         &add_content2xml_hash($out_hash, "error", "macaddress");
253         &main::daemon_log("$session_id ERROR: no macaddress specified or macaddress tag invalid: $msg", 1); 
254     }
256     if (not $error) {
257         # Get hostID
258         $hostId = @{$msg_hash->{'hostId'}}[0];
259         &add_content2xml_hash($out_hash, "hostId", $hostId);
261         # Get macaddress
262         $mac = @{$msg_hash->{'macaddress'}}[0];
263         &add_content2xml_hash($out_hash, "macaddress", $mac);
265         my $name= $hostId;
266         $name=~ s/^([^.]+).*$/$1/;
267         my $domain= $hostId;
268         $domain=~ s/^[^.]+\.(.*)$/$1/;
269         my ($description, $notes, $ip);
271         if (defined @{$msg_hash->{'description'}}[0]){
272             $description = @{$msg_hash->{'description'}}[0];
273         }
274         if (defined @{$msg_hash->{'notes'}}[0]){
275             $notes = @{$msg_hash->{'notes'}}[0];
276         }
277         if (defined @{$msg_hash->{'ip'}}[0]){
278             $ip = @{$msg_hash->{'ip'}}[0];
279         }
281         my $callobj;
282         $callobj = {
283             method  => 'createClient',
284             params  => [ $name, $domain, $description, $notes, $ip, $mac ],
285             id  => 1,
286         };
288         $sres = $main::opsi_client->call($main::opsi_url, $callobj);
289         ($sres_err, $sres_err_string) = &check_opsi_res($sres);
290         if ($sres_err){
291             &main::daemon_log("$session_id ERROR: cannot create client: ".$sres_err_string, 1);
292             &add_content2xml_hash($out_hash, "error", $sres_err_string);
293         } else {
294             &main::daemon_log("$session_id INFO: add opsi client '$hostId' with mac '$mac'", 5); 
295         }
296     }
298     # Return message
299     return ( &create_xml_string($out_hash) );
302 ## @method opsi_modify_client
303 # Modifies the parameters description, mac or notes for an Opsi client if the corresponding message tags are given.
304 # @param msg - STRING - xml message with tag hostId and optional description, mac or notes
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 # @return out_msg - STRING - feedback to GOsa in success and error case
308 sub opsi_modify_client {
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;
315     my $error = 0;
316     my ($sres, $sres_err, $sres_err_string);
318     # Build return message with twisted target and source
319     my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
320     if (defined $forward_to_gosa) {
321         &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
322     }
324     # Sanity check of needed parameter
325     if ((not exists $msg_hash->{'hostId'}) || (@{$msg_hash->{'hostId'}} != 1))  {
326         $error++;
327         &add_content2xml_hash($out_hash, "error_string", "no hostId specified or hostId tag invalid");
328         &add_content2xml_hash($out_hash, "error", "hostId");
329         &main::daemon_log("$session_id ERROR: no hostId specified or hostId tag invalid: $msg", 1); 
330     }
332     if (not $error) {
333         # Get hostID
334         $hostId = @{$msg_hash->{'hostId'}}[0];
335         &add_content2xml_hash($out_hash, "hostId", $hostId);
336         my $name= $hostId;
337         $name=~ s/^([^.]+).*$/$1/;
338         my $domain= $hostId;
339         $domain=~ s/^[^.]+(.*)$/$1/;
341         # Modify description, notes or mac if defined
342         my ($description, $notes, $mac);
343         my $callobj;
344         if ((exists $msg_hash->{'description'}) && (@{$msg_hash->{'description'}} == 1) ){
345             $description = @{$msg_hash->{'description'}}[0];
346             $callobj = {
347                 method  => 'setHostDescription',
348                 params  => [ $hostId, $description ],
349                 id  => 1,
350             };
351             my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
352             my ($sres_err, $sres_err_string) = &check_opsi_res($sres);
353             if ($sres_err){
354                 &main::daemon_log("ERROR: cannot set description: ".$sres_err_string, 1);
355                 &add_content2xml_hash($out_hash, "error", $sres_err_string);
356             }
357         }
358         if ((exists $msg_hash->{'notes'}) && (@{$msg_hash->{'notes'}} == 1)) {
359             $notes = @{$msg_hash->{'notes'}}[0];
360             $callobj = {
361                 method  => 'setHostNotes',
362                 params  => [ $hostId, $notes ],
363                 id  => 1,
364             };
365             my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
366             my ($sres_err, $sres_err_string) = &check_opsi_res($sres);
367             if ($sres_err){
368                 &main::daemon_log("ERROR: cannot set notes: ".$sres_err_string, 1);
369                 &add_content2xml_hash($out_hash, "error", $sres_err_string);
370             }
371         }
372         if ((exists $msg_hash->{'mac'}) && (@{$msg_hash->{'mac'}} == 1)){
373             $mac = @{$msg_hash->{'mac'}}[0];
374             $callobj = {
375                 method  => 'setMacAddress',
376                 params  => [ $hostId, $mac ],
377                 id  => 1,
378             };
379             my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
380             my ($sres_err, $sres_err_string) = &check_opsi_res($sres);
381             if ($sres_err){
382                 &main::daemon_log("ERROR: cannot set mac address: ".$sres_err_string, 1);
383                 &add_content2xml_hash($out_hash, "error", $sres_err_string);
384             }
385         }
386     }
388     # Return message
389     return ( &create_xml_string($out_hash) );
392     
393 ## @method opsi_get_netboot_products
394 # Get netboot products for specific host.
395 # @param msg - STRING - xml message with tag hostId
396 # @param msg_hash - HASHREF - message information parsed into a hash
397 # @param session_id - INTEGER - POE session id of the processing of this message
398 # @return out_msg - STRING - feedback to GOsa in success and error case
399 sub opsi_get_netboot_products {
400     my ($msg, $msg_hash, $session_id) = @_;
401     my $header = @{$msg_hash->{'header'}}[0];
402     my $source = @{$msg_hash->{'source'}}[0];
403     my $target = @{$msg_hash->{'target'}}[0];
404     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
405     my $hostId;
406     my $xml_msg;
408     # Build return message with twisted target and source
409     my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
410     if (defined $forward_to_gosa) {
411         &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
412     }
414     # Get hostID if defined
415     if ((exists $msg_hash->{'hostId'}) && (@{$msg_hash->{'hostId'}} == 1))  {
416         $hostId = @{$msg_hash->{'hostId'}}[0];
417         &add_content2xml_hash($out_hash, "hostId", $hostId);
418     }
420     &add_content2xml_hash($out_hash, "xxx", "");
421     $xml_msg= &create_xml_string($out_hash);
423     # For hosts, only return the products that are or get installed
424     my $callobj;
425     $callobj = {
426         method  => 'getNetBootProductIds_list',
427         params  => [ ],
428         id  => 1,
429     };
431     my $res = $main::opsi_client->call($main::opsi_url, $callobj);
432     my %r = ();
433     for (@{$res->result}) { $r{$_} = 1 }
435     if (not &check_opsi_res($res)){
437         if (defined $hostId){
438             $callobj = {
439                 method  => 'getProductStates_hash',
440                 params  => [ $hostId ],
441                 id  => 1,
442             };
444             my $hres = $main::opsi_client->call($main::opsi_url, $callobj);
445             if (not &check_opsi_res($hres)){
446                 my $htmp= $hres->result->{$hostId};
448                 # check state != not_installed or action == setup -> load and add
449                 foreach my $product (@{$htmp}){
451                     if (!defined ($r{$product->{'productId'}})){
452                         next;
453                     }
455                     # Now we've a couple of hashes...
456                     if ($product->{'installationStatus'} ne "not_installed" or
457                             $product->{'actionRequest'} eq "setup"){
458                         my $state= "<state>".$product->{'installationStatus'}."</state><action>".$product->{'actionRequest'}."</action>";
460                         $callobj = {
461                             method  => 'getProduct_hash',
462                             params  => [ $product->{'productId'} ],
463                             id  => 1,
464                         };
466                         my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
467                         if (not &check_opsi_res($sres)){
468                             my $tres= $sres->result;
470                             my $name= xml_quote($tres->{'name'});
471                             my $r= $product->{'productId'};
472                             my $description= xml_quote($tres->{'description'});
473                             $name=~ s/\//\\\//;
474                             $description=~ s/\//\\\//;
475                             $xml_msg=~ s/<xxx><\/xxx>/\n<item><productId>$r<\/productId><name><\/name><description>$description<\/description><\/item>$state<xxx><\/xxx>/;
476                         }
477                     }
478                 }
480             }
482         } else {
483             foreach my $r (@{$res->result}) {
484                 $callobj = {
485                     method  => 'getProduct_hash',
486                     params  => [ $r ],
487                     id  => 1,
488                 };
490                 my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
491                 if (not &check_opsi_res($sres)){
492                     my $tres= $sres->result;
494                     my $name= xml_quote($tres->{'name'});
495                     my $description= xml_quote($tres->{'description'});
496                     $name=~ s/\//\\\//;
497                     $description=~ s/\//\\\//;
498                     $xml_msg=~ s/<xxx><\/xxx>/\n<item><productId>$r<\/productId><name><\/name><description>$description<\/description><\/item><xxx><\/xxx>/;
499                 }
500             }
502         }
503     }
504     $xml_msg=~ s/<xxx><\/xxx>//;
506     # Return message
507     return ( $xml_msg );
511 ## @method opsi_get_product_properties
512 # Get product properties for a product and a specific host or gobally for a product.
513 # @param msg - STRING - xml message with tags productId and optional hostId
514 # @param msg_hash - HASHREF - message information parsed into a hash
515 # @param session_id - INTEGER - POE session id of the processing of this message
516 # @return out_msg - STRING - feedback to GOsa in success and error case
517 sub opsi_get_product_properties {
518     my ($msg, $msg_hash, $session_id) = @_;
519     my $header = @{$msg_hash->{'header'}}[0];
520     my $source = @{$msg_hash->{'source'}}[0];
521     my $target = @{$msg_hash->{'target'}}[0];
522     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
523     my ($hostId, $productId);
524     my $xml_msg;
526     # Build return message with twisted target and source
527     my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
528     if (defined $forward_to_gosa) {
529         &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
530     }
532     # Sanity check of needed parameter
533     if ((not exists $msg_hash->{'productId'}) || (@{$msg_hash->{'productId'}} != 1))  {
534         &add_content2xml_hash($out_hash, "error_string", "no productId specified or productId tag invalid");
535         &add_content2xml_hash($out_hash, "error", "productId");
536         &main::daemon_log("$session_id ERROR: no productId specified or productId tag invalid: $msg", 1); 
538         # Return message
539         return ( &create_xml_string($out_hash) );
540     }
542     # Get productid
543     $productId = @{$msg_hash->{'productId'}}[0];
544     &add_content2xml_hash($out_hash, "producId", "$productId");
546     # Get hostID if defined
547     if (defined @{$msg_hash->{'hostId'}}[0]){
548       $hostId = @{$msg_hash->{'hostId'}}[0];
549       &add_content2xml_hash($out_hash, "hostId", $hostId);
550     }
552     # Load actions
553     my $callobj = {
554       method  => 'getPossibleProductActions_list',
555       params  => [ $productId ],
556       id  => 1,
557     };
558     my $res = $main::opsi_client->call($main::opsi_url, $callobj);
559     if (not &check_opsi_res($res)){
560       foreach my $action (@{$res->result}){
561         &add_content2xml_hash($out_hash, "action", $action);
562       }
563     }
565     # Add place holder
566     &add_content2xml_hash($out_hash, "xxx", "");
568     # Move to XML string
569     $xml_msg= &create_xml_string($out_hash);
571     # JSON Query
572     if (defined $hostId){
573       $callobj = {
574           method  => 'getProductProperties_hash',
575           params  => [ $productId, $hostId ],
576           id  => 1,
577       };
578     } else {
579       $callobj = {
580           method  => 'getProductProperties_hash',
581           params  => [ $productId ],
582           id  => 1,
583       };
584     }
585     $res = $main::opsi_client->call($main::opsi_url, $callobj);
587     # JSON Query 2
588     $callobj = {
589       method  => 'getProductPropertyDefinitions_listOfHashes',
590       params  => [ $productId ],
591       id  => 1,
592     };
594     # Assemble options
595     my $res2 = $main::opsi_client->call($main::opsi_url, $callobj);
596     my $values = {};
597     my $descriptions = {};
598     if (not &check_opsi_res($res2)){
599         my $r= $res2->result;
601           foreach my $entr (@$r){
602             # Unroll values
603             my $cnv;
604             if (UNIVERSAL::isa( $entr->{'values'}, "ARRAY" )){
605               foreach my $v (@{$entr->{'values'}}){
606                 $cnv.= "<value>$v</value>";
607               }
608             } else {
609               $cnv= $entr->{'values'};
610             }
611             $values->{$entr->{'name'}}= $cnv;
612             $descriptions->{$entr->{'name'}}= "<description>".$entr->{'description'}."</description>";
613           }
614     }
616     if (not &check_opsi_res($res)){
617         my $r= $res->result;
618         foreach my $key (keys %{$r}) {
619             my $item= "\n<item>";
620             my $value= $r->{$key};
621             my $dsc= "";
622             my $vals= "";
623             if (defined $descriptions->{$key}){
624               $dsc= $descriptions->{$key};
625             }
626             if (defined $values->{$key}){
627               $vals= $values->{$key};
628             }
629             $item.= "<$key>$dsc<default>".xml_quote($value)."</default>$vals</$key>";
630             $item.= "</item>";
631             $xml_msg=~ s/<xxx><\/xxx>/$item<xxx><\/xxx>/;
632         }
633     }
635     $xml_msg=~ s/<xxx><\/xxx>//;
637     # Return message
638     return ( $xml_msg );
642 ## @method opsi_set_product_properties
643 # Set product properities for a specific host or globaly. Message needs one xml tag 'item' and within one xml tag 'name' and 'value'. The xml tags action and state are optional.
644 # @param msg - STRING - xml message with tags productId, action, state and optional hostId, action and state
645 # @param msg_hash - HASHREF - message information parsed into a hash
646 # @param session_id - INTEGER - POE session id of the processing of this message
647 # @return out_msg - STRING - feedback to GOsa in success and error case
648 sub opsi_set_product_properties {
649     my ($msg, $msg_hash, $session_id) = @_;
650     my $header = @{$msg_hash->{'header'}}[0];
651     my $source = @{$msg_hash->{'source'}}[0];
652     my $target = @{$msg_hash->{'target'}}[0];
653     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
654     my ($productId, $hostId);
656     # Build return message with twisted target and source
657     my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
658     if (defined $forward_to_gosa) {
659         &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
660     }
662     # Sanity check of needed parameter
663     if ((not exists $msg_hash->{'productId'}) || (@{$msg_hash->{'productId'}} != 1))  {
664         &add_content2xml_hash($out_hash, "error_string", "no productId specified or productId tag invalid");
665         &add_content2xml_hash($out_hash, "error", "productId");
666         &main::daemon_log("$session_id ERROR: no productId specified or productId tag invalid: $msg", 1); 
667         return ( &create_xml_string($out_hash) );
668     }
669     if (not exists $msg_hash->{'item'}) {
670         &add_content2xml_hash($out_hash, "error_string", "message needs one xml-tag 'item' and within the xml-tags 'name' and 'value'");
671         &add_content2xml_hash($out_hash, "error", "item");
672         &main::daemon_log("$session_id ERROR: message needs one xml-tag 'item' and within the xml-tags 'name' and 'value': $msg", 1); 
673         return ( &create_xml_string($out_hash) );
674     } else {
675         if ((not exists @{$msg_hash->{'item'}}[0]->{'name'}) || (@{@{$msg_hash->{'item'}}[0]->{'name'}} != 1 )) {
676             &add_content2xml_hash($out_hash, "error_string", "message needs within the xml-tag 'item' one xml-tags 'name'");
677             &add_content2xml_hash($out_hash, "error", "name");
678             &main::daemon_log("$session_id ERROR: message needs within the xml-tag 'item' one xml-tags 'name': $msg", 1); 
679             return ( &create_xml_string($out_hash) );
680         }
681         if ((not exists @{$msg_hash->{'item'}}[0]->{'value'}) || (@{@{$msg_hash->{'item'}}[0]->{'value'}} != 1 )) {
682             &add_content2xml_hash($out_hash, "error_string", "message needs within the xml-tag 'item' one xml-tags 'value'");
683             &add_content2xml_hash($out_hash, "error", "value");
684             &main::daemon_log("$session_id ERROR: message needs within the xml-tag 'item' one xml-tags 'value': $msg", 1); 
685             return ( &create_xml_string($out_hash) );
686         }
687     }
688     if ((exists $msg_hash->{'hostId'}) && (@{$msg_hash->{'hostId'}} != 1))  {
689         &add_content2xml_hash($out_hash, "error_string", "hostId contains no or more than one values");
690         &add_content2xml_hash($out_hash, "error", "hostId");
691         &main::daemon_log("$session_id ERROR: hostId contains no or more than one values: $msg", 1); 
692         return ( &create_xml_string($out_hash) );
693     }
695         
696     # Get productId
697     $productId =  @{$msg_hash->{'productId'}}[0];
698     &add_content2xml_hash($out_hash, "productId", $productId);
700     # Get hostID if defined
701     if (exists $msg_hash->{'hostId'}){
702         $hostId = @{$msg_hash->{'hostId'}}[0];
703         &add_content2xml_hash($out_hash, "hostId", $hostId);
704     }
706     # Set product states if requested
707     if (defined @{$msg_hash->{'action'}}[0]){
708         &_set_action($productId, @{$msg_hash->{'action'}}[0], $hostId);
709     }
710     if (defined @{$msg_hash->{'state'}}[0]){
711         &_set_state($productId, @{$msg_hash->{'state'}}[0], $hostId);
712     }
714     # Find properties
715     foreach my $item (@{$msg_hash->{'item'}}){
716         # JSON Query
717         my $callobj;
719         if (defined $hostId){
720             $callobj = {
721                 method  => 'setProductProperty',
722                 params  => [ $productId, $item->{'name'}[0], $item->{'value'}[0], $hostId ],
723                 id  => 1,
724             };
725         } else {
726             $callobj = {
727                 method  => 'setProductProperty',
728                 params  => [ $productId, $item->{'name'}[0], $item->{'value'}[0] ],
729                 id  => 1,
730             };
731         }
733         my $res = $main::opsi_client->call($main::opsi_url, $callobj);
734         my ($res_err, $res_err_string) = &check_opsi_res($res);
736         if ($res_err){
737             &man::daemon_log("$session_id ERROR: communication failed while setting '".$item->{'name'}[0]."': ".$res_err_string, 1);
738             &add_content2xml_hash($out_hash, "error", $res_err_string);
739         }
740     }
743     # Return message
744     return ( &create_xml_string($out_hash) );
748 ## @method opsi_get_client_hardware
749 # Reports client hardware inventory.
750 # @param msg - STRING - xml message with tag hostId
751 # @param msg_hash - HASHREF - message information parsed into a hash
752 # @param session_id - INTEGER - POE session id of the processing of this message
753 # @return out_msg - STRING - feedback to GOsa in success and error case
754 sub opsi_get_client_hardware {
755     my ($msg, $msg_hash, $session_id) = @_;
756     my $header = @{$msg_hash->{'header'}}[0];
757     my $source = @{$msg_hash->{'source'}}[0];
758     my $target = @{$msg_hash->{'target'}}[0];
759     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
760     my $hostId;
761     my $error = 0;
762     my $xml_msg;
764     # Build return message with twisted target and source
765     my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
766     if (defined $forward_to_gosa) {
767       &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
768     }
770     # Sanity check of needed parameter
771     if ((exists $msg_hash->{'hostId'}) && (@{$msg_hash->{'hostId'}} != 1))  {
772         $error++;
773         &add_content2xml_hash($out_hash, "error_string", "hostId contains no or more than one values");
774         &add_content2xml_hash($out_hash, "error", "hostId");
775         &main::daemon_log("$session_id ERROR: hostId contains no or more than one values: $msg", 1); 
776     }
778     if (not $error) {
780     # Get hostID
781         $hostId = @{$msg_hash->{'hostId'}}[0];
782         &add_content2xml_hash($out_hash, "hostId", "$hostId");
783         &add_content2xml_hash($out_hash, "xxx", "");
784     }    
786     # Move to XML string
787     $xml_msg= &create_xml_string($out_hash);
788     
789     if (not $error) {
791     # JSON Query
792         my $callobj = {
793             method  => 'getHardwareInformation_hash',
794             params  => [ $hostId ],
795             id  => 1,
796         };
798         my $res = $main::opsi_client->call($main::opsi_url, $callobj);
799         if (not &check_opsi_res($res)){
800             my $result= $res->result;
801             if (ref $result eq "HASH") {
802                 foreach my $r (keys %{$result}){
803                     my $item= "\n<item><id>".xml_quote($r)."</id>";
804                     my $value= $result->{$r};
805                     foreach my $sres (@{$value}){
807                         foreach my $dres (keys %{$sres}){
808                             if (defined $sres->{$dres}){
809                                 $item.= "<$dres>".xml_quote($sres->{$dres})."</$dres>";
810                             }
811                         }
813                     }
814                     $item.= "</item>";
815                     $xml_msg=~ s%<xxx></xxx>%$item<xxx></xxx>%;
817                 }
818             }
819         }
821         $xml_msg=~ s/<xxx><\/xxx>//;
823     }
825     # Return message
826     return ( $xml_msg );
830 ## @method opsi_list_clients
831 # Reports all Opsi clients. 
832 # @param msg - STRING - xml message 
833 # @param msg_hash - HASHREF - message information parsed into a hash
834 # @param session_id - INTEGER - POE session id of the processing of this message
835 # @return out_msg - STRING - feedback to GOsa in success and error case
836 sub opsi_list_clients {
837     my ($msg, $msg_hash, $session_id) = @_;
838     my $header = @{$msg_hash->{'header'}}[0];
839     my $source = @{$msg_hash->{'source'}}[0];
840     my $target = @{$msg_hash->{'target'}}[0];
841     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
843     # Build return message with twisted target and source
844     my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
845     if (defined $forward_to_gosa) {
846       &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
847     }
848     &add_content2xml_hash($out_hash, "xxx", "");
850     # Move to XML string
851     my $xml_msg= &create_xml_string($out_hash);
853     # JSON Query
854     my $callobj = {
855         method  => 'getClients_listOfHashes',
856         params  => [ ],
857         id  => 1,
858     };
859     my $res = $main::opsi_client->call($main::opsi_url, $callobj);
860     if (not &check_opsi_res($res)){
861         foreach my $host (@{$res->result}){
862             my $item= "\n<item><name>".$host->{'hostId'}."</name>";
863             if (defined($host->{'description'})){
864                 $item.= "<description>".xml_quote($host->{'description'})."</description>";
865             }
866             if (defined($host->{'notes'})){
867                 $item.= "<notes>".xml_quote($host->{'notes'})."</notes>";
868             }
869             if (defined($host->{'lastSeen'})){
870                 $item.= "<lastSeen>".xml_quote($host->{'lastSeen'})."</lastSeen>";
871             }
873             $callobj = {
874               method  => 'getIpAddress',
875               params  => [ $host->{'hostId'} ],
876               id  => 1,
877             };
878             my $sres= $main::opsi_client->call($main::opsi_url, $callobj);
879             if ( not &check_opsi_res($sres)){
880               $item.= "<ip>".xml_quote($sres->result)."</ip>";
881             }
883             $callobj = {
884               method  => 'getMacAddress',
885               params  => [ $host->{'hostId'} ],
886               id  => 1,
887             };
888             $sres= $main::opsi_client->call($main::opsi_url, $callobj);
889             if ( not &check_opsi_res($sres)){
890                 $item.= "<mac>".xml_quote($sres->result)."</mac>";
891             }
892             $item.= "</item>";
893             $xml_msg=~ s%<xxx></xxx>%$item<xxx></xxx>%;
894         }
895     }
897     $xml_msg=~ s/<xxx><\/xxx>//;
898     return ( $xml_msg );
903 ## @method opsi_get_client_software
904 # Reports client software inventory.
905 # @param msg - STRING - xml message with tag hostId
906 # @param msg_hash - HASHREF - message information parsed into a hash
907 # @param session_id - INTEGER - POE session id of the processing of this message
908 # @return out_msg - STRING - feedback to GOsa in success and error case
909 sub opsi_get_client_software {
910     my ($msg, $msg_hash, $session_id) = @_;
911     my $header = @{$msg_hash->{'header'}}[0];
912     my $source = @{$msg_hash->{'source'}}[0];
913     my $target = @{$msg_hash->{'target'}}[0];
914     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
915     my $error = 0;
916     my $hostId;
917     my $xml_msg;
919     # Build return message with twisted target and source
920     my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
921     if (defined $forward_to_gosa) {
922       &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
923     }
925     # Sanity check of needed parameter
926     if ((exists $msg_hash->{'hostId'}) && (@{$msg_hash->{'hostId'}} != 1))  {
927         $error++;
928         &add_content2xml_hash($out_hash, "error_string", "hostId contains no or more than one values");
929         &add_content2xml_hash($out_hash, "error", "hostId");
930         &main::daemon_log("$session_id ERROR: hostId contains no or more than one values: $msg", 1); 
931     }
933     if (not $error) {
935     # Get hostID
936         $hostId = @{$msg_hash->{'hostId'}}[0];
937         &add_content2xml_hash($out_hash, "hostId", "$hostId");
938         &add_content2xml_hash($out_hash, "xxx", "");
939     }
941     $xml_msg= &create_xml_string($out_hash);
943     if (not $error) {
945     # JSON Query
946         my $callobj = {
947             method  => 'getSoftwareInformation_hash',
948             params  => [ $hostId ],
949             id  => 1,
950         };
952         my $res = $main::opsi_client->call($main::opsi_url, $callobj);
953         if (not &check_opsi_res($res)){
954             my $result= $res->result;
955 # TODO : Ist das hier schon fertig???   
956         }
958         $xml_msg=~ s/<xxx><\/xxx>//;
960     }
962     # Return message
963     return ( $xml_msg );
967 ## @method opsi_get_local_products
968 # Reports product for given hostId or globally.
969 # @param msg - STRING - xml message with optional tag hostId
970 # @param msg_hash - HASHREF - message information parsed into a hash
971 # @param session_id - INTEGER - POE session id of the processing of this message
972 # @return out_msg - STRING - feedback to GOsa in success and error case
973 sub opsi_get_local_products {
974     my ($msg, $msg_hash, $session_id) = @_;
975     my $header = @{$msg_hash->{'header'}}[0];
976     my $source = @{$msg_hash->{'source'}}[0];
977     my $target = @{$msg_hash->{'target'}}[0];
978     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
979     my $hostId;
981     # Build return message with twisted target and source
982     my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
983     if (defined $forward_to_gosa) {
984         &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
985     }
986     &add_content2xml_hash($out_hash, "xxx", "");
988     # Get hostID if defined
989     if ((exists $msg_hash->{'hostId'}) && (@{$msg_hash->{'hostId'}} == 1))  {
990         $hostId = @{$msg_hash->{'hostId'}}[0];
991         &add_content2xml_hash($out_hash, "hostId", $hostId);
992     }
994     # Move to XML string
995     my $xml_msg= &create_xml_string($out_hash);
997     # For hosts, only return the products that are or get installed
998     my $callobj;
999     $callobj = {
1000         method  => 'getLocalBootProductIds_list',
1001         params  => [ ],
1002         id  => 1,
1003     };
1005     my $res = $main::opsi_client->call($main::opsi_url, $callobj);
1006     my %r = ();
1007     for (@{$res->result}) { $r{$_} = 1 }
1009     if (not &check_opsi_res($res)){
1011         if (defined $hostId){
1012             $callobj = {
1013                 method  => 'getProductStates_hash',
1014                 params  => [ $hostId ],
1015                 id  => 1,
1016             };
1018             my $hres = $main::opsi_client->call($main::opsi_url, $callobj);
1019             if (not &check_opsi_res($hres)){
1020                 my $htmp= $hres->result->{$hostId};
1022                 # Check state != not_installed or action == setup -> load and add
1023                 foreach my $product (@{$htmp}){
1025                     if (!defined ($r{$product->{'productId'}})){
1026                         next;
1027                     }
1029                     # Now we've a couple of hashes...
1030                     if ($product->{'installationStatus'} ne "not_installed" or
1031                             $product->{'actionRequest'} eq "setup"){
1032                         my $state= "<state>".$product->{'installationStatus'}."</state><action>".$product->{'actionRequest'}."</action>";
1034                         $callobj = {
1035                             method  => 'getProduct_hash',
1036                             params  => [ $product->{'productId'} ],
1037                             id  => 1,
1038                         };
1040                         my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
1041                         if (not &check_opsi_res($sres)){
1042                             my $tres= $sres->result;
1044                             my $name= xml_quote($tres->{'name'});
1045                             my $r= $product->{'productId'};
1046                             my $description= xml_quote($tres->{'description'});
1047                             $name=~ s/\//\\\//;
1048                             $description=~ s/\//\\\//;
1049                             $xml_msg=~ s/<xxx><\/xxx>/\n<item><productId>$r<\/productId><name><\/name><description>$description<\/description><\/item>$state<xxx><\/xxx>/;
1050                         }
1052                     }
1053                 }
1055             }
1057         } else {
1058             foreach my $r (@{$res->result}) {
1059                 $callobj = {
1060                     method  => 'getProduct_hash',
1061                     params  => [ $r ],
1062                     id  => 1,
1063                 };
1065                 my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
1066                 if (not &check_opsi_res($sres)){
1067                     my $tres= $sres->result;
1069                     my $name= xml_quote($tres->{'name'});
1070                     my $description= xml_quote($tres->{'description'});
1071                     $name=~ s/\//\\\//;
1072                     $description=~ s/\//\\\//;
1073                     $xml_msg=~ s/<xxx><\/xxx>/\n<item><productId>$r<\/productId><name><\/name><description>$description<\/description><\/item><xxx><\/xxx>/;
1074                 }
1076             }
1078         }
1079     }
1081     $xml_msg=~ s/<xxx><\/xxx>//;
1083     # Retrun Message
1084     return ( $xml_msg );
1088 ## @method opsi_del_client
1089 # Deletes a client from Opsi.
1090 # @param msg - STRING - xml message with tag hostId
1091 # @param msg_hash - HASHREF - message information parsed into a hash
1092 # @param session_id - INTEGER - POE session id of the processing of this message
1093 # @return out_msg - STRING - feedback to GOsa in success and error case
1094 sub opsi_del_client {
1095     my ($msg, $msg_hash, $session_id) = @_;
1096     my $header = @{$msg_hash->{'header'}}[0];
1097     my $source = @{$msg_hash->{'source'}}[0];
1098     my $target = @{$msg_hash->{'target'}}[0];
1099     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
1100     my $hostId;
1101     my $error = 0;
1103     # Build return message with twisted target and source
1104     my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
1105     if (defined $forward_to_gosa) {
1106       &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
1107     }
1109     # Sanity check of needed parameter
1110     if ((exists $msg_hash->{'hostId'}) && (@{$msg_hash->{'hostId'}} != 1))  {
1111         $error++;
1112         &add_content2xml_hash($out_hash, "error_string", "hostId contains no or more than one values");
1113         &add_content2xml_hash($out_hash, "error", "hostId");
1114         &main::daemon_log("$session_id ERROR: hostId contains no or more than one values: $msg", 1); 
1115     }
1117     if (not $error) {
1119     # Get hostID
1120         $hostId = @{$msg_hash->{'hostId'}}[0];
1121         &add_content2xml_hash($out_hash, "hostId", "$hostId");
1123     # JSON Query
1124         my $callobj = {
1125             method  => 'deleteClient',
1126             params  => [ $hostId ],
1127             id  => 1,
1128         };
1129         my $res = $main::opsi_client->call($main::opsi_url, $callobj);
1130     }
1132     # Move to XML string
1133     my $xml_msg= &create_xml_string($out_hash);
1135     # Return message
1136     return ( $xml_msg );
1140 ## @method opsi_install_client
1141 # Set a client in Opsi to install and trigger a wake on lan message (WOL).  
1142 # @param msg - STRING - xml message with tags hostId, macaddress
1143 # @param msg_hash - HASHREF - message information parsed into a hash
1144 # @param session_id - INTEGER - POE session id of the processing of this message
1145 # @return out_msg - STRING - feedback to GOsa in success and error case
1146 sub opsi_install_client {
1147     my ($msg, $msg_hash, $session_id) = @_;
1148     my $header = @{$msg_hash->{'header'}}[0];
1149     my $source = @{$msg_hash->{'source'}}[0];
1150     my $target = @{$msg_hash->{'target'}}[0];
1151     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
1154     my ($hostId, $macaddress);
1156     my $error = 0;
1157     my @out_msg_l;
1159     # Build return message with twisted target and source
1160     my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
1161     if (defined $forward_to_gosa) {
1162         &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
1163     }
1165     # Sanity check of needed parameter
1166     if ((not exists $msg_hash->{'hostId'}) || (@{$msg_hash->{'hostId'}} != 1))  {
1167         $error++;
1168         &add_content2xml_hash($out_hash, "error_string", "no hostId specified or hostId tag invalid");
1169         &add_content2xml_hash($out_hash, "error", "hostId");
1170         &main::daemon_log("$session_id ERROR: no hostId specified or hostId tag invalid: $msg", 1); 
1171     }
1172     if ((not exists $msg_hash->{'macaddress'}) || (@{$msg_hash->{'macaddress'}} != 1))  {
1173         $error++;
1174         &add_content2xml_hash($out_hash, "error_string", "no macaddress specified or macaddress tag invalid");
1175         &add_content2xml_hash($out_hash, "error", "macaddress");
1176         &main::daemon_log("$session_id ERROR: no macaddress specified or macaddress tag invalid: $msg", 1); 
1177     } else {
1178         if ((exists $msg_hash->{'macaddress'}) && 
1179                 ($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)) {  
1180             $macaddress = $1; 
1181         } else { 
1182             $error ++; 
1183             &add_content2xml_hash($out_hash, "error_string", "given mac address is not correct");
1184             &add_content2xml_hash($out_hash, "error", "macaddress");
1185             &main::daemon_log("$session_id ERROR: given mac address is not correct: $msg", 1); 
1186         }
1187     }
1189     if (not $error) {
1191     # Get hostId
1192         $hostId = @{$msg_hash->{'hostId'}}[0];
1193         &add_content2xml_hash($out_hash, "hostId", "$hostId");
1195         # Load all products for this host with status != "not_installed" or actionRequest != "none"
1196         my $callobj = {
1197             method  => 'getProductStates_hash',
1198             params  => [ $hostId ],
1199             id  => 1,
1200         };
1202         my $hres = $main::opsi_client->call($main::opsi_url, $callobj);
1203         if (not &check_opsi_res($hres)){
1204             my $htmp= $hres->result->{$hostId};
1206             # check state != not_installed or action == setup -> load and add
1207             foreach my $product (@{$htmp}){
1208                 # Now we've a couple of hashes...
1209                 if ($product->{'installationStatus'} ne "not_installed" or
1210                         $product->{'actionRequest'} ne "none"){
1212                     # Do an action request for all these -> "setup".
1213                     $callobj = {
1214                         method  => 'setProductActionRequest',
1215                         params  => [ $product->{'productId'}, $hostId, "setup" ],
1216                         id  => 1,
1217                     };
1218                     my $res = $main::opsi_client->call($main::opsi_url, $callobj);
1219                     my ($res_err, $res_err_string) = &check_opsi_res($res);
1220                     if ($res_err){
1221                         &main::daemon_log("$session_id ERROR: cannot set product action request for '$hostId': ".$product->{'productId'}, 1);
1222                     } else {
1223                         &main::daemon_log("$session_id INFO: requesting 'setup' for '".$product->{'productId'}."' on $hostId", 1);
1224                     }
1225                 }
1226             }
1227         }
1228         push(@out_msg_l, &create_xml_string($out_hash));
1229     
1231     # Build wakeup message for client
1232         if (not $error) {
1233             my $wakeup_hash = &create_xml_hash("trigger_wake", "GOSA", "KNOWN_SERVER");
1234             &add_content2xml_hash($wakeup_hash, 'macaddress', $macaddress);
1235             my $wakeup_msg = &create_xml_string($wakeup_hash);
1236             push(@out_msg_l, $wakeup_msg);
1238             # invoke trigger wake for this gosa-si-server
1239             &main::server_server_com::trigger_wake($wakeup_msg, $wakeup_hash, $session_id);
1240         }
1241     }
1242     
1243     # Return messages
1244     return @out_msg_l;
1248 ## @method _set_action
1249 # Set action for an Opsi client
1250 # @param product - STRING - Opsi product
1251 # @param action - STRING - action
1252 # @param hostId - STRING - Opsi hostId
1253 sub _set_action {
1254   my $product= shift;
1255   my $action = shift;
1256   my $hostId = shift;
1257   my $callobj;
1259   $callobj = {
1260     method  => 'setProductActionRequest',
1261     params  => [ $product, $hostId, $action],
1262     id  => 1,
1263   };
1265   $main::opsi_client->call($main::opsi_url, $callobj);
1268 ## @method _set_state
1269 # Set state for an Opsi client
1270 # @param product - STRING - Opsi product
1271 # @param action - STRING - state
1272 # @param hostId - STRING - Opsi hostId
1273 sub _set_state {
1274   my $product = shift;
1275   my $state = shift;
1276   my $hostId = shift;
1277   my $callobj;
1279   $callobj = {
1280     method  => 'setProductState',
1281     params  => [ $product, $hostId, $state ],
1282     id  => 1,
1283   };
1285   $main::opsi_client->call($main::opsi_url, $callobj);
1288 1;