Project

General

Profile

« Previous | Next » 

Revision 1928b953

Added by Benoît PECCATTE over 7 years ago

Fixes #8127: On agent, check inventory before sending it to Rudder server

View differences:

initial-promises/node-server/inventory/1.0/fusionAgent.cf
"any" usebundle => download_server_uuid;
uuid_valid.(!inventory_sent|force_inventory)::
"any" usebundle => fusionAgent;
"any" usebundle => listInstalledVM;
"any" usebundle => generateExtraInformations;
"any" usebundle => turnUsersToUnicode;
"any" usebundle => addInformationsToInventory;
"any" usebundle => checkInventoryFile;
uuid_valid.(!inventory_sent|force_inventory).inventory_valid::
"any" usebundle => moveInventoryToFinalDestination;
"any" usebundle => signInventories;
"any" usebundle => compressInventories;
......
uuid_succesfully_downloaded.uuid_validity_checked.!uuid_valid::
"@@Inventory@@result_error@@inventory-all@@inventory-all@@00@@inventory@@None@@${g.execRun}##${g.uuid}@#Could not retrieve a valid UUID from the policy server";
# Send reports to confirm this PT's success even if we don't need to send an inventory
# Send reports to confirm this technique success even if we don't need to send an inventory
inventory_sent::
"@@Inventory@@log_info@@inventory-all@@inventory-all@@00@@inventory@@None@@${g.execRun}##${g.uuid}@#An inventory was already sent less than 8 hours ago";
......
edit_defaults => def_no_backup;
}
# Check that the inventory file is valid
bundle agent checkInventoryFile
{
vars:
"inventory_file" slist => findfiles("${g.rudder_var_tmp}/inventory/*.ocs");
!windows.has_rudder_perl::
"perl_command" string => "/opt/rudder/bin/perl -I /opt/rudder/lib/perl5";
!windows.!has_rudder_perl::
"perl_command" string => "/usr/bin/perl";
windows::
"perl_command" string => "C:\Program Files\FusionInventory-Agent\perl\bin\perl.exe"
classes:
"inventory_file_exist" expression => filesexist("@{inventory_file}");
"has_rudder_perl" => fileexists("/opt/rudder/bin/perl");
inventory_file_exist.pass2::
"inventory_valid" expression => returnszero("${perl_command} ${this.promise_dirname}/test-inventory.pl ${inventory_file}"),
scope => "namespace";
"pass2" expression => "any";
reports:
inventory_file_exist.!inventory_valid::
"@@Inventory@@result_error@@inventory-all@@inventory-all@@00@@inventory@@None@@${g.execRun}##${g.uuid}@#Generated inventory has been detected as invalid";
# Print information to the user in addition to the reporting
"********************************************************************************
* WARNING Generated inventory is not valid, as it is missing mandatory fields. *
* Not sending it to the Rudder Server *
* You can check the invalid inventory in ${g.rudder_var_tmp}/inventory/ *
********************************************************************************";
}
# Move the inventory file in the shared directory
bundle agent moveInventoryToFinalDestination
{
initial-promises/node-server/inventory/1.0/test-inventory.pl
#!/usr/bin/perl
use warnings;
use strict;
use XML::TreePP;
use Data::Dumper;
my $file = $ARGV[0];
if(!defined $file || $file eq "") {
print "Usage check-inventory <filename>\n";
exit 2;
}
my $tpp = XML::TreePP->new();
my $tree = $tpp->parsefile( $file );
my $os = $tree->{REQUEST}->{CONTENT}->{OPERATINGSYSTEM};
# Test extension
my $rudder = $tree->{REQUEST}->{CONTENT}->{RUDDER};
if(!defined $rudder) {
print "Inventory ERROR: No RUDDER extension\n";
exit 1;
}
# Test RUDDER/UUID
my $uuid = $rudder->{UUID};
if(!defined $uuid || $uuid eq "" || ($uuid ne "root" && $uuid !~ /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i)) {
print "Inventory ERROR: No valid UUID\n";
exit 1;
}
# Test RUDDER/HOSTNAME or OPERATINGSYSTEM/FQDN
my $hostname = $rudder->{HOSTNAME};
my $fqdn = $os->{FQDN};
if( (!defined $hostname || $hostname eq "") && (!defined $fqdn || $fqdn eq "")) {
print "Inventory ERROR: No RUDDER/HOSTNAME or OPERATINGSYSTEM/FQDN\n";
exit 1;
}
# more than one agent are possible
my @agents;
if(!defined $rudder->{AGENT}) {
print "Inventory ERROR: No RUDDER/AGENT\n";
exit 1;
} elsif(ref($rudder->{AGENT}) eq 'HASH') {
# One RUDDER/AGENT
@agents = ($rudder->{AGENT});
} else {
# Many RUDDER/AGENT
@agents = @{$rudder->{AGENT}};
}
foreach my $agent (@agents) {
# Test RUDDER/AGENT/OWNER
my $owner = $agent->{OWNER};
if(!defined $owner || $owner eq "") {
print "Inventory ERROR: No RUDDER/AGENT/OWNER\n";
exit 1;
}
# Test RUDDER/AGENT/POLICY_SERVER_UUID
my $server_uuid = $agent->{POLICY_SERVER_UUID};
if(!defined $server_uuid || $server_uuid eq "" || ($server_uuid ne "root" && $server_uuid !~ /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i)) {
print "Inventory ERROR: No RUDDER/AGENT/POLICY_SERVER_UUID\n";
exit 1;
}
# Test RUDDER/AGENT/AGENT_NAME
my $agent_name = $agent->{AGENT_NAME};
if(!defined $agent_name || $agent_name eq "") {
print "Inventory ERROR: No RUDDER/AGENT/AGENT_NAME\n";
exit 1;
}
}
# Test OPERATINGSYSTEM/{FULL_NAME or KERNEL_NAME or NAME}
if(!defined $os->{FULL_NAME} || !defined $os->{KERNEL_NAME} || !defined $os->{NAME}) {
print "Inventory ERROR: No OPERATINGSYSTEM/FULL_NAME nor OPERATINGSYSTEM/KERNEL_NAME nor OPERATINGSYSTEM/NAME\n";
exit 1;
}
# Test OPERATINGSYSTEM/KERNEL_VERSION or if OPERATINGSYSTEM/KERNEL_NAME.toLowerCase == aix: HARDWARE/OSVERSION
if(defined $os->{KERNEL_NAME} && lc($os->{KERNEL_NAME}) eq "aix") {
if(!defined $tree->{REQUEST}->{CONTENT}->{HARDWARE}->{OSVERSION}) {
print "Inventory ERROR: No HARDWARE/OSVERSION\n";
exit 1;
}
} else {
if(!defined $os->{KERNEL_VERSION}) {
print "Inventory ERROR: No OPERATINGSYSTEM/KERNEL_VERSION\n";
exit 1
}
}
exit 0;
scripts/check-techniques.sh
done || EXIT=1
# check that techniques do not use reports:
${REPOSITORY_PATH}/scripts/technique-files -l -f '*.cf' -f '*.st' "${REPOSITORY_PATH}" | grep -v initial-promises | egrep -v "techniques/system/common/1.0/(rudder_stdlib.st|update.st|promises.st|process_matching.st|rudder_stdlib_core.st)|techniques/system/distributePolicy/1.0/rsyslogConf.st" | grep -v cfengine_stdlib | while read filename
${REPOSITORY_PATH}/scripts/technique-files -l -f '*.cf' -f '*.st' "${REPOSITORY_PATH}" | grep -v initial-promises | egrep -v "techniques/system/common/1.0/(rudder_stdlib.st|update.st|promises.st|process_matching.st|rudder_stdlib_core.st)|techniques/system/distributePolicy/1.0/rsyslogConf.st|techniques/system/inventory/1.0/fusionAgent.st" | grep -v cfengine_stdlib | while read filename
do
if egrep '^[[:space:]]*reports:' "${filename}" >/dev/null; then
echo "The file ${filename} uses reports: instead of rudder_common_report"
techniques/system/inventory/1.0/fusionAgent.st
"any" usebundle => generateExtraInformations;
"any" usebundle => turnUsersToUnicode;
"any" usebundle => addInformationsToInventory;
"any" usebundle => checkInventoryFile;
uuid_valid.(force_inventory|(inventory_time.!inventory_sent)).inventory_valid::
"any" usebundle => moveInventoryToFinalDestination;
"any" usebundle => signInventories;
"any" usebundle => compressInventories;
......
pass3.(uuid_succesfully_downloaded.uuid_validity_checked.!uuid_valid)::
"any" usebundle => rudder_common_report("Inventory", "result_error", "&TRACKINGKEY&", "inventory", "None", "Could not retrieve a valid UUID from the policy server");
# Send reports to confirm this PT's success even if we don't need to send an inventory
# Send reports to confirm this technique success even if we don't need to send an inventory
pass3.inventory_sent::
"any" usebundle => rudder_common_report("Inventory", "log_info", "&TRACKINGKEY&", "inventory", "None", "An inventory was already sent less than 8 hours ago");
......
edit_defaults => def_no_backup;
}
# Check that the inventory file is valid
bundle agent checkInventoryFile
{
vars:
"inventory_file" slist => findfiles("${g.rudder_var_tmp}/inventory/*.ocs");
!windows.has_rudder_perl::
"perl_command" string => "/opt/rudder/bin/perl -I /opt/rudder/lib/perl5";
!windows.!has_rudder_perl::
"perl_command" string => "/usr/bin/perl";
windows::
"perl_command" string => "C:\Program Files\FusionInventory-Agent\perl\bin\perl.exe"
classes:
"inventory_file_exist" expression => filesexist("@{inventory_file}");
"has_rudder_perl" => fileexists("/opt/rudder/bin/perl");
inventory_file_exist.pass2::
"inventory_valid" expression => returnszero("${perl_command} ${this.promise_dirname}/test-inventory.pl ${inventory_file}"),
scope => "namespace";
"pass2" expression => "any";
methods:
inventory_file_exist.!inventory_valid::
"any" usebundle => rudder_common_report("Inventory", "result_error", "&TRACKINGKEY&", "inventory", "None", "Generated inventory has been detected as invalid");
reports:
inventory_file_exist.!inventory_valid::
# Print information to the user in addition to the reporting
"********************************************************************************
* WARNING Generated inventory is not valid, as it is missing mandatory fields. *
* Not sending it to the Rudder Server *
* You can check the invalid inventory in ${g.rudder_var_tmp}/inventory/ *
********************************************************************************";
}
# Move the inventory file in the shared directory
bundle agent moveInventoryToFinalDestination
techniques/system/inventory/1.0/metadata.xml
<TML name="fetchFusionTools"/>
<TML name="virtualMachines"/>
<TML name="fusionAgent"/>
<TML name="test-inventory.pl">
<OUTPATH>inventory/1.0/test-inventory.pl</OUTPATH>
<INCLUDED>false</INCLUDED>
</TML>
</TMLS>
<SECTIONS/>
techniques/system/inventory/1.0/test-inventory.pl.st
#!/usr/bin/perl
use warnings;
use strict;
use XML::TreePP;
use Data::Dumper;
my $file = $ARGV[0];
if(!defined $file || $file eq "") {
print "Usage check-inventory <filename>\n";
exit 2;
}
my $tpp = XML::TreePP->new();
my $tree = $tpp->parsefile( $file );
my $os = $tree->{REQUEST}->{CONTENT}->{OPERATINGSYSTEM};
# Test extension
my $rudder = $tree->{REQUEST}->{CONTENT}->{RUDDER};
if(!defined $rudder) {
print "Inventory ERROR: No RUDDER extension\n";
exit 1;
}
# Test RUDDER/UUID
my $uuid = $rudder->{UUID};
if(!defined $uuid || $uuid eq "" || ($uuid ne "root" \&\& $uuid !~ /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i)) {
print "Inventory ERROR: No valid UUID\n";
exit 1;
}
# Test RUDDER/HOSTNAME or OPERATINGSYSTEM/FQDN
my $hostname = $rudder->{HOSTNAME};
my $fqdn = $os->{FQDN};
if( (!defined $hostname || $hostname eq "") \&\& (!defined $fqdn || $fqdn eq "")) {
print "Inventory ERROR: No RUDDER/HOSTNAME or OPERATINGSYSTEM/FQDN\n";
exit 1;
}
# more than one agent are possible
my @agents;
if(!defined $rudder->{AGENT}) {
print "Inventory ERROR: No RUDDER/AGENT\n";
exit 1;
} elsif(ref($rudder->{AGENT}) eq 'HASH') {
# One RUDDER/AGENT
@agents = ($rudder->{AGENT});
} else {
# Many RUDDER/AGENT
@agents = @{$rudder->{AGENT}};
}
foreach my $agent (@agents) {
# Test RUDDER/AGENT/OWNER
my $owner = $agent->{OWNER};
if(!defined $owner || $owner eq "") {
print "Inventory ERROR: No RUDDER/AGENT/OWNER\n";
exit 1;
}
# Test RUDDER/AGENT/POLICY_SERVER_UUID
my $server_uuid = $agent->{POLICY_SERVER_UUID};
if(!defined $server_uuid || $server_uuid eq "" || ($server_uuid ne "root" \&\& $server_uuid !~ /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i)) {
print "Inventory ERROR: No RUDDER/AGENT/POLICY_SERVER_UUID\n";
exit 1;
}
# Test RUDDER/AGENT/AGENT_NAME
my $agent_name = $agent->{AGENT_NAME};
if(!defined $agent_name || $agent_name eq "") {
print "Inventory ERROR: No RUDDER/AGENT/AGENT_NAME\n";
exit 1;
}
}
# Test OPERATINGSYSTEM/{FULL_NAME or KERNEL_NAME or NAME}
if(!defined $os->{FULL_NAME} || !defined $os->{KERNEL_NAME} || !defined $os->{NAME}) {
print "Inventory ERROR: No OPERATINGSYSTEM/FULL_NAME nor OPERATINGSYSTEM/KERNEL_NAME nor OPERATINGSYSTEM/NAME\n";
exit 1;
}
# Test OPERATINGSYSTEM/KERNEL_VERSION or if OPERATINGSYSTEM/KERNEL_NAME.toLowerCase == aix: HARDWARE/OSVERSION
if(defined $os->{KERNEL_NAME} \&\& lc($os->{KERNEL_NAME}) eq "aix") {
if(!defined $tree->{REQUEST}->{CONTENT}->{HARDWARE}->{OSVERSION}) {
print "Inventory ERROR: No HARDWARE/OSVERSION\n";
exit 1;
}
} else {
if(!defined $os->{KERNEL_VERSION}) {
print "Inventory ERROR: No OPERATINGSYSTEM/KERNEL_VERSION\n";
exit 1
}
}
exit 0;

Also available in: Unified diff