Code

bugfix: add answer message in error case for get_netboot_products
[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 }
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, "hostId_error", "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, "productId_error", "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, "hostId_error", "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, "productId_error", "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, "hostId_error", "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, "macaddress_error", "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, "hostId_error", "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     # Sanity check of needed parameter
415     if ((not exists $msg_hash->{'hostId'}) || (@{$msg_hash->{'hostId'}} != 1))  {
416         &add_content2xml_hash($out_hash, "hostId_error", "no hostId specified or hostId tag invalid");
417         &add_content2xml_hash($out_hash, "error", "hostId");
418         &main::daemon_log("$session_id ERROR: no hostId specified or hostId tag invalid: $msg", 1); 
419         return &create_xml_string($out_hash);
420     }
422     # Get hostID if defined
423     $hostId = @{$msg_hash->{'hostId'}}[0];
424     &add_content2xml_hash($out_hash, "hostId", $hostId);
426     &add_content2xml_hash($out_hash, "xxx", "");
427     $xml_msg= &create_xml_string($out_hash);
429     # For hosts, only return the products that are or get installed
430     my $callobj;
431     $callobj = {
432         method  => 'getNetBootProductIds_list',
433         params  => [ ],
434         id  => 1,
435     };
437     my $res = $main::opsi_client->call($main::opsi_url, $callobj);
438     my %r = ();
439     for (@{$res->result}) { $r{$_} = 1 }
441     if (not &check_opsi_res($res)){
443         if (defined $hostId){
444             $callobj = {
445                 method  => 'getProductStates_hash',
446                 params  => [ $hostId ],
447                 id  => 1,
448             };
450             my $hres = $main::opsi_client->call($main::opsi_url, $callobj);
451             if (not &check_opsi_res($hres)){
452                 my $htmp= $hres->result->{$hostId};
454                 # check state != not_installed or action == setup -> load and add
455                 foreach my $product (@{$htmp}){
457                     if (!defined ($r{$product->{'productId'}})){
458                         next;
459                     }
461                     # Now we've a couple of hashes...
462                     if ($product->{'installationStatus'} ne "not_installed" or
463                             $product->{'actionRequest'} eq "setup"){
464                         my $state= "<state>".$product->{'installationStatus'}."</state><action>".$product->{'actionRequest'}."</action>";
466                         $callobj = {
467                             method  => 'getProduct_hash',
468                             params  => [ $product->{'productId'} ],
469                             id  => 1,
470                         };
472                         my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
473                         if (not &check_opsi_res($sres)){
474                             my $tres= $sres->result;
476                             my $name= xml_quote($tres->{'name'});
477                             my $r= $product->{'productId'};
478                             my $description= xml_quote($tres->{'description'});
479                             $name=~ s/\//\\\//;
480                             $description=~ s/\//\\\//;
481                             $xml_msg=~ s/<xxx><\/xxx>/<item><productId>$r<\/productId><name><\/name><description>$description<\/description><\/item>$state<xxx><\/xxx>/;
482                         }
483                     }
484                 }
486             }
488         } else {
489             foreach my $r (@{$res->result}) {
490                 $callobj = {
491                     method  => 'getProduct_hash',
492                     params  => [ $r ],
493                     id  => 1,
494                 };
496                 my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
497                 if (not &check_opsi_res($sres)){
498                     my $tres= $sres->result;
500                     my $name= xml_quote($tres->{'name'});
501                     my $description= xml_quote($tres->{'description'});
502                     $name=~ s/\//\\\//;
503                     $description=~ s/\//\\\//;
504                     $xml_msg=~ s/<xxx><\/xxx>/<item><productId>$r<\/productId><name><\/name><description>$description<\/description><\/item><xxx><\/xxx>/;
505                 }
506             }
508         }
509     }
510     $xml_msg=~ s/<xxx><\/xxx>//;
512     # Return message
513     return ( $xml_msg );
517 ## @method opsi_get_product_properties
518 # Get product properties for a product and a specific host or gobally for a product.
519 # @param msg - STRING - xml message with tags productId and optional hostId
520 # @param msg_hash - HASHREF - message information parsed into a hash
521 # @param session_id - INTEGER - POE session id of the processing of this message
522 # @return out_msg - STRING - feedback to GOsa in success and error case
523 sub opsi_get_product_properties {
524     my ($msg, $msg_hash, $session_id) = @_;
525     my $header = @{$msg_hash->{'header'}}[0];
526     my $source = @{$msg_hash->{'source'}}[0];
527     my $target = @{$msg_hash->{'target'}}[0];
528     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
529     my ($hostId, $productId);
530     my $xml_msg;
532     # Build return message with twisted target and source
533     my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
534     if (defined $forward_to_gosa) {
535         &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
536     }
538     # Sanity check of needed parameter
539     if ((not exists $msg_hash->{'productId'}) || (@{$msg_hash->{'productId'}} != 1))  {
540         &add_content2xml_hash($out_hash, "productId_error", "no productId specified or productId tag invalid");
541         &add_content2xml_hash($out_hash, "error", "productId");
542         &main::daemon_log("$session_id ERROR: no productId specified or productId tag invalid: $msg", 1); 
544         # Return message
545         return ( &create_xml_string($out_hash) );
546     }
548     # Get productid
549     $productId = @{$msg_hash->{'productId'}}[0];
550     &add_content2xml_hash($out_hash, "producId", "$productId");
552     # Get hostID if defined
553     if (defined @{$msg_hash->{'hostId'}}[0]){
554       $hostId = @{$msg_hash->{'hostId'}}[0];
555       &add_content2xml_hash($out_hash, "hostId", $hostId);
556     }
558     # Load actions
559     my $callobj = {
560       method  => 'getPossibleProductActions_list',
561       params  => [ $productId ],
562       id  => 1,
563     };
564     my $res = $main::opsi_client->call($main::opsi_url, $callobj);
565     if (not &check_opsi_res($res)){
566       foreach my $action (@{$res->result}){
567         &add_content2xml_hash($out_hash, "action", $action);
568       }
569     }
571     # Add place holder
572     &add_content2xml_hash($out_hash, "xxx", "");
574     # Move to XML string
575     $xml_msg= &create_xml_string($out_hash);
577     # JSON Query
578     if (defined $hostId){
579       $callobj = {
580           method  => 'getProductProperties_hash',
581           params  => [ $productId, $hostId ],
582           id  => 1,
583       };
584     } else {
585       $callobj = {
586           method  => 'getProductProperties_hash',
587           params  => [ $productId ],
588           id  => 1,
589       };
590     }
592     $res = $main::opsi_client->call($main::opsi_url, $callobj);
593     if (not &check_opsi_res($res)){
594         my $r= $res->result;
595         foreach my $key (keys %{$r}) {
596             my $item= "<item>";
597             my $value= $r->{$key};
598             if (UNIVERSAL::isa( $value, "ARRAY" )){
599                 foreach my $subval (@{$value}){
600                     $item.= "<$key>".xml_quote($subval)."</$key>";
601                 }
602             } else {
603                 $item.= "<$key>".xml_quote($value)."</$key>";
604             }
605             $item.= "</item>";
606             $xml_msg=~ s/<xxx><\/xxx>/$item<xxx><\/xxx>/;
607         }
608     }
610     $xml_msg=~ s/<xxx><\/xxx>//;
612     # Return message
613     return ( $xml_msg );
617 ## @method opsi_set_product_properties
618 # 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.
619 # @param msg - STRING - xml message with tags productId, action, state and optional hostId, action and state
620 # @param msg_hash - HASHREF - message information parsed into a hash
621 # @param session_id - INTEGER - POE session id of the processing of this message
622 # @return out_msg - STRING - feedback to GOsa in success and error case
623 sub opsi_set_product_properties {
624     my ($msg, $msg_hash, $session_id) = @_;
625     my $header = @{$msg_hash->{'header'}}[0];
626     my $source = @{$msg_hash->{'source'}}[0];
627     my $target = @{$msg_hash->{'target'}}[0];
628     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
629     my ($productId, $hostId);
631     # Build return message with twisted target and source
632     my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
633     if (defined $forward_to_gosa) {
634         &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
635     }
637     # Sanity check of needed parameter
638     if ((not exists $msg_hash->{'productId'}) || (@{$msg_hash->{'productId'}} != 1))  {
639         &add_content2xml_hash($out_hash, "productId_error", "no productId specified or productId tag invalid");
640         &add_content2xml_hash($out_hash, "error", "productId");
641         &main::daemon_log("$session_id ERROR: no productId specified or productId tag invalid: $msg", 1); 
642         return ( &create_xml_string($out_hash) );
643     }
644     if (not exists $msg_hash->{'item'}) {
645         &add_content2xml_hash($out_hash, "item_error", "message needs one xml-tag 'item' and within the xml-tags 'name' and 'value'");
646         &add_content2xml_hash($out_hash, "error", "item");
647         &main::daemon_log("$session_id ERROR: message needs one xml-tag 'item' and within the xml-tags 'name' and 'value': $msg", 1); 
648         return ( &create_xml_string($out_hash) );
649     } else {
650         if ((not exists @{$msg_hash->{'item'}}[0]->{'name'}) || (@{@{$msg_hash->{'item'}}[0]->{'name'}} != 1 )) {
651             &add_content2xml_hash($out_hash, "name_error", "message needs within the xml-tag 'item' one xml-tags 'name'");
652             &add_content2xml_hash($out_hash, "error", "name");
653             &main::daemon_log("$session_id ERROR: message needs within the xml-tag 'item' one xml-tags 'name': $msg", 1); 
654             return ( &create_xml_string($out_hash) );
655         }
656         if ((not exists @{$msg_hash->{'item'}}[0]->{'value'}) || (@{@{$msg_hash->{'item'}}[0]->{'value'}} != 1 )) {
657             &add_content2xml_hash($out_hash, "value_error", "message needs within the xml-tag 'item' one xml-tags 'value'");
658             &add_content2xml_hash($out_hash, "error", "value");
659             &main::daemon_log("$session_id ERROR: message needs within the xml-tag 'item' one xml-tags 'value': $msg", 1); 
660             return ( &create_xml_string($out_hash) );
661         }
662     }
663     if ((exists $msg_hash->{'hostId'}) && (@{$msg_hash->{'hostId'}} != 1))  {
664         &add_content2xml_hash($out_hash, "hostId_error", "hostId contains no or more than one values");
665         &add_content2xml_hash($out_hash, "error", "hostId");
666         &main::daemon_log("$session_id ERROR: hostId contains no or more than one values: $msg", 1); 
667         return ( &create_xml_string($out_hash) );
668     }
670         
671     # Get productId
672     $productId =  @{$msg_hash->{'productId'}}[0];
673     &add_content2xml_hash($out_hash, "productId", $productId);
675     # Get hostID if defined
676     if (exists $msg_hash->{'hostId'}){
677         $hostId = @{$msg_hash->{'hostId'}}[0];
678         &add_content2xml_hash($out_hash, "hostId", $hostId);
679     }
681     # Set product states if requested
682     if (defined @{$msg_hash->{'action'}}[0]){
683         &_set_action($productId, @{$msg_hash->{'action'}}[0], $hostId);
684     }
685     if (defined @{$msg_hash->{'state'}}[0]){
686         &_set_state($productId, @{$msg_hash->{'state'}}[0], $hostId);
687     }
689     # Find properties
690     foreach my $item (@{$msg_hash->{'item'}}){
691         # JSON Query
692         my $callobj;
694         if (defined $hostId){
695             $callobj = {
696                 method  => 'setProductProperty',
697                 params  => [ $productId, $item->{'name'}[0], $item->{'value'}[0], $hostId ],
698                 id  => 1,
699             };
700         } else {
701             $callobj = {
702                 method  => 'setProductProperty',
703                 params  => [ $productId, $item->{'name'}[0], $item->{'value'}[0] ],
704                 id  => 1,
705             };
706         }
708         my $res = $main::opsi_client->call($main::opsi_url, $callobj);
709         my ($res_err, $res_err_string) = &check_opsi_res($res);
711         if ($res_err){
712             &man::daemon_log("$session_id ERROR: communication failed while setting '".$item->{'name'}[0]."': ".$res_err_string, 1);
713             &add_content2xml_hash($out_hash, "error", $res_err_string);
714         }
715     }
718     # Return message
719     return ( &create_xml_string($out_hash) );
723 ## @method opsi_get_client_hardware
724 # Reports client hardware inventory.
725 # @param msg - STRING - xml message with tag hostId
726 # @param msg_hash - HASHREF - message information parsed into a hash
727 # @param session_id - INTEGER - POE session id of the processing of this message
728 # @return out_msg - STRING - feedback to GOsa in success and error case
729 sub opsi_get_client_hardware {
730     my ($msg, $msg_hash, $session_id) = @_;
731     my $header = @{$msg_hash->{'header'}}[0];
732     my $source = @{$msg_hash->{'source'}}[0];
733     my $target = @{$msg_hash->{'target'}}[0];
734     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
735     my $hostId;
736     my $error = 0;
737     my $xml_msg;
739     # Build return message with twisted target and source
740     my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
741     if (defined $forward_to_gosa) {
742       &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
743     }
745     # Sanity check of needed parameter
746     if ((exists $msg_hash->{'hostId'}) && (@{$msg_hash->{'hostId'}} != 1))  {
747         $error++;
748         &add_content2xml_hash($out_hash, "hostId_error", "hostId contains no or more than one values");
749         &add_content2xml_hash($out_hash, "error", "hostId");
750         &main::daemon_log("$session_id ERROR: hostId contains no or more than one values: $msg", 1); 
751     }
753     if (not $error) {
755     # Get hostID
756         $hostId = @{$msg_hash->{'hostId'}}[0];
757         &add_content2xml_hash($out_hash, "hostId", "$hostId");
758         &add_content2xml_hash($out_hash, "xxx", "");
759     }    
761     # Move to XML string
762     $xml_msg= &create_xml_string($out_hash);
763     
764     if (not $error) {
766     # JSON Query
767         my $callobj = {
768             method  => 'getHardwareInformation_hash',
769             params  => [ $hostId ],
770             id  => 1,
771         };
773         my $res = $main::opsi_client->call($main::opsi_url, $callobj);
774         if (not &check_opsi_res($res)){
775             my $result= $res->result;
776             foreach my $r (keys %{$result}){
777                 my $item= "<item><id>".xml_quote($r)."</id>";
778                 my $value= $result->{$r};
779                 foreach my $sres (@{$value}){
781                     foreach my $dres (keys %{$sres}){
782                         if (defined $sres->{$dres}){
783                             $item.= "<$dres>".xml_quote($sres->{$dres})."</$dres>";
784                         }
785                     }
787                 }
788                 $item.= "</item>";
789                 $xml_msg=~ s%<xxx></xxx>%$item<xxx></xxx>%;
791             }
792         }
794         $xml_msg=~ s/<xxx><\/xxx>//;
796     }
798     # Return message
799     return ( $xml_msg );
803 ## @method opsi_list_clients
804 # Reports all Opsi clients. 
805 # @param msg - STRING - xml message 
806 # @param msg_hash - HASHREF - message information parsed into a hash
807 # @param session_id - INTEGER - POE session id of the processing of this message
808 # @return out_msg - STRING - feedback to GOsa in success and error case
809 sub opsi_list_clients {
810     my ($msg, $msg_hash, $session_id) = @_;
811     my $header = @{$msg_hash->{'header'}}[0];
812     my $source = @{$msg_hash->{'source'}}[0];
813     my $target = @{$msg_hash->{'target'}}[0];
814     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
816     # Build return message with twisted target and source
817     my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
818     if (defined $forward_to_gosa) {
819       &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
820     }
821     &add_content2xml_hash($out_hash, "xxx", "");
823     # Move to XML string
824     my $xml_msg= &create_xml_string($out_hash);
826     # JSON Query
827     my $callobj = {
828         method  => 'getClients_listOfHashes',
829         params  => [ ],
830         id  => 1,
831     };
832     my $res = $main::opsi_client->call($main::opsi_url, $callobj);
833     if (not &check_opsi_res($res)){
834         foreach my $host (@{$res->result}){
835             my $item= "<item><name>".$host->{'hostId'}."</name>";
836             if (defined($host->{'description'})){
837                 $item.= "<description>".xml_quote($host->{'description'})."</description>";
838             }
839             if (defined($host->{'notes'})){
840                 $item.= "<notes>".xml_quote($host->{'notes'})."</notes>";
841             }
843             $callobj = {
844               method  => 'getIpAddress',
845               params  => [ $host->{'hostId'} ],
846               id  => 1,
847             };
848             my $sres= $main::opsi_client->call($main::opsi_url, $callobj);
849             if ( not &check_opsi_res($sres)){
850               $item.= "<ip>".xml_quote($sres->result)."</ip>";
851             }
853             $callobj = {
854               method  => 'getMacAddress',
855               params  => [ $host->{'hostId'} ],
856               id  => 1,
857             };
858             $sres= $main::opsi_client->call($main::opsi_url, $callobj);
859             if ( not &check_opsi_res($sres)){
860                 $item.= "<mac>".xml_quote($sres->result)."</mac>";
861             }
862             $item.= "</item>";
863             $xml_msg=~ s%<xxx></xxx>%$item<xxx></xxx>%;
864         }
865     }
867     $xml_msg=~ s/<xxx><\/xxx>//;
868     return ( $xml_msg );
872 ## @method opsi_get_client_software
873 # Reports client software inventory.
874 # @param msg - STRING - xml message with tag hostId
875 # @param msg_hash - HASHREF - message information parsed into a hash
876 # @param session_id - INTEGER - POE session id of the processing of this message
877 # @return out_msg - STRING - feedback to GOsa in success and error case
878 sub opsi_get_client_software {
879     my ($msg, $msg_hash, $session_id) = @_;
880     my $header = @{$msg_hash->{'header'}}[0];
881     my $source = @{$msg_hash->{'source'}}[0];
882     my $target = @{$msg_hash->{'target'}}[0];
883     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
884     my $error = 0;
885     my $hostId;
886     my $xml_msg;
888     # Build return message with twisted target and source
889     my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
890     if (defined $forward_to_gosa) {
891       &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
892     }
894     # Sanity check of needed parameter
895     if ((exists $msg_hash->{'hostId'}) && (@{$msg_hash->{'hostId'}} != 1))  {
896         $error++;
897         &add_content2xml_hash($out_hash, "hostId_error", "hostId contains no or more than one values");
898         &add_content2xml_hash($out_hash, "error", "hostId");
899         &main::daemon_log("$session_id ERROR: hostId contains no or more than one values: $msg", 1); 
900     }
902     if (not $error) {
904     # Get hostID
905         $hostId = @{$msg_hash->{'hostId'}}[0];
906         &add_content2xml_hash($out_hash, "hostId", "$hostId");
907         &add_content2xml_hash($out_hash, "xxx", "");
908     }
910     $xml_msg= &create_xml_string($out_hash);
912     if (not $error) {
914     # JSON Query
915         my $callobj = {
916             method  => 'getSoftwareInformation_hash',
917             params  => [ $hostId ],
918             id  => 1,
919         };
921         my $res = $main::opsi_client->call($main::opsi_url, $callobj);
922         if (not &check_opsi_res($res)){
923             my $result= $res->result;
924 # TODO : Ist das hier schon fertig???   
925         }
927         $xml_msg=~ s/<xxx><\/xxx>//;
929     }
931     # Return message
932     return ( $xml_msg );
936 ## @method opsi_get_local_products
937 # Reports product for given hostId or globally.
938 # @param msg - STRING - xml message with optional tag hostId
939 # @param msg_hash - HASHREF - message information parsed into a hash
940 # @param session_id - INTEGER - POE session id of the processing of this message
941 # @return out_msg - STRING - feedback to GOsa in success and error case
942 sub opsi_get_local_products {
943     my ($msg, $msg_hash, $session_id) = @_;
944     my $header = @{$msg_hash->{'header'}}[0];
945     my $source = @{$msg_hash->{'source'}}[0];
946     my $target = @{$msg_hash->{'target'}}[0];
947     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
948     my $hostId;
950     # Build return message with twisted target and source
951     my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
952     if (defined $forward_to_gosa) {
953         &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
954     }
955     &add_content2xml_hash($out_hash, "xxx", "");
957     # Get hostID if defined
958     if ((exists $msg_hash->{'hostId'}) && (@{$msg_hash->{'hostId'}} == 1))  {
959         $hostId = @{$msg_hash->{'hostId'}}[0];
960         &add_content2xml_hash($out_hash, "hostId", $hostId);
961     }
963     # Move to XML string
964     my $xml_msg= &create_xml_string($out_hash);
966     # For hosts, only return the products that are or get installed
967     my $callobj;
968     $callobj = {
969         method  => 'getLocalBootProductIds_list',
970         params  => [ ],
971         id  => 1,
972     };
974     my $res = $main::opsi_client->call($main::opsi_url, $callobj);
975     my %r = ();
976     for (@{$res->result}) { $r{$_} = 1 }
978     if (not &check_opsi_res($res)){
980         if (defined $hostId){
981             $callobj = {
982                 method  => 'getProductStates_hash',
983                 params  => [ $hostId ],
984                 id  => 1,
985             };
987             my $hres = $main::opsi_client->call($main::opsi_url, $callobj);
988             if (not &check_opsi_res($hres)){
989                 my $htmp= $hres->result->{$hostId};
991                 # Check state != not_installed or action == setup -> load and add
992                 foreach my $product (@{$htmp}){
994                     if (!defined ($r{$product->{'productId'}})){
995                         next;
996                     }
998                     # Now we've a couple of hashes...
999                     if ($product->{'installationStatus'} ne "not_installed" or
1000                             $product->{'actionRequest'} eq "setup"){
1001                         my $state= "<state>".$product->{'installationStatus'}."</state><action>".$product->{'actionRequest'}."</action>";
1003                         $callobj = {
1004                             method  => 'getProduct_hash',
1005                             params  => [ $product->{'productId'} ],
1006                             id  => 1,
1007                         };
1009                         my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
1010                         if (not &check_opsi_res($sres)){
1011                             my $tres= $sres->result;
1013                             my $name= xml_quote($tres->{'name'});
1014                             my $r= $product->{'productId'};
1015                             my $description= xml_quote($tres->{'description'});
1016                             $name=~ s/\//\\\//;
1017                             $description=~ s/\//\\\//;
1018                             $xml_msg=~ s/<xxx><\/xxx>/<item><productId>$r<\/productId><name><\/name><description>$description<\/description><\/item>$state<xxx><\/xxx>/;
1019                         }
1021                     }
1022                 }
1024             }
1026         } else {
1027             foreach my $r (@{$res->result}) {
1028                 $callobj = {
1029                     method  => 'getProduct_hash',
1030                     params  => [ $r ],
1031                     id  => 1,
1032                 };
1034                 my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
1035                 if (not &check_opsi_res($sres)){
1036                     my $tres= $sres->result;
1038                     my $name= xml_quote($tres->{'name'});
1039                     my $description= xml_quote($tres->{'description'});
1040                     $name=~ s/\//\\\//;
1041                     $description=~ s/\//\\\//;
1042                     $xml_msg=~ s/<xxx><\/xxx>/<item><productId>$r<\/productId><name><\/name><description>$description<\/description><\/item><xxx><\/xxx>/;
1043                 }
1045             }
1047         }
1048     }
1050     $xml_msg=~ s/<xxx><\/xxx>//;
1052     # Retrun Message
1053     return ( $xml_msg );
1057 ## @method opsi_del_client
1058 # Deletes a client from Opsi.
1059 # @param msg - STRING - xml message with tag hostId
1060 # @param msg_hash - HASHREF - message information parsed into a hash
1061 # @param session_id - INTEGER - POE session id of the processing of this message
1062 # @return out_msg - STRING - feedback to GOsa in success and error case
1063 sub opsi_del_client {
1064     my ($msg, $msg_hash, $session_id) = @_;
1065     my $header = @{$msg_hash->{'header'}}[0];
1066     my $source = @{$msg_hash->{'source'}}[0];
1067     my $target = @{$msg_hash->{'target'}}[0];
1068     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
1069     my $hostId;
1070     my $error = 0;
1072     # Build return message with twisted target and source
1073     my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
1074     if (defined $forward_to_gosa) {
1075       &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
1076     }
1078     # Sanity check of needed parameter
1079     if ((exists $msg_hash->{'hostId'}) && (@{$msg_hash->{'hostId'}} != 1))  {
1080         $error++;
1081         &add_content2xml_hash($out_hash, "hostId_error", "hostId contains no or more than one values");
1082         &add_content2xml_hash($out_hash, "error", "hostId");
1083         &main::daemon_log("$session_id ERROR: hostId contains no or more than one values: $msg", 1); 
1084     }
1086     if (not $error) {
1088     # Get hostID
1089         $hostId = @{$msg_hash->{'hostId'}}[0];
1090         &add_content2xml_hash($out_hash, "hostId", "$hostId");
1092     # JSON Query
1093         my $callobj = {
1094             method  => 'deleteClient',
1095             params  => [ $hostId ],
1096             id  => 1,
1097         };
1098         my $res = $main::opsi_client->call($main::opsi_url, $callobj);
1099     }
1101     # Move to XML string
1102     my $xml_msg= &create_xml_string($out_hash);
1104     # Return message
1105     return ( $xml_msg );
1109 ## @method opsi_install_client
1110 # Set a client in Opsi to install and trigger a wake on lan message (WOL).  
1111 # @param msg - STRING - xml message with tags hostId, macaddress
1112 # @param msg_hash - HASHREF - message information parsed into a hash
1113 # @param session_id - INTEGER - POE session id of the processing of this message
1114 # @return out_msg - STRING - feedback to GOsa in success and error case
1115 sub opsi_install_client {
1116     my ($msg, $msg_hash, $session_id) = @_;
1117     my $header = @{$msg_hash->{'header'}}[0];
1118     my $source = @{$msg_hash->{'source'}}[0];
1119     my $target = @{$msg_hash->{'target'}}[0];
1120     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
1123     my ($hostId, $macaddress);
1125     my $error = 0;
1126     my @out_msg_l;
1128     # Build return message with twisted target and source
1129     my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
1130     if (defined $forward_to_gosa) {
1131         &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
1132     }
1134     # Sanity check of needed parameter
1135     if ((not exists $msg_hash->{'hostId'}) || (@{$msg_hash->{'hostId'}} != 1))  {
1136         $error++;
1137         &add_content2xml_hash($out_hash, "hostId_error", "no hostId specified or hostId tag invalid");
1138         &add_content2xml_hash($out_hash, "error", "hostId");
1139         &main::daemon_log("$session_id ERROR: no hostId specified or hostId tag invalid: $msg", 1); 
1140     }
1141     if ((not exists $msg_hash->{'macaddress'}) || (@{$msg_hash->{'macaddress'}} != 1))  {
1142         $error++;
1143         &add_content2xml_hash($out_hash, "macaddress_error", "no macaddress specified or macaddress tag invalid");
1144         &add_content2xml_hash($out_hash, "error", "macaddress");
1145         &main::daemon_log("$session_id ERROR: no macaddress specified or macaddress tag invalid: $msg", 1); 
1146     } else {
1147         if ((exists $msg_hash->{'macaddress'}) && 
1148                 ($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)) {  
1149             $macaddress = $1; 
1150         } else { 
1151             $error ++; 
1152             &add_content2xml_hash($out_hash, "macaddress_error", "given mac address is not correct");
1153             &add_content2xml_hash($out_hash, "error", "macaddress");
1154             &main::daemon_log("$session_id ERROR: given mac address is not correct: $msg", 1); 
1155         }
1156     }
1158     if (not $error) {
1160     # Get hostId
1161         $hostId = @{$msg_hash->{'hostId'}}[0];
1162         &add_content2xml_hash($out_hash, "hostId", "$hostId");
1164         # Load all products for this host with status != "not_installed" or actionRequest != "none"
1165         my $callobj = {
1166             method  => 'getProductStates_hash',
1167             params  => [ $hostId ],
1168             id  => 1,
1169         };
1171         my $hres = $main::opsi_client->call($main::opsi_url, $callobj);
1172         if (not &check_opsi_res($hres)){
1173             my $htmp= $hres->result->{$hostId};
1175             # check state != not_installed or action == setup -> load and add
1176             foreach my $product (@{$htmp}){
1177                 # Now we've a couple of hashes...
1178                 if ($product->{'installationStatus'} ne "not_installed" or
1179                         $product->{'actionRequest'} ne "none"){
1181                     # Do an action request for all these -> "setup".
1182                     $callobj = {
1183                         method  => 'setProductActionRequest',
1184                         params  => [ $product->{'productId'}, $hostId, "setup" ],
1185                         id  => 1,
1186                     };
1187                     my $res = $main::opsi_client->call($main::opsi_url, $callobj);
1188                     my ($res_err, $res_err_string) = &check_opsi_res($res);
1189                     if ($res_err){
1190                         &main::daemon_log("$session_id ERROR: cannot set product action request for '$hostId': ".$product->{'productId'}, 1);
1191                     } else {
1192                         &main::daemon_log("$session_id INFO: requesting 'setup' for '".$product->{'productId'}."' on $hostId", 1);
1193                     }
1194                 }
1195             }
1196         }
1197         push(@out_msg_l, &create_xml_string($out_hash));
1198     
1200     # Build wakeup message for client
1201         if (not $error) {
1202             my $wakeup_hash = &create_xml_hash("trigger_wake", "GOSA", "KNOWN_SERVER");
1203             &add_content2xml_hash($wakeup_hash, 'macAddress', $macaddress);
1204             my $wakeup_msg = &create_xml_string($wakeup_hash);
1205             push(@out_msg_l, $wakeup_msg);
1207             # invoke trigger wake for this gosa-si-server
1208             &main::server_server_com::trigger_wake($wakeup_msg, $wakeup_hash, $session_id);
1209         }
1210     }
1211     
1212     # Return messages
1213     return @out_msg_l;
1217 ## @method _set_action
1218 # Set action for an Opsi client
1219 # @param product - STRING - Opsi product
1220 # @param action - STRING - action
1221 # @param hostId - STRING - Opsi hostId
1222 sub _set_action {
1223   my $product= shift;
1224   my $action = shift;
1225   my $hostId = shift;
1226   my $callobj;
1228   $callobj = {
1229     method  => 'setProductActionRequest',
1230     params  => [ $product, $hostId, $action],
1231     id  => 1,
1232   };
1234   $main::opsi_client->call($main::opsi_url, $callobj);
1237 ## @method _set_state
1238 # Set state for an Opsi client
1239 # @param product - STRING - Opsi product
1240 # @param action - STRING - state
1241 # @param hostId - STRING - Opsi hostId
1242 sub _set_state {
1243   my $product = shift;
1244   my $state = shift;
1245   my $hostId = shift;
1246   my $callobj;
1248   $callobj = {
1249     method  => 'setProductState',
1250     params  => [ $product, $hostId, $state ],
1251     id  => 1,
1252   };
1254   $main::opsi_client->call($main::opsi_url, $callobj);
1257 1;