| Line 178... |
Line 178... |
| 178 |
#
|
178 |
#
|
| 179 |
# Version 3.4.1 20191117 RWR
|
179 |
# Version 3.4.1 20191117 RWR
|
| 180 |
# Added syslog as a possible option for logging.
|
180 |
# Added syslog as a possible option for logging.
|
| 181 |
#
|
181 |
#
|
| 182 |
|
182 |
|
| 183 |
|
- |
|
| 184 |
# find our location and use it for searching for libraries
|
183 |
# find our location and use it for searching for libraries
|
| 185 |
BEGIN {
|
184 |
BEGIN {
|
| 186 |
use FindBin;
|
185 |
use FindBin;
|
| 187 |
use File::Spec;
|
186 |
use File::Spec;
|
| 188 |
use lib File::Spec->catdir($FindBin::Bin);
|
187 |
use lib File::Spec->catdir($FindBin::Bin);
|
| - |
|
188 |
eval( 'use YAML::Tiny;' );
|
| - |
|
189 |
eval( 'use Data::Dumper;' );
|
| 189 |
}
|
190 |
}
|
| 190 |
|
191 |
|
| - |
|
192 |
# contains the directory our script is in
|
| - |
|
193 |
my $sourceDir = File::Spec->catdir($FindBin::Bin);
|
| - |
|
194 |
|
| - |
|
195 |
# define the version number
|
| - |
|
196 |
# see https://metacpan.org/pod/release/JPEACOCK/version-0.97/lib/version.pod
|
| 191 |
use YAML::Tiny;
|
197 |
use version;
|
| - |
|
198 |
our $VERSION = version->declare("v3.5.0");
|
| - |
|
199 |
our $DATA_VERSION = version->declare( 'v3.0.0' ); # used in sending the data file. sets version of XML/YAML data file
|
| - |
|
200 |
|
| - |
|
201 |
# see https://perldoc.perl.org/Getopt/Long.html
|
| 192 |
use Data::Dumper;
|
202 |
use Getopt::Long;
|
| - |
|
203 |
# allow -vvn (ie, --verbose --verbose --dryrun)
|
| - |
|
204 |
Getopt::Long::Configure ("bundling");
|
| 193 |
|
205 |
|
| 194 |
# Following are global variables overridden if configuration file exists
|
206 |
# Following are global variables overridden if configuration file exists
|
| 195 |
|
207 |
|
| 196 |
my $TESTING = 0; # if set to 1, will do everything, but will dump output to /tmp/sysinfo.testing.yaml
|
208 |
my $TESTING = 0; # if set to 1, will do everything, but will dump output to /tmp/sysinfo.testing.yaml
|
| 197 |
|
209 |
|
| 198 |
our $VERSION = '3.4.1';
|
- |
|
| 199 |
|
- |
|
| 200 |
my $indentLevel = 2; # number of spaces to indent per level in XML or YAML
|
210 |
my $indentLevel = 2; # number of spaces to indent per level in XML or YAML
|
| 201 |
|
211 |
|
| 202 |
# paths to search for configuration file
|
212 |
# paths to search for configuration file
|
| 203 |
my @confFileSearchPath = ( '.', '/etc/camp/sysinfo-client', '/etc/camp', '/usr/local/etc/camp/sysinfo-client' );
|
213 |
my @confFileSearchPath = ( '.', '/etc/camp/sysinfo-client', '/etc/camp', '/usr/local/etc/camp/sysinfo-client' );
|
| 204 |
|
214 |
|
| 205 |
my $configurationFile = 'sysinfo-client.yaml'; # name of the configuration file
|
215 |
my $configurationFile = 'sysinfo-client.yaml'; # name of the configuration file
|
| 206 |
|
216 |
|
| 207 |
my $reportDate = &timeStamp(); # set report date
|
217 |
my $reportDate = &timeStamp(); # set report date
|
| 208 |
|
218 |
|
| - |
|
219 |
my $interactive = 0; # if set to 1, will go into interactive mode and output to local file
|
| - |
|
220 |
my $periodicOverrideFile = '/tmp/sysinfo.firstrun'; # if this file exists, library.pm will tell all periodic modules to run anyway
|
| - |
|
221 |
my $periodic = 0; # if set to 1, will do modules which are only supposed to run weekly, monthly, etc...
|
| - |
|
222 |
|
| - |
|
223 |
my $version;
|
| - |
|
224 |
my $help;
|
| - |
|
225 |
|
| 209 |
my %configuration = (
|
226 |
my %configuration = (
|
| 210 |
'logging' => { 'log type' => 'cache', 'log level' => 0 }, # if set, will point to logging
|
227 |
'logging' => { 'log type' => 'cache', 'log level' => 0 }, # if set, will point to logging
|
| 211 |
'moduleDirs' => [], # search paths for modules
|
228 |
'moduleDirs' => ["$sourceDir/modules"], # search paths for modules
|
| 212 |
'scriptDirs' => [], # search paths for scripts
|
229 |
'scriptDirs' => ["$sourceDir/scripts"], # search paths for scripts
|
| 213 |
'clientName' => '', # Required!! Must be set in conf file (no defaults)
|
230 |
'clientName' => '', # Required!! Must be set in conf file (no defaults)
|
| 214 |
'serialNumber' => '', # serial number of machine
|
231 |
'serialNumber' => '', # serial number of machine
|
| 215 |
'UUID' => '', # UUID of machine
|
232 |
'UUID' => '', # UUID of machine
|
| 216 |
'transports' => [], # hash with various transports
|
233 |
'transports' => {'3' => { '-name-' => 'saveLocal', 'sendScript' => 'save_local', 'output directory' => "$sourceDir/reports" } }, # hash with various transports
|
| 217 |
'hostname' => &getHostName() # fully qualified host name of machine
|
234 |
'hostname' => &getHostName() # fully qualified host name of machine
|
| 218 |
)
|
- |
|
| 219 |
;
|
235 |
);
|
| 220 |
|
236 |
|
| 221 |
my $DATA_VERSION = '3.0.0'; # used in sending the data file. sets version of XML/YAML data file
|
- |
|
| 222 |
|
237 |
|
| 223 |
|
238 |
|
| 224 |
#######################################################
|
239 |
#######################################################
|
| 225 |
#
|
240 |
#
|
| 226 |
# timeStamp
|
241 |
# timeStamp
|
| Line 309... |
Line 324... |
| 309 |
#
|
324 |
#
|
| 310 |
# loadConfigurationFile($confFile)
|
325 |
# loadConfigurationFile($confFile)
|
| 311 |
#
|
326 |
#
|
| 312 |
# Loads configuration file defined by $configurationFile, and dies if not available
|
327 |
# Loads configuration file defined by $configurationFile, and dies if not available
|
| 313 |
# This is a YAML file containing serialized contents of
|
328 |
# This is a YAML file containing serialized contents of
|
| - |
|
329 |
# Parameters:
|
| 314 |
# Parameters: configuration file fully path/file name
|
330 |
# $fileName - name of file to look for
|
| 315 |
# NOTE: conf file must be a valid Perl file
|
331 |
# @searchPath - array of paths to find $filename
|
| 316 |
#
|
332 |
#
|
| 317 |
#######################################################
|
333 |
#######################################################
|
| 318 |
|
334 |
|
| 319 |
sub loadConfigurationFile {
|
335 |
sub loadConfigurationFile {
|
| 320 |
my ( $fileName, @searchPath ) = @_;
|
336 |
my ( $fileName, @searchPath ) = @_;
|
| Line 590... |
Line 606... |
| 590 |
} # foreach
|
606 |
} # foreach
|
| 591 |
# add sysinfo-client (me) to the software list, since we're obviously installed
|
607 |
# add sysinfo-client (me) to the software list, since we're obviously installed
|
| 592 |
&tabDelimitedToHash( $system, "software\tsysinfo-client\tversion\t$main::VERSION\n" );
|
608 |
&tabDelimitedToHash( $system, "software\tsysinfo-client\tversion\t$main::VERSION\n" );
|
| 593 |
}
|
609 |
}
|
| 594 |
|
610 |
|
| 595 |
sub processParameters {
|
611 |
sub getDMIDecode {
|
| - |
|
612 |
my ( $key, $type ) = @_;
|
| - |
|
613 |
my $command = 'dmidecode ';
|
| 596 |
while ( my $parameter = shift ) {
|
614 |
$command .= "-t $type " if $type;
|
| - |
|
615 |
$command .= " | grep -i '$key'";
|
| - |
|
616 |
my $value = `$command`;
|
| - |
|
617 |
chomp $value;
|
| 597 |
if ( $parameter eq '-v' ) {
|
618 |
if ( $value =~ m/:\s*(.*)\s*$/ ) {
|
| 598 |
print "$main::VERSION\n";
|
619 |
return $1;
|
| - |
|
620 |
} else {
|
| 599 |
exit;
|
621 |
return '';
|
| - |
|
622 |
}
|
| - |
|
623 |
}
|
| - |
|
624 |
|
| - |
|
625 |
sub interactiveConfig {
|
| - |
|
626 |
my $config = shift;
|
| - |
|
627 |
$config->{'moduleDirs'} = $config->{'moduleDirs'}[0];
|
| - |
|
628 |
$config->{'scriptDirs'} = $config->{'scriptDirs'}[0];
|
| - |
|
629 |
$config->{'UUID'} = getDMIDecode( 'uuid', 'system' ) unless $config->{'UUID'};
|
| - |
|
630 |
$config->{'serialNumber'} = getDMIDecode( 'serial number', 'system' ) unless $config->{'serialNumber'};
|
| - |
|
631 |
|
| - |
|
632 |
my %menu = (
|
| 600 |
} elsif ( $parameter eq 'firstrun' ) {
|
633 |
1 => {'prompt' => 'Host Name', 'key' => 'hostname' },
|
| - |
|
634 |
2 => {'prompt' => 'Client Name', 'key' => 'clientName' },
|
| - |
|
635 |
3 => {'prompt' => 'Serial Number', 'key' => 'serialNumber' },
|
| - |
|
636 |
4 => {'prompt' => 'UUID', 'key' => 'UUID' },
|
| - |
|
637 |
5 => {'prompt' => 'Modules Directory', 'key' => 'moduleDirs' },
|
| - |
|
638 |
6 => {'prompt' => 'Scripts Directory', 'key' => 'scriptDirs' }
|
| - |
|
639 |
);
|
| - |
|
640 |
my $choice = 'quit';
|
| - |
|
641 |
while ( $choice ) {
|
| 601 |
`touch /tmp/sysinfo.firstrun`;
|
642 |
foreach my $menuItem ( sort keys %menu ) {
|
| - |
|
643 |
print "$menuItem\. " . $menu{$menuItem}{'prompt'} . ': ' . $config->{$menu{$menuItem}{'key'}} . "\n";
|
| 602 |
}
|
644 |
}
|
| - |
|
645 |
print "Enter Menu Item to change, or press Enter to proceed ";
|
| - |
|
646 |
$choice = <>;
|
| 603 |
} # while
|
647 |
chomp $choice;
|
| - |
|
648 |
last unless $choice;
|
| - |
|
649 |
print $menu{$choice}{'prompt'} . ' [' . $config->{$menu{$choice}{'key'}} . '] : ';
|
| - |
|
650 |
my $value = <>;
|
| - |
|
651 |
chomp $value;
|
| - |
|
652 |
$config->{$menu{$choice}{'key'}} = $value if ($value);
|
| - |
|
653 |
}
|
| - |
|
654 |
$config->{'moduleDirs'} = [ $config->{'moduleDirs'} ];
|
| - |
|
655 |
$config->{'scriptDirs'} = [ $config->{'scriptDirs'} ];
|
| - |
|
656 |
return $config;
|
| - |
|
657 |
}
|
| - |
|
658 |
|
| - |
|
659 |
# simple display if --help is passed
|
| - |
|
660 |
sub help {
|
| - |
|
661 |
use File::Basename;
|
| - |
|
662 |
print basename($0) . " $VERSION\n";
|
| - |
|
663 |
print <<END
|
| - |
|
664 |
$0 [options]
|
| - |
|
665 |
Options:
|
| - |
|
666 |
-i,
|
| - |
|
667 |
--interactive - do not read configuration file
|
| - |
|
668 |
--version - display version and exit
|
| - |
|
669 |
-c,
|
| - |
|
670 |
--client='xxx' - Client name for interactive mode
|
| - |
|
671 |
-s,
|
| - |
|
672 |
--serial='xxx' - Serial Number for interactive mode
|
| - |
|
673 |
-h,
|
| - |
|
674 |
--hostname='xxx' - override hostname
|
| - |
|
675 |
-m,
|
| - |
|
676 |
--modules=/path/ - override path to modules
|
| - |
|
677 |
--scripts=/path/ - override path to scripts
|
| - |
|
678 |
-p,
|
| - |
|
679 |
--periodic - runs modules designed to be run only weekly, monthly, etc...
|
| - |
|
680 |
END
|
| 604 |
}
|
681 |
}
|
| 605 |
|
682 |
|
| 606 |
&processParameters( @ARGV );
|
- |
|
| 607 |
|
683 |
|
| - |
|
684 |
# handle any command line parameters that may have been passed in
|
| - |
|
685 |
|
| - |
|
686 |
GetOptions (
|
| - |
|
687 |
'interactive|i' => \$interactive, # ask questions instead of using config file
|
| - |
|
688 |
'periodic|p' => \$periodic, # will do modules which are marked as periodic
|
| - |
|
689 |
'help|h' => \$help,
|
| - |
|
690 |
'version' => \$version,
|
| - |
|
691 |
'client|c=s' => \$configuration{clientName},
|
| - |
|
692 |
'serial|s=s' => \$configuration{serialNumber},
|
| - |
|
693 |
'hostname=s' => \$configuration{hostname},
|
| - |
|
694 |
'modules|m=s' => \$configuration{moduleDirs},
|
| - |
|
695 |
'scripts=s' => \$configuration{scriptDirs},
|
| - |
|
696 |
) or die "Error parsing command line\n";
|
| - |
|
697 |
|
| - |
|
698 |
|
| - |
|
699 |
if ( $help ) { &help() ; exit; }
|
| - |
|
700 |
if ( $version ) { use File::Basename; print basename($0) . " $VERSION\n"; exit; }
|
| - |
|
701 |
|
| - |
|
702 |
if ( $interactive ) {
|
| - |
|
703 |
%configuration = %{ &interactiveConfig( \%configuration ) };
|
| - |
|
704 |
} else {
|
| 608 |
# load the configuration file
|
705 |
# load the configuration file
|
| 609 |
%configuration = %{ &loadConfigurationFile( $configurationFile, @confFileSearchPath) };
|
706 |
%configuration = %{ &loadConfigurationFile( $configurationFile, @confFileSearchPath) };
|
| - |
|
707 |
}
|
| - |
|
708 |
|
| - |
|
709 |
`touch $periodicOverrideFile` if $periodic; # tells periodic modules to run
|
| - |
|
710 |
|
| - |
|
711 |
#die Dumper (\%configuration );
|
| 610 |
|
712 |
|
| 611 |
# user did not define a serial number, so make something up
|
713 |
# user did not define a serial number, so make something up
|
| 612 |
$configuration{'serialNumber'} = '' unless $configuration{'serialNumber'};
|
714 |
$configuration{'serialNumber'} = '' unless $configuration{'serialNumber'};
|
| 613 |
# oops, no client name (required) so tell them and exit
|
715 |
# oops, no client name (required) so tell them and exit
|
| 614 |
die "No client name defined in $configurationFile" unless $configuration{'clientName'};
|
716 |
die "No client name defined in $configurationFile" unless $configuration{'clientName'};
|
| Line 621... |
Line 723... |
| 621 |
&logIt( 0, "Testing => $TESTING" ) if $TESTING;
|
723 |
&logIt( 0, "Testing => $TESTING" ) if $TESTING;
|
| 622 |
|
724 |
|
| 623 |
|
725 |
|
| 624 |
my $System; # hash reference that will store all info we are going to send to the server
|
726 |
my $System; # hash reference that will store all info we are going to send to the server
|
| 625 |
# some defaults.
|
727 |
# some defaults.
|
| 626 |
$System->{'report'}->{'version'} = $DATA_VERSION;
|
728 |
$System->{'report'}->{'version'} = $DATA_VERSION->normal;
|
| 627 |
$System->{'report'}->{'date'} = $reportDate;
|
729 |
$System->{'report'}->{'date'} = $reportDate;
|
| 628 |
$System->{'report'}->{'client'} = $configuration{'clientName'};
|
730 |
$System->{'report'}->{'client'} = $configuration{'clientName'};
|
| 629 |
$System->{'system'}->{'hostname'} = $configuration{'hostname'};
|
731 |
$System->{'system'}->{'hostname'} = $configuration{'hostname'};
|
| 630 |
$System->{'system'}->{'serial'} = $configuration{'serialNumber'};
|
732 |
$System->{'system'}->{'serial'} = $configuration{'serialNumber'};
|
| 631 |
$System->{'system'}->{'UUID'} = $configuration{'UUID'};
|
733 |
$System->{'system'}->{'UUID'} = $configuration{'UUID'};
|
| Line 638... |
Line 740... |
| 638 |
&ProcessModules( $System, "$moduleDir/" );
|
740 |
&ProcessModules( $System, "$moduleDir/" );
|
| 639 |
}
|
741 |
}
|
| 640 |
|
742 |
|
| 641 |
&logIt( 4, "After processing modules\n" . Data::Dumper->Dump( [$System], [qw( $System )] ) );
|
743 |
&logIt( 4, "After processing modules\n" . Data::Dumper->Dump( [$System], [qw( $System )] ) );
|
| 642 |
|
744 |
|
| 643 |
# now, everything ins in $System, so convert it to the proper output format
|
- |
|
| 644 |
#my $out = "#sysinfo: $VERSION YAML\n---\n" . &hashToYAML( $System ) . "...\n";
|
- |
|
| 645 |
|
- |
|
| 646 |
my $out = "#sysinfo: $VERSION YAML\n" . Dump( $System );
|
745 |
my $out = sprintf( "#sysinfo: %s YAML\n", $VERSION->normal ) . &Dump( $System );
|
| 647 |
|
746 |
|
| 648 |
&logIt( 4, 'At line number ' . __LINE__ . "\n" . Data::Dumper->Dump([$System],[qw($System)]) );
|
747 |
&logIt( 4, 'At line number ' . __LINE__ . "\n" . Data::Dumper->Dump([$System],[qw($System)]) );
|
| 649 |
|
748 |
|
| 650 |
# load some global values for use in the script, if required
|
749 |
# load some global values for use in the script, if required
|
| 651 |
my $globals = {
|
750 |
my $globals = {
|
| 652 |
'data version' => $DATA_VERSION,
|
751 |
'data version' => $DATA_VERSION->normal,
|
| 653 |
'report date' => $reportDate,
|
752 |
'report date' => $reportDate,
|
| 654 |
'client name' => $configuration{'clientName'},
|
753 |
'client name' => $configuration{'clientName'},
|
| 655 |
'host name' => $configuration{'hostname'},
|
754 |
'host name' => $configuration{'hostname'},
|
| 656 |
'serial number'=> $configuration{'serialNumber'},
|
755 |
'serial number'=> $configuration{'serialNumber'},
|
| 657 |
'UUID' => $configuration{'UUID'}
|
756 |
'UUID' => $configuration{'UUID'}
|
| Line 668... |
Line 767... |
| 668 |
if ( my $success = &sendResults( $globals, $configuration{'transports'}, $out, $configuration{'scriptDirs'} ) != 1 ) {
|
767 |
if ( my $success = &sendResults( $globals, $configuration{'transports'}, $out, $configuration{'scriptDirs'} ) != 1 ) {
|
| 669 |
&logIt( 0, "Error $success while sending report from $configuration{'hostname'}" );
|
768 |
&logIt( 0, "Error $success while sending report from $configuration{'hostname'}" );
|
| 670 |
}
|
769 |
}
|
| 671 |
}
|
770 |
}
|
| 672 |
|
771 |
|
| - |
|
772 |
unlink ( $periodicOverrideFile ) if -e $periodicOverrideFile;
|
| 673 |
&logIt( 0, 'Ending sysinfo Run' );
|
773 |
&logIt( 0, 'Ending sysinfo Run' );
|
| 674 |
|
774 |
|
| - |
|
775 |
|
| 675 |
1;
|
776 |
1;
|