1 ## @file
2 # @details A GOsa-SI-server event module containing all functions for message handling.
3 # @brief Implementation of an event module for GOsa-SI-server.
6 package opsi_com;
7 use Exporter;
8 @ISA = qw(Exporter);
9 my @events = (
10 "get_events",
11 "opsi_install_client",
12 "opsi_get_netboot_products",
13 "opsi_get_local_products",
14 "opsi_get_client_hardware",
15 "opsi_get_client_software",
16 "opsi_get_product_properties",
17 "opsi_set_product_properties",
18 "opsi_list_clients",
19 "opsi_del_client",
20 "opsi_add_client",
21 "opsi_modify_client",
22 "opsi_add_product_to_client",
23 "opsi_del_product_from_client",
24 );
25 @EXPORT = @events;
27 use strict;
28 use warnings;
29 use GOSA::GosaSupportDaemon;
30 use Data::Dumper;
31 use XML::Quote qw(:all);
34 BEGIN {}
36 END {}
38 ## @method get_events()
39 # A brief function returning a list of functions which are exported by importing the module.
40 # @return List of all provided functions
41 sub get_events {
42 return \@events;
43 }
46 sub opsi_add_product_to_client {
47 my ($msg, $msg_hash, $session_id) = @_;
48 my $header = @{$msg_hash->{'header'}}[0];
49 my $source = @{$msg_hash->{'source'}}[0];
50 my $target = @{$msg_hash->{'target'}}[0];
51 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
52 my ($hostId, $productId);
54 # TODO: check dependencies later on?
56 # build return message with twisted target and source
57 my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
58 if (defined $forward_to_gosa) {
59 &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
60 }
62 # Get hostID
63 $hostId = @{$msg_hash->{'hostId'}}[0];
64 &add_content2xml_hash($out_hash, "hostId", $hostId);
66 # Get productID
67 $productId = @{$msg_hash->{'productId'}}[0];
68 &add_content2xml_hash($out_hash, "productId", $productId);
70 # Do an action request for all these -> "setup".
71 my $callobj = {
72 method => 'setProductActionRequest',
73 params => [ $productId, $hostId, "setup" ],
74 id => 1, };
76 my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
77 if (&main::check_opsi_res($sres)){
78 &main::daemon_log("ERROR: cannot add product: ".$sres->error_message, 1);
79 &add_content2xml_hash($out_hash, "error", $sres->error_message);
80 }
82 # return message
83 return ( &create_xml_string($out_hash) );
84 }
87 sub opsi_del_product_from_client {
88 my ($msg, $msg_hash, $session_id) = @_;
89 my $header = @{$msg_hash->{'header'}}[0];
90 my $source = @{$msg_hash->{'source'}}[0];
91 my $target = @{$msg_hash->{'target'}}[0];
92 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
93 my ($hostId, $productId);
95 # build return message with twisted target and source
96 my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
97 if (defined $forward_to_gosa) {
98 &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
99 }
101 # Get hostID
102 $hostId = @{$msg_hash->{'hostId'}}[0];
103 &add_content2xml_hash($out_hash, "hostId", $hostId);
105 # Get productID
106 $productId = @{$msg_hash->{'productId'}}[0];
107 &add_content2xml_hash($out_hash, "productId", $productId);
110 #TODO: check the results for more than one entry which is currently installed
111 #$callobj = {
112 # method => 'getProductDependencies_listOfHashes',
113 # params => [ $productId ],
114 # id => 1, };
115 #
116 #my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
117 #if (&main::check_opsi_res($sres)){
118 # &main::daemon_log("ERROR: cannot perform dependency check: ".$res->error_message, 1);
119 # &add_content2xml_hash($out_hash, "error", $res->error_message);
120 # return ( &create_xml_string($out_hash) );
121 #}
124 # Check for uninstall method
125 my $callobj = {
126 method => 'getPossibleProductActions_list',
127 params => [ $productId ],
128 id => 1, };
130 my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
131 if (&main::check_opsi_res($sres)){
132 &main::daemon_log("ERROR: cannot get product action list: ".$sres->error_message, 1);
133 &add_content2xml_hash($out_hash, "error", $sres->error_message);
134 return ( &create_xml_string($out_hash) );
135 }
136 my $uninst_possible= 0;
137 foreach my $r (@{$sres->result}) {
138 if ($r eq 'uninstall') {
139 $uninst_possible= 1;
140 }
141 }
142 if (!$uninst_possible){
143 &main::daemon_log("ERROR: cannot uninstall product", 1);
144 &add_content2xml_hash($out_hash, "error", "product is not uninstallable");
145 return ( &create_xml_string($out_hash) );
146 }
148 # Set product state to "none"
149 # Do an action request for all these -> "setup".
150 $callobj = {
151 method => 'setProductActionRequest',
152 params => [ $productId, $hostId, "none" ],
153 id => 1, };
155 $sres = $main::opsi_client->call($main::opsi_url, $callobj);
156 if (&main::check_opsi_res($sres)){
157 &main::daemon_log("ERROR: cannot delete product: ".$sres->error_message, 1);
158 &add_content2xml_hash($out_hash, "error", $sres->error_message);
159 return ( &create_xml_string($out_hash) );
160 }
162 # return message
163 return ( &create_xml_string($out_hash) );
164 }
167 sub opsi_add_client {
168 my ($msg, $msg_hash, $session_id) = @_;
169 my $header = @{$msg_hash->{'header'}}[0];
170 my $source = @{$msg_hash->{'source'}}[0];
171 my $target = @{$msg_hash->{'target'}}[0];
172 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
173 my $hostId;
175 # build return message with twisted target and source
176 my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
177 if (defined $forward_to_gosa) {
178 &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
179 }
181 # Get hostID
182 $hostId = @{$msg_hash->{'hostId'}}[0];
183 &add_content2xml_hash($out_hash, "hostId", $hostId);
184 my $name= $hostId;
185 $name=~ s/^([^.]+).*$/$1/;
186 my $domain= $hostId;
187 $domain=~ s/^[^.]+(.*)$/$1/;
188 my ($description, $notes, $ip, $mac);
190 if (defined @{$msg_hash->{'description'}}[0]){
191 $description = @{$msg_hash->{'description'}}[0];
192 }
193 if (defined @{$msg_hash->{'notes'}}[0]){
194 $notes = @{$msg_hash->{'notes'}}[0];
195 }
196 if (defined @{$msg_hash->{'ip'}}[0]){
197 $ip = @{$msg_hash->{'ip'}}[0];
198 }
199 if (defined @{$msg_hash->{'mac'}}[0]){
200 $mac = @{$msg_hash->{'mac'}}[0];
201 }
203 my $callobj;
204 $callobj = {
205 method => 'createclient',
206 params => [ $name, $domain, $description, $notes, $ip, $mac ],
207 id => 1,
208 };
210 my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
211 if (&main::check_opsi_res($sres)){
212 &main::daemon_log("ERROR: cannot create client: ".$sres->error_message, 1);
213 &add_content2xml_hash($out_hash, "error", $sres->error_message);
214 }
216 # return message
217 return ( &create_xml_string($out_hash) );
218 }
221 sub opsi_modify_client {
222 my ($msg, $msg_hash, $session_id) = @_;
223 my $header = @{$msg_hash->{'header'}}[0];
224 my $source = @{$msg_hash->{'source'}}[0];
225 my $target = @{$msg_hash->{'target'}}[0];
226 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
227 my $hostId;
229 # build return message with twisted target and source
230 my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
231 if (defined $forward_to_gosa) {
232 &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
233 }
235 # Get hostID
236 $hostId = @{$msg_hash->{'hostId'}}[0];
237 &add_content2xml_hash($out_hash, "hostId", $hostId);
238 my $name= $hostId;
239 $name=~ s/^([^.]+).*$/$1/;
240 my $domain= $hostId;
241 $domain=~ s/^[^.]+(.*)$/$1/;
242 my ($description, $notes, $ip, $mac);
244 my $callobj;
246 if (defined @{$msg_hash->{'description'}}[0]){
247 $description = @{$msg_hash->{'description'}}[0];
248 $callobj = {
249 method => 'setHostDescription',
250 params => [ $hostId, $description ],
251 id => 1,
252 };
253 my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
254 if (&main::check_opsi_res($sres)){
255 &main::daemon_log("ERROR: cannot set description: ".$sres->error_message, 1);
256 &add_content2xml_hash($out_hash, "error", $sres->error_message);
257 return ( &create_xml_string($out_hash) );
258 }
259 }
260 if (defined @{$msg_hash->{'notes'}}[0]){
261 $notes = @{$msg_hash->{'notes'}}[0];
262 $callobj = {
263 method => 'setHostNotes',
264 params => [ $hostId, $notes ],
265 id => 1,
266 };
267 my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
268 if (&main::check_opsi_res($sres)){
269 &main::daemon_log("ERROR: cannot set notes: ".$sres->error_message, 1);
270 &add_content2xml_hash($out_hash, "error", $sres->error_message);
271 return ( &create_xml_string($out_hash) );
272 }
273 }
274 if (defined @{$msg_hash->{'mac'}}[0]){
275 $mac = @{$msg_hash->{'mac'}}[0];
276 $callobj = {
277 method => 'setMacAddress',
278 params => [ $hostId, $mac ],
279 id => 1,
280 };
281 my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
282 if (&main::check_opsi_res($sres)){
283 &main::daemon_log("ERROR: cannot set mac address: ".$sres->error_message, 1);
284 &add_content2xml_hash($out_hash, "error", $sres->error_message);
285 return ( &create_xml_string($out_hash) );
286 }
287 }
289 # return message
290 return ( &create_xml_string($out_hash) );
291 }
294 ## @method opsi_get_netboot_products
295 # ???
296 # @param msg - STRING - xml message with tag hostId
297 # @param msg_hash - HASHREF - message information parsed into a hash
298 # @param session_id - INTEGER - POE session id of the processing of this message
299 sub opsi_get_netboot_products {
300 my ($msg, $msg_hash, $session_id) = @_;
301 my $header = @{$msg_hash->{'header'}}[0];
302 my $source = @{$msg_hash->{'source'}}[0];
303 my $target = @{$msg_hash->{'target'}}[0];
304 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
305 my $hostId;
307 # build return message with twisted target and source
308 my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
309 if (defined $forward_to_gosa) {
310 &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
311 }
313 # Get hostID if defined
314 if (defined @{$msg_hash->{'hostId'}}[0]){
315 $hostId = @{$msg_hash->{'hostId'}}[0];
316 &add_content2xml_hash($out_hash, "hostId", $hostId);
317 }
319 &add_content2xml_hash($out_hash, "xxx", "");
320 my $xml_msg= &create_xml_string($out_hash);
322 # For hosts, only return the products that are or get installed
323 my $callobj;
324 $callobj = {
325 method => 'getNetBootProductIds_list',
326 params => [ ],
327 id => 1,
328 };
330 my $res = $main::opsi_client->call($main::opsi_url, $callobj);
331 my %r = ();
332 for (@{$res->result}) { $r{$_} = 1 }
334 if (&main::check_opsi_res($res)){
336 if (defined $hostId){
337 $callobj = {
338 method => 'getProductStates_hash',
339 params => [ $hostId ],
340 id => 1,
341 };
343 my $hres = $main::opsi_client->call($main::opsi_url, $callobj);
344 if (&main::check_opsi_res($hres)){
345 my $htmp= $hres->result->{$hostId};
347 # check state != not_installed or action == setup -> load and add
348 foreach my $product (@{$htmp}){
350 if (!defined ($r{$product->{'productId'}})){
351 next;
352 }
354 # Now we've a couple of hashes...
355 if ($product->{'installationStatus'} ne "not_installed" or
356 $product->{'actionRequest'} eq "setup"){
357 my $state= "<state>".$product->{'installationStatus'}."</state><action>".$product->{'actionRequest'}."</action>";
359 $callobj = {
360 method => 'getProduct_hash',
361 params => [ $product->{'productId'} ],
362 id => 1,
363 };
365 my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
366 if (&main::check_opsi_res($sres)){
367 my $tres= $sres->result;
369 my $name= xml_quote($tres->{'name'});
370 my $r= $product->{'productId'};
371 my $description= xml_quote($tres->{'description'});
372 $name=~ s/\//\\\//;
373 $description=~ s/\//\\\//;
374 $xml_msg=~ s/<xxx><\/xxx>/<item><ProductId>$r<\/ProductId><name><\/name><description>$description<\/description><\/item>$state<xxx><\/xxx>/;
375 }
377 }
378 }
380 }
382 } else {
383 foreach my $r (@{$res->result}) {
384 $callobj = {
385 method => 'getProduct_hash',
386 params => [ $r ],
387 id => 1,
388 };
390 my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
391 if (&main::check_opsi_res($sres)){
392 my $tres= $sres->result;
394 my $name= xml_quote($tres->{'name'});
395 my $description= xml_quote($tres->{'description'});
396 $name=~ s/\//\\\//;
397 $description=~ s/\//\\\//;
398 $xml_msg=~ s/<xxx><\/xxx>/<item><ProductId>$r<\/ProductId><name><\/name><description>$description<\/description><\/item><xxx><\/xxx>/;
399 }
401 }
403 }
404 }
406 $xml_msg=~ s/<xxx><\/xxx>//;
408 return ($xml_msg);
409 }
412 ## @method opsi_get_product_properties
413 # ???
414 # @param msg - STRING - xml message with tags ProductId and hostId
415 # @param msg_hash - HASHREF - message information parsed into a hash
416 # @param session_id - INTEGER - POE session id of the processing of this message
417 sub opsi_get_product_properties {
418 my ($msg, $msg_hash, $session_id) = @_;
419 my $header = @{$msg_hash->{'header'}}[0];
420 my $source = @{$msg_hash->{'source'}}[0];
421 my $target = @{$msg_hash->{'target'}}[0];
422 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
423 my $productId = @{$msg_hash->{'ProductId'}}[0];
424 my $hostId;
426 # build return message with twisted target and source
427 my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
429 # Get hostID if defined
430 if (defined @{$msg_hash->{'hostId'}}[0]){
431 $hostId = @{$msg_hash->{'hostId'}}[0];
432 &add_content2xml_hash($out_hash, "hostId", $hostId);
433 }
435 if (defined $forward_to_gosa) {
436 &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
437 }
438 &add_content2xml_hash($out_hash, "ProducId", "$productId");
440 # Load actions
441 my $callobj = {
442 method => 'getPossibleProductActions_list',
443 params => [ $productId ],
444 id => 1,
445 };
446 my $res = $main::opsi_client->call($main::opsi_url, $callobj);
447 if (&main::check_opsi_res($res)){
448 foreach my $action (@{$res->result}){
449 &add_content2xml_hash($out_hash, "action", $action);
450 }
451 }
453 # Add place holder
454 &add_content2xml_hash($out_hash, "xxx", "");
456 # Move to XML string
457 my $xml_msg= &create_xml_string($out_hash);
459 # JSON Query
460 $callobj = {
461 method => 'getProductProperties_hash',
462 params => [ $productId ],
463 id => 1,
464 };
466 $res = $main::opsi_client->call($main::opsi_url, $callobj);
468 if (&main::check_opsi_res($res)){
469 my $r= $res->result;
470 foreach my $key (keys %{$r}) {
471 my $item= "<item>";
472 my $value= $r->{$key};
473 if (UNIVERSAL::isa( $value, "ARRAY" )){
474 foreach my $subval (@{$value}){
475 $item.= "<$key>".xml_quote($subval)."</$key>";
476 }
477 } else {
478 $item.= "<$key>".xml_quote($value)."</$key>";
479 }
480 $item.= "</item>";
481 $xml_msg=~ s/<xxx><\/xxx>/$item<xxx><\/xxx>/;
482 }
483 }
486 $xml_msg=~ s/<xxx><\/xxx>//;
488 return ($xml_msg);
489 }
492 ## @method opsi_set_product_properties
493 # ???
494 # @param msg - STRING - xml message with tags ProductId, hostId, action and state
495 # @param msg_hash - HASHREF - message information parsed into a hash
496 # @param session_id - INTEGER - POE session id of the processing of this message
497 sub opsi_set_product_properties {
498 my ($msg, $msg_hash, $session_id) = @_;
499 my $header = @{$msg_hash->{'header'}}[0];
500 my $source = @{$msg_hash->{'source'}}[0];
501 my $target = @{$msg_hash->{'target'}}[0];
502 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
503 my $productId = @{$msg_hash->{'ProductId'}}[0];
504 my $hostId;
506 # build return message with twisted target and source
507 my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
508 &add_content2xml_hash($out_hash, "ProductId", $productId);
510 # Get hostID if defined
511 if (defined @{$msg_hash->{'hostId'}}[0]){
512 $hostId = @{$msg_hash->{'hostId'}}[0];
513 &add_content2xml_hash($out_hash, "hostId", $hostId);
514 }
516 # Set product states if requested
517 if (defined @{$msg_hash->{'action'}}[0]){
518 &_set_action($productId, @{$msg_hash->{'action'}}[0], $hostId);
519 }
520 if (defined @{$msg_hash->{'state'}}[0]){
521 &_set_state($productId, @{$msg_hash->{'state'}}[0], $hostId);
522 }
524 if (defined $forward_to_gosa) {
525 &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
526 }
528 # Find properties
529 foreach my $item (@{$msg_hash->{'item'}}){
530 # JSON Query
531 my $callobj;
533 if (defined $hostId){
534 $callobj = {
535 method => 'setProductProperty',
536 params => [ $productId, $item->{'name'}[0], $item->{'value'}[0], $hostId ],
537 id => 1,
538 };
539 } else {
540 $callobj = {
541 method => 'setProductProperty',
542 params => [ $productId, $item->{'name'}[0], $item->{'value'}[0] ],
543 id => 1,
544 };
545 }
547 my $res = $main::opsi_client->call($main::opsi_url, $callobj);
549 if (!&main::check_opsi_res($res)){
550 &main::daemon_log("ERROR: no communication failed while setting '".$item->{'name'}[0]."': ".$res->error_message, 1);
551 &add_content2xml_hash($out_hash, "error", $res->error_message);
552 }
554 }
556 # return message
557 return ( &create_xml_string($out_hash) );
558 }
561 ## @method opsi_get_client_hardware
562 # ???
563 # @param msg - STRING - xml message with tag hostId
564 # @param msg_hash - HASHREF - message information parsed into a hash
565 # @param session_id - INTEGER - POE session id of the processing of this message
566 sub opsi_get_client_hardware {
567 my ($msg, $msg_hash, $session_id) = @_;
568 my $header = @{$msg_hash->{'header'}}[0];
569 my $source = @{$msg_hash->{'source'}}[0];
570 my $target = @{$msg_hash->{'target'}}[0];
571 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
572 my $hostId = @{$msg_hash->{'hostId'}}[0];
574 # build return message with twisted target and source
575 my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
577 if (defined $forward_to_gosa) {
578 &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
579 }
580 &add_content2xml_hash($out_hash, "hostId", "$hostId");
581 &add_content2xml_hash($out_hash, "xxx", "");
582 my $xml_msg= &create_xml_string($out_hash);
584 # JSON Query
585 my $callobj = {
586 method => 'getHardwareInformation_hash',
587 params => [ $hostId ],
588 id => 1,
589 };
591 my $res = $main::opsi_client->call($main::opsi_url, $callobj);
592 if (&main::check_opsi_res($res)){
593 my $result= $res->result;
594 foreach my $r (keys %{$result}){
595 my $item= "<item><id>".xml_quote($r)."</id>";
596 my $value= $result->{$r};
597 foreach my $sres (@{$value}){
599 foreach my $dres (keys %{$sres}){
600 if (defined $sres->{$dres}){
601 $item.= "<$dres>".xml_quote($sres->{$dres})."</$dres>";
602 }
603 }
605 }
606 $item.= "</item>";
607 $xml_msg=~ s%<xxx></xxx>%$item<xxx></xxx>%;
609 }
610 }
612 $xml_msg=~ s/<xxx><\/xxx>//;
614 return ( $xml_msg );
615 }
618 ## @method opsi_list_clients
619 # ???
620 # @param msg - STRING - xml message
621 # @param msg_hash - HASHREF - message information parsed into a hash
622 # @param session_id - INTEGER - POE session id of the processing of this message
623 sub opsi_list_clients {
624 my ($msg, $msg_hash, $session_id) = @_;
625 my $header = @{$msg_hash->{'header'}}[0];
626 my $source = @{$msg_hash->{'source'}}[0];
627 my $target = @{$msg_hash->{'target'}}[0];
628 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
630 # build return message with twisted target and source
631 my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
633 if (defined $forward_to_gosa) {
634 &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
635 }
637 &add_content2xml_hash($out_hash, "xxx", "");
638 my $xml_msg= &create_xml_string($out_hash);
640 # JSON Query
641 my $callobj = {
642 method => 'getClients_listOfHashes',
643 params => [ ],
644 id => 1,
645 };
647 my $res = $main::opsi_client->call($main::opsi_url, $callobj);
648 if (&main::check_opsi_res($res)){
650 foreach my $host (@{$res->result}){
651 my $item= "<item><name>".$host->{'hostId'}."</name>";
652 if (defined($host->{'description'})){
653 $item.= "<description>".xml_quote($host->{'description'})."</description>";
654 }
655 $item.= "</item>";
656 $xml_msg=~ s%<xxx></xxx>%$item<xxx></xxx>%;
657 }
659 }
661 $xml_msg=~ s/<xxx><\/xxx>//;
662 return ( $xml_msg );
663 }
666 ## @method opsi_get_client_software
667 # ???
668 # @param msg - STRING - xml message with tag hostId
669 # @param msg_hash - HASHREF - message information parsed into a hash
670 # @param session_id - INTEGER - POE session id of the processing of this message
671 sub opsi_get_client_software {
672 my ($msg, $msg_hash, $session_id) = @_;
673 my $header = @{$msg_hash->{'header'}}[0];
674 my $source = @{$msg_hash->{'source'}}[0];
675 my $target = @{$msg_hash->{'target'}}[0];
676 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
677 my $hostId = @{$msg_hash->{'hostId'}}[0];
679 # build return message with twisted target and source
680 my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
682 if (defined $forward_to_gosa) {
683 &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
684 }
685 &add_content2xml_hash($out_hash, "hostId", "$hostId");
686 &add_content2xml_hash($out_hash, "xxx", "");
687 my $xml_msg= &create_xml_string($out_hash);
689 # JSON Query
690 my $callobj = {
691 method => 'getSoftwareInformation_hash',
692 params => [ $hostId ],
693 id => 1,
694 };
696 my $res = $main::opsi_client->call($main::opsi_url, $callobj);
697 if (&main::check_opsi_res($res)){
698 my $result= $res->result;
699 }
701 $xml_msg=~ s/<xxx><\/xxx>//;
703 return ( $xml_msg );
704 }
707 ## @method opsi_get_local_products
708 # ???
709 # @param msg - STRING - xml message with tag hostId
710 # @param msg_hash - HASHREF - message information parsed into a hash
711 # @param session_id - INTEGER - POE session id of the processing of this message
712 sub opsi_get_local_products {
713 my ($msg, $msg_hash, $session_id) = @_;
714 my $header = @{$msg_hash->{'header'}}[0];
715 my $source = @{$msg_hash->{'source'}}[0];
716 my $target = @{$msg_hash->{'target'}}[0];
717 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
718 my $hostId;
720 # build return message with twisted target and source
721 my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
723 # Get hostID if defined
724 if (defined @{$msg_hash->{'hostId'}}[0]){
725 $hostId = @{$msg_hash->{'hostId'}}[0];
726 &add_content2xml_hash($out_hash, "hostId", $hostId);
727 }
729 if (defined $forward_to_gosa) {
730 &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
731 }
732 &add_content2xml_hash($out_hash, "xxx", "");
733 my $xml_msg= &create_xml_string($out_hash);
735 # For hosts, only return the products that are or get installed
736 my $callobj;
737 $callobj = {
738 method => 'getLocalBootProductIds_list',
739 params => [ ],
740 id => 1,
741 };
743 my $res = $main::opsi_client->call($main::opsi_url, $callobj);
744 my %r = ();
745 for (@{$res->result}) { $r{$_} = 1 }
747 if (&main::check_opsi_res($res)){
749 if (defined $hostId){
750 $callobj = {
751 method => 'getProductStates_hash',
752 params => [ $hostId ],
753 id => 1,
754 };
756 my $hres = $main::opsi_client->call($main::opsi_url, $callobj);
757 if (&main::check_opsi_res($hres)){
758 my $htmp= $hres->result->{$hostId};
760 # check state != not_installed or action == setup -> load and add
761 foreach my $product (@{$htmp}){
763 if (!defined ($r{$product->{'productId'}})){
764 next;
765 }
767 # Now we've a couple of hashes...
768 if ($product->{'installationStatus'} ne "not_installed" or
769 $product->{'actionRequest'} eq "setup"){
770 my $state= "<state>".$product->{'installationStatus'}."</state><action>".$product->{'actionRequest'}."</action>";
772 $callobj = {
773 method => 'getProduct_hash',
774 params => [ $product->{'productId'} ],
775 id => 1,
776 };
778 my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
779 if (&main::check_opsi_res($sres)){
780 my $tres= $sres->result;
782 my $name= xml_quote($tres->{'name'});
783 my $r= $product->{'productId'};
784 my $description= xml_quote($tres->{'description'});
785 $name=~ s/\//\\\//;
786 $description=~ s/\//\\\//;
787 $xml_msg=~ s/<xxx><\/xxx>/<item><ProductId>$r<\/ProductId><name><\/name><description>$description<\/description><\/item>$state<xxx><\/xxx>/;
788 }
790 }
791 }
793 }
795 } else {
796 foreach my $r (@{$res->result}) {
797 $callobj = {
798 method => 'getProduct_hash',
799 params => [ $r ],
800 id => 1,
801 };
803 my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
804 if (&main::check_opsi_res($sres)){
805 my $tres= $sres->result;
807 my $name= xml_quote($tres->{'name'});
808 my $description= xml_quote($tres->{'description'});
809 $name=~ s/\//\\\//;
810 $description=~ s/\//\\\//;
811 $xml_msg=~ s/<xxx><\/xxx>/<item><ProductId>$r<\/ProductId><name><\/name><description>$description<\/description><\/item><xxx><\/xxx>/;
812 }
814 }
816 }
817 }
819 $xml_msg=~ s/<xxx><\/xxx>//;
821 return ( $xml_msg );
822 }
825 ## @method opsi_del_client
826 # ???
827 # @param msg - STRING - xml message with tag hostId
828 # @param msg_hash - HASHREF - message information parsed into a hash
829 # @param session_id - INTEGER - POE session id of the processing of this message
830 sub opsi_del_client {
831 my ($msg, $msg_hash, $session_id) = @_;
832 my $header = @{$msg_hash->{'header'}}[0];
833 my $source = @{$msg_hash->{'source'}}[0];
834 my $target = @{$msg_hash->{'target'}}[0];
835 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
836 my $hostId = @{$msg_hash->{'hostId'}}[0];
838 # build return message with twisted target and source
839 my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
841 if (defined $forward_to_gosa) {
842 &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
843 }
844 &add_content2xml_hash($out_hash, "hostId", "$hostId");
846 # JSON Query
847 my $callobj = {
848 method => 'deleteClient',
849 params => [ $hostId ],
850 id => 1,
851 };
853 my $res = $main::opsi_client->call($main::opsi_url, $callobj);
855 my $xml_msg= &create_xml_string($out_hash);
856 return ( $xml_msg );
857 }
860 ## @method opsi_install_client
861 # ???
862 # @param msg - STRING - xml message with tags hostId, macaddress
863 # @param msg_hash - HASHREF - message information parsed into a hash
864 # @param session_id - INTEGER - POE session id of the processing of this message
865 sub opsi_install_client {
866 my ($msg, $msg_hash, $session_id) = @_;
867 my $header = @{$msg_hash->{'header'}}[0];
868 my $source = @{$msg_hash->{'source'}}[0];
869 my $target = @{$msg_hash->{'target'}}[0];
870 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
871 my $hostId = @{$msg_hash->{'hostId'}}[0];
872 my $error = 0;
873 my @out_msg_l;
875 # If no macaddress is specified, raise error
876 my $macaddress;
877 if ((exists $msg_hash->{'macaddress'}) &&
878 ($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)) {
879 $macaddress = $1;
880 } else {
881 $error ++;
882 my $out_msg = "<xml>".
883 "<header>answer</header>".
884 "<source>$main::server_address</source>".
885 "<target>GOSA</target>".
886 "<answer1>1</answer1>".
887 "<error_string>no mac address specified in macaddres-tag</error_string>".
888 "</xml>";
889 push(@out_msg_l, $out_msg);
890 }
892 # Set parameters in opsi
893 if (not $error) {
894 # build return message with twisted target and source
895 my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
897 if (defined $forward_to_gosa) {
898 &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
899 }
900 &add_content2xml_hash($out_hash, "hostId", "$hostId");
902 # Load all products for this host with status != "not_installed" or actionRequest != "none"
903 if (defined $hostId){
904 my $callobj = {
905 method => 'getProductStates_hash',
906 params => [ $hostId ],
907 id => 1,
908 };
910 my $hres = $main::opsi_client->call($main::opsi_url, $callobj);
911 if (&main::check_opsi_res($hres)){
912 my $htmp= $hres->result->{$hostId};
914 # check state != not_installed or action == setup -> load and add
915 foreach my $product (@{$htmp}){
916 # Now we've a couple of hashes...
917 if ($product->{'installationStatus'} ne "not_installed" or
918 $product->{'actionRequest'} ne "none"){
920 # Do an action request for all these -> "setup".
921 $callobj = {
922 method => 'setProductActionRequest',
923 params => [ $product->{'productId'}, $hostId, "setup" ],
924 id => 1,
925 };
926 my $res = $main::opsi_client->call($main::opsi_url, $callobj);
927 if (!&main::check_opsi_res($res)){
928 &main::daemon_log("ERROR: cannot set product action request for $hostId!", 1);
929 } else {
930 &main::daemon_log("INFO: requesting 'setup' for '".$product->{'productId'}."' on $hostId", 1);
931 }
933 }
934 }
935 }
936 }
938 push(@out_msg_l, &create_xml_string($out_hash));
939 }
941 # Build wakeup message for client
942 if (not $error) {
943 my $wakeup_hash = &create_xml_hash("trigger_wake", "GOSA", "KNOWN_SERVER");
944 &add_content2xml_hash($wakeup_hash, 'macAddress', $macaddress);
945 my $wakeup_msg = &create_xml_string($wakeup_hash);
946 push(@out_msg_l, $wakeup_msg);
948 # invoke trigger wake for this gosa-si-server
949 &main::server_server_com::trigger_wake($wakeup_msg, $wakeup_hash, $session_id);
950 }
953 return @out_msg_l;
954 }
957 ## @method _set_action
958 # ???
959 # @param product - STRING - ???
960 # @param action - STRING - ???
961 # @param hostId - STRING - ???
962 sub _set_action {
963 my $product= shift;
964 my $action = shift;
965 my $hostId = shift;
966 my $callobj;
968 $callobj = {
969 method => 'setProductActionRequest',
970 params => [ $product, $hostId, $action],
971 id => 1,
972 };
974 $main::opsi_client->call($main::opsi_url, $callobj);
975 }
977 ## @method _set_state
978 # ???
979 # @param product - STRING - ???
980 # @param action - STRING - ???
981 # @param hostId - STRING - ???
982 sub _set_state {
983 my $product = shift;
984 my $hostId = shift;
985 my $action = shift;
986 my $callobj;
988 $callobj = {
989 method => 'setProductState',
990 params => [ $product, $hostId, $action ],
991 id => 1,
992 };
994 $main::opsi_client->call($main::opsi_url, $callobj);
995 }
997 1;