#!/usr/bin/perl ############################################################################### # # Copyright (c) 2009 Artica Soluciones Tecnologicas S.L. # # inventory Generate a hardware/software inventory. # # Sample usage: ./inventory [cpu] [ram] [video] [nic] [hd] [cdrom] [software] [init_services] [filesystem] [process] [users] # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; version 2 of the License. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # ############################################################################### use strict; use constant TSTAMP_FILE => '/tmp/pandora_inventory.tstamp'; # Parse module information sub get_module_data ($$$$) { my ($name, $hwinfo, $keys, $modules) = @_; my %module; # Parse module data while (my $line = shift (@{$hwinfo})) { if ($line =~ /\s+\*\-/) { unshift (@{$hwinfo}, $line); last; } foreach my $key (@{$keys}) { if ($line =~ /$key:\s+(.+)/) { $module{$key} = $1; push (@{$module{'_keys'}}, $key); } } } # No data found my @data = keys (%module); return unless ($#data >= 0); push (@{$modules->{$name}}, \%module); } # Get a list of information file system in machine sub get_file_system($$) { my ($name, $modules) = @_; my @fileSystems = `df -h | tail -n +2`; #remove the titles of columns foreach my $row (@fileSystems) { next unless ($row =~ /^(\S+)\s+\S+\s+(\S+)\s+(\S+)\s+\S+\s+(\S+)/); my %module; $module{'filesystem'} = $1; $module{'used'} = $2; $module{'avail'} = $3; $module{'mount'} = $4; $module{'_keys'} = ['filesystem', 'used','avail', 'mount']; push (@{$modules->{$name}}, \%module); } } # Get a list of services init in machine sub get_servicies_init_machine($$) { my ($name, $modules) = @_; my $runlevel = `runlevel | cut -d' ' -f2`; #ini trim($runlevel) $runlevel =~ s/^\s*//; #ltrim $runlevel =~ s/\s*$//; #rtrim #end trim($runlevel) my $script = "ls /etc/rc" . $runlevel .".d/ -l | grep \"^l.*\" | grep \" S.* \" | cut -d' ' -f11"; my @services = `$script`; foreach my $row (@services) { next unless ($row =~ /^\S+\/(\S+)$/); my %module; $module{'service'} = $1; $module{'_keys'} = ['service']; push (@{$modules->{$name}}, \%module); } } # Get a list of running processes sub get_processes ($$) { my ($name, $modules) = @_; my $script = "ps -eo command"; my @services = `$script`; foreach my $row (@services) { my %module; # Remove carriage returns $row =~ s/[\n\l\f]//g; $module{'service'} = $row; $module{'_keys'} = ['service']; push (@{$modules->{$name}}, \%module); } } # Get a list of valid users in the system sub get_users ($$) { my ($name, $modules) = @_; my $script = "cat /etc/passwd"; my $user = ""; my $estado = ""; my @services = `$script`; foreach my $row (@services) { my %module; next unless ($row =~ /^([A-Za-z0-9\-\_]*)/); $user = $1; $script = `passwd -S $user`; if ( $script =~ /^(\S+)\sP./){ $module{'user'} = $user; $module{'_keys'} = ['user']; push (@{$modules->{$name}}, \%module); } } } # Get a list of installed programs sub get_software_module_data ($$) { my ($name, $modules) = @_; # Guess the current distribution my $distrib_id = ""; if ( -e "/etc/SuSE-release"){ $distrib_id = "SUSE"; } else { open (RELEASE_FILE, '< /etc/lsb-release') or return; $distrib_id = ; last unless ($distrib_id =~ m/DISTRIB_ID\s*=\s*(\S+)/); $distrib_id = $1; } # List installed programs my @soft; if ($distrib_id eq 'Ubuntu') { @soft = `dpkg -l | grep ii`; } else { @soft = `rpm -q -a --qf "ii\t%{NAME}\t%{VERSION}\t%{SUMMARY}\n"`; } # Parse data foreach my $row (@soft) { next unless ($row =~ /^ii\s+(\S+)\s+(\S+)\s+([^\n]+)/); my %module; $module{'program'} = $1; $module{'version'} = $2; $module{'description'} = $3; $module{'_keys'} = ['program', 'version','description']; push (@{$modules->{$name}}, \%module); } } # Print module data sub print_module ($$) { my ($name, $module) = @_; print " \n"; print " \n"; print " \n"; foreach my $item (@{$module}) { # Compose module data my $data = ''; foreach my $key (@{$item->{'_keys'}}) { next unless defined ($item->{$key}); $data .= ($data eq '' ? '' : ';') . $item->{$key}; } print " \n"; } print " \n"; print " \n"; } # Check command line parameters if ($#ARGV < 0) { print "Usage: $0 [cpu] [ram] [video] [nic] [hd] [cdrom] [software] [init_services] [filesystem] [users] [process] \n\n"; exit 1; } # Parse command line parameters my %enabled; my $interval = 1; my $enable_all = 0; $interval = $ARGV[0]; if ($#ARGV == 0){ $enable_all = 1; } foreach my $module (@ARGV) { if ($module eq "all"){ $enable_all = 1; } $enabled{$module} = 1; } # Check execution interval if (-f TSTAMP_FILE) { open (FILE, '<' . TSTAMP_FILE) || exit 1; my $last_execution = ; close (FILE); exit 0 if ($last_execution + 86400 * $interval > time ()); } open (FILE, '>' . TSTAMP_FILE) || exit 1; print FILE time (); close (FILE); # Retrieve hardware information my @hwinfo = `lshw 2>/dev/null`; # Parse hardware information my %modules; while (my $line = shift (@hwinfo)) { chomp ($line); # CPU if ($line =~ /\*\-cpu/ && ($enable_all == 1 || $enabled{'cpu'} == 1)) { get_module_data ('CPU', \@hwinfo, ['product', 'vendor', 'capacity'], \%modules); } # RAM if ($line =~ /\*\-bank/ && ($enable_all == 1 || $enabled{'ram'} == 1)) { get_module_data ('RAM', \@hwinfo, ['description', 'size'], \%modules); } # VIDEO if ($line =~ /\*\-display/ && ($enable_all == 1 || $enabled{'video'} == 1)) { get_module_data ('VIDEO', \@hwinfo, ['product', 'description', 'vendor'], \%modules); } # NIC if ($line =~ /\*\-network/ && ($enable_all == 1 || $enabled{'nic'} == 1)) { get_module_data ('NIC', \@hwinfo, ['product', 'description', 'vendor'], \%modules); } # CDROM if ($line =~ /\*\-cdrom/ && ($enable_all == 1 || $enabled{'cdrom'} == 1)) { get_module_data ('CDROM', \@hwinfo, ['product', 'description', 'vendor'], \%modules); } # HD if ($line =~ /\*\-disk/ && ($enable_all == 1 || $enabled{'hd'} == 1)) { get_module_data ('HD', \@hwinfo, ['product', 'description', 'size'], \%modules); } } # Software if ($enable_all == 1 || $enabled{'software'} == 1) { get_software_module_data ('Software', \%modules); } #init_services if ($enable_all == 1 || $enabled{'init_services'} == 1) { get_servicies_init_machine ('Init services', \%modules); } #filesystem if ($enable_all == 1 || $enabled{'filesystem'} == 1) { get_file_system('File system', \%modules); } #processes if ($enable_all == 1 || $enabled{'process'} == 1) { get_processes('Process', \%modules); } #users if ($enable_all == 1 || $enabled{'users'} == 1){ get_users ('Users', \%modules); } # Print module data print "\n"; while (my ($name, $module) = each (%modules)) { print_module ($name, $module); } print "\n"; exit 0;