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", $main::server_address, $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 my ($sres_err, $sres_err_string) = &check_opsi_res($sres);
78 if ($sres_err){
79 &main::daemon_log("$session_id ERROR: cannot add product: ".$sres_err_string, 1);
80 &add_content2xml_hash($out_hash, "error", $sres_err_string);
81 }
83 # return message
84 return ( &create_xml_string($out_hash) );
85 }
88 sub opsi_del_product_from_client {
89 my ($msg, $msg_hash, $session_id) = @_;
90 my $header = @{$msg_hash->{'header'}}[0];
91 my $source = @{$msg_hash->{'source'}}[0];
92 my $target = @{$msg_hash->{'target'}}[0];
93 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
94 my ($hostId, $productId);
96 # build return message with twisted target and source
97 my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
98 if (defined $forward_to_gosa) {
99 &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
100 }
102 # Get hostID
103 $hostId = @{$msg_hash->{'hostId'}}[0];
104 &add_content2xml_hash($out_hash, "hostId", $hostId);
106 # Get productID
107 $productId = @{$msg_hash->{'productId'}}[0];
108 &add_content2xml_hash($out_hash, "productId", $productId);
111 #TODO: check the results for more than one entry which is currently installed
112 #$callobj = {
113 # method => 'getProductDependencies_listOfHashes',
114 # params => [ $productId ],
115 # id => 1, };
116 #
117 #my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
118 #my ($sres_err, $sres_err_string) = &check_opsi_res($sres);
119 #if ($sres_err){
120 # &main::daemon_log("ERROR: cannot perform dependency check: ".$sres_err_string, 1);
121 # &add_content2xml_hash($out_hash, "error", $sres_err_string);
122 # return ( &create_xml_string($out_hash) );
123 #}
126 # Check for uninstall method
127 my $callobj = {
128 method => 'getPossibleProductActions_list',
129 params => [ $productId ],
130 id => 1, };
132 my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
133 my ($sres_err, $sres_err_string) = &check_opsi_res($sres);
134 if ($sres_err){
135 &main::daemon_log("$session_id ERROR: cannot get product action list: ".$sres_err_string, 1);
136 &add_content2xml_hash($out_hash, "error", $sres_err_string);
137 return ( &create_xml_string($out_hash) );
138 }
139 my $uninst_possible= 0;
140 foreach my $r (@{$sres->result}) {
141 if ($r eq 'uninstall') {
142 $uninst_possible= 1;
143 }
144 }
145 if (!$uninst_possible){
146 &main::daemon_log("$session_id ERROR: cannot uninstall product", 1);
147 &add_content2xml_hash($out_hash, "error", "product is not uninstallable");
148 return ( &create_xml_string($out_hash) );
149 }
151 # Set product state to "none"
152 # Do an action request for all these -> "setup".
153 $callobj = {
154 method => 'setProductActionRequest',
155 params => [ $productId, $hostId, "none" ],
156 id => 1, };
158 $sres = $main::opsi_client->call($main::opsi_url, $callobj);
159 my ($sres_err, $sres_err_string) = &check_opsi_res($sres);
160 if ($sres_err){
161 &main::daemon_log("$session_id ERROR: cannot delete product: ".$sres_err_string, 1);
162 &add_content2xml_hash($out_hash, "error", $sres_err_string);
163 return ( &create_xml_string($out_hash) );
164 }
166 # return message
167 return ( &create_xml_string($out_hash) );
168 }
171 sub opsi_add_client {
172 my ($msg, $msg_hash, $session_id) = @_;
173 my $header = @{$msg_hash->{'header'}}[0];
174 my $source = @{$msg_hash->{'source'}}[0];
175 my $target = @{$msg_hash->{'target'}}[0];
176 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
177 my $hostId;
179 # build return message with twisted target and source
180 my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
181 if (defined $forward_to_gosa) {
182 &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
183 }
185 # Get hostID
186 $hostId = @{$msg_hash->{'hostId'}}[0];
187 &add_content2xml_hash($out_hash, "hostId", $hostId);
188 my $name= $hostId;
189 $name=~ s/^([^.]+).*$/$1/;
190 my $domain= $hostId;
191 $domain=~ s/^[^.]+\.(.*)$/$1/;
192 my ($description, $notes, $ip, $mac);
194 if (defined @{$msg_hash->{'description'}}[0]){
195 $description = @{$msg_hash->{'description'}}[0];
196 }
197 if (defined @{$msg_hash->{'notes'}}[0]){
198 $notes = @{$msg_hash->{'notes'}}[0];
199 }
200 if (defined @{$msg_hash->{'ip'}}[0]){
201 $ip = @{$msg_hash->{'ip'}}[0];
202 }
203 if (defined @{$msg_hash->{'macaddress'}}[0]){
204 $mac = @{$msg_hash->{'macaddress'}}[0];
205 }
207 my $callobj;
208 $callobj = {
209 method => 'createClient',
210 params => [ $name, $domain, $description, $notes, $ip, $mac ],
211 id => 1,
212 };
214 my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
215 my ($sres_err, $sres_err_string) = &check_opsi_res($sres);
216 if ($sres_err){
217 &main::daemon_log("$session_id ERROR: cannot create client: ".$sres_err_string, 1);
218 &add_content2xml_hash($out_hash, "error", $sres_err_string);
219 }
221 # return message
222 return ( &create_xml_string($out_hash) );
223 }
226 sub opsi_modify_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;
234 # build return message with twisted target and source
235 my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
236 if (defined $forward_to_gosa) {
237 &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
238 }
240 # Get hostID
241 $hostId = @{$msg_hash->{'hostId'}}[0];
242 &add_content2xml_hash($out_hash, "hostId", $hostId);
243 my $name= $hostId;
244 $name=~ s/^([^.]+).*$/$1/;
245 my $domain= $hostId;
246 $domain=~ s/^[^.]+(.*)$/$1/;
247 my ($description, $notes, $ip, $mac);
249 my $callobj;
251 if (defined @{$msg_hash->{'description'}}[0]){
252 $description = @{$msg_hash->{'description'}}[0];
253 $callobj = {
254 method => 'setHostDescription',
255 params => [ $hostId, $description ],
256 id => 1,
257 };
258 my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
259 my ($sres_err, $sres_err_string) = &check_opsi_res($sres);
260 if ($sres_err){
261 &main::daemon_log("ERROR: cannot set description: ".$sres_err_string, 1);
262 &add_content2xml_hash($out_hash, "error", $sres_err_string);
263 return ( &create_xml_string($out_hash) );
264 }
265 }
266 if (defined @{$msg_hash->{'notes'}}[0]){
267 $notes = @{$msg_hash->{'notes'}}[0];
268 $callobj = {
269 method => 'setHostNotes',
270 params => [ $hostId, $notes ],
271 id => 1,
272 };
273 my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
274 my ($sres_err, $sres_err_string) = &check_opsi_res($sres);
275 if ($sres_err){
276 &main::daemon_log("ERROR: cannot set notes: ".$sres_err_string, 1);
277 &add_content2xml_hash($out_hash, "error", $sres_err_string);
278 return ( &create_xml_string($out_hash) );
279 }
280 }
281 if (defined @{$msg_hash->{'mac'}}[0]){
282 $mac = @{$msg_hash->{'mac'}}[0];
283 $callobj = {
284 method => 'setMacAddress',
285 params => [ $hostId, $mac ],
286 id => 1,
287 };
288 my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
289 my ($sres_err, $sres_err_string) = &check_opsi_res($sres);
290 if ($sres_err){
291 &main::daemon_log("ERROR: cannot set mac address: ".$sres_err_string, 1);
292 &add_content2xml_hash($out_hash, "error", $sres_err_string);
293 return ( &create_xml_string($out_hash) );
294 }
295 }
297 # return message
298 return ( &create_xml_string($out_hash) );
299 }
302 ## @method opsi_get_netboot_products
303 # ???
304 # @param msg - STRING - xml message with tag hostId
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 sub opsi_get_netboot_products {
308 my ($msg, $msg_hash, $session_id) = @_;
309 my $header = @{$msg_hash->{'header'}}[0];
310 my $source = @{$msg_hash->{'source'}}[0];
311 my $target = @{$msg_hash->{'target'}}[0];
312 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
313 my $hostId;
315 # build return message with twisted target and source
316 my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
317 if (defined $forward_to_gosa) {
318 &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
319 }
321 # Get hostID if defined
322 if (defined @{$msg_hash->{'hostId'}}[0]){
323 $hostId = @{$msg_hash->{'hostId'}}[0];
324 &add_content2xml_hash($out_hash, "hostId", $hostId);
325 }
327 &add_content2xml_hash($out_hash, "xxx", "");
328 my $xml_msg= &create_xml_string($out_hash);
330 # For hosts, only return the products that are or get installed
331 my $callobj;
332 $callobj = {
333 method => 'getNetBootProductIds_list',
334 params => [ ],
335 id => 1,
336 };
338 my $res = $main::opsi_client->call($main::opsi_url, $callobj);
339 my %r = ();
340 for (@{$res->result}) { $r{$_} = 1 }
342 if (&check_opsi_res($res)){
344 if (defined $hostId){
345 $callobj = {
346 method => 'getProductStates_hash',
347 params => [ $hostId ],
348 id => 1,
349 };
351 my $hres = $main::opsi_client->call($main::opsi_url, $callobj);
352 if (&check_opsi_res($hres)){
353 my $htmp= $hres->result->{$hostId};
355 # check state != not_installed or action == setup -> load and add
356 foreach my $product (@{$htmp}){
358 if (!defined ($r{$product->{'productId'}})){
359 next;
360 }
362 # Now we've a couple of hashes...
363 if ($product->{'installationStatus'} ne "not_installed" or
364 $product->{'actionRequest'} eq "setup"){
365 my $state= "<state>".$product->{'installationStatus'}."</state><action>".$product->{'actionRequest'}."</action>";
367 $callobj = {
368 method => 'getProduct_hash',
369 params => [ $product->{'productId'} ],
370 id => 1,
371 };
373 my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
374 if (&check_opsi_res($sres)){
375 my $tres= $sres->result;
377 my $name= xml_quote($tres->{'name'});
378 my $r= $product->{'productId'};
379 my $description= xml_quote($tres->{'description'});
380 $name=~ s/\//\\\//;
381 $description=~ s/\//\\\//;
382 $xml_msg=~ s/<xxx><\/xxx>/<item><productId>$r<\/productId><name><\/name><description>$description<\/description><\/item>$state<xxx><\/xxx>/;
383 }
385 }
386 }
388 }
390 } else {
391 foreach my $r (@{$res->result}) {
392 $callobj = {
393 method => 'getProduct_hash',
394 params => [ $r ],
395 id => 1,
396 };
398 my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
399 if (&check_opsi_res($sres)){
400 my $tres= $sres->result;
402 my $name= xml_quote($tres->{'name'});
403 my $description= xml_quote($tres->{'description'});
404 $name=~ s/\//\\\//;
405 $description=~ s/\//\\\//;
406 $xml_msg=~ s/<xxx><\/xxx>/<item><productId>$r<\/productId><name><\/name><description>$description<\/description><\/item><xxx><\/xxx>/;
407 }
409 }
411 }
412 }
414 $xml_msg=~ s/<xxx><\/xxx>//;
416 return ($xml_msg);
417 }
420 ## @method opsi_get_product_properties
421 # ???
422 # @param msg - STRING - xml message with tags ProductId and hostId
423 # @param msg_hash - HASHREF - message information parsed into a hash
424 # @param session_id - INTEGER - POE session id of the processing of this message
425 sub opsi_get_product_properties {
426 my ($msg, $msg_hash, $session_id) = @_;
427 my $header = @{$msg_hash->{'header'}}[0];
428 my $source = @{$msg_hash->{'source'}}[0];
429 my $target = @{$msg_hash->{'target'}}[0];
430 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
431 my $productId = @{$msg_hash->{'productId'}}[0];
432 my $hostId;
434 # build return message with twisted target and source
435 my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
437 # Get hostID if defined
438 if (defined @{$msg_hash->{'hostId'}}[0]){
439 $hostId = @{$msg_hash->{'hostId'}}[0];
440 &add_content2xml_hash($out_hash, "hostId", $hostId);
441 }
443 if (defined $forward_to_gosa) {
444 &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
445 }
446 &add_content2xml_hash($out_hash, "ProducId", "$productId");
448 # Load actions
449 my $callobj = {
450 method => 'getPossibleProductActions_list',
451 params => [ $productId ],
452 id => 1,
453 };
454 my $res = $main::opsi_client->call($main::opsi_url, $callobj);
455 if (&check_opsi_res($res)){
456 foreach my $action (@{$res->result}){
457 &add_content2xml_hash($out_hash, "action", $action);
458 }
459 }
461 # Add place holder
462 &add_content2xml_hash($out_hash, "xxx", "");
464 # Move to XML string
465 my $xml_msg= &create_xml_string($out_hash);
467 # JSON Query
468 $callobj = {
469 method => 'getProductProperties_hash',
470 params => [ $productId ],
471 id => 1,
472 };
474 $res = $main::opsi_client->call($main::opsi_url, $callobj);
476 if (&check_opsi_res($res)){
477 my $r= $res->result;
478 foreach my $key (keys %{$r}) {
479 my $item= "<item>";
480 my $value= $r->{$key};
481 if (UNIVERSAL::isa( $value, "ARRAY" )){
482 foreach my $subval (@{$value}){
483 $item.= "<$key>".xml_quote($subval)."</$key>";
484 }
485 } else {
486 $item.= "<$key>".xml_quote($value)."</$key>";
487 }
488 $item.= "</item>";
489 $xml_msg=~ s/<xxx><\/xxx>/$item<xxx><\/xxx>/;
490 }
491 }
494 $xml_msg=~ s/<xxx><\/xxx>//;
496 return ($xml_msg);
497 }
500 ## @method opsi_set_product_properties
501 # ???
502 # @param msg - STRING - xml message with tags ProductId, hostId, action and state
503 # @param msg_hash - HASHREF - message information parsed into a hash
504 # @param session_id - INTEGER - POE session id of the processing of this message
505 sub opsi_set_product_properties {
506 my ($msg, $msg_hash, $session_id) = @_;
507 my $header = @{$msg_hash->{'header'}}[0];
508 my $source = @{$msg_hash->{'source'}}[0];
509 my $target = @{$msg_hash->{'target'}}[0];
510 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
511 my $productId = @{$msg_hash->{'productId'}}[0];
512 my $hostId;
514 # build return message with twisted target and source
515 my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
516 &add_content2xml_hash($out_hash, "productId", $productId);
518 # Get hostID if defined
519 if (defined @{$msg_hash->{'hostId'}}[0]){
520 $hostId = @{$msg_hash->{'hostId'}}[0];
521 &add_content2xml_hash($out_hash, "hostId", $hostId);
522 }
524 # Set product states if requested
525 if (defined @{$msg_hash->{'action'}}[0]){
526 &_set_action($productId, @{$msg_hash->{'action'}}[0], $hostId);
527 }
528 if (defined @{$msg_hash->{'state'}}[0]){
529 &_set_state($productId, @{$msg_hash->{'state'}}[0], $hostId);
530 }
532 if (defined $forward_to_gosa) {
533 &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
534 }
536 # Find properties
537 foreach my $item (@{$msg_hash->{'item'}}){
538 # JSON Query
539 my $callobj;
541 if (defined $hostId){
542 $callobj = {
543 method => 'setProductProperty',
544 params => [ $productId, $item->{'name'}[0], $item->{'value'}[0], $hostId ],
545 id => 1,
546 };
547 } else {
548 $callobj = {
549 method => 'setProductProperty',
550 params => [ $productId, $item->{'name'}[0], $item->{'value'}[0] ],
551 id => 1,
552 };
553 }
555 my $res = $main::opsi_client->call($main::opsi_url, $callobj);
556 my ($res_err, $res_err_string) = &check_opsi_res($res);
557 # TODO : This error message sounds strange
558 if ($res_err){
559 &man::daemon_log("$session_id ERROR: no communication failed while setting '".$item->{'name'}[0]."': ".$res_err_string, 1);
560 &add_content2xml_hash($out_hash, "error", $res_err_string);
561 }
563 }
565 # return message
566 return ( &create_xml_string($out_hash) );
567 }
570 ## @method opsi_get_client_hardware
571 # ???
572 # @param msg - STRING - xml message with tag hostId
573 # @param msg_hash - HASHREF - message information parsed into a hash
574 # @param session_id - INTEGER - POE session id of the processing of this message
575 sub opsi_get_client_hardware {
576 my ($msg, $msg_hash, $session_id) = @_;
577 my $header = @{$msg_hash->{'header'}}[0];
578 my $source = @{$msg_hash->{'source'}}[0];
579 my $target = @{$msg_hash->{'target'}}[0];
580 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
581 my $hostId = @{$msg_hash->{'hostId'}}[0];
583 # build return message with twisted target and source
584 my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
586 if (defined $forward_to_gosa) {
587 &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
588 }
589 &add_content2xml_hash($out_hash, "hostId", "$hostId");
590 &add_content2xml_hash($out_hash, "xxx", "");
591 my $xml_msg= &create_xml_string($out_hash);
593 # JSON Query
594 my $callobj = {
595 method => 'getHardwareInformation_hash',
596 params => [ $hostId ],
597 id => 1,
598 };
600 my $res = $main::opsi_client->call($main::opsi_url, $callobj);
601 if (&check_opsi_res($res)){
602 my $result= $res->result;
603 foreach my $r (keys %{$result}){
604 my $item= "<item><id>".xml_quote($r)."</id>";
605 my $value= $result->{$r};
606 foreach my $sres (@{$value}){
608 foreach my $dres (keys %{$sres}){
609 if (defined $sres->{$dres}){
610 $item.= "<$dres>".xml_quote($sres->{$dres})."</$dres>";
611 }
612 }
614 }
615 $item.= "</item>";
616 $xml_msg=~ s%<xxx></xxx>%$item<xxx></xxx>%;
618 }
619 }
621 $xml_msg=~ s/<xxx><\/xxx>//;
623 return ( $xml_msg );
624 }
627 ## @method opsi_list_clients
628 # ???
629 # @param msg - STRING - xml message
630 # @param msg_hash - HASHREF - message information parsed into a hash
631 # @param session_id - INTEGER - POE session id of the processing of this message
632 sub opsi_list_clients {
633 my ($msg, $msg_hash, $session_id) = @_;
634 my $header = @{$msg_hash->{'header'}}[0];
635 my $source = @{$msg_hash->{'source'}}[0];
636 my $target = @{$msg_hash->{'target'}}[0];
637 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
639 # build return message with twisted target and source
640 my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
642 if (defined $forward_to_gosa) {
643 &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
644 }
646 &add_content2xml_hash($out_hash, "xxx", "");
647 my $xml_msg= &create_xml_string($out_hash);
649 # JSON Query
650 my $callobj = {
651 method => 'getClients_listOfHashes',
652 params => [ ],
653 id => 1,
654 };
656 my $res = $main::opsi_client->call($main::opsi_url, $callobj);
657 if (&check_opsi_res($res)){
659 foreach my $host (@{$res->result}){
660 my $item= "<item><name>".$host->{'hostId'}."</name>";
661 if (defined($host->{'description'})){
662 $item.= "<description>".xml_quote($host->{'description'})."</description>";
663 }
664 $item.= "</item>";
665 $xml_msg=~ s%<xxx></xxx>%$item<xxx></xxx>%;
666 }
668 }
670 $xml_msg=~ s/<xxx><\/xxx>//;
671 return ( $xml_msg );
672 }
675 ## @method opsi_get_client_software
676 # ???
677 # @param msg - STRING - xml message with tag hostId
678 # @param msg_hash - HASHREF - message information parsed into a hash
679 # @param session_id - INTEGER - POE session id of the processing of this message
680 sub opsi_get_client_software {
681 my ($msg, $msg_hash, $session_id) = @_;
682 my $header = @{$msg_hash->{'header'}}[0];
683 my $source = @{$msg_hash->{'source'}}[0];
684 my $target = @{$msg_hash->{'target'}}[0];
685 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
686 my $hostId = @{$msg_hash->{'hostId'}}[0];
688 # build return message with twisted target and source
689 my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
691 if (defined $forward_to_gosa) {
692 &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
693 }
694 &add_content2xml_hash($out_hash, "hostId", "$hostId");
695 &add_content2xml_hash($out_hash, "xxx", "");
696 my $xml_msg= &create_xml_string($out_hash);
698 # JSON Query
699 my $callobj = {
700 method => 'getSoftwareInformation_hash',
701 params => [ $hostId ],
702 id => 1,
703 };
705 my $res = $main::opsi_client->call($main::opsi_url, $callobj);
706 if (&check_opsi_res($res)){
707 my $result= $res->result;
708 }
710 $xml_msg=~ s/<xxx><\/xxx>//;
712 return ( $xml_msg );
713 }
716 ## @method opsi_get_local_products
717 # ???
718 # @param msg - STRING - xml message with tag hostId
719 # @param msg_hash - HASHREF - message information parsed into a hash
720 # @param session_id - INTEGER - POE session id of the processing of this message
721 sub opsi_get_local_products {
722 my ($msg, $msg_hash, $session_id) = @_;
723 my $header = @{$msg_hash->{'header'}}[0];
724 my $source = @{$msg_hash->{'source'}}[0];
725 my $target = @{$msg_hash->{'target'}}[0];
726 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
727 my $hostId;
729 # build return message with twisted target and source
730 my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
732 # Get hostID if defined
733 if (defined @{$msg_hash->{'hostId'}}[0]){
734 $hostId = @{$msg_hash->{'hostId'}}[0];
735 &add_content2xml_hash($out_hash, "hostId", $hostId);
736 }
738 if (defined $forward_to_gosa) {
739 &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
740 }
741 &add_content2xml_hash($out_hash, "xxx", "");
742 my $xml_msg= &create_xml_string($out_hash);
744 # For hosts, only return the products that are or get installed
745 my $callobj;
746 $callobj = {
747 method => 'getLocalBootProductIds_list',
748 params => [ ],
749 id => 1,
750 };
752 my $res = $main::opsi_client->call($main::opsi_url, $callobj);
753 my %r = ();
754 for (@{$res->result}) { $r{$_} = 1 }
756 if (&check_opsi_res($res)){
758 if (defined $hostId){
759 $callobj = {
760 method => 'getProductStates_hash',
761 params => [ $hostId ],
762 id => 1,
763 };
765 my $hres = $main::opsi_client->call($main::opsi_url, $callobj);
766 if (&check_opsi_res($hres)){
767 my $htmp= $hres->result->{$hostId};
769 # check state != not_installed or action == setup -> load and add
770 foreach my $product (@{$htmp}){
772 if (!defined ($r{$product->{'productId'}})){
773 next;
774 }
776 # Now we've a couple of hashes...
777 if ($product->{'installationStatus'} ne "not_installed" or
778 $product->{'actionRequest'} eq "setup"){
779 my $state= "<state>".$product->{'installationStatus'}."</state><action>".$product->{'actionRequest'}."</action>";
781 $callobj = {
782 method => 'getProduct_hash',
783 params => [ $product->{'productId'} ],
784 id => 1,
785 };
787 my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
788 if (&check_opsi_res($sres)){
789 my $tres= $sres->result;
791 my $name= xml_quote($tres->{'name'});
792 my $r= $product->{'productId'};
793 my $description= xml_quote($tres->{'description'});
794 $name=~ s/\//\\\//;
795 $description=~ s/\//\\\//;
796 $xml_msg=~ s/<xxx><\/xxx>/<item><productId>$r<\/productId><name><\/name><description>$description<\/description><\/item>$state<xxx><\/xxx>/;
797 }
799 }
800 }
802 }
804 } else {
805 foreach my $r (@{$res->result}) {
806 $callobj = {
807 method => 'getProduct_hash',
808 params => [ $r ],
809 id => 1,
810 };
812 my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
813 if (&check_opsi_res($sres)){
814 my $tres= $sres->result;
816 my $name= xml_quote($tres->{'name'});
817 my $description= xml_quote($tres->{'description'});
818 $name=~ s/\//\\\//;
819 $description=~ s/\//\\\//;
820 $xml_msg=~ s/<xxx><\/xxx>/<item><productId>$r<\/productId><name><\/name><description>$description<\/description><\/item><xxx><\/xxx>/;
821 }
823 }
825 }
826 }
828 $xml_msg=~ s/<xxx><\/xxx>//;
830 return ( $xml_msg );
831 }
834 ## @method opsi_del_client
835 # ???
836 # @param msg - STRING - xml message with tag hostId
837 # @param msg_hash - HASHREF - message information parsed into a hash
838 # @param session_id - INTEGER - POE session id of the processing of this message
839 sub opsi_del_client {
840 my ($msg, $msg_hash, $session_id) = @_;
841 my $header = @{$msg_hash->{'header'}}[0];
842 my $source = @{$msg_hash->{'source'}}[0];
843 my $target = @{$msg_hash->{'target'}}[0];
844 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
845 my $hostId = @{$msg_hash->{'hostId'}}[0];
847 # build return message with twisted target and source
848 my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
850 if (defined $forward_to_gosa) {
851 &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
852 }
853 &add_content2xml_hash($out_hash, "hostId", "$hostId");
855 # JSON Query
856 my $callobj = {
857 method => 'deleteClient',
858 params => [ $hostId ],
859 id => 1,
860 };
862 my $res = $main::opsi_client->call($main::opsi_url, $callobj);
864 my $xml_msg= &create_xml_string($out_hash);
865 return ( $xml_msg );
866 }
869 ## @method opsi_install_client
870 # ???
871 # @param msg - STRING - xml message with tags hostId, macaddress
872 # @param msg_hash - HASHREF - message information parsed into a hash
873 # @param session_id - INTEGER - POE session id of the processing of this message
874 sub opsi_install_client {
875 my ($msg, $msg_hash, $session_id) = @_;
876 my $header = @{$msg_hash->{'header'}}[0];
877 my $source = @{$msg_hash->{'source'}}[0];
878 my $target = @{$msg_hash->{'target'}}[0];
879 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
880 my $hostId = @{$msg_hash->{'hostId'}}[0];
881 my $error = 0;
882 my @out_msg_l;
884 # If no macaddress is specified, raise error
885 my $macaddress;
886 if ((exists $msg_hash->{'macaddress'}) &&
887 ($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)) {
888 $macaddress = $1;
889 } else {
890 $error ++;
891 my $out_msg = "<xml>".
892 "<header>answer</header>".
893 "<source>$main::server_address</source>".
894 "<target>GOSA</target>".
895 "<answer1>1</answer1>".
896 "<error_string>no mac address specified in macaddres-tag</error_string>".
897 "</xml>";
898 push(@out_msg_l, $out_msg);
899 }
901 # Set parameters in opsi
902 if (not $error) {
903 # build return message with twisted target and source
904 my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
906 if (defined $forward_to_gosa) {
907 &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
908 }
909 &add_content2xml_hash($out_hash, "hostId", "$hostId");
911 # Load all products for this host with status != "not_installed" or actionRequest != "none"
912 if (defined $hostId){
913 my $callobj = {
914 method => 'getProductStates_hash',
915 params => [ $hostId ],
916 id => 1,
917 };
919 my $hres = $main::opsi_client->call($main::opsi_url, $callobj);
920 if (&check_opsi_res($hres)){
921 my $htmp= $hres->result->{$hostId};
923 # check state != not_installed or action == setup -> load and add
924 foreach my $product (@{$htmp}){
925 # Now we've a couple of hashes...
926 if ($product->{'installationStatus'} ne "not_installed" or
927 $product->{'actionRequest'} ne "none"){
929 # Do an action request for all these -> "setup".
930 $callobj = {
931 method => 'setProductActionRequest',
932 params => [ $product->{'productId'}, $hostId, "setup" ],
933 id => 1,
934 };
935 my $res = $main::opsi_client->call($main::opsi_url, $callobj);
936 if (!&check_opsi_res($res)){
937 &main::daemon_log("ERROR: cannot set product action request for $hostId!", 1);
938 } else {
939 &main::daemon_log("INFO: requesting 'setup' for '".$product->{'productId'}."' on $hostId", 1);
940 }
942 }
943 }
944 }
945 }
947 push(@out_msg_l, &create_xml_string($out_hash));
948 }
950 # Build wakeup message for client
951 if (not $error) {
952 my $wakeup_hash = &create_xml_hash("trigger_wake", "GOSA", "KNOWN_SERVER");
953 &add_content2xml_hash($wakeup_hash, 'macAddress', $macaddress);
954 my $wakeup_msg = &create_xml_string($wakeup_hash);
955 push(@out_msg_l, $wakeup_msg);
957 # invoke trigger wake for this gosa-si-server
958 &main::server_server_com::trigger_wake($wakeup_msg, $wakeup_hash, $session_id);
959 }
962 return @out_msg_l;
963 }
966 ## @method _set_action
967 # ???
968 # @param product - STRING - ???
969 # @param action - STRING - ???
970 # @param hostId - STRING - ???
971 sub _set_action {
972 my $product= shift;
973 my $action = shift;
974 my $hostId = shift;
975 my $callobj;
977 $callobj = {
978 method => 'setProductActionRequest',
979 params => [ $product, $hostId, $action],
980 id => 1,
981 };
983 $main::opsi_client->call($main::opsi_url, $callobj);
984 }
986 ## @method _set_state
987 # ???
988 # @param product - STRING - ???
989 # @param action - STRING - ???
990 # @param hostId - STRING - ???
991 sub _set_state {
992 my $product = shift;
993 my $hostId = shift;
994 my $action = shift;
995 my $callobj;
997 $callobj = {
998 method => 'setProductState',
999 params => [ $product, $hostId, $action ],
1000 id => 1,
1001 };
1003 $main::opsi_client->call($main::opsi_url, $callobj);
1004 }
1006 1;