Code

bugfix: delete print STDERR line
[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 $error = 0;
407     my $xml_msg;
409     # Build return message with twisted target and source
410     my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
411     if (defined $forward_to_gosa) {
412         &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
413     }
415     # Sanity check of needed parameter
416     if ((not exists $msg_hash->{'hostId'}) || (@{$msg_hash->{'hostId'}} != 1))  {
417         $error++;
418         &add_content2xml_hash($out_hash, "hostId_error", "no hostId specified or hostId tag invalid");
419         &add_content2xml_hash($out_hash, "error", "hostId");
420         &main::daemon_log("$session_id ERROR: no hostId specified or hostId tag invalid: $msg", 1); 
421     }
423     if (not $error) {
425         # Get hostID if defined
426         $hostId = @{$msg_hash->{'hostId'}}[0];
427         &add_content2xml_hash($out_hash, "hostId", $hostId);
429         &add_content2xml_hash($out_hash, "xxx", "");
430         $xml_msg= &create_xml_string($out_hash);
432         # For hosts, only return the products that are or get installed
433         my $callobj;
434         $callobj = {
435             method  => 'getNetBootProductIds_list',
436             params  => [ ],
437             id  => 1,
438         };
440         my $res = $main::opsi_client->call($main::opsi_url, $callobj);
441         my %r = ();
442         for (@{$res->result}) { $r{$_} = 1 }
444         if (not &check_opsi_res($res)){
446             if (defined $hostId){
447                 $callobj = {
448                     method  => 'getProductStates_hash',
449                     params  => [ $hostId ],
450                     id  => 1,
451                 };
453                 my $hres = $main::opsi_client->call($main::opsi_url, $callobj);
454                 if (not &check_opsi_res($hres)){
455                     my $htmp= $hres->result->{$hostId};
457                     # check state != not_installed or action == setup -> load and add
458                     foreach my $product (@{$htmp}){
460                         if (!defined ($r{$product->{'productId'}})){
461                             next;
462                         }
464                         # Now we've a couple of hashes...
465                         if ($product->{'installationStatus'} ne "not_installed" or
466                                 $product->{'actionRequest'} eq "setup"){
467                             my $state= "<state>".$product->{'installationStatus'}."</state><action>".$product->{'actionRequest'}."</action>";
469                             $callobj = {
470                                 method  => 'getProduct_hash',
471                                 params  => [ $product->{'productId'} ],
472                                 id  => 1,
473                             };
475                             my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
476                             if (not &check_opsi_res($sres)){
477                                 my $tres= $sres->result;
479                                 my $name= xml_quote($tres->{'name'});
480                                 my $r= $product->{'productId'};
481                                 my $description= xml_quote($tres->{'description'});
482                                 $name=~ s/\//\\\//;
483                                 $description=~ s/\//\\\//;
484                                 $xml_msg=~ s/<xxx><\/xxx>/<item><productId>$r<\/productId><name><\/name><description>$description<\/description><\/item>$state<xxx><\/xxx>/;
485                             }
486                         }
487                     }
489                 }
491             } else {
492                 foreach my $r (@{$res->result}) {
493                     $callobj = {
494                         method  => 'getProduct_hash',
495                         params  => [ $r ],
496                         id  => 1,
497                     };
499                     my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
500                     if (not &check_opsi_res($sres)){
501                         my $tres= $sres->result;
503                         my $name= xml_quote($tres->{'name'});
504                         my $description= xml_quote($tres->{'description'});
505                         $name=~ s/\//\\\//;
506                         $description=~ s/\//\\\//;
507                         $xml_msg=~ s/<xxx><\/xxx>/<item><productId>$r<\/productId><name><\/name><description>$description<\/description><\/item><xxx><\/xxx>/;
508                     }
509                 }
511             }
512         }
513         $xml_msg=~ s/<xxx><\/xxx>//;
514     }
516     # Return message
517     return ( $xml_msg );
521 ## @method opsi_get_product_properties
522 # Get product properties for a product and a specific host or gobally for a product.
523 # @param msg - STRING - xml message with tags productId and optional hostId
524 # @param msg_hash - HASHREF - message information parsed into a hash
525 # @param session_id - INTEGER - POE session id of the processing of this message
526 # @return out_msg - STRING - feedback to GOsa in success and error case
527 sub opsi_get_product_properties {
528     my ($msg, $msg_hash, $session_id) = @_;
529     my $header = @{$msg_hash->{'header'}}[0];
530     my $source = @{$msg_hash->{'source'}}[0];
531     my $target = @{$msg_hash->{'target'}}[0];
532     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
533     my ($hostId, $productId);
534     my $xml_msg;
536     # Build return message with twisted target and source
537     my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
538     if (defined $forward_to_gosa) {
539         &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
540     }
542     # Sanity check of needed parameter
543     if ((not exists $msg_hash->{'productId'}) || (@{$msg_hash->{'productId'}} != 1))  {
544         &add_content2xml_hash($out_hash, "productId_error", "no productId specified or productId tag invalid");
545         &add_content2xml_hash($out_hash, "error", "productId");
546         &main::daemon_log("$session_id ERROR: no productId specified or productId tag invalid: $msg", 1); 
548         # Return message
549         return ( &create_xml_string($out_hash) );
550     }
552     # Get productid
553     $productId = @{$msg_hash->{'productId'}}[0];
554     &add_content2xml_hash($out_hash, "producId", "$productId");
556     # Get hostID if defined
557     if (defined @{$msg_hash->{'hostId'}}[0]){
558       $hostId = @{$msg_hash->{'hostId'}}[0];
559       &add_content2xml_hash($out_hash, "hostId", $hostId);
560     }
562     # Load actions
563     my $callobj = {
564       method  => 'getPossibleProductActions_list',
565       params  => [ $productId ],
566       id  => 1,
567     };
568     my $res = $main::opsi_client->call($main::opsi_url, $callobj);
569     if (not &check_opsi_res($res)){
570       foreach my $action (@{$res->result}){
571         &add_content2xml_hash($out_hash, "action", $action);
572       }
573     }
575     # Add place holder
576     &add_content2xml_hash($out_hash, "xxx", "");
578     # Move to XML string
579     $xml_msg= &create_xml_string($out_hash);
581     # JSON Query
582     if (defined $hostId){
583       $callobj = {
584           method  => 'getProductProperties_hash',
585           params  => [ $productId, $hostId ],
586           id  => 1,
587       };
588     } else {
589       $callobj = {
590           method  => 'getProductProperties_hash',
591           params  => [ $productId ],
592           id  => 1,
593       };
594     }
596     $res = $main::opsi_client->call($main::opsi_url, $callobj);
597     if (not &check_opsi_res($res)){
598         my $r= $res->result;
599         foreach my $key (keys %{$r}) {
600             my $item= "<item>";
601             my $value= $r->{$key};
602             if (UNIVERSAL::isa( $value, "ARRAY" )){
603                 foreach my $subval (@{$value}){
604                     $item.= "<$key>".xml_quote($subval)."</$key>";
605                 }
606             } else {
607                 $item.= "<$key>".xml_quote($value)."</$key>";
608             }
609             $item.= "</item>";
610             $xml_msg=~ s/<xxx><\/xxx>/$item<xxx><\/xxx>/;
611         }
612     }
614     $xml_msg=~ s/<xxx><\/xxx>//;
616     # Return message
617     return ( $xml_msg );
621 ## @method opsi_set_product_properties
622 # 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.
623 # @param msg - STRING - xml message with tags productId, action, state and optional hostId, action and state
624 # @param msg_hash - HASHREF - message information parsed into a hash
625 # @param session_id - INTEGER - POE session id of the processing of this message
626 # @return out_msg - STRING - feedback to GOsa in success and error case
627 sub opsi_set_product_properties {
628     my ($msg, $msg_hash, $session_id) = @_;
629     my $header = @{$msg_hash->{'header'}}[0];
630     my $source = @{$msg_hash->{'source'}}[0];
631     my $target = @{$msg_hash->{'target'}}[0];
632     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
633     my ($productId, $hostId);
635     # Build return message with twisted target and source
636     my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
637     if (defined $forward_to_gosa) {
638         &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
639     }
641     # Sanity check of needed parameter
642     if ((not exists $msg_hash->{'productId'}) || (@{$msg_hash->{'productId'}} != 1))  {
643         &add_content2xml_hash($out_hash, "productId_error", "no productId specified or productId tag invalid");
644         &add_content2xml_hash($out_hash, "error", "productId");
645         &main::daemon_log("$session_id ERROR: no productId specified or productId tag invalid: $msg", 1); 
646         return ( &create_xml_string($out_hash) );
647     }
648     if (not exists $msg_hash->{'item'}) {
649         &add_content2xml_hash($out_hash, "item_error", "message needs one xml-tag 'item' and within the xml-tags 'name' and 'value'");
650         &add_content2xml_hash($out_hash, "error", "item");
651         &main::daemon_log("$session_id ERROR: message needs one xml-tag 'item' and within the xml-tags 'name' and 'value': $msg", 1); 
652         return ( &create_xml_string($out_hash) );
653     } else {
654         if ((not exists @{$msg_hash->{'item'}}[0]->{'name'}) || (@{@{$msg_hash->{'item'}}[0]->{'name'}} != 1 )) {
655             &add_content2xml_hash($out_hash, "name_error", "message needs within the xml-tag 'item' one xml-tags 'name'");
656             &add_content2xml_hash($out_hash, "error", "name");
657             &main::daemon_log("$session_id ERROR: message needs within the xml-tag 'item' one xml-tags 'name': $msg", 1); 
658             return ( &create_xml_string($out_hash) );
659         }
660         if ((not exists @{$msg_hash->{'item'}}[0]->{'value'}) || (@{@{$msg_hash->{'item'}}[0]->{'value'}} != 1 )) {
661             &add_content2xml_hash($out_hash, "value_error", "message needs within the xml-tag 'item' one xml-tags 'value'");
662             &add_content2xml_hash($out_hash, "error", "value");
663             &main::daemon_log("$session_id ERROR: message needs within the xml-tag 'item' one xml-tags 'value': $msg", 1); 
664             return ( &create_xml_string($out_hash) );
665         }
666     }
667     if ((exists $msg_hash->{'hostId'}) && (@{$msg_hash->{'hostId'}} != 1))  {
668         &add_content2xml_hash($out_hash, "hostId_error", "hostId contains no or more than one values");
669         &add_content2xml_hash($out_hash, "error", "hostId");
670         &main::daemon_log("$session_id ERROR: hostId contains no or more than one values: $msg", 1); 
671         return ( &create_xml_string($out_hash) );
672     }
674         
675     # Get productId
676     $productId =  @{$msg_hash->{'productId'}}[0];
677     &add_content2xml_hash($out_hash, "productId", $productId);
679     # Get hostID if defined
680     if (exists $msg_hash->{'hostId'}){
681         $hostId = @{$msg_hash->{'hostId'}}[0];
682         &add_content2xml_hash($out_hash, "hostId", $hostId);
683     }
685     # Set product states if requested
686     if (defined @{$msg_hash->{'action'}}[0]){
687         &_set_action($productId, @{$msg_hash->{'action'}}[0], $hostId);
688     }
689     if (defined @{$msg_hash->{'state'}}[0]){
690         &_set_state($productId, @{$msg_hash->{'state'}}[0], $hostId);
691     }
693     # Find properties
694     foreach my $item (@{$msg_hash->{'item'}}){
695         # JSON Query
696         my $callobj;
698         if (defined $hostId){
699             $callobj = {
700                 method  => 'setProductProperty',
701                 params  => [ $productId, $item->{'name'}[0], $item->{'value'}[0], $hostId ],
702                 id  => 1,
703             };
704         } else {
705             $callobj = {
706                 method  => 'setProductProperty',
707                 params  => [ $productId, $item->{'name'}[0], $item->{'value'}[0] ],
708                 id  => 1,
709             };
710         }
712         my $res = $main::opsi_client->call($main::opsi_url, $callobj);
713         my ($res_err, $res_err_string) = &check_opsi_res($res);
715         if ($res_err){
716             &man::daemon_log("$session_id ERROR: communication failed while setting '".$item->{'name'}[0]."': ".$res_err_string, 1);
717             &add_content2xml_hash($out_hash, "error", $res_err_string);
718         }
719     }
722     # Return message
723     return ( &create_xml_string($out_hash) );
727 ## @method opsi_get_client_hardware
728 # Reports client hardware inventory.
729 # @param msg - STRING - xml message with tag hostId
730 # @param msg_hash - HASHREF - message information parsed into a hash
731 # @param session_id - INTEGER - POE session id of the processing of this message
732 # @return out_msg - STRING - feedback to GOsa in success and error case
733 sub opsi_get_client_hardware {
734     my ($msg, $msg_hash, $session_id) = @_;
735     my $header = @{$msg_hash->{'header'}}[0];
736     my $source = @{$msg_hash->{'source'}}[0];
737     my $target = @{$msg_hash->{'target'}}[0];
738     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
739     my $hostId;
740     my $error = 0;
741     my $xml_msg;
743     # Build return message with twisted target and source
744     my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
745     if (defined $forward_to_gosa) {
746       &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
747     }
749     # Sanity check of needed parameter
750     if ((exists $msg_hash->{'hostId'}) && (@{$msg_hash->{'hostId'}} != 1))  {
751         $error++;
752         &add_content2xml_hash($out_hash, "hostId_error", "hostId contains no or more than one values");
753         &add_content2xml_hash($out_hash, "error", "hostId");
754         &main::daemon_log("$session_id ERROR: hostId contains no or more than one values: $msg", 1); 
755     }
757     if (not $error) {
759     # Get hostID
760         $hostId = @{$msg_hash->{'hostId'}}[0];
761         &add_content2xml_hash($out_hash, "hostId", "$hostId");
762         &add_content2xml_hash($out_hash, "xxx", "");
763     }    
765     # Move to XML string
766     $xml_msg= &create_xml_string($out_hash);
767     
768     if (not $error) {
770     # JSON Query
771         my $callobj = {
772             method  => 'getHardwareInformation_hash',
773             params  => [ $hostId ],
774             id  => 1,
775         };
777         my $res = $main::opsi_client->call($main::opsi_url, $callobj);
778         if (not &check_opsi_res($res)){
779             my $result= $res->result;
780             foreach my $r (keys %{$result}){
781                 my $item= "<item><id>".xml_quote($r)."</id>";
782                 my $value= $result->{$r};
783                 foreach my $sres (@{$value}){
785                     foreach my $dres (keys %{$sres}){
786                         if (defined $sres->{$dres}){
787                             $item.= "<$dres>".xml_quote($sres->{$dres})."</$dres>";
788                         }
789                     }
791                 }
792                 $item.= "</item>";
793                 $xml_msg=~ s%<xxx></xxx>%$item<xxx></xxx>%;
795             }
796         }
798         $xml_msg=~ s/<xxx><\/xxx>//;
800     }
802     # Return message
803     return ( $xml_msg );
807 ## @method opsi_list_clients
808 # Reports all Opsi clients. 
809 # @param msg - STRING - xml message 
810 # @param msg_hash - HASHREF - message information parsed into a hash
811 # @param session_id - INTEGER - POE session id of the processing of this message
812 # @return out_msg - STRING - feedback to GOsa in success and error case
813 sub opsi_list_clients {
814     my ($msg, $msg_hash, $session_id) = @_;
815     my $header = @{$msg_hash->{'header'}}[0];
816     my $source = @{$msg_hash->{'source'}}[0];
817     my $target = @{$msg_hash->{'target'}}[0];
818     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
820     # Build return message with twisted target and source
821     my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
822     if (defined $forward_to_gosa) {
823       &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
824     }
825     &add_content2xml_hash($out_hash, "xxx", "");
827     # Move to XML string
828     my $xml_msg= &create_xml_string($out_hash);
830     # JSON Query
831     my $callobj = {
832         method  => 'getClients_listOfHashes',
833         params  => [ ],
834         id  => 1,
835     };
836     my $res = $main::opsi_client->call($main::opsi_url, $callobj);
837     if (not &check_opsi_res($res)){
838         foreach my $host (@{$res->result}){
839             my $item= "<item><name>".$host->{'hostId'}."</name>";
840             if (defined($host->{'description'})){
841                 $item.= "<description>".xml_quote($host->{'description'})."</description>";
842             }
843             if (defined($host->{'notes'})){
844                 $item.= "<notes>".xml_quote($host->{'notes'})."</notes>";
845             }
847             $callobj = {
848               method  => 'getIpAddress',
849               params  => [ $host->{'hostId'} ],
850               id  => 1,
851             };
852             my $sres= $main::opsi_client->call($main::opsi_url, $callobj);
853             if ( not &check_opsi_res($sres)){
854               $item.= "<ip>".xml_quote($sres->result)."</ip>";
855             }
857             $callobj = {
858               method  => 'getMacAddress',
859               params  => [ $host->{'hostId'} ],
860               id  => 1,
861             };
862             $sres= $main::opsi_client->call($main::opsi_url, $callobj);
863             if ( not &check_opsi_res($sres)){
864                 $item.= "<mac>".xml_quote($sres->result)."</mac>";
865             }
866             $item.= "</item>";
867             $xml_msg=~ s%<xxx></xxx>%$item<xxx></xxx>%;
868         }
869     }
871     $xml_msg=~ s/<xxx><\/xxx>//;
872     return ( $xml_msg );
876 ## @method opsi_get_client_software
877 # Reports client software inventory.
878 # @param msg - STRING - xml message with tag hostId
879 # @param msg_hash - HASHREF - message information parsed into a hash
880 # @param session_id - INTEGER - POE session id of the processing of this message
881 # @return out_msg - STRING - feedback to GOsa in success and error case
882 sub opsi_get_client_software {
883     my ($msg, $msg_hash, $session_id) = @_;
884     my $header = @{$msg_hash->{'header'}}[0];
885     my $source = @{$msg_hash->{'source'}}[0];
886     my $target = @{$msg_hash->{'target'}}[0];
887     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
888     my $error = 0;
889     my $hostId;
890     my $xml_msg;
892     # Build return message with twisted target and source
893     my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
894     if (defined $forward_to_gosa) {
895       &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
896     }
898     # Sanity check of needed parameter
899     if ((exists $msg_hash->{'hostId'}) && (@{$msg_hash->{'hostId'}} != 1))  {
900         $error++;
901         &add_content2xml_hash($out_hash, "hostId_error", "hostId contains no or more than one values");
902         &add_content2xml_hash($out_hash, "error", "hostId");
903         &main::daemon_log("$session_id ERROR: hostId contains no or more than one values: $msg", 1); 
904     }
906     if (not $error) {
908     # Get hostID
909         $hostId = @{$msg_hash->{'hostId'}}[0];
910         &add_content2xml_hash($out_hash, "hostId", "$hostId");
911         &add_content2xml_hash($out_hash, "xxx", "");
912     }
914     $xml_msg= &create_xml_string($out_hash);
916     if (not $error) {
918     # JSON Query
919         my $callobj = {
920             method  => 'getSoftwareInformation_hash',
921             params  => [ $hostId ],
922             id  => 1,
923         };
925         my $res = $main::opsi_client->call($main::opsi_url, $callobj);
926         if (not &check_opsi_res($res)){
927             my $result= $res->result;
928 # TODO : Ist das hier schon fertig???   
929         }
931         $xml_msg=~ s/<xxx><\/xxx>//;
933     }
935     # Return message
936     return ( $xml_msg );
940 ## @method opsi_get_local_products
941 # Reports product for given hostId or globally.
942 # @param msg - STRING - xml message with optional tag hostId
943 # @param msg_hash - HASHREF - message information parsed into a hash
944 # @param session_id - INTEGER - POE session id of the processing of this message
945 # @return out_msg - STRING - feedback to GOsa in success and error case
946 sub opsi_get_local_products {
947     my ($msg, $msg_hash, $session_id) = @_;
948     my $header = @{$msg_hash->{'header'}}[0];
949     my $source = @{$msg_hash->{'source'}}[0];
950     my $target = @{$msg_hash->{'target'}}[0];
951     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
952     my $hostId;
954     # Build return message with twisted target and source
955     my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
956     if (defined $forward_to_gosa) {
957         &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
958     }
959     &add_content2xml_hash($out_hash, "xxx", "");
961     # Get hostID if defined
962     if ((exists $msg_hash->{'hostId'}) && (@{$msg_hash->{'hostId'}} == 1))  {
963         $hostId = @{$msg_hash->{'hostId'}}[0];
964         &add_content2xml_hash($out_hash, "hostId", $hostId);
965     }
967     # Move to XML string
968     my $xml_msg= &create_xml_string($out_hash);
970     # For hosts, only return the products that are or get installed
971     my $callobj;
972     $callobj = {
973         method  => 'getLocalBootProductIds_list',
974         params  => [ ],
975         id  => 1,
976     };
978     my $res = $main::opsi_client->call($main::opsi_url, $callobj);
979     my %r = ();
980     for (@{$res->result}) { $r{$_} = 1 }
982     if (not &check_opsi_res($res)){
984         if (defined $hostId){
985             $callobj = {
986                 method  => 'getProductStates_hash',
987                 params  => [ $hostId ],
988                 id  => 1,
989             };
991             my $hres = $main::opsi_client->call($main::opsi_url, $callobj);
992             if (not &check_opsi_res($hres)){
993                 my $htmp= $hres->result->{$hostId};
995                 # Check state != not_installed or action == setup -> load and add
996                 foreach my $product (@{$htmp}){
998                     if (!defined ($r{$product->{'productId'}})){
999                         next;
1000                     }
1002                     # Now we've a couple of hashes...
1003                     if ($product->{'installationStatus'} ne "not_installed" or
1004                             $product->{'actionRequest'} eq "setup"){
1005                         my $state= "<state>".$product->{'installationStatus'}."</state><action>".$product->{'actionRequest'}."</action>";
1007                         $callobj = {
1008                             method  => 'getProduct_hash',
1009                             params  => [ $product->{'productId'} ],
1010                             id  => 1,
1011                         };
1013                         my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
1014                         if (not &check_opsi_res($sres)){
1015                             my $tres= $sres->result;
1017                             my $name= xml_quote($tres->{'name'});
1018                             my $r= $product->{'productId'};
1019                             my $description= xml_quote($tres->{'description'});
1020                             $name=~ s/\//\\\//;
1021                             $description=~ s/\//\\\//;
1022                             $xml_msg=~ s/<xxx><\/xxx>/<item><productId>$r<\/productId><name><\/name><description>$description<\/description><\/item>$state<xxx><\/xxx>/;
1023                         }
1025                     }
1026                 }
1028             }
1030         } else {
1031             foreach my $r (@{$res->result}) {
1032                 $callobj = {
1033                     method  => 'getProduct_hash',
1034                     params  => [ $r ],
1035                     id  => 1,
1036                 };
1038                 my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
1039                 if (not &check_opsi_res($sres)){
1040                     my $tres= $sres->result;
1042                     my $name= xml_quote($tres->{'name'});
1043                     my $description= xml_quote($tres->{'description'});
1044                     $name=~ s/\//\\\//;
1045                     $description=~ s/\//\\\//;
1046                     $xml_msg=~ s/<xxx><\/xxx>/<item><productId>$r<\/productId><name><\/name><description>$description<\/description><\/item><xxx><\/xxx>/;
1047                 }
1049             }
1051         }
1052     }
1054     $xml_msg=~ s/<xxx><\/xxx>//;
1056     # Retrun Message
1057     return ( $xml_msg );
1061 ## @method opsi_del_client
1062 # Deletes a client from Opsi.
1063 # @param msg - STRING - xml message with tag hostId
1064 # @param msg_hash - HASHREF - message information parsed into a hash
1065 # @param session_id - INTEGER - POE session id of the processing of this message
1066 # @return out_msg - STRING - feedback to GOsa in success and error case
1067 sub opsi_del_client {
1068     my ($msg, $msg_hash, $session_id) = @_;
1069     my $header = @{$msg_hash->{'header'}}[0];
1070     my $source = @{$msg_hash->{'source'}}[0];
1071     my $target = @{$msg_hash->{'target'}}[0];
1072     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
1073     my $hostId;
1074     my $error = 0;
1076     # Build return message with twisted target and source
1077     my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
1078     if (defined $forward_to_gosa) {
1079       &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
1080     }
1082     # Sanity check of needed parameter
1083     if ((exists $msg_hash->{'hostId'}) && (@{$msg_hash->{'hostId'}} != 1))  {
1084         $error++;
1085         &add_content2xml_hash($out_hash, "hostId_error", "hostId contains no or more than one values");
1086         &add_content2xml_hash($out_hash, "error", "hostId");
1087         &main::daemon_log("$session_id ERROR: hostId contains no or more than one values: $msg", 1); 
1088     }
1090     if (not $error) {
1092     # Get hostID
1093         $hostId = @{$msg_hash->{'hostId'}}[0];
1094         &add_content2xml_hash($out_hash, "hostId", "$hostId");
1096     # JSON Query
1097         my $callobj = {
1098             method  => 'deleteClient',
1099             params  => [ $hostId ],
1100             id  => 1,
1101         };
1102         my $res = $main::opsi_client->call($main::opsi_url, $callobj);
1103     }
1105     # Move to XML string
1106     my $xml_msg= &create_xml_string($out_hash);
1108     # Return message
1109     return ( $xml_msg );
1113 ## @method opsi_install_client
1114 # Set a client in Opsi to install and trigger a wake on lan message (WOL).  
1115 # @param msg - STRING - xml message with tags hostId, macaddress
1116 # @param msg_hash - HASHREF - message information parsed into a hash
1117 # @param session_id - INTEGER - POE session id of the processing of this message
1118 # @return out_msg - STRING - feedback to GOsa in success and error case
1119 sub opsi_install_client {
1120     my ($msg, $msg_hash, $session_id) = @_;
1121     my $header = @{$msg_hash->{'header'}}[0];
1122     my $source = @{$msg_hash->{'source'}}[0];
1123     my $target = @{$msg_hash->{'target'}}[0];
1124     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
1127     my ($hostId, $macaddress);
1129     my $error = 0;
1130     my @out_msg_l;
1132     # Build return message with twisted target and source
1133     my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
1134     if (defined $forward_to_gosa) {
1135         &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
1136     }
1138     # Sanity check of needed parameter
1139     if ((not exists $msg_hash->{'hostId'}) || (@{$msg_hash->{'hostId'}} != 1))  {
1140         $error++;
1141         &add_content2xml_hash($out_hash, "hostId_error", "no hostId specified or hostId tag invalid");
1142         &add_content2xml_hash($out_hash, "error", "hostId");
1143         &main::daemon_log("$session_id ERROR: no hostId specified or hostId tag invalid: $msg", 1); 
1144     }
1145     if ((not exists $msg_hash->{'macaddress'}) || (@{$msg_hash->{'macaddress'}} != 1))  {
1146         $error++;
1147         &add_content2xml_hash($out_hash, "macaddress_error", "no macaddress specified or macaddress tag invalid");
1148         &add_content2xml_hash($out_hash, "error", "macaddress");
1149         &main::daemon_log("$session_id ERROR: no macaddress specified or macaddress tag invalid: $msg", 1); 
1150     } else {
1151         if ((exists $msg_hash->{'macaddress'}) && 
1152                 ($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)) {  
1153             $macaddress = $1; 
1154         } else { 
1155             $error ++; 
1156             &add_content2xml_hash($out_hash, "macaddress_error", "given mac address is not correct");
1157             &add_content2xml_hash($out_hash, "error", "macaddress");
1158             &main::daemon_log("$session_id ERROR: given mac address is not correct: $msg", 1); 
1159         }
1160     }
1162     if (not $error) {
1164     # Get hostId
1165         $hostId = @{$msg_hash->{'hostId'}}[0];
1166         &add_content2xml_hash($out_hash, "hostId", "$hostId");
1168         # Load all products for this host with status != "not_installed" or actionRequest != "none"
1169         my $callobj = {
1170             method  => 'getProductStates_hash',
1171             params  => [ $hostId ],
1172             id  => 1,
1173         };
1175         my $hres = $main::opsi_client->call($main::opsi_url, $callobj);
1176         if (not &check_opsi_res($hres)){
1177             my $htmp= $hres->result->{$hostId};
1179             # check state != not_installed or action == setup -> load and add
1180             foreach my $product (@{$htmp}){
1181                 # Now we've a couple of hashes...
1182                 if ($product->{'installationStatus'} ne "not_installed" or
1183                         $product->{'actionRequest'} ne "none"){
1185                     # Do an action request for all these -> "setup".
1186                     $callobj = {
1187                         method  => 'setProductActionRequest',
1188                         params  => [ $product->{'productId'}, $hostId, "setup" ],
1189                         id  => 1,
1190                     };
1191                     my $res = $main::opsi_client->call($main::opsi_url, $callobj);
1192                     my ($res_err, $res_err_string) = &check_opsi_res($res);
1193                     if ($res_err){
1194                         &main::daemon_log("$session_id ERROR: cannot set product action request for '$hostId': ".$product->{'productId'}, 1);
1195                     } else {
1196                         &main::daemon_log("$session_id INFO: requesting 'setup' for '".$product->{'productId'}."' on $hostId", 1);
1197                     }
1198                 }
1199             }
1200         }
1201         push(@out_msg_l, &create_xml_string($out_hash));
1202     
1204     # Build wakeup message for client
1205         if (not $error) {
1206             my $wakeup_hash = &create_xml_hash("trigger_wake", "GOSA", "KNOWN_SERVER");
1207             &add_content2xml_hash($wakeup_hash, 'macAddress', $macaddress);
1208             my $wakeup_msg = &create_xml_string($wakeup_hash);
1209             push(@out_msg_l, $wakeup_msg);
1211             # invoke trigger wake for this gosa-si-server
1212             &main::server_server_com::trigger_wake($wakeup_msg, $wakeup_hash, $session_id);
1213         }
1214     }
1215     
1216     # Return messages
1217     return @out_msg_l;
1221 ## @method _set_action
1222 # Set action for an Opsi client
1223 # @param product - STRING - Opsi product
1224 # @param action - STRING - action
1225 # @param hostId - STRING - Opsi hostId
1226 sub _set_action {
1227   my $product= shift;
1228   my $action = shift;
1229   my $hostId = shift;
1230   my $callobj;
1232   $callobj = {
1233     method  => 'setProductActionRequest',
1234     params  => [ $product, $hostId, $action],
1235     id  => 1,
1236   };
1238   $main::opsi_client->call($main::opsi_url, $callobj);
1241 ## @method _set_state
1242 # Set state for an Opsi client
1243 # @param product - STRING - Opsi product
1244 # @param action - STRING - state
1245 # @param hostId - STRING - Opsi hostId
1246 sub _set_state {
1247   my $product = shift;
1248   my $state = shift;
1249   my $hostId = shift;
1250   my $callobj;
1252   $callobj = {
1253     method  => 'setProductState',
1254     params  => [ $product, $hostId, $state ],
1255     id  => 1,
1256   };
1258   $main::opsi_client->call($main::opsi_url, $callobj);
1261 1;