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