Code

Updated some sieve templates
[gosa.git] / gosa-si / server / events / opsi_com.pm
index 2f5fdf894b1f1181113b1bd98fd5471b3e791f0a..c6fee306ac2a0b02d626b75da569738457fd5b31 100644 (file)
@@ -4,8 +4,18 @@
 
 
 package opsi_com;
+
+use strict;
+use warnings;
+
 use Exporter;
-@ISA = qw(Exporter);
+use UNIVERSAL 'isa';
+use GOSA::GosaSupportDaemon;
+use Data::Dumper;
+use XML::Quote qw(:all);
+
+our @ISA = qw(Exporter);
+
 my @events = (
     "get_events",
     "opsi_install_client",
@@ -14,6 +24,7 @@ my @events = (
     "opsi_get_client_hardware",
     "opsi_get_client_software",
     "opsi_get_product_properties",
+    "opsi_get_full_product_host_information",
     "opsi_set_product_properties",
     "opsi_list_clients",
     "opsi_del_client",
@@ -21,34 +32,29 @@ my @events = (
     "opsi_modify_client",
     "opsi_add_product_to_client",
     "opsi_del_product_from_client",
-       "opsi_createLicensePool",
-       "opsi_deleteLicensePool",
-       "opsi_createLicense",
-       "opsi_assignSoftwareLicenseToHost",
-       "opsi_unassignSoftwareLicenseFromHost",
-       "opsi_unassignAllSoftwareLicensesFromHost",
-       "opsi_getSoftwareLicense_hash",
-       "opsi_getLicensePool_hash",
-       "opsi_getSoftwareLicenseUsages",
-       "opsi_getSoftwareLicenseUsagesForProductId",
-       "opsi_getLicensePools_listOfHashes",
-       "opsi_getLicenseInformationForProduct",
-       "opsi_getPool",
-       "opsi_getAllSoftwareLicenses",
-       "opsi_removeLicense",
-       "opsi_getReservedLicenses",
-       "opsi_boundHostToLicense",
-       "opsi_unboundHostFromLicense",
-       "opsi_test",
+    "opsi_createLicensePool",
+    "opsi_deleteLicensePool",
+    "opsi_createLicense",
+    "opsi_assignSoftwareLicenseToHost",
+    "opsi_unassignSoftwareLicenseFromHost",
+    "opsi_unassignAllSoftwareLicensesFromHost",
+    "opsi_getSoftwareLicense_hash",
+    "opsi_getLicensePool_hash",
+    "opsi_getSoftwareLicenseUsages",
+    "opsi_getSoftwareLicenseUsagesForProductId",
+    "opsi_getLicensePools_listOfHashes",
+    "opsi_getLicenseInformationForProduct",
+    "opsi_getPool",
+    "opsi_getAllSoftwareLicenses",
+    "opsi_removeLicense",
+    "opsi_getReservedLicenses",
+    "opsi_boundHostToLicense",
+    "opsi_unboundHostFromLicense",
+    "opsi_test",
    );
-@EXPORT = @events;
 
-use strict;
-use warnings;
-use GOSA::GosaSupportDaemon;
-use Data::Dumper;
-use XML::Quote qw(:all);
-use Time::HiRes qw( time );
+our @EXPORT = @events;
+
 
 BEGIN {}
 
@@ -59,8 +65,29 @@ END {}
 # ----------------------------------------------------------------------------
 
 my $licenseTyp_hash = { 'OEM'=>'', 'VOLUME'=>'', 'RETAIL'=>''};
-
-
+my ($opsi_enabled, $opsi_server, $opsi_admin, $opsi_password, $opsi_url, $opsi_client);
+my %cfg_defaults = (
+               "Opsi" => {
+               "enabled"  => [\$opsi_enabled, "false"],
+               "server"   => [\$opsi_server, "localhost"],
+               "admin"    => [\$opsi_admin, "opsi-admin"],
+               "password" => [\$opsi_password, "secret"],
+               },
+);
+&read_configfile($main::cfg_file, %cfg_defaults);
+if ($opsi_enabled eq "true") {
+       use JSON::RPC::Client;
+       use XML::Quote qw(:all);
+       use Time::HiRes qw( time );
+       $opsi_url= "https://".$opsi_admin.":".$opsi_password."@".$opsi_server.":4447/rpc";
+       $opsi_client = new JSON::RPC::Client;
+
+       # Check version dependencies
+       eval { &myXmlHashToString(); };
+       if ($@ ) {
+               die "\nThe version of the Opsi plugin you want to use requires a newer version of GosaSupportDaemon. Please update your GOsa-SI or deactivate the Opsi plugin.\n";
+       }
+}
 
 # ----------------------------------------------------------------------------
 #   external methods handling the comunication with GOsa/GOsa-si
@@ -403,20 +430,20 @@ sub opsi_modify_client {
 # @param session_id - INTEGER - POE session id of the processing of this message
 # @return out_msg - STRING - feedback to GOsa in success and error case
 sub opsi_get_netboot_products {
-       my $startTime = Time::HiRes::time;
+    my $startTime = Time::HiRes::time;
     my ($msg, $msg_hash, $session_id) = @_;
     my $header = @{$msg_hash->{'header'}}[0];
     my $source = @{$msg_hash->{'source'}}[0];
     my $target = @{$msg_hash->{'target'}}[0];
     my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
     my $hostId;
-    my $xml_msg;
 
     # Build return message with twisted target and source
     my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
     if (defined $forward_to_gosa) {
         &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
     }
+    &add_content2xml_hash($out_hash, "xxx", "");
 
     # Get hostId if defined
     if ((exists $msg_hash->{'hostId'}) && (@{$msg_hash->{'hostId'}} == 1))  {
@@ -424,96 +451,47 @@ sub opsi_get_netboot_products {
         &add_content2xml_hash($out_hash, "hostId", $hostId);
     }
 
-    &add_content2xml_hash($out_hash, "xxx", "");
-    $xml_msg = &create_xml_string($out_hash);
-    # For hosts, only return the products that are or get installed
+    # Move to XML string
+    my $xml_msg= &create_xml_string($out_hash);
+
     my $callobj;
-    $callobj = {
-        method  => 'getNetBootProductIds_list',
-        params  => [ ],
-        id  => 1,
-    };
-    &main::daemon_log("$session_id DEBUG: send callobj to opsi_client: ".&opsi_callobj2string($callobj), 7);
-    &main::daemon_log("$session_id DEBUG: opsi_url $main::opsi_url", 7);
-    &main::daemon_log("$session_id DEBUG: waiting for answer from opsi_client!", 7);
-    my $res = $main::opsi_client->call($main::opsi_url, $callobj);
-    &main::daemon_log("$session_id DEBUG: get answer from opsi_client", 7);
-    my %r = ();
-    for (@{$res->result}) { $r{$_} = 1 }
+    # Check if we need to get host or global information
+    if (defined $hostId){
+      $callobj = {
+          method  => 'getProductHostInformation_list',
+          params  => [ $hostId, undef, 'netboot'],
+          id  => 1,
+      };
 
+      my $res = $main::opsi_client->call($main::opsi_url, $callobj);
       if (not &check_opsi_res($res)){
+          foreach my $product (@{$res->result}){
+               my $replace= "<item><productId>".xml_quote($product->{'productId'})."<\/productId><name>".xml_quote($product->{'name'})."<\/name><description>".xml_quote($product->{'description'})."<\/description><state>".xml_quote($product->{'installationStatus'})."</state><action>".xml_quote($product->{'actionRequest'})."</action><\/item><xxx><\/xxx>";
+               $xml_msg=~ s/<xxx><\/xxx>/\n$replace/;
+          }
+      }
 
-        if (defined $hostId){
-
-            $callobj = {
-                method  => 'getProductStates_hash',
-                params  => [ $hostId ],
-                id  => 1,
-            };
-
-            my $hres = $main::opsi_client->call($main::opsi_url, $callobj);
-            if (not &check_opsi_res($hres)){
-                my $htmp= $hres->result->{$hostId};
-
-                # check state != not_installed or action == setup -> load and add
-                foreach my $product (@{$htmp}){
-
-                    if (!defined ($r{$product->{'productId'}})){
-                        next;
-                    }
-
-                    # Now we've a couple of hashes...
-                    if ($product->{'installationStatus'} ne "not_installed" or
-                            $product->{'actionRequest'} eq "setup"){
-                        my $state= "<state>".$product->{'installationStatus'}."</state><action>".$product->{'actionRequest'}."</action>";
-
-                        $callobj = {
-                            method  => 'getProduct_hash',
-                            params  => [ $product->{'productId'} ],
-                            id  => 1,
-                        };
-
-                        my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
-                        if (not &check_opsi_res($sres)){
-                            my $tres= $sres->result;
-
-                            my $name= xml_quote($tres->{'name'});
-                            my $r= $product->{'productId'};
-                            my $description= xml_quote($tres->{'description'});
-                            $name=~ s/\//\\\//;
-                            $description=~ s/\//\\\//;
-                            $xml_msg=~ s/<xxx><\/xxx>/\n<item><productId>$r<\/productId><name>$name<\/name><description>$description<\/description><\/item>$state<xxx><\/xxx>/;
-                        }
-                    }
-                }
-
-            }
+    } else {
 
-        } else {
-            foreach my $r (@{$res->result}) {
-                $callobj = {
-                    method  => 'getProduct_hash',
-                    params  => [ $r ],
-                    id  => 1,
-                };
-
-                my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
-                if (not &check_opsi_res($sres)){
-                    my $tres= $sres->result;
-
-                    my $name= xml_quote($tres->{'name'});
-                    my $description= xml_quote($tres->{'description'});
-                    $name=~ s/\//\\\//;
-                    $description=~ s/\//\\\//;
-                    $xml_msg=~ s/<xxx><\/xxx>/\n<item><productId>$r<\/productId><name>$name<\/name><description>$description<\/description><\/item><xxx><\/xxx>/;
-                }
-            }
+      # For hosts, only return the products that are or get installed
+      $callobj = {
+          method  => 'getProductInformation_list',
+          params  => [ undef, 'netboot' ],
+          id  => 1,
+      };
 
-        }
+      my $res = $main::opsi_client->call($main::opsi_url, $callobj);
+      if (not &check_opsi_res($res)){
+          foreach my $product (@{$res->result}) {
+               my $replace= "<item><productId>".xml_quote($product->{'productId'})."<\/productId><name>".xml_quote($product->{'name'})."<\/name><description>".xml_quote($product->{'description'})."<\/description><\/item><xxx><\/xxx>";
+               $xml_msg=~ s/<xxx><\/xxx>/\n$replace/;
+          }
+      }
     }
+
     $xml_msg=~ s/<xxx><\/xxx>//;
 
-    # Return message
+    # Retrun Message
        &main::daemon_log("0 DEBUG: time to process gosa-si message '$header' : ".sprintf("%.4f", (Time::HiRes::time - $startTime))." seconds", 1034);
     return ( $xml_msg );
 }
@@ -637,7 +615,7 @@ sub opsi_get_product_properties {
             if (defined $values->{$key}){
               $vals= $values->{$key};
             }
-            $item.= "<$key>$dsc<default>".xml_quote($value)."</default>$vals</$key>";
+            $item.= "<$key>$dsc<current>".xml_quote($value)."</current>$vals</$key>";
             $item.= "</item>";
             $xml_msg=~ s/<xxx><\/xxx>/$item<xxx><\/xxx>/;
         }
@@ -852,14 +830,16 @@ sub opsi_list_clients {
 
     # JSON Query
     my $callobj = {
-        method  => 'getClients_listOfHashes',
+        method  => 'getClientsInformation_listOfHashes',
         params  => [ ],
         id  => 1,
     };
+
     my $res = $main::opsi_client->call($main::opsi_url, $callobj);
     if (not &check_opsi_res($res)){
         foreach my $host (@{$res->result}){
             my $item= "\n<item><name>".$host->{'hostId'}."</name>";
+            $item.= "<mac>".xml_quote($host->{'macAddress'})."</mac>";
             if (defined($host->{'description'})){
                 $item.= "<description>".xml_quote($host->{'description'})."</description>";
             }
@@ -870,25 +850,6 @@ sub opsi_list_clients {
                 $item.= "<lastSeen>".xml_quote($host->{'lastSeen'})."</lastSeen>";
             }
 
-            $callobj = {
-              method  => 'getIpAddress',
-              params  => [ $host->{'hostId'} ],
-              id  => 1,
-            };
-            my $sres= $main::opsi_client->call($main::opsi_url, $callobj);
-            if ( not &check_opsi_res($sres)){
-              $item.= "<ip>".xml_quote($sres->result)."</ip>";
-            }
-
-            $callobj = {
-              method  => 'getMacAddress',
-              params  => [ $host->{'hostId'} ],
-              id  => 1,
-            };
-            $sres= $main::opsi_client->call($main::opsi_url, $callobj);
-            if ( not &check_opsi_res($sres)){
-                $item.= "<mac>".xml_quote($sres->result)."</mac>";
-            }
             $item.= "</item>";
             $xml_msg=~ s%<xxx></xxx>%$item<xxx></xxx>%;
         }
@@ -970,7 +931,7 @@ sub opsi_get_client_software {
 # @param session_id - INTEGER - POE session id of the processing of this message
 # @return out_msg - STRING - feedback to GOsa in success and error case
 sub opsi_get_local_products {
-       my $startTime = Time::HiRes::time;
+    my $startTime = Time::HiRes::time;
     my ($msg, $msg_hash, $session_id) = @_;
     my $header = @{$msg_hash->{'header'}}[0];
     my $source = @{$msg_hash->{'source'}}[0];
@@ -991,91 +952,43 @@ sub opsi_get_local_products {
         &add_content2xml_hash($out_hash, "hostId", $hostId);
     }
 
-    # Move to XML string
-    my $xml_msg= &create_xml_string($out_hash);
-
-    # For hosts, only return the products that are or get installed
     my $callobj;
-    $callobj = {
-        method  => 'getLocalBootProductIds_list',
-        params  => [ ],
-        id  => 1,
-    };
 
-    my $res = $main::opsi_client->call($main::opsi_url, $callobj);
-    my %r = ();
-    for (@{$res->result}) { $r{$_} = 1 }
-
-    if (not &check_opsi_res($res)){
-
-        if (defined $hostId){
-            $callobj = {
-                method  => 'getProductStates_hash',
-                params  => [ $hostId ],
-                id  => 1,
-            };
-
-            my $hres = $main::opsi_client->call($main::opsi_url, $callobj);
-            if (not &check_opsi_res($hres)){
-                my $htmp= $hres->result->{$hostId};
-
-                # Check state != not_installed or action == setup -> load and add
-                foreach my $product (@{$htmp}){
-
-                    if (!defined ($r{$product->{'productId'}})){
-                        next;
-                    }
-
-                    # Now we've a couple of hashes...
-                    if ($product->{'installationStatus'} ne "not_installed" or
-                            $product->{'actionRequest'} eq "setup"){
-                        my $state= "<state>".$product->{'installationStatus'}."</state><action>".$product->{'actionRequest'}."</action>";
-
-                        $callobj = {
-                            method  => 'getProduct_hash',
-                            params  => [ $product->{'productId'} ],
-                            id  => 1,
-                        };
-
-                        my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
-                        if (not &check_opsi_res($sres)){
-                            my $tres= $sres->result;
-
-                            my $name= xml_quote($tres->{'name'});
-                            my $r= $product->{'productId'};
-                            my $description= xml_quote($tres->{'description'});
-                            $name=~ s/\//\\\//;
-                            $description=~ s/\//\\\//;
-                            $xml_msg=~ s/<xxx><\/xxx>/\n<item><productId>$r<\/productId><name>$name<\/name><description>$description<\/description><\/item>$state<xxx><\/xxx>/;
-                        }
+    # Move to XML string
+    my $xml_msg= &create_xml_string($out_hash);
 
-                    }
-                }
+    # Check if we need to get host or global information
+    if (defined $hostId){
+      $callobj = {
+          method  => 'getProductHostInformation_list',
+          params  => [ $hostId ],
+          id  => 1,
+      };
 
-            }
+      my $res = $main::opsi_client->call($main::opsi_url, $callobj);
+      if (not &check_opsi_res($res)){
+          foreach my $product (@{$res->result}){
+               my $replace= "<item><productId>".xml_quote($product->{'productId'})."<\/productId><name>".xml_quote($product->{'name'})."<\/name><description>".xml_quote($product->{'description'})."<\/description><state>".xml_quote($product->{'installationStatus'})."</state><action>".xml_quote($product->{'actionRequest'})."</action><\/item><xxx><\/xxx>";
+               $xml_msg=~ s/<xxx><\/xxx>/\n$replace/;
+          }
+      }
 
-        } else {
-            foreach my $r (@{$res->result}) {
-                $callobj = {
-                    method  => 'getProduct_hash',
-                    params  => [ $r ],
-                    id  => 1,
-                };
-
-                my $sres = $main::opsi_client->call($main::opsi_url, $callobj);
-                if (not &check_opsi_res($sres)){
-                    my $tres= $sres->result;
-
-                    my $name= xml_quote($tres->{'name'});
-                    my $description= xml_quote($tres->{'description'});
-                    $name=~ s/\//\\\//;
-                    $description=~ s/\//\\\//;
-                    $xml_msg=~ s/<xxx><\/xxx>/\n<item><productId>$r<\/productId><name>$name<\/name><description>$description<\/description><\/item><xxx><\/xxx>/;
-                }
+    } else {
 
-            }
+      # For hosts, only return the products that are or get installed
+      $callobj = {
+          method  => 'getProductInformation_list',
+          params  => [ undef, 'localboot' ],
+          id  => 1,
+      };
 
-        }
+      my $res = $main::opsi_client->call($main::opsi_url, $callobj);
+      if (not &check_opsi_res($res)){
+          foreach my $product (@{$res->result}) {
+               my $replace= "<item><productId>".xml_quote($product->{'productId'})."<\/productId><name>".xml_quote($product->{'name'})."<\/name><description>".xml_quote($product->{'description'})."<\/description><\/item><xxx><\/xxx>";
+               $xml_msg=~ s/<xxx><\/xxx>/\n$replace/;
+          }
+      }
     }
 
     $xml_msg=~ s/<xxx><\/xxx>//;
@@ -1513,28 +1426,26 @@ sub opsi_getSoftwareLicenseUsagesForProductId {
        # Fetch licensePoolId for productId
        my ($res, $err) = &_getLicensePoolId('productId'=>$productId);
        if ($err){
-               return &_giveErrorFeedback($msg_hash, "cannot fetch licensePoolId for given productId : ".$res, $session_id);
+                my $out_hash = &create_xml_hash("answer_$header", $main::server_address, $source);
+                $out_hash->{result} = [];
+               return ( &create_xml_string($out_hash) );
        }
-
-       my $licensePoolId;
+       my $licensePoolId = $res;   # We assume that there is only one pool for each productID!!!
 
        # Fetch softwareLiceceUsages for licensePoolId
        ($res, $err) = &_getSoftwareLicenseUsages_listOfHashes('licensePoolId'=>$licensePoolId);
        if ($err){
                return &_giveErrorFeedback($msg_hash, "cannot fetch software licenses from license pool : ".$res, $session_id);
        }
-
        # Parse Opsi result
        my $res_hash = &_parse_getSoftwareLicenseUsages($res);
 
        # Create function result message
-       my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
+       my $out_hash = &create_xml_hash("answer_$header", $main::server_address, $source);
        if (exists $msg_hash->{forward_to_gosa}) { &add_content2xml_hash($out_hash, "forward_to_gosa", @{$msg_hash->{'forward_to_gosa'}}[0]); }
        $out_hash->{result} = [$res_hash];
 
-       my $endTime = Time::HiRes::time;
-       my $elapsedTime = sprintf("%.4f", ($endTime - $startTime));
-       &main::daemon_log("0 DEBUG: time to process gosa-si message '$header' : $elapsedTime seconds", 1034);
+       &main::daemon_log("0 DEBUG: time to process gosa-si message '$header' : ".sprintf("%.4f", (Time::HiRes::time - $startTime))." seconds", 1034);
        return ( &create_xml_string($out_hash) );
 }
 
@@ -1965,7 +1876,8 @@ sub opsi_getLicenseInformationForProduct {
         params  => [ $productId ],
         id  => 1,
     };
-    my $res = $main::opsi_client->call($main::opsi_url, $callobj);
+    #my $res = $main::opsi_client->call($main::opsi_url, $callobj);
+    my $res = $opsi_client->call($opsi_url, $callobj);
 
        # Check Opsi error
        my ($res_error, $res_error_str) = &check_opsi_res($res);
@@ -1981,7 +1893,7 @@ sub opsi_getLicenseInformationForProduct {
                params  => [ ],
                id  => 1,
        };
-       $res = $main::opsi_client->call($main::opsi_url, $callobj);
+       $res = $opsi_client->call($opsi_url, $callobj);
 
        # Check Opsi error
        ($res_error, $res_error_str) = &check_opsi_res($res);
@@ -2374,9 +2286,7 @@ sub opsi_unboundHostFromLicense {
        my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
        if (exists $msg_hash->{forward_to_gosa}) { &add_content2xml_hash($out_hash, "forward_to_gosa", @{$msg_hash->{'forward_to_gosa'}}[0]); }
 
-       my $endTime = Time::HiRes::time;
-       my $elapsedTime = sprintf("%.4f", ($endTime - $startTime));
-       &main::daemon_log("0 DEBUG: time to process gosa-si message '$header' : $elapsedTime seconds", 1034);
+       &main::daemon_log("0 DEBUG: time to process gosa-si message '$header' : ".sprintf("%.4f", (Time::HiRes::time - $startTime))." seconds", 1034);
     return ( &create_xml_string($out_hash) );
 }
 
@@ -2416,19 +2326,110 @@ sub opsi_getAllSoftwareLicenses {
        $out_hash->{licenses} = [$res_hash];
        if (exists $msg_hash->{forward_to_gosa}) { &add_content2xml_hash($out_hash, "forward_to_gosa", @{$msg_hash->{'forward_to_gosa'}}[0]); }
 
-       my $endTime = Time::HiRes::time;
-       my $elapsedTime = sprintf("%.4f", ($endTime - $startTime));
-       &main::daemon_log("0 DEBUG: time to process gosa-si message '$header' : $elapsedTime seconds", 1034);
+       &main::daemon_log("0 DEBUG: time to process gosa-si message '$header' : ".sprintf("%.4f", (Time::HiRes::time - $startTime))." seconds", 1034);
     return ( &create_xml_string($out_hash) );
 }
 
+
+################################
+# @brief Returns a list of values for a given host. Values: priority, onceScript, licenseRequired, packageVersion, productVersion, advice, setupScript, windowsSoftwareIds, installationStatus, pxeConfigTemplate, name, creationTimestamp, alwaysScript, productId, description, properties, actionRequest, uninstallScript, action, updateScript and productClassNames 
+# @param hostId Opsi hostId
+sub opsi_get_full_product_host_information {
+       my $startTime = Time::HiRes::time;
+       my ($msg, $msg_hash, $session_id) = @_;
+       my $header = @{$msg_hash->{'header'}}[0];
+       my $source = @{$msg_hash->{'source'}}[0];
+        my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
+        my $hostId;
+
+       my ($res, $err) = &_get_full_product_host_information( hostId=>@{$msg_hash->{'hostId'}}[0]);
+       if ($err) {
+               return &_giveErrorFeedback($msg_hash, "cannot fetch full_product_host_information from Opsi server : ".$res, $session_id);
+       }
+
+        # Build return message with twisted target and source
+        my $out_hash = &main::create_xml_hash("answer_$header", $main::server_address, $source);
+        if (defined $forward_to_gosa) {
+            &add_content2xml_hash($out_hash, "forward_to_gosa", $forward_to_gosa);
+        }
+        &add_content2xml_hash($out_hash, "xxx", "");
+
+        # Get hostId if defined
+        if ((exists $msg_hash->{'hostId'}) && (@{$msg_hash->{'hostId'}} == 1))  {
+            $hostId = @{$msg_hash->{'hostId'}}[0];
+            &add_content2xml_hash($out_hash, "hostId", $hostId);
+        }
+
+        # Move to XML string
+        my $xml_msg= &create_xml_string($out_hash);
+        
+        # Convert result in something usable
+        my $replace= "";
+       foreach my $product ( @$res) {
+
+          # Open item
+          $replace.= "<item>";
+
+          # Add flat hash information
+          my @entries= ( "priority", "onceScript", "licenseRequired", "packageVersion", "productVersion", "advice",
+                              "setupScript", "windowsSoftwareIds", "installationStatus", "pxeConfigTemplate", "name", "type",
+                              "creationTimestamp", "alwaysScript", "productId", "description", "actionRequest", "uninstallScript",
+                              "action", "updateScript", "productClassNames");
+          foreach my $entry (@entries) {
+            if (defined $product->{$entry}) {
+              my $value= $product->{$entry};
+
+              if(ref($value) eq 'ARRAY'){
+                my $tmp= "";
+                foreach my $element (@$value) {
+                  $tmp.= "<element>$element</element>";
+                }
+                $replace.= "<$entry>$tmp</$entry>";
+              } else {
+                $replace.= "<$entry>$value</$entry>";
+              }
+            }
+          }
+
+          # Add property information
+          if (defined $product->{'properties'}) {
+            $replace.= "<properties>";
+            while ((my $key, my $value) = each(%{$product->{'properties'}})){
+              $replace.= "<$key>";
+
+              while ((my $pkey, my $pvalue) = each(%$value)){
+                if(ref($pvalue) eq 'ARRAY'){
+                  my $tmp= "";
+                  foreach my $element (@$pvalue) {
+                    $tmp.= "<element>$element</element>";
+                  }
+                  $replace.= "<$pkey>$tmp</$pkey>";
+                } else {
+                  $replace.= "<$pkey>$pvalue</$pkey>";
+                }
+              }
+              $replace.= "</$key>";
+            }
+            $replace.= "</properties>";
+          }
+
+          # Close item
+          $replace.= "</item>";
+        }
+
+        $xml_msg=~ s/<xxx><\/xxx>/\n$replace/;
+
+       &main::daemon_log("0 DEBUG: time to process gosa-si message '$header' : ".sprintf("%.4f", (Time::HiRes::time - $startTime))." seconds", 1034);
+    return ( $xml_msg );
+}
+
+
 sub opsi_test {
     my ($msg, $msg_hash, $session_id) = @_;
     my $header = @{$msg_hash->{'header'}}[0];
     my $source = @{$msg_hash->{'source'}}[0];
        my $pram1 = @{$msg_hash->{'productId'}}[0];
 
-print STDERR Dumper $pram1;
 
        # Fetch infos from Opsi server
     my $callobj = {
@@ -2438,7 +2439,6 @@ print STDERR Dumper $pram1;
     };
     my $res = $main::opsi_client->call($main::opsi_url, $callobj);
 
-       print STDERR Dumper $res;
        return ();
 }
 
@@ -2487,7 +2487,7 @@ sub _callOpsi {
        };
 
        my $startTime = Time::HiRes::time;
-       my $opsiResult = $main::opsi_client->call($main::opsi_url, $callObject);
+       my $opsiResult = $opsi_client->call($opsi_url, $callObject);
        my $endTime = Time::HiRes::time;
        my $elapsedTime = sprintf("%.4f", ($endTime - $startTime));
 
@@ -2651,4 +2651,28 @@ sub _addSoftwareLicenseToLicensePool {
        return ($res->result, 0);
 }
 
+sub _getProductStates_hash {
+       my %arg = (     'hostId' => undef, @_ );
+
+       if (not defined $arg{hostId} ) {
+               return ("function requires hostId as parameter", 1);
+       }
+
+       my $res = &_callOpsi( method => 'getProductStates_hash', params => [$arg{hostId}]);
+       my ($res_error, $res_error_str) = &check_opsi_res($res);
+       if ($res_error){ return ( (caller(0))[3]." : ".$res_error_str, 1 ); }
+
+       return ($res->result, 0);
+}
+
+sub _get_full_product_host_information {
+       my %arg = ( 'hostId' => undef, @_ );
+
+       my $res = &_callOpsi( method => 'getFullProductHostInformation_list',  params => [$arg{hostId}]);
+       my ($res_error, $res_error_str) = &check_opsi_res($res);
+       if ($res_error){ return ((caller(0))[3]." : ".$res_error_str, 1); }
+
+       return ($res->result, 0);
+}
+
 1;