Pages

Sunday, June 26, 2011

Auto/Bulk Add devices in Cacti

Hi folks, I was doing some work with Cacti, and I had to add multiple devices in the graphing console automatically. Actually, the script is still incomplete and I have only added the graphs that don’t need a Data queries. This system consist of custom host templates and scripts (Like using iControl for F5 Monitoring and WebAPI for Bluecoat Monitoring), I may post those scripts later, but I thought, you could use this as a starting point.
For people who are wondering, cacti is a open source rrdtool based monitoring system, with a huge user base I must say. (http://cacti.net/) . It has multiple plugins which makes it even more fun to use.
Ok, things to note before you go on using the Script
  • Cacti system, built and ready
  • The graphs will be added in tree with subdivisions as areas. In my case, I divided into (Americas, Asia Pacific and Europe and Middle East)
  • This script adds the device and decides the zones by the domain name.
  • You need another bootstrap script to call this for adding multiple devices.
  • You can use any device template, please notice, that the interface graphs will not be added as I haven’t coded it to go to data queries).
  • I have also installed the Plugin Architecture and installed the “Monitor Plugin” (http://docs.cacti.net/plugin:monitor)
  • I will also add the device to monitoring using the script.
#!/usr/bin/perl
# Author : Alok. A. S (alokshrivastwa@hotmail.com)
# Script to add multiple devices and thier corresponding graphs.
# Module List
use Net::SNMP; # For PreChecks
use Getopt::Long;
use Mysql;
## Variables ##
my $device_name = $ARGV[0];
my $device_template = $ARGV[1];
my $community_string = "$ARGV[2]";
my $skip_check = "$ARGV[3]";
my $OID_sysname = '1.3.6.1.2.1.1.5.0';
$device_name = lc($device_name);
##
## Check if all input are there
##
if (($device_name == "" ) or ($device_template == "") or ($community_string == ""))
{
&help();
exit 127;
}
sub help($_)
{
print "\n-----------------\nTo invoke this script the format is \n\n";
print "./scriptname.pl <hostname.domain.com> <device template> <SNMP Community> [skip_check]\n";
print "\nDevice template can be : SGOS5/SGOS4/f5/Checkpoint/ASA\n";
print "please use \"skip_check\" if you want to skip the SNMP checks and add the device\n";
}
##
## Check if SNMP is working and the Device Name is proper, meaning we are not going to another device.
## This is to ensure that the wrong device doesn't get added in monitoring or the same device doesnt get added in Monitoring
##
if ($skip_check != "skip_check")
{
my ($session, $error) = Net::SNMP->session(
-hostname  => $device_name,
-community => $community_string,
);
if (!defined $session) {
printf "\nCannot add Device, SNMP not working with the error - ERROR: %s.\n", $error;
exit 1;
}
my $result = $session->get_request(-varbindlist => [ $OID_sysname ],);
if (!defined $result) {
printf "\nCannot get the SysName OID, cannot continue due to the following error - ERROR: %s.\n", $session->error();
$session->close();
exit 1;
}
$SNMP_name = $result->{$OID_sysname};
printf "The System Name Configured for host '%s' is %s.\n",
$session->hostname(), $SNMP_name;
$session->close();
$SNMP_name = lc($SNMP_name);
}
if ($skip_check != "skip_check")
{
if ($device_name !~ m/$SNMP_name/i)
{
print "The SNMP Device name doesn't match the input name, Cannot Continue";
exit 1;
}
}
##
## If we have made it so far, we need to see if the host template is available for the device and then decide to continue
## We will also set some variables, which will be used in the actual addition of the devices.
##
$php_var = '/usr/bin/php';
$cli_command_dir = '/var/www/cacti/cli';
my $system_get_template_id=`php -q $cli_command_dir/add_device.php --list-host-templates | grep "[0-9]" | grep -i "$device_template" | awk '{print \$1}'`;
chomp ($system_get_template_id);
if (($system_get_template_id == '0' ) or ($system_get_template_id == '' ))
{
print "Unknown template or template not in system, Quitting....";
exit 1;
}
##
## If we have come so far, then we need to
##     1. Add the Device in the Cacti
##     2. Find assocaiated templates
##     3. Add Graphs
##
my $new_desc = $device_name;
my $region="Americas";
if ($device_name =~ m/\.aspac.domain.com$/i)
{
$region="ASPAC";
}
if ($device_name =~ m/\.emea.domain.com$/i)
{
$region="EMEA";
}
$new_desc =~ s/\..*//g;
system("php -q $cli_command_dir/add_device.php --description=$new_desc --ip=\"$device_name\" --template=\"$system_get_template_id\" --avail=snmp --ping_retries=2 --version=2 --community=\"$community_string\" --port=161 --timeout=500");
##
## Get the Host-ID and add the corresponding graphs which need no data query
##
my $added_host_id = `php -q $cli_command_dir/add_tree.php --list-hosts | grep $new_desc |awk '{print \$1}'`;
chomp($added_host_id);
if (!($added_host_id >= '1'))
{
print "unknown host, possibly not added yet, quitting...";
exit 1;
}
print "The host, $device_name has the id $added_host_id\n";
## Update the Database to start monitoring ##
my $database = "cacti";
my $host = "localhost";
my $port = "3306";
my $user = "cactiusername";
my $pw = "cactipassword";
my $cactiquery = "update host set monitor='on' where id=\'$added_host_id\'";
my $connect1 = Mysql->connect($host, $database, $user, $pw);
$connect1->selectdb($database);
my $execute1 = $connect1->query($cactiquery);
## Getting the Graph ID's and adding the Graphs that dont need query, you will need to add the queried graphs explicitly.
my @graph_template_ids=`php -q $cli_command_dir/add_graphs.php  --list-graph-templates --host-template-id=$system_get_template_id | grep [0-9].* | awk '{print \$1}'`;
foreach $id (@graph_template_ids)
{
chomp($id);
if(length($id))
{
system("php -q $cli_command_dir/add_graphs.php --host-id=$added_host_id --graph-type=cg --graph-template-id=$id");
}
}
##
## At this point, the graphs will be added but they will not be shown in the tree.
##
my $main_tree_id = `php -q $cli_command_dir/add_tree.php --list-trees | grep "$device_template" | awk '{print \$1}'`;
chomp($main_tree_id);
my $parent_id = `php -q $cli_command_dir/add_tree.php  --list-nodes --tree-id=$main_tree_id | grep $region |  awk '{print \$2}'`;
chomp($parent_id);
my $already_on_branch = `php -q $cli_command_dir/add_tree.php  --list-nodes --tree-id=$main_tree_id | grep $device_name |  awk '{print \$2}'`;
if (($already_on_branch >= '1'))
{
print "\nDevice already on branch, Not adding...";
exit 1;
}
## Add device to the tree
system("php -q $cli_command_dir/add_tree.php --type=node --node-type=host --host-id=$added_host_id --tree-id=$main_tree_id --parent-node=$parent_id");
print "\nDevice Added!!!";
exit 0;

In the above script, I have used 3 different domain names, in order for the region to be determined.



You will have to create a treee structure prior to this like this



  • Device Type (Tree Name)
    • Americas (header)
    • EMEA (header)
    • ASPAC (header)
So in my case I created the tree structure

  • SGOS5
    • Americas
    • EMEA
    • ASPAC
  • SGOS4
    • Americas
    • EMEA
    • ASPAC
  • f5
    • Americas
    • EMEA
    • ASPAC

Another point I failed to mention is that, this is not the final script that I created, I followed the perl best practices in development and also made it modular, but I throw this out, so people can play with the script. Once I have the final script, I may post it on another blog. you can couple this with PHP and call it from there for bulk addition and things like that.

Till then, Ciao…



2 comments:

  1. Hay,

    Did you ever get the final script together. Be interested to see it as i am trying to automate my cacti setup

    ReplyDelete
  2. Hi davwalker23 .... Yes I did ... I'll have to dig around to find where I put it ... will post it once I find it ... (But this script is pretty similar) Is there some thing you are trying and is not happening in this script ?

    ReplyDelete