I just started testing out ZABBIX yesterday (1.1a6) and had a need to bulk load large amounts of snmpwalk data into ZABBIX templates using vendor specific MIBs. Manually adding hundreds of items for a template through the UI could take a while and I didn't notice a ZABBIX provided tool that did this. So, I wrote a simple loader. It works in my test environment for the equipment I'm using, but I suspect that it may need changes for other MIBs and environments. Please read the code for more details and use at your own risk as this hasn't been tested very much yet
Also, I haven't bothered to write the snmptranslate in perl so '-m all' is quite expensive each time snmptranslate loads. It's best to just -m the MIBs you care about.
Thanks,
Steven
Also, I haven't bothered to write the snmptranslate in perl so '-m all' is quite expensive each time snmptranslate loads. It's best to just -m the MIBs you care about.
Thanks,
Steven
Code:
#!/usr/bin/perl
####################################
#
# zload_snmpwalk
# Author: Steven Dossett
# Email: sd at panath.com
#
####################################
# Disclaimer:
# This script has only been used with ZABBIX 1.1alpha6. It isn't thoroughly
# tested. It isn't very efficient. It may eat your database or cause other
# unintentional harm. Be careful and use at your own risk.
# Please share bug fixes and improvements that you make...
#
# See usage instructions by running: zload_snmpwalk -h
#
# Description:
# Creating new ZABBIX host templates can be time consuming. This script
# automates some of the process by loading snmpwalk data into a ZABBIX
# template. It is very important to use a MIB so that keys and descriptions
# for the data are usable. MIBs can be specified on the command line or
# snmpwalk may find them via your MIBS environment variable. The template
# items will need modification from the ZABBIX UI after bulk loading. The
# script doesn't attempt to manage interesting things like 'units' or 'custom
# multipliers'. The script also has a limited notion of what qualifies as
# 'Character' data and defaults to 'Numeric' for just about everything.
# Update the script to properly identify more types.
#
# An example session might work like the following:
#
# 1 - Create a new host template in the Zabbix UI. Make note of the ID for the
# new template.
# 2 - Use an additional -T option to test the examples in 2a and 2b.
# 2a - Build an initial set of items for the template. In the example below
# the template id 10015 is used:
# zload_snmpwalk -m SOMEVENDOR-MASTER-MIB secretstring dbuser dbpass 10015 somehost .iso.org.dod.internet.private
# 2b - Alternatively, the template can be created from saved snmpwalk data:
# zload_snmpwalk -m SOMEVENDOR-MASTER-MIB secretstring dbuser dbpass 10015 somefile
# For the option above, the data must be in 'snmpwalk -Of' format.
# 3 - Next, the template should be tweaked and tested from the Zabbix UI before
# applying to hosts.
#
use Getopt::Std;
use DBI;
use strict;
use vars qw($PROG $VERSION $community $host $mib $usagetxt %OPTS
$dbhost $dbuser $dbpass $zabbix_db $zabbix_id $translate $dbh
$zabbix_port $zabbix_delay $zabbix_history $zabbix_trends
$TEST);
$VERSION = "1.0";
$PROG = "zload_snmpwalk";
$usagetxt = qq {
USAGE:
$PROG [OPTIONS] <community> <dbuser> <dbpasswd> <zabbix_id> <agent> <oid>
$PROG [OPTIONS] <community> <dbuser> <dbpasswd> <zabbix_id> <file>
Version: $VERSION
snmpwalk the target <agent> from the starting <oid> and then store the results
in the ZABBIX template <zabbix_id>. Alternatively, a <file> containing the
output of a previous snmpwalk can be used. The data is expected in the format
generated by 'smpwalk -Of' and should be generated using the appropriate MIB(s)
so that meaningful descriptions can be created for ZABBIX. Without using a
MIB, the attempt will likely fail as the descriptions used for ZABBIX keys will
be duplicated.
Be sure to test your data with the -T option first!
BASIC ENVIRONMENT REQUIREMENTS:
Zabbix 1.1alpha6 - Not tested with any other versions.
perl - Tested with 5.8.0
Mysql & perl DBI - Might work with postgres after minor changes.
net-snmp - Tested with net-snmp 5.0.8
PRIMARY ARGUMENTS:
<community> SNMP community string
<dbuser> DB user that can update ZABBIX tables
<dbpasswd> DB password for the user
<zabbix_id> Zabbix template id for a template created from the UI
DATA SOURCES:
<agent> Target SNMP host/agent
<oid> Beginning oid - example: .iso.org.dod.internet.private
OR
<file> File containing snmpwalk data in '-Of' format to be loaded
OPTIONS:
-T Test Mode. No DB updates - just view the new records.
-v 1|2c SNMP version
-m MIB[:...] load given list of MIBs (ALL loads everything)
-p port SNMP port, default is 161
Database or ZABBIX data related options:
-r delay SNMP polling delay, default is 60
-h history How long to keep polling history, default is 7
-t trends How long to keep polling trends, default is 365
-s server Database server, default is localhost
-d database Database, default is zabbix
};
sub connect_db {
my $db = "DBI:mysql:$zabbix_db:$dbhost";
$dbh = DBI->connect($db, $dbuser, $dbpass) ||
die "Can't connect to DB: $dbh->errstr\n";
$dbh->{AutoCommit} = 0;
}
sub get_zabbix_description
{
my $raw_oid = shift(@_);
my $pos;
# Step back 2 positions for a description string and key
$pos = rindex($raw_oid,'.');
$pos = rindex($raw_oid,'.',$pos - 1);
return substr($raw_oid, $pos + 1);
}
sub get_zabbix_oid
{
my $raw_oid = shift(@_);
my $zabbix_oid = `$translate $raw_oid`;
chomp($zabbix_oid);
return $zabbix_oid;
}
sub get_zabbix_value_type
{
my $snmp_type = shift(@_);
my $zabbix_value_type;
# Zabbix types
# 0 = Numeric
# 1 = Character
# Add additional character types as needed. More are needed..
SWITCH:
{
if ($snmp_type eq "STRING")
{ $zabbix_value_type = 1; last SWITCH; }
$zabbix_value_type = 0;
}
return $zabbix_value_type;
}
sub usage
{
print $usagetxt;
exit 0;
}
MAIN:
$| = 1; # no print delay
my $input;
my $sql;
my $tcounter = 0;
if (!getopts('d:h:m:p:r:s:t:u:v:T', \%OPTS))
{
usage();
}
if (@ARGV == 5 || @ARGV == 6)
{
$TEST = exists($OPTS{T}) ? "1" : "0";
$community = $ARGV[0];
$dbuser = $ARGV[1];
$dbpass = $ARGV[2];
$zabbix_id = $ARGV[3];
$dbhost = exists($OPTS{s}) ? ($OPTS{s}) : "localhost";
$zabbix_db = exists($OPTS{d}) ? ($OPTS{d}) : "zabbix";
$zabbix_port = exists($OPTS{p}) ? ($OPTS{p}) : "161";
$zabbix_delay = exists($OPTS{r}) ? ($OPTS{r}) : "60";
$zabbix_history = exists($OPTS{h}) ? ($OPTS{h}) : "7";
$zabbix_trends = exists($OPTS{t}) ? ($OPTS{t}) : "365";
$translate = "snmptranslate -Ofn ";
$translate .= exists($OPTS{m}) ? ("-m $OPTS{m} ") : "";
# Input from file by default, might change below
$input = "<$ARGV[4]";
}
else
{
usage();
};
# Data from live snmpwalk
if (@ARGV == 6)
{
$host = $ARGV[4];
$input = "snmpwalk -c $community ";
$input .= exists($OPTS{m}) ? ("-m $OPTS{m} ") : "";
$input .= exists($OPTS{v}) ? ("-v $OPTS{v} ") : "";
# Host
$input .= "-Of $host";
$input .= exists($OPTS{p}) ? (":$OPTS{p} ") : ":161 ";
# OID
$input .= "$ARGV[5]|";
}
connect_db();
open(SWALK,$input) or die "Can't open $input\n";
print "Processing Data from $input ";
$sql = $dbh->prepare("INSERT INTO items (type, snmp_community, snmp_oid, snmp_port, hostid, description, key_, delay, history, trends, value_type) VALUES (?,?,?,?,?,?,?,?,?,?,?)");
while(my $line = <SWALK>)
{
my $zabbix_value_type;
my $zabbix_description;
my $zabbix_oid;
next if ($line !~ /(.iso.org.dod.*) = (.*):/ );
#$1 = oid string to translate
#$2 = integer, string or other snmp type
#More snmp "character" types should be added
$zabbix_description = get_zabbix_description($1);
$zabbix_oid = get_zabbix_oid($1);
$zabbix_value_type = get_zabbix_value_type($2);
if ($TEST)
{
if (($tcounter++ % 10) == 0)
{
print "\ntype\tsnmp_community\tsnmp_oid\tsnmp_port\t",
"hostid\tdescription\tkey_\tdelay\t",
"history\ttrends\tvalue_type\n";
}
print "4\t$community\t$zabbix_oid\t$zabbix_port\t",
"$zabbix_id\t$zabbix_description\t",
"$zabbix_description\t$zabbix_delay\t",
"$zabbix_history\t$zabbix_trends\t",
"$zabbix_value_type\n";
}
else
{
print "." if (($tcounter++ % 10) == 0 );
$sql->execute(4, $community, $zabbix_oid, $zabbix_port,
$zabbix_id, $zabbix_description, $zabbix_description,
$zabbix_delay, $zabbix_history, $zabbix_trends,
$zabbix_value_type) || die "Insert Failure: $sql->strerror\n";
}
}
close(SWALK);
$dbh->commit();
$dbh->disconnect();
print "Finished\n";
exit 0;

Comment