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…



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

Post a Comment

Popular posts from this blog

HA Proxy for Exchange 2010 Deployment & SMTP Restriction

Juniper Aggregate Interfaces (LACP/No LACP)

Configuring Multicasting with Juniper EX switches (Part 1)