Code

Added samba options
[gosa.git] / gosa-si / client / events / opsi.pm
1 package opsi;
2 use Exporter;
3 @ISA = qw(Exporter);
4 my @events = (
5     "get_events",
6     "_opsi_get_client_status",
7     "opsi_get_netboot_products",  
8     "opsi_get_local_products",
9     "opsi_get_client_hardware",
10     "opsi_get_client_software",
11     "opsi_get_product_properties",
12     "opsi_set_product_properties",
13     "opsi_list_clients",
14     "opsi_del_client",
15     "opsi_install_client",
17     #"opsi_add_client",
18     # Client hinzufügen
19     # -> voll qualifizierter name
20     # -> IP
21     # -> MAC
22     # -> Description
23     # -> Notizen
25     #"opsi_modify_client",
27     #"opsi_add_product_to_client",
28     # -> set product state auf "setup"
29     # -> Abhängigkeit prüfen und evtl. erweitern
30     # createProductDependency('productId', 'action', '*requiredProductId', '*requiredProductClassId', '*requiredAction', '*requiredInstallationStatus', '*requirementType', '*depotIds')
32     #"opsi_del_product_from_client",
33     # -> Abhängigkeit prüfen und evtl. verweigern
34     # createProductDependency('productId', 'action', '*requiredProductId', '*requiredProductClassId', '*requiredAction', '*requiredInstallationStatus', '*requirementType', '*depotIds')
35     # -> delete nur wenn eine "uninstall" methode existiert
36     # -> set product state auf "none"
38     );
39 @EXPORT = @events;
41 use strict;
42 use warnings;
43 use Data::Dumper;
44 use GOSA::GosaSupportDaemon;
45 use JSON::RPC::Client;
46 use XML::Quote qw(:all);
48 BEGIN {}
50 END {}
52 ### Start ######################################################################
54 my $opsi_server;
55 my $opsi_admin;
56 my $opsi_password;
58 my %cfg_defaults = (
59 "opsi" => {
60    "server" => [\$opsi_server, "localhost"],
61    "admin" => [\$opsi_admin, "opsi-admin"],
62    "password" => [\$opsi_password, "secret"],
63    },
64 );
65 &read_configfile($main::cfg_file, %cfg_defaults);
67 # Assemble opsi URL
68 my $opsi_url= "https://".$opsi_admin.":".$opsi_password."@".$opsi_server.":4447/rpc";
69 my $client = new JSON::RPC::Client;
71 sub check_res {
72   my $res= shift;
73   # TODO: We need to return the outhash!?
74   my $out_hash;
76   if($res) {
77     if ($res->is_error) {
78       &main::daemon_log("ERROR: opsi configed communication failed: ".$res->error_message, 1);
79       &add_content2xml_hash($out_hash, "error", $res->error_message);
80     } else {
81       return 1;
82     }
83   } else {
84     &main::daemon_log("ERROR: opsi configed communication failed: ".$client->status_line, 1);
85     &add_content2xml_hash($out_hash, "error", $client->status_line);
86   }
88   return 0;
89 }
92 sub read_configfile {
93     my ($cfg_file, %cfg_defaults) = @_;
94     my $cfg;
96     if( defined( $cfg_file) && ( (-s $cfg_file) > 0 )) {
97         if( -r $cfg_file ) {
98             $cfg = Config::IniFiles->new( -file => $cfg_file );
99         } else {
100             &main::daemon_log("ERROR: opsi.pm couldn't read config file!", 1);
101         }
102     } else {
103         $cfg = Config::IniFiles->new() ;
104     }
105     foreach my $section (keys %cfg_defaults) {
106         foreach my $param (keys %{$cfg_defaults{ $section }}) {
107             my $pinfo = $cfg_defaults{ $section }{ $param };
108             ${@$pinfo[0]} = $cfg->val( $section, $param, @$pinfo[1] );
109         }
110     }
114 sub get_events { return \@events; }
117 sub opsi_get_netboot_products {
118   my ($msg, $msg_hash) = @_;
119   my $header = @{$msg_hash->{'header'}}[0];
120   my $source = @{$msg_hash->{'source'}}[0];
121   my $target = @{$msg_hash->{'target'}}[0];
122   my $session_id = @{$msg_hash->{'session_id'}}[0];
123   my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
124   my $hostId;
126   # build return message with twisted target and source
127   my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
128   &add_content2xml_hash($out_hash, "session_id", $session_id);
130   # Get hostID if defined
131   if (defined @{$msg_hash->{'hostId'}}[0]){
132     $hostId = @{$msg_hash->{'hostId'}}[0];
133     &add_content2xml_hash($out_hash, "hostId", $hostId);
134   }
136   if (defined $forward_to_gosa) {
137     &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
138   }
139   &add_content2xml_hash($out_hash, "xxx", "");
140   my $xml_msg= &create_xml_string($out_hash);
142   # For hosts, only return the products that are or get installed
143   my $callobj;
144   $callobj = {
145     method  => 'getNetBootProductIds_list',
146     params  => [ ],
147     id  => 1,
148   };
150   my $res = $client->call($opsi_url, $callobj);
151   my %r = ();
152   for (@{$res->result}) { $r{$_} = 1 }
154   if (check_res($res)){
156     if (defined $hostId){
157       $callobj = {
158         method  => 'getProductStates_hash',
159         params  => [ $hostId ],
160         id  => 1,
161       };
163       my $hres = $client->call($opsi_url, $callobj);
164       if (check_res($hres)){
165         my $htmp= $hres->result->{$hostId};
167         # check state != not_installed or action == setup -> load and add
168         foreach my $product (@{$htmp}){
170           if (!defined ($r{$product->{'productId'}})){
171             next;
172           }
174           # Now we've a couple of hashes...
175           if ($product->{'installationStatus'} ne "not_installed" or
176               $product->{'actionRequest'} eq "setup"){
177             my $state= "<state>".$product->{'installationStatus'}."</state><action>".$product->{'actionRequest'}."</action>";
179             $callobj = {
180               method  => 'getProduct_hash',
181               params  => [ $product->{'productId'} ],
182               id  => 1,
183             };
185             my $sres = $client->call($opsi_url, $callobj);
186             if (check_res($sres)){
187               my $tres= $sres->result;
189               my $name= xml_quote($tres->{'name'});
190               my $r= $product->{'productId'};
191               my $description= xml_quote($tres->{'description'});
192               $name=~ s/\//\\\//;
193               $description=~ s/\//\\\//;
194               $xml_msg=~ s/<xxx><\/xxx>/<item><ProductId>$r<\/ProductId><name><\/name><description>$description<\/description><\/item>$state<xxx><\/xxx>/;
195             }
197           }
198         }
200       }
202     } else {
203       foreach my $r (@{$res->result}) {
204         $callobj = {
205           method  => 'getProduct_hash',
206           params  => [ $r ],
207           id  => 1,
208         };
210         my $sres = $client->call($opsi_url, $callobj);
211         if (check_res($sres)){
212           my $tres= $sres->result;
214           my $name= xml_quote($tres->{'name'});
215           my $description= xml_quote($tres->{'description'});
216           $name=~ s/\//\\\//;
217           $description=~ s/\//\\\//;
218           $xml_msg=~ s/<xxx><\/xxx>/<item><ProductId>$r<\/ProductId><name><\/name><description>$description<\/description><\/item><xxx><\/xxx>/;
219         }
221       }
223     }
224   }
226   $xml_msg=~ s/<xxx><\/xxx>//;
228   return $xml_msg;
232 sub opsi_get_product_properties {
233     my ($msg, $msg_hash) = @_;
234     my $header = @{$msg_hash->{'header'}}[0];
235     my $source = @{$msg_hash->{'source'}}[0];
236     my $target = @{$msg_hash->{'target'}}[0];
237     my $session_id = @{$msg_hash->{'session_id'}}[0];
238     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
239     my $productId = @{$msg_hash->{'ProductId'}}[0];
240     my $hostId;
242     # build return message with twisted target and source
243     my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
244     &add_content2xml_hash($out_hash, "session_id", $session_id);
246     # Get hostID if defined
247     if (defined @{$msg_hash->{'hostId'}}[0]){
248       $hostId = @{$msg_hash->{'hostId'}}[0];
249       &add_content2xml_hash($out_hash, "hostId", $hostId);
250     }
252     if (defined $forward_to_gosa) {
253       &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
254     }
255     &add_content2xml_hash($out_hash, "ProducId", "$productId");
257     # Load actions
258     my $callobj = {
259       method  => 'getPossibleProductActions_list',
260       params  => [ $productId ],
261       id  => 1,
262     };
263     my $res = $client->call($opsi_url, $callobj);
264     if (check_res($res)){
265       foreach my $action (@{$res->result}){
266         &add_content2xml_hash($out_hash, "action", $action);
267       }
268     }
270     # Add place holder
271     &add_content2xml_hash($out_hash, "xxx", "");
273     # Move to XML string
274     my $xml_msg= &create_xml_string($out_hash);
276     # JSON Query
277     $callobj = {
278       method  => 'getProductProperties_hash',
279       params  => [ $productId ],
280       id  => 1,
281     };
283     $res = $client->call($opsi_url, $callobj);
285     if (check_res($res)){
286         my $r= $res->result;
287         foreach my $key (keys %{$r}) {
288           my $item= "<item>";
289           my $value= $r->{$key};
290           if (UNIVERSAL::isa( $value, "ARRAY" )){
291             foreach my $subval (@{$value}){
292               $item.= "<$key>".xml_quote($subval)."</$key>";
293             }
294           } else {
295             $item.= "<$key>".xml_quote($value)."</$key>";
296           }
297           $item.= "</item>";
298           $xml_msg=~ s/<xxx><\/xxx>/$item<xxx><\/xxx>/;
299         }
300     }
303   $xml_msg=~ s/<xxx><\/xxx>//;
305   return $xml_msg;
309 sub opsi_set_product_properties {
310     my ($msg, $msg_hash) = @_;
311     my $header = @{$msg_hash->{'header'}}[0];
312     my $source = @{$msg_hash->{'source'}}[0];
313     my $target = @{$msg_hash->{'target'}}[0];
314     my $session_id = @{$msg_hash->{'session_id'}}[0];
315     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
316     my $productId = @{$msg_hash->{'ProductId'}}[0];
317     my $hostId;
319     # build return message with twisted target and source
320     my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
321     &add_content2xml_hash($out_hash, "session_id", $session_id);
322     &add_content2xml_hash($out_hash, "ProductId", $productId);
324     # Get hostID if defined
325     if (defined @{$msg_hash->{'hostId'}}[0]){
326       $hostId = @{$msg_hash->{'hostId'}}[0];
327       &add_content2xml_hash($out_hash, "hostId", $hostId);
328     }
330     # Set product states if requested
331     if (defined @{$msg_hash->{'action'}}[0]){
332       &_set_action($productId, @{$msg_hash->{'action'}}[0], $hostId);
333     }
334     if (defined @{$msg_hash->{'state'}}[0]){
335       &_set_state($productId, @{$msg_hash->{'state'}}[0], $hostId);
336     }
338     if (defined $forward_to_gosa) {
339         &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
340     }
342     # Find properties
343     foreach my $item (@{$msg_hash->{'item'}}){
344       # JSON Query
345       my $callobj;
347       if (defined $hostId){
348         $callobj = {
349           method  => 'setProductProperty',
350           params  => [ $productId, $item->{'name'}[0], $item->{'value'}[0], $hostId ],
351           id  => 1,
352         };
353       } else {
354         $callobj = {
355           method  => 'setProductProperty',
356           params  => [ $productId, $item->{'name'}[0], $item->{'value'}[0] ],
357           id  => 1,
358         };
359       }
361       my $res = $client->call($opsi_url, $callobj);
363       if (!check_res($res)){
364         &main::daemon_log("ERROR: no communication failed while setting '".$item->{'name'}[0]."': ".$res->error_message, 1);
365         &add_content2xml_hash($out_hash, "error", $res->error_message);
366       }
368     }
370     # return message
371     return &create_xml_string($out_hash);
375 sub opsi_get_client_hardware {
376     my ($msg, $msg_hash) = @_;
377     my $header = @{$msg_hash->{'header'}}[0];
378     my $source = @{$msg_hash->{'source'}}[0];
379     my $target = @{$msg_hash->{'target'}}[0];
380     my $session_id = @{$msg_hash->{'session_id'}}[0];
381     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
382     my $hostId = @{$msg_hash->{'hostId'}}[0];
384     # build return message with twisted target and source
385     my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
386     &add_content2xml_hash($out_hash, "session_id", $session_id);
388     if (defined $forward_to_gosa) {
389       &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
390     }
391     &add_content2xml_hash($out_hash, "hostId", "$hostId");
392     &add_content2xml_hash($out_hash, "xxx", "");
393     my $xml_msg= &create_xml_string($out_hash);
395     # JSON Query
396     my $callobj = {
397       method  => 'getHardwareInformation_hash',
398       params  => [ $hostId ],
399       id  => 1,
400     };
402     my $res = $client->call($opsi_url, $callobj);
403     if (check_res($res)){
404       my $result= $res->result;
405       foreach my $r (keys %{$result}){
406         my $item= "<item><id>".xml_quote($r)."</id>";
407         my $value= $result->{$r};
408         foreach my $sres (@{$value}){
410           foreach my $dres (keys %{$sres}){
411             if (defined $sres->{$dres}){
412               $item.= "<$dres>".xml_quote($sres->{$dres})."</$dres>";
413             }
414           }
416         }
417           $item.= "</item>";
418           $xml_msg=~ s%<xxx></xxx>%$item<xxx></xxx>%;
420       }
421     }
423     $xml_msg=~ s/<xxx><\/xxx>//;
425     return $xml_msg;
429 sub opsi_list_clients {
430     my ($msg, $msg_hash) = @_;
431     my $header = @{$msg_hash->{'header'}}[0];
432     my $source = @{$msg_hash->{'source'}}[0];
433     my $target = @{$msg_hash->{'target'}}[0];
434     my $session_id = @{$msg_hash->{'session_id'}}[0];
435     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
437     # build return message with twisted target and source
438     my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
439     &add_content2xml_hash($out_hash, "session_id", $session_id);
441     if (defined $forward_to_gosa) {
442       &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
443     }
445     &add_content2xml_hash($out_hash, "xxx", "");
446     my $xml_msg= &create_xml_string($out_hash);
448     # JSON Query
449     my $callobj = {
450       method  => 'getClients_listOfHashes',
451       params  => [ ],
452       id  => 1,
453     };
455     my $res = $client->call($opsi_url, $callobj);
456     if (check_res($res)){
458       foreach my $host (@{$res->result}){
459         my $item= "<item><name>".$host->{'hostId'}."</name>";
460         if (defined($host->{'description'})){
461           $item.= "<description>".xml_quote($host->{'description'})."</description>";
462         }
463         $item.= "</item>";
464         $xml_msg=~ s%<xxx></xxx>%$item<xxx></xxx>%;
465       }
467     }
469     $xml_msg=~ s/<xxx><\/xxx>//;
470     return $xml_msg;
474 sub opsi_get_client_software {
475     my ($msg, $msg_hash) = @_;
476     my $header = @{$msg_hash->{'header'}}[0];
477     my $source = @{$msg_hash->{'source'}}[0];
478     my $target = @{$msg_hash->{'target'}}[0];
479     my $session_id = @{$msg_hash->{'session_id'}}[0];
480     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
481     my $hostId = @{$msg_hash->{'hostId'}}[0];
483     # build return message with twisted target and source
484     my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
485     &add_content2xml_hash($out_hash, "session_id", $session_id);
487     if (defined $forward_to_gosa) {
488       &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
489     }
490     &add_content2xml_hash($out_hash, "hostId", "$hostId");
491     &add_content2xml_hash($out_hash, "xxx", "");
492     my $xml_msg= &create_xml_string($out_hash);
494     # JSON Query
495     my $callobj = {
496       method  => 'getSoftwareInformation_hash',
497       params  => [ $hostId ],
498       id  => 1,
499     };
501     my $res = $client->call($opsi_url, $callobj);
502     if (check_res($res)){
503       my $result= $res->result;
504     }
506     $xml_msg=~ s/<xxx><\/xxx>//;
508     return $xml_msg;
512 sub opsi_get_local_products {
513   my ($msg, $msg_hash) = @_;
514   my $header = @{$msg_hash->{'header'}}[0];
515   my $source = @{$msg_hash->{'source'}}[0];
516   my $target = @{$msg_hash->{'target'}}[0];
517   my $session_id = @{$msg_hash->{'session_id'}}[0];
518   my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
519   my $hostId;
521   # build return message with twisted target and source
522   my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
523   &add_content2xml_hash($out_hash, "session_id", $session_id);
525   # Get hostID if defined
526   if (defined @{$msg_hash->{'hostId'}}[0]){
527     $hostId = @{$msg_hash->{'hostId'}}[0];
528     &add_content2xml_hash($out_hash, "hostId", $hostId);
529   }
531   if (defined $forward_to_gosa) {
532     &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
533   }
534   &add_content2xml_hash($out_hash, "xxx", "");
535   my $xml_msg= &create_xml_string($out_hash);
537   # For hosts, only return the products that are or get installed
538   my $callobj;
539   $callobj = {
540     method  => 'getLocalBootProductIds_list',
541     params  => [ ],
542     id  => 1,
543   };
545   my $res = $client->call($opsi_url, $callobj);
546   my %r = ();
547   for (@{$res->result}) { $r{$_} = 1 }
549   if (check_res($res)){
551     if (defined $hostId){
552       $callobj = {
553         method  => 'getProductStates_hash',
554         params  => [ $hostId ],
555         id  => 1,
556       };
558       my $hres = $client->call($opsi_url, $callobj);
559       if (check_res($hres)){
560         my $htmp= $hres->result->{$hostId};
562         # check state != not_installed or action == setup -> load and add
563         foreach my $product (@{$htmp}){
565           if (!defined ($r{$product->{'productId'}})){
566             next;
567           }
569           # Now we've a couple of hashes...
570           if ($product->{'installationStatus'} ne "not_installed" or
571               $product->{'actionRequest'} eq "setup"){
572             my $state= "<state>".$product->{'installationStatus'}."</state><action>".$product->{'actionRequest'}."</action>";
574             $callobj = {
575               method  => 'getProduct_hash',
576               params  => [ $product->{'productId'} ],
577               id  => 1,
578             };
580             my $sres = $client->call($opsi_url, $callobj);
581             if (check_res($sres)){
582               my $tres= $sres->result;
584               my $name= xml_quote($tres->{'name'});
585               my $r= $product->{'productId'};
586               my $description= xml_quote($tres->{'description'});
587               $name=~ s/\//\\\//;
588               $description=~ s/\//\\\//;
589               $xml_msg=~ s/<xxx><\/xxx>/<item><ProductId>$r<\/ProductId><name><\/name><description>$description<\/description><\/item>$state<xxx><\/xxx>/;
590             }
592           }
593         }
595       }
597     } else {
598       foreach my $r (@{$res->result}) {
599         $callobj = {
600           method  => 'getProduct_hash',
601           params  => [ $r ],
602           id  => 1,
603         };
605         my $sres = $client->call($opsi_url, $callobj);
606         if (check_res($sres)){
607           my $tres= $sres->result;
609           my $name= xml_quote($tres->{'name'});
610           my $description= xml_quote($tres->{'description'});
611           $name=~ s/\//\\\//;
612           $description=~ s/\//\\\//;
613           $xml_msg=~ s/<xxx><\/xxx>/<item><ProductId>$r<\/ProductId><name><\/name><description>$description<\/description><\/item><xxx><\/xxx>/;
614         }
616       }
618     }
619   }
621   $xml_msg=~ s/<xxx><\/xxx>//;
623   return $xml_msg;
627 sub _opsi_get_client_status {
628   my $hostId = shift;
629   my $result= {};
631   # For hosts, only return the products that are or get installed
632   my $callobj;
633   $callobj = {
634     method  => 'getProductStates_hash',
635     params  => [ $hostId ],
636     id  => 1,
637   };
639   my $hres = $client->call($opsi_url, $callobj);
640   if (check_res($hres)){
641     my $htmp= $hres->result->{$hostId};
643     # check state != not_installed or action == setup -> load and add
644     my $products= 0;
645     my $installed= 0;
646     my $error= 0;
647     foreach my $product (@{$htmp}){
649       if ($product->{'installationStatus'} ne "not_installed" or
650           $product->{'actionRequest'} eq "setup"){
652         # Increase number of products for this host
653         $products++;
655         if ($product->{'installationStatus'} eq "failed"){
656           $result->{$product->{'productId'}}= "error";
657           $error++;
658         }
659         if ($product->{'installationStatus'} eq "installed"){
660           $result->{$product->{'productId'}}= "installed";
661           $installed++;
662         }
663         if ($product->{'installationStatus'} eq "installing"){
664           $result->{$product->{'productId'}}= "installing";
665         }
666       }
667     }
669     # Estimate "rough" progress
670     $result->{'progress'}= int($installed * 100 / $products);
671   }
673   return $result;
677 sub opsi_del_client {
678     my ($msg, $msg_hash) = @_;
679     my $header = @{$msg_hash->{'header'}}[0];
680     my $source = @{$msg_hash->{'source'}}[0];
681     my $target = @{$msg_hash->{'target'}}[0];
682     my $session_id = @{$msg_hash->{'session_id'}}[0];
683     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
684     my $hostId = @{$msg_hash->{'hostId'}}[0];
686     # build return message with twisted target and source
687     my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
688     &add_content2xml_hash($out_hash, "session_id", $session_id);
690     if (defined $forward_to_gosa) {
691       &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
692     }
693     &add_content2xml_hash($out_hash, "hostId", "$hostId");
695     # JSON Query
696     my $callobj = {
697       method  => 'deleteClient',
698       params  => [ $hostId ],
699       id  => 1,
700     };
702     my $res = $client->call($opsi_url, $callobj);
704     my $xml_msg= &create_xml_string($out_hash);
705     return $xml_msg;
709 # Setze alles was auf "installed" steht auf setup
710 sub opsi_install_client {
711     my ($msg, $msg_hash) = @_;
712     my $header = @{$msg_hash->{'header'}}[0];
713     my $source = @{$msg_hash->{'source'}}[0];
714     my $target = @{$msg_hash->{'target'}}[0];
715     my $session_id = @{$msg_hash->{'session_id'}}[0];
716     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
717     my $hostId = @{$msg_hash->{'hostId'}}[0];
719     # build return message with twisted target and source
720     my $out_hash = &main::create_xml_hash("answer_$header", $target, $source);
721     &add_content2xml_hash($out_hash, "session_id", $session_id);
723     if (defined $forward_to_gosa) {
724       &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
725     }
726     &add_content2xml_hash($out_hash, "hostId", "$hostId");
728 # Schaue nach produkten für diesen Host
729 # Setze alle Produkte dieses Hosts auf "setup"
731 #    # JSON Query
732 #    my $callobj = {
733 #      method  => 'deleteClient',
734 #      params  => [ $hostId ],
735 #      id  => 1,
736 #    };
738 #    my $res = $client->call($opsi_url, $callobj);
740     my $xml_msg= &create_xml_string($out_hash);
741     return $xml_msg;
745 sub _set_action {
746   my $product= shift;
747   my $action = shift;
748   my $hostId = shift;
749   my $callobj;
751   $callobj = {
752     method  => 'setProductActionRequest',
753     params  => [ $product, $hostId, $action],
754     id  => 1,
755   };
757   $client->call($opsi_url, $callobj);
761 sub _set_state {
762   my $product = shift;
763   my $hostId = shift;
764   my $action = shift;
765   my $callobj;
767   $callobj = {
768     method  => 'setProductState',
769     params  => [ $product, $hostId, $action ],
770     id  => 1,
771   };
773   $client->call($opsi_url, $callobj);
776 1;