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, };
131 my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
132 my ($sres_err, $sres_err_string) = &check_opsi_res($sres);
133 if ($sres_err){
134 &main::daemon_log("$session_id ERROR: cannot get product action list: ".$sres_err_string, 1);
135 &add_content2xml_hash($out_hash, "error", $sres_err_string);
136 return ( &create_xml_string($out_hash) );
137 }
138 my $uninst_possible= 0;
139 foreach my $r (@{$sres->result}) {
140 if ($r eq 'uninstall') {
141 $uninst_possible= 1;
142 }
143 }
144 if (!$uninst_possible){
145 &main::daemon_log("$session_id ERROR: cannot uninstall product '$productId', product do not has the action 'uninstall'", 1);
146 &add_content2xml_hash($out_hash, "error", "cannot uninstall product '$productId', product do not has the action 'uninstall'");
147 return ( &create_xml_string($out_hash) );
148 }
150 # Set product state to "none"
151 # Do an action request for all these -> "setup".
152 $callobj = {
153 method => 'setProductActionRequest',
154 params => [ $productId, $hostId, "none" ],
155 id => 1, };
157 print STDERR Dumper($callobj);
159 my $res = $main::opsi_client->call($main::opsi_url, $callobj);
160 my ($res_err, $res_err_string) = &check_opsi_res($res);
161 if ($res_err){
162 &main::daemon_log("$session_id ERROR: cannot delete product: ".$res_err_string, 1);
163 &add_content2xml_hash($out_hash, "error", $res_err_string);
164 return ( &create_xml_string($out_hash) );
165 }
167 # return message
168 return ( &create_xml_string($out_hash) );
169 }
172 sub opsi_add_client {
173 my ($msg, $msg_hash, $session_id) = @_;
174 my $header = @{$msg_hash->{'header'}}[0];
175 my $source = @{$msg_hash->{'source'}}[0];
176 my $target = @{$msg_hash->{'target'}}[0];
177 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
178 my $hostId;
180 # build return message with twisted target and source
181 my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
182 if (defined $forward_to_gosa) {
183 &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
184 }
186 # Get hostID
187 $hostId = @{$msg_hash->{'hostId'}}[0];
188 &add_content2xml_hash($out_hash, "hostId", $hostId);
189 my $name= $hostId;
190 $name=~ s/^([^.]+).*$/$1/;
191 my $domain= $hostId;
192 $domain=~ s/^[^.]+\.(.*)$/$1/;
193 my ($description, $notes, $ip, $mac);
195 if (defined @{$msg_hash->{'description'}}[0]){
196 $description = @{$msg_hash->{'description'}}[0];
197 }
198 if (defined @{$msg_hash->{'notes'}}[0]){
199 $notes = @{$msg_hash->{'notes'}}[0];
200 }
201 if (defined @{$msg_hash->{'ip'}}[0]){
202 $ip = @{$msg_hash->{'ip'}}[0];
203 }
204 if (defined @{$msg_hash->{'macaddress'}}[0]){
205 $mac = @{$msg_hash->{'macaddress'}}[0];
206 }
208 my $callobj;
209 $callobj = {
210 method => 'createClient',
211 params => [ $name, $domain, $description, $notes, $ip, $mac ],
212 id => 1,
213 };
215 my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
216 my ($sres_err, $sres_err_string) = &check_opsi_res($sres);
217 if ($sres_err){
218 &main::daemon_log("$session_id ERROR: cannot create client: ".$sres_err_string, 1);
219 &add_content2xml_hash($out_hash, "error", $sres_err_string);
220 }
222 # return message
223 return ( &create_xml_string($out_hash) );
224 }
227 sub opsi_modify_client {
228 my ($msg, $msg_hash, $session_id) = @_;
229 my $header = @{$msg_hash->{'header'}}[0];
230 my $source = @{$msg_hash->{'source'}}[0];
231 my $target = @{$msg_hash->{'target'}}[0];
232 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
233 my $hostId;
235 # build return message with twisted target and source
236 my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
237 if (defined $forward_to_gosa) {
238 &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
239 }
241 # Get hostID
242 $hostId = @{$msg_hash->{'hostId'}}[0];
243 &add_content2xml_hash($out_hash, "hostId", $hostId);
244 my $name= $hostId;
245 $name=~ s/^([^.]+).*$/$1/;
246 my $domain= $hostId;
247 $domain=~ s/^[^.]+(.*)$/$1/;
248 my ($description, $notes, $ip, $mac);
250 my $callobj;
252 if (defined @{$msg_hash->{'description'}}[0]){
253 $description = @{$msg_hash->{'description'}}[0];
254 $callobj = {
255 method => 'setHostDescription',
256 params => [ $hostId, $description ],
257 id => 1,
258 };
259 my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
260 my ($sres_err, $sres_err_string) = &check_opsi_res($sres);
261 if ($sres_err){
262 &main::daemon_log("ERROR: cannot set description: ".$sres_err_string, 1);
263 &add_content2xml_hash($out_hash, "error", $sres_err_string);
264 return ( &create_xml_string($out_hash) );
265 }
266 }
267 if (defined @{$msg_hash->{'notes'}}[0]){
268 $notes = @{$msg_hash->{'notes'}}[0];
269 $callobj = {
270 method => 'setHostNotes',
271 params => [ $hostId, $notes ],
272 id => 1,
273 };
274 my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
275 my ($sres_err, $sres_err_string) = &check_opsi_res($sres);
276 if ($sres_err){
277 &main::daemon_log("ERROR: cannot set notes: ".$sres_err_string, 1);
278 &add_content2xml_hash($out_hash, "error", $sres_err_string);
279 return ( &create_xml_string($out_hash) );
280 }
281 }
282 if (defined @{$msg_hash->{'mac'}}[0]){
283 $mac = @{$msg_hash->{'mac'}}[0];
284 $callobj = {
285 method => 'setMacAddress',
286 params => [ $hostId, $mac ],
287 id => 1,
288 };
289 my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
290 my ($sres_err, $sres_err_string) = &check_opsi_res($sres);
291 if ($sres_err){
292 &main::daemon_log("ERROR: cannot set mac address: ".$sres_err_string, 1);
293 &add_content2xml_hash($out_hash, "error", $sres_err_string);
294 return ( &create_xml_string($out_hash) );
295 }
296 }
298 # return message
299 return ( &create_xml_string($out_hash) );
300 }
303 ## @method opsi_get_netboot_products
304 # ???
305 # @param msg - STRING - xml message with tag hostId
306 # @param msg_hash - HASHREF - message information parsed into a hash
307 # @param session_id - INTEGER - POE session id of the processing of this message
308 sub opsi_get_netboot_products {
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;
316 # build return message with twisted target and source
317 my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
318 if (defined $forward_to_gosa) {
319 &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
320 }
322 # Get hostID if defined
323 if (defined @{$msg_hash->{'hostId'}}[0]){
324 $hostId = @{$msg_hash->{'hostId'}}[0];
325 &add_content2xml_hash($out_hash, "hostId", $hostId);
326 }
328 &add_content2xml_hash($out_hash, "xxx", "");
329 my $xml_msg= &create_xml_string($out_hash);
331 # For hosts, only return the products that are or get installed
332 my $callobj;
333 $callobj = {
334 method => 'getNetBootProductIds_list',
335 params => [ ],
336 id => 1,
337 };
339 my $res = $main::opsi_client->call($main::opsi_url, $callobj);
340 my %r = ();
341 for (@{$res->result}) { $r{$_} = 1 }
343 if (&check_opsi_res($res)){
345 if (defined $hostId){
346 $callobj = {
347 method => 'getProductStates_hash',
348 params => [ $hostId ],
349 id => 1,
350 };
352 my $hres = $main::opsi_client->call($main::opsi_url, $callobj);
353 if (&check_opsi_res($hres)){
354 my $htmp= $hres->result->{$hostId};
356 # check state != not_installed or action == setup -> load and add
357 foreach my $product (@{$htmp}){
359 if (!defined ($r{$product->{'productId'}})){
360 next;
361 }
363 # Now we've a couple of hashes...
364 if ($product->{'installationStatus'} ne "not_installed" or
365 $product->{'actionRequest'} eq "setup"){
366 my $state= "<state>".$product->{'installationStatus'}."</state><action>".$product->{'actionRequest'}."</action>";
368 $callobj = {
369 method => 'getProduct_hash',
370 params => [ $product->{'productId'} ],
371 id => 1,
372 };
374 my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
375 if (&check_opsi_res($sres)){
376 my $tres= $sres->result;
378 my $name= xml_quote($tres->{'name'});
379 my $r= $product->{'productId'};
380 my $description= xml_quote($tres->{'description'});
381 $name=~ s/\//\\\//;
382 $description=~ s/\//\\\//;
383 $xml_msg=~ s/<xxx><\/xxx>/<item><productId>$r<\/productId><name><\/name><description>$description<\/description><\/item>$state<xxx><\/xxx>/;
384 }
386 }
387 }
389 }
391 } else {
392 foreach my $r (@{$res->result}) {
393 $callobj = {
394 method => 'getProduct_hash',
395 params => [ $r ],
396 id => 1,
397 };
399 my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
400 if (&check_opsi_res($sres)){
401 my $tres= $sres->result;
403 my $name= xml_quote($tres->{'name'});
404 my $description= xml_quote($tres->{'description'});
405 $name=~ s/\//\\\//;
406 $description=~ s/\//\\\//;
407 $xml_msg=~ s/<xxx><\/xxx>/<item><productId>$r<\/productId><name><\/name><description>$description<\/description><\/item><xxx><\/xxx>/;
408 }
410 }
412 }
413 }
415 $xml_msg=~ s/<xxx><\/xxx>//;
417 return ($xml_msg);
418 }
421 ## @method opsi_get_product_properties
422 # ???
423 # @param msg - STRING - xml message with tags ProductId and hostId
424 # @param msg_hash - HASHREF - message information parsed into a hash
425 # @param session_id - INTEGER - POE session id of the processing of this message
426 sub opsi_get_product_properties {
427 my ($msg, $msg_hash, $session_id) = @_;
428 my $header = @{$msg_hash->{'header'}}[0];
429 my $source = @{$msg_hash->{'source'}}[0];
430 my $target = @{$msg_hash->{'target'}}[0];
431 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
432 my $productId = @{$msg_hash->{'productId'}}[0];
433 my $hostId;
435 # build return message with twisted target and source
436 my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
438 # Get hostID if defined
439 if (defined @{$msg_hash->{'hostId'}}[0]){
440 $hostId = @{$msg_hash->{'hostId'}}[0];
441 &add_content2xml_hash($out_hash, "hostId", $hostId);
442 }
444 if (defined $forward_to_gosa) {
445 &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
446 }
447 &add_content2xml_hash($out_hash, "ProducId", "$productId");
449 # Load actions
450 my $callobj = {
451 method => 'getPossibleProductActions_list',
452 params => [ $productId ],
453 id => 1,
454 };
455 my $res = $main::opsi_client->call($main::opsi_url, $callobj);
456 if (&check_opsi_res($res)){
457 foreach my $action (@{$res->result}){
458 &add_content2xml_hash($out_hash, "action", $action);
459 }
460 }
462 # Add place holder
463 &add_content2xml_hash($out_hash, "xxx", "");
465 # Move to XML string
466 my $xml_msg= &create_xml_string($out_hash);
468 # JSON Query
469 $callobj = {
470 method => 'getProductProperties_hash',
471 params => [ $productId ],
472 id => 1,
473 };
475 $res = $main::opsi_client->call($main::opsi_url, $callobj);
477 if (&check_opsi_res($res)){
478 my $r= $res->result;
479 foreach my $key (keys %{$r}) {
480 my $item= "<item>";
481 my $value= $r->{$key};
482 if (UNIVERSAL::isa( $value, "ARRAY" )){
483 foreach my $subval (@{$value}){
484 $item.= "<$key>".xml_quote($subval)."</$key>";
485 }
486 } else {
487 $item.= "<$key>".xml_quote($value)."</$key>";
488 }
489 $item.= "</item>";
490 $xml_msg=~ s/<xxx><\/xxx>/$item<xxx><\/xxx>/;
491 }
492 }
495 $xml_msg=~ s/<xxx><\/xxx>//;
497 return ($xml_msg);
498 }
501 ## @method opsi_set_product_properties
502 # ???
503 # @param msg - STRING - xml message with tags ProductId, hostId, action and state
504 # @param msg_hash - HASHREF - message information parsed into a hash
505 # @param session_id - INTEGER - POE session id of the processing of this message
506 sub opsi_set_product_properties {
507 my ($msg, $msg_hash, $session_id) = @_;
508 my $header = @{$msg_hash->{'header'}}[0];
509 my $source = @{$msg_hash->{'source'}}[0];
510 my $target = @{$msg_hash->{'target'}}[0];
511 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
512 my $productId = @{$msg_hash->{'productId'}}[0];
513 my $hostId;
515 # build return message with twisted target and source
516 my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
517 &add_content2xml_hash($out_hash, "productId", $productId);
519 # Get hostID if defined
520 if (defined @{$msg_hash->{'hostId'}}[0]){
521 $hostId = @{$msg_hash->{'hostId'}}[0];
522 &add_content2xml_hash($out_hash, "hostId", $hostId);
523 }
525 # Set product states if requested
526 if (defined @{$msg_hash->{'action'}}[0]){
527 &_set_action($productId, @{$msg_hash->{'action'}}[0], $hostId);
528 }
529 if (defined @{$msg_hash->{'state'}}[0]){
530 &_set_state($productId, @{$msg_hash->{'state'}}[0], $hostId);
531 }
533 if (defined $forward_to_gosa) {
534 &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
535 }
537 # Find properties
538 foreach my $item (@{$msg_hash->{'item'}}){
539 # JSON Query
540 my $callobj;
542 if (defined $hostId){
543 $callobj = {
544 method => 'setProductProperty',
545 params => [ $productId, $item->{'name'}[0], $item->{'value'}[0], $hostId ],
546 id => 1,
547 };
548 } else {
549 $callobj = {
550 method => 'setProductProperty',
551 params => [ $productId, $item->{'name'}[0], $item->{'value'}[0] ],
552 id => 1,
553 };
554 }
556 my $res = $main::opsi_client->call($main::opsi_url, $callobj);
557 my ($res_err, $res_err_string) = &check_opsi_res($res);
558 # TODO : This error message sounds strange
559 if ($res_err){
560 &man::daemon_log("$session_id ERROR: no communication failed while setting '".$item->{'name'}[0]."': ".$res_err_string, 1);
561 &add_content2xml_hash($out_hash, "error", $res_err_string);
562 }
564 }
566 # return message
567 return ( &create_xml_string($out_hash) );
568 }
571 ## @method opsi_get_client_hardware
572 # ???
573 # @param msg - STRING - xml message with tag hostId
574 # @param msg_hash - HASHREF - message information parsed into a hash
575 # @param session_id - INTEGER - POE session id of the processing of this message
576 sub opsi_get_client_hardware {
577 my ($msg, $msg_hash, $session_id) = @_;
578 my $header = @{$msg_hash->{'header'}}[0];
579 my $source = @{$msg_hash->{'source'}}[0];
580 my $target = @{$msg_hash->{'target'}}[0];
581 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
582 my $hostId = @{$msg_hash->{'hostId'}}[0];
584 # build return message with twisted target and source
585 my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
587 if (defined $forward_to_gosa) {
588 &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
589 }
590 &add_content2xml_hash($out_hash, "hostId", "$hostId");
591 &add_content2xml_hash($out_hash, "xxx", "");
592 my $xml_msg= &create_xml_string($out_hash);
594 # JSON Query
595 my $callobj = {
596 method => 'getHardwareInformation_hash',
597 params => [ $hostId ],
598 id => 1,
599 };
601 my $res = $main::opsi_client->call($main::opsi_url, $callobj);
602 if (&check_opsi_res($res)){
603 my $result= $res->result;
604 foreach my $r (keys %{$result}){
605 my $item= "<item><id>".xml_quote($r)."</id>";
606 my $value= $result->{$r};
607 foreach my $sres (@{$value}){
609 foreach my $dres (keys %{$sres}){
610 if (defined $sres->{$dres}){
611 $item.= "<$dres>".xml_quote($sres->{$dres})."</$dres>";
612 }
613 }
615 }
616 $item.= "</item>";
617 $xml_msg=~ s%<xxx></xxx>%$item<xxx></xxx>%;
619 }
620 }
622 $xml_msg=~ s/<xxx><\/xxx>//;
624 return ( $xml_msg );
625 }
628 ## @method opsi_list_clients
629 # ???
630 # @param msg - STRING - xml message
631 # @param msg_hash - HASHREF - message information parsed into a hash
632 # @param session_id - INTEGER - POE session id of the processing of this message
633 sub opsi_list_clients {
634 my ($msg, $msg_hash, $session_id) = @_;
635 my $header = @{$msg_hash->{'header'}}[0];
636 my $source = @{$msg_hash->{'source'}}[0];
637 my $target = @{$msg_hash->{'target'}}[0];
638 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
640 # build return message with twisted target and source
641 my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
643 if (defined $forward_to_gosa) {
644 &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
645 }
647 &add_content2xml_hash($out_hash, "xxx", "");
648 my $xml_msg= &create_xml_string($out_hash);
650 # JSON Query
651 my $callobj = {
652 method => 'getClients_listOfHashes',
653 params => [ ],
654 id => 1,
655 };
657 my $res = $main::opsi_client->call($main::opsi_url, $callobj);
658 if (&check_opsi_res($res)){
660 foreach my $host (@{$res->result}){
661 my $item= "<item><name>".$host->{'hostId'}."</name>";
662 if (defined($host->{'description'})){
663 $item.= "<description>".xml_quote($host->{'description'})."</description>";
664 }
665 $item.= "</item>";
666 $xml_msg=~ s%<xxx></xxx>%$item<xxx></xxx>%;
667 }
669 }
671 $xml_msg=~ s/<xxx><\/xxx>//;
672 return ( $xml_msg );
673 }
676 ## @method opsi_get_client_software
677 # ???
678 # @param msg - STRING - xml message with tag hostId
679 # @param msg_hash - HASHREF - message information parsed into a hash
680 # @param session_id - INTEGER - POE session id of the processing of this message
681 sub opsi_get_client_software {
682 my ($msg, $msg_hash, $session_id) = @_;
683 my $header = @{$msg_hash->{'header'}}[0];
684 my $source = @{$msg_hash->{'source'}}[0];
685 my $target = @{$msg_hash->{'target'}}[0];
686 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
687 my $hostId = @{$msg_hash->{'hostId'}}[0];
689 # build return message with twisted target and source
690 my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
692 if (defined $forward_to_gosa) {
693 &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
694 }
695 &add_content2xml_hash($out_hash, "hostId", "$hostId");
696 &add_content2xml_hash($out_hash, "xxx", "");
697 my $xml_msg= &create_xml_string($out_hash);
699 # JSON Query
700 my $callobj = {
701 method => 'getSoftwareInformation_hash',
702 params => [ $hostId ],
703 id => 1,
704 };
706 my $res = $main::opsi_client->call($main::opsi_url, $callobj);
707 if (&check_opsi_res($res)){
708 my $result= $res->result;
709 }
711 $xml_msg=~ s/<xxx><\/xxx>//;
713 return ( $xml_msg );
714 }
717 ## @method opsi_get_local_products
718 # ???
719 # @param msg - STRING - xml message with tag hostId
720 # @param msg_hash - HASHREF - message information parsed into a hash
721 # @param session_id - INTEGER - POE session id of the processing of this message
722 sub opsi_get_local_products {
723 my ($msg, $msg_hash, $session_id) = @_;
724 my $header = @{$msg_hash->{'header'}}[0];
725 my $source = @{$msg_hash->{'source'}}[0];
726 my $target = @{$msg_hash->{'target'}}[0];
727 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
728 my $hostId;
730 # build return message with twisted target and source
731 my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
733 # Get hostID if defined
734 if (defined @{$msg_hash->{'hostId'}}[0]){
735 $hostId = @{$msg_hash->{'hostId'}}[0];
736 &add_content2xml_hash($out_hash, "hostId", $hostId);
737 }
739 if (defined $forward_to_gosa) {
740 &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
741 }
742 &add_content2xml_hash($out_hash, "xxx", "");
743 my $xml_msg= &create_xml_string($out_hash);
745 # For hosts, only return the products that are or get installed
746 my $callobj;
747 $callobj = {
748 method => 'getLocalBootProductIds_list',
749 params => [ ],
750 id => 1,
751 };
753 my $res = $main::opsi_client->call($main::opsi_url, $callobj);
754 my %r = ();
755 for (@{$res->result}) { $r{$_} = 1 }
757 if (&check_opsi_res($res)){
759 if (defined $hostId){
760 $callobj = {
761 method => 'getProductStates_hash',
762 params => [ $hostId ],
763 id => 1,
764 };
766 my $hres = $main::opsi_client->call($main::opsi_url, $callobj);
767 if (&check_opsi_res($hres)){
768 my $htmp= $hres->result->{$hostId};
770 # check state != not_installed or action == setup -> load and add
771 foreach my $product (@{$htmp}){
773 if (!defined ($r{$product->{'productId'}})){
774 next;
775 }
777 # Now we've a couple of hashes...
778 if ($product->{'installationStatus'} ne "not_installed" or
779 $product->{'actionRequest'} eq "setup"){
780 my $state= "<state>".$product->{'installationStatus'}."</state><action>".$product->{'actionRequest'}."</action>";
782 $callobj = {
783 method => 'getProduct_hash',
784 params => [ $product->{'productId'} ],
785 id => 1,
786 };
788 my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
789 if (&check_opsi_res($sres)){
790 my $tres= $sres->result;
792 my $name= xml_quote($tres->{'name'});
793 my $r= $product->{'productId'};
794 my $description= xml_quote($tres->{'description'});
795 $name=~ s/\//\\\//;
796 $description=~ s/\//\\\//;
797 $xml_msg=~ s/<xxx><\/xxx>/<item><productId>$r<\/productId><name><\/name><description>$description<\/description><\/item>$state<xxx><\/xxx>/;
798 }
800 }
801 }
803 }
805 } else {
806 foreach my $r (@{$res->result}) {
807 $callobj = {
808 method => 'getProduct_hash',
809 params => [ $r ],
810 id => 1,
811 };
813 my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
814 if (&check_opsi_res($sres)){
815 my $tres= $sres->result;
817 my $name= xml_quote($tres->{'name'});
818 my $description= xml_quote($tres->{'description'});
819 $name=~ s/\//\\\//;
820 $description=~ s/\//\\\//;
821 $xml_msg=~ s/<xxx><\/xxx>/<item><productId>$r<\/productId><name><\/name><description>$description<\/description><\/item><xxx><\/xxx>/;
822 }
824 }
826 }
827 }
829 $xml_msg=~ s/<xxx><\/xxx>//;
831 return ( $xml_msg );
832 }
835 ## @method opsi_del_client
836 # ???
837 # @param msg - STRING - xml message with tag hostId
838 # @param msg_hash - HASHREF - message information parsed into a hash
839 # @param session_id - INTEGER - POE session id of the processing of this message
840 sub opsi_del_client {
841 my ($msg, $msg_hash, $session_id) = @_;
842 my $header = @{$msg_hash->{'header'}}[0];
843 my $source = @{$msg_hash->{'source'}}[0];
844 my $target = @{$msg_hash->{'target'}}[0];
845 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
846 my $hostId = @{$msg_hash->{'hostId'}}[0];
848 # build return message with twisted target and source
849 my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
851 if (defined $forward_to_gosa) {
852 &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
853 }
854 &add_content2xml_hash($out_hash, "hostId", "$hostId");
856 # JSON Query
857 my $callobj = {
858 method => 'deleteClient',
859 params => [ $hostId ],
860 id => 1,
861 };
863 my $res = $main::opsi_client->call($main::opsi_url, $callobj);
865 my $xml_msg= &create_xml_string($out_hash);
866 return ( $xml_msg );
867 }
870 ## @method opsi_install_client
871 # ???
872 # @param msg - STRING - xml message with tags hostId, macaddress
873 # @param msg_hash - HASHREF - message information parsed into a hash
874 # @param session_id - INTEGER - POE session id of the processing of this message
875 sub opsi_install_client {
876 my ($msg, $msg_hash, $session_id) = @_;
877 my $header = @{$msg_hash->{'header'}}[0];
878 my $source = @{$msg_hash->{'source'}}[0];
879 my $target = @{$msg_hash->{'target'}}[0];
880 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
881 my $hostId = @{$msg_hash->{'hostId'}}[0];
882 my $error = 0;
883 my @out_msg_l;
885 # If no macaddress is specified, raise error
886 my $macaddress;
887 if ((exists $msg_hash->{'macaddress'}) &&
888 ($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)) {
889 $macaddress = $1;
890 } else {
891 $error ++;
892 my $out_msg = "<xml>".
893 "<header>answer</header>".
894 "<source>$main::server_address</source>".
895 "<target>GOSA</target>".
896 "<answer1>1</answer1>".
897 "<error_string>no mac address specified in macaddres-tag</error_string>".
898 "</xml>";
899 push(@out_msg_l, $out_msg);
900 }
902 # Set parameters in opsi
903 if (not $error) {
904 # build return message with twisted target and source
905 my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
907 if (defined $forward_to_gosa) {
908 &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
909 }
910 &add_content2xml_hash($out_hash, "hostId", "$hostId");
912 # Load all products for this host with status != "not_installed" or actionRequest != "none"
913 if (defined $hostId){
914 my $callobj = {
915 method => 'getProductStates_hash',
916 params => [ $hostId ],
917 id => 1,
918 };
920 my $hres = $main::opsi_client->call($main::opsi_url, $callobj);
921 if (&check_opsi_res($hres)){
922 my $htmp= $hres->result->{$hostId};
924 # check state != not_installed or action == setup -> load and add
925 foreach my $product (@{$htmp}){
926 # Now we've a couple of hashes...
927 if ($product->{'installationStatus'} ne "not_installed" or
928 $product->{'actionRequest'} ne "none"){
930 # Do an action request for all these -> "setup".
931 $callobj = {
932 method => 'setProductActionRequest',
933 params => [ $product->{'productId'}, $hostId, "setup" ],
934 id => 1,
935 };
936 my $res = $main::opsi_client->call($main::opsi_url, $callobj);
937 if (!&check_opsi_res($res)){
938 &main::daemon_log("ERROR: cannot set product action request for $hostId!", 1);
939 } else {
940 &main::daemon_log("INFO: requesting 'setup' for '".$product->{'productId'}."' on $hostId", 1);
941 }
943 }
944 }
945 }
946 }
948 push(@out_msg_l, &create_xml_string($out_hash));
949 }
951 # Build wakeup message for client
952 if (not $error) {
953 my $wakeup_hash = &create_xml_hash("trigger_wake", "GOSA", "KNOWN_SERVER");
954 &add_content2xml_hash($wakeup_hash, 'macAddress', $macaddress);
955 my $wakeup_msg = &create_xml_string($wakeup_hash);
956 push(@out_msg_l, $wakeup_msg);
958 # invoke trigger wake for this gosa-si-server
959 &main::server_server_com::trigger_wake($wakeup_msg, $wakeup_hash, $session_id);
960 }
963 return @out_msg_l;
964 }
967 ## @method _set_action
968 # ???
969 # @param product - STRING - ???
970 # @param action - STRING - ???
971 # @param hostId - STRING - ???
972 sub _set_action {
973 my $product= shift;
974 my $action = shift;
975 my $hostId = shift;
976 my $callobj;
978 $callobj = {
979 method => 'setProductActionRequest',
980 params => [ $product, $hostId, $action],
981 id => 1,
982 };
984 $main::opsi_client->call($main::opsi_url, $callobj);
985 }
987 ## @method _set_state
988 # ???
989 # @param product - STRING - ???
990 # @param action - STRING - ???
991 # @param hostId - STRING - ???
992 sub _set_state {
993 my $product = shift;
994 my $hostId = shift;
995 my $action = shift;
996 my $callobj;
998 $callobj = {
999 method => 'setProductState',
1000 params => [ $product, $hostId, $action ],
1001 id => 1,
1002 };
1004 $main::opsi_client->call($main::opsi_url, $callobj);
1005 }
1007 1;