1
0
Fork 0
mirror of https://github.com/munin-monitoring/contrib.git synced 2025-07-21 18:41:03 +00:00

Plugin-Gallery: Better 2nd level headings

This commit is contained in:
dipohl 2017-02-24 03:40:55 +01:00
parent ae4e85ab60
commit e10e386b02
10 changed files with 7 additions and 2 deletions

132
plugins/router/ag241-adsl Executable file
View file

@ -0,0 +1,132 @@
#!/usr/bin/ruby
# munin plugin to retrieve connection statistics from the web admin interface
# on a Linksys AG241v2 ADSL modem
# Makes use of the http://modemaddress/ADSLCStatus.htm page
#This plugin has only been tested on a Debian testing system
# This modem also has some basic SNMP support so you can configure it
# as per the instructions on the munin wiki
# http://munin.projects.linpro.no/wiki/Using_SNMP_plugins
# By default the SNMP server is disabled, you can enable it in the web admin
# You will need to set up the "virtual node" configuration as detailed
# for snmp plugins
# Plugin will require some configuration in /etc/munin/plugin-conf.d/ag241_MODEMADDRESS
# e.g.
# [ag241_vocume.stargate_*]
# env.user admin
# env.pass password
# #env.port 80
# Once you have the above config set you will need to symlink the plugin to
# /etc/munin/plugins/ag241_MODEMADDRESS_syncrate
# /etc/munin/plugins/ag241_MODEMADDRESS_attenutation
# /etc/munin/plugins/ag241_MODEMADDRESS_noise
# now restart munin-node.
# hopefully in 20-30mins you will have some nice graphs
#Some magical munin foo...
#%# family=manual
#%# capabilities=
# Require this module, it is part of the standard ruby lib AFAIK
require 'net/http'
#default parameters
host = nil
port = ENV['port'] || 80
user = ENV['user'] || 'admin'
pass = ENV['pass'] || 'forhax' #dont remember what the default admin password was
stat = nil
# Check executeable "name" for parameter count
params = $0.split('_')
if params.size != 3
puts "Incorrect number of parameters"
exit 1
end
# first param after the plugin name is the host to query
# second is the statistic to query
host = params[1]
stat = params[2]
unless ENV['debug'].nil?
puts "user = "+ user
puts "pass = "+ pass
puts "host = "+ host
puts "port = "+ port
puts "stat = "+ stat
end
# Dump the graph configuration data
if ARGV[0] == 'config'
puts 'host_name ' + host
puts 'graph_category network'
case stat
when 'syncrate'
puts 'graph_info This graph shows the ADSL line sync rate.'
puts 'graph_title ADSL line sync rate'
puts 'graph_vlabel connection rate bits / second'
puts 'graph_args --base 1000 -l 0 '
when 'attenuation'
puts 'graph_info This graph shows the ADSL line attenuation.'
puts 'graph_title ADSL line attenuation'
puts 'graph_vlabel attenuation dB'
when 'margin','noise'
puts 'graph_info This graph shows the ADSL SNR margin.'
puts 'graph_title ADSL line SNR margin'
puts 'graph_vlabel noise margin dB'
end
puts 'down.label downstream'
puts 'up.label upstream'
exit 0
end
# Connect to the webadmin
http = Net::HTTP.start(host,port)
req = Net::HTTP::Get.new('/ADSLCStatus.htm')
# send the login info
req.basic_auth user, pass
response = http.request(req)
s = response.body
#Make sure we got the page successfully
if response.code != '200'
puts "Getting web page failed:"
case response.code
when '401'
puts 'Probably because the username and password are incorrect'
#Looks like the modem respons with 200 when you try to access a page that doesnt exist >_>
#when '404'
# puts 'Looks like the page this plugin needs isn\'t available...'
# puts 'Check your modem make/model/version'
end
puts s
exit 1
end
# Apply voodoo regex to the result HTML to get the data we want.
case stat
when 'syncrate'
a = s.scan(/.*share\.curstate.*\n.*share\.downstr[^0-9]*([0-9]+).*share\.upstr[^0-9]*([0-9]+).*$/)
b,c = a[0]
puts 'down.value '+ (b.to_i*1000).to_s + "\n" + 'up.value '+ (c.to_i*1000).to_s
exit 0
when 'attenuation'
a = s.scan(/.*share\.lineatt.*\n.*share\.down[^0-9]*([0-9]+).*share\.up[^0-9]*([0-9]+).*$/)
b,c = a[0]
puts 'down.value '+ (b.to_i).to_s + "\n" + 'up.value '+ (c.to_i).to_s
exit 0
when 'margin','noise'
a = s.scan(/.*share\.noise.*\n.*share\.down[^0-9]*([0-9]+).*share\.up[^0-9]*([0-9]+).*$/)
b,c = a[0]
puts 'down.value '+ (b.to_i).to_s + "\n" + 'up.value '+ (c.to_i).to_s
exit 0
else
puts 'Statistic ' + stat.to_s + ' not known, would you like me to fabricate it for you?'
exit 1
end

View file

@ -0,0 +1,135 @@
#!/usr/bin/php
<?php
##############################
#
# Plugin: AVM Fritz!Box WAN traffic (over UPNP)
#
# Author: Andreas Kreisl
#
# Licence: Creative Commons - Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
# http://creativecommons.org/licenses/by-sa/3.0/
#
##############################
#%# family=auto
#%# capabilities=autoconf
$host = "fritz.box";
if(isset($argv[1]) && $argv[1] == "autoconf") {
echo "yes\n";
} else if(isset($argv[1]) && $argv[1] == "config") {
$data_prop = GetCommonLinkProperties();
//$data_ip = GetExternalIP(); // $data_ip['NewExternalIPAddress']
echo "graph_order down up maxdown maxup\n";
echo "graph_title AVM Fritz!Box WAN traffic\n";
echo "graph_args --base 1024\n";
echo "graph_vlabel bits in (-) / out (+) per \${graph_period}\n";
echo "graph_category network\n";
echo "graph_info This graph shows the traffic of the AVM Fritz!Box WAN network interface. Please note that the traffic is shown in bits per second, not bytes.\n";
echo "down.label received\n";
echo "down.type DERIVE\n";
echo "down.graph no\n";
echo "down.cdef down,8,*\n";
echo "down.min 0\n";
echo "down.max 1000000000\n";
echo "up.label " . $data_prop['NewWANAccessType'] . " (" . $data_prop['NewPhysicalLinkStatus'] . ")\n";
echo "up.type DERIVE\n";
echo "up.negative down\n";
echo "up.draw AREA\n";
echo "up.cdef up,8,*\n";
echo "up.min 0\n";
echo "up.max 1000000000\n";
echo "up.info Traffic of the WAN interface.\n";
echo "maxdown.label received\n";
echo "maxdown.type GAUGE\n";
echo "maxdown.graph no\n";
echo "maxup.label MAX\n";
echo "maxup.type GAUGE\n";
echo "maxup.negative maxdown\n";
echo "maxup.draw LINE1\n";
echo "maxup.info Maximum speed of the WAN interface.\n";
} else {
$data_prop = GetCommonLinkProperties();
$data_stats = GetAddonInfos();
echo "up.value " . $data_stats['NewTotalBytesSent'] . "\n";
echo "down.value " . $data_stats['NewTotalBytesReceived'] . "\n";
echo "maxup.value " . $data_prop['NewLayer1UpstreamMaxBitRate'] . "\n";
echo "maxdown.value " . $data_prop['NewLayer1DownstreamMaxBitRate'] . "\n";
}
function GetCommonLinkProperties() {
$data_url = '/igdupnp/control/WANCommonIFC1';
$data_soap = '"urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1#GetCommonLinkProperties"';
$data_xml = '<?xml version="1.0" encoding="utf-8"?><s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:GetCommonLinkProperties xmlns:u=urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1 /></s:Body></s:Envelope>';
$tmp = DoCurl($data_url,$data_soap,$data_xml);
$data_result = Array();
$data_result['NewLayer1UpstreamMaxBitRate'] = FindKey($tmp,"NewLayer1UpstreamMaxBitRate");
$data_result['NewLayer1DownstreamMaxBitRate'] = FindKey($tmp,"NewLayer1DownstreamMaxBitRate");
$data_result['NewWANAccessType'] = FindKey($tmp,"NewWANAccessType");
$data_result['NewPhysicalLinkStatus'] = FindKey($tmp,"NewPhysicalLinkStatus");
return $data_result;
}
function GetAddonInfos() {
$data_url = '/igdupnp/control/WANCommonIFC1';
$data_soap = '"urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1#GetAddonInfos"';
$data_xml = '<?xml version="1.0" encoding="utf-8"?><s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:GetAddonInfos xmlns:u=urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1 /></s:Body></s:Envelope>';
$tmp = DoCurl($data_url,$data_soap,$data_xml);
$data_result = Array();
$data_result['NewTotalBytesSent'] = FindKey($tmp,"NewTotalBytesSent");
$data_result['NewTotalBytesReceived'] = FindKey($tmp,"NewTotalBytesReceived");
return $data_result;
}
function GetExternalIP() {
$data_url = '/igdupnp/control/WANIPConn1';
$data_soap = '"urn:schemas-upnp-org:service:WANIPConnection:1#GetExternalIPAddress"';
$data_xml = '<?xml version="1.0" encoding="utf-8"?><s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:GetExternalIPAddress xmlns:u=urn:schemas-upnp-org:service:WANIPConnection:1 /></s:Body></s:Envelope>';
$tmp = DoCurl($data_url,$data_soap,$data_xml);
$data_result = Array();
$data_result['NewExternalIPAddress'] = FindKey($tmp,"NewExternalIPAddress");
return $data_result;
}
function DoCurl($url,$soap,$xml) {
$ch = curl_init("http://" . $GLOBALS["host"] . ":49000" . $url);
$headers = array();
//$headers[] = 'POST ' . $url . ' HTTP/1.1'; // Will be automatically set.
$headers[] = 'Content-Type: text/xml; charset="utf-8"';
$headers[] = 'HOST: ' . $GLOBALS["host"] . ':49000';
$headers[] = 'Content-Length: ' . strlen($xml);
$headers[] = 'SOAPACTION: ' . $soap;
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_IPRESOLVE, 1); // Force IPv4
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml); // Add XML in POST-Header
$tmp = curl_exec($ch);
curl_close($ch);
return $tmp;
}
function FindKey($text,$key) {
$p1 = strpos($text,$key);
if($p1 === false) {
$tmp = "";
} else {
$p1 = strpos($text,'>',$p1) +1;
$p2 = strpos($text,'<',$p1);
if($p2 === false) {
$tmp = "";
} else {
$tmp = substr($text,$p1,$p2-$p1);
}
}
return $tmp;
}
?>

68
plugins/router/conexant_adsl Executable file
View file

@ -0,0 +1,68 @@
#!/bin/bash
#
#
# Script to show adsl router stats for routers with Conexant based chips and the standard Conexant web admin gui like the eTec EpicRouter...
#
# Parameters understood:
#
# config (required)
# autoconf (optional - used by munin-config)
#
#
# Magic markers (optional - used by munin-config and installation
# scripts):
#
#%# family=auto
#%# capabilities=autoconf
USERNAME=admin
PASSWORD=epicrouter
MAXLABEL=20
if [ "$1" = "autoconf" ]; then
echo yes
exit 0
fi
if [ "$1" = "config" ]; then
echo 'graph_title ADSL Connection Statistics'
echo 'graph_args --base 1000 -l 0'
echo 'graph_category network'
echo 'graph_vlabel Daily Connection Statistics'
echo 'st_dw_crc.label Downstream CRC count'
echo 'st_up_crc.label Upstream CRC count'
echo 'st_dw_data_rate.label Downstream Data Rate'
echo 'st_up_data_rate.label Upstream Data Rate'
echo 'st_dw_line_attenuation.label Downstream Line Attenuation'
echo 'st_up_line_attenuation.label Upstream Line Attenuation'
echo 'st_dw_errored_seconds.label Downstream Errored Seconds'
echo 'st_up_errored_seconds.label Upstream Errored Seconds'
exit 0
fi
wget -q --http-user=admin --http-passwd=epicrouter http://10.0.0.2/doc/adsl.htm -O /tmp/adsl.htm
echo -en "st_dw_crc.value "
echo $((`grep 'var st_dw_crc' /tmp/adsl.htm | sed 's/[var st_dw_crc=;"]//g'`))
echo -n
echo -en "st_up_crc.value "
echo $((`grep 'var st_up_crc' /tmp/adsl.htm | sed 's/[var st_up_crc=;"]//g'`))
echo -n
echo -en "st_dw_data_rate.value "
echo $((`grep 'var st_dw_data_rate' /tmp/adsl.htm | sed 's/[var st_dw_data_rate=;"]//g'`))
echo -n
echo -en "st_up_data_rate.value "
echo $((`grep 'var st_up_data_rate' /tmp/adsl.htm | sed 's/[var st_up_data_rate=;"]//g'`))
echo -n
echo -en "st_dw_line_attenuation.value "
echo $((`grep 'var st_dw_line_attenuation' /tmp/adsl.htm | sed 's/[var st_dw_line_attenuation=\.;"]//g'`))
echo -n
echo -en "st_up_line_attenuation.value "
echo $((`grep 'var st_up_line_attenuation' /tmp/adsl.htm | sed 's/[var st_up_line_attenuation=;\."]//g'`))
echo -n
echo -en "st_dw_errored_seconds.value "
echo $((`grep 'var st_dw_errored_seconds' /tmp/adsl.htm | sed 's/[var st_dw_errored_seconds=;"]//g'`))
echo -n
echo -en "st_up_errored_seconds.value "
echo $((`grep 'var st_up_errored_seconds' /tmp/adsl.htm | sed 's/[var st_up_errored_seconds=;"]//g'`))
echo -n
rm /tmp/adsl.htm

View file

@ -0,0 +1,48 @@
#!/bin/bash
case $1 in
config)
cat <<'EOM'
graph_order downspeed upspeed
graph_title DSL Connection Speed
graph_args --base 1000 -l 1000 --upper-limit 42000
graph_category network
graph_scale no
graph_vlabel DSL up / down speed
downspeed.label Down speed
downspeed.type GAUGE
upspeed.label Up speed
upspeed.type GAUGE
graph_info Graph of DSL Connection Speed
EOM
exit 0;;
esac
# verify we have the IP for the modem
if [[ "$DSLMODEMIP" == "" ]]
then
echo "DSLMODEMIP variable must be set!"
exit 1
fi
# create temp file for storing wget output
TMPFILE=$(mktemp)
# if we have auth variables then add them to
# wget cmdline
if [[ "$DSLUSER" != "" && "$DSLPASS" != "" ]]
then
AUTH_OPT="--user=$DSLUSER --password='$DSLPASS' "
fi
# get wan stats page and store it to temp file
wget $AUTH_OPT --tries=1 --timeout=10 -q -O $TMPFILE http://$DSLMODEMIP/modemstatus_wanstatus.html
# parse tempfile to get connection speeds
DOWNRATE=$(cat $TMPFILE | grep downrate= | sed -e "s/var.*downrate='\(.*\)';.*/\1/g" | sed -e 's/\s//g' | tail -n 1)
UPRATE=$(cat $TMPFILE | grep uprate= | sed -e "s/var.*uprate='\(.*\)';.*/\1/g" | sed -e 's/\s//g' | tail -n 1)
# done with the temp file, remove
rm $TMPFILE
# done, output speeds
echo "upspeed.value $UPRATE"
echo "downspeed.value $DOWNRATE"

57
plugins/router/dsl-stats Executable file
View file

@ -0,0 +1,57 @@
#!/bin/bash
case $1 in
config)
cat <<'EOM'
graph_order snrdown snrup pwrdown pwrup
graph_title dsl stats
graph_args --base 1000
graph_category network
graph_scale no
graph_vlabel DSL SNR and Power
attndown.label Down Attenuation
attndown.type GAUGE
attnup.label Up Attenuation
attnup.type GAUGE
snrdown.label Down SNR
snrdown.type GAUGE
snrup.label Up SNR
snrup.type GAUGE
pwrup.label Up Power
pwrup.type GAUGE
pwrdown.label Down Power
pwrdown.type GAUGE
pwrdown.cdef pwrdown,10,/
pwrup.cdef pwrup,10,/
graph_info Graph of DSL Connection Stats
EOM
exit 0;;
esac
# verify we have the IP for the modem
if [[ "$DSLMODEMIP" == "" ]]
then
echo "DSLMODEMIP variable must be set!"
exit 1
fi
# create temp file for storing wget output
TMPFILE=$(mktemp)
# if we have auth variables then add them to
# wget cmdline
if [[ "$DSLUSER" != "" && "$DSLPASS" != "" ]]
then
AUTH_OPT="--user=$DSLUSER --password='$DSLPASS' "
fi
# get wan stats page and store it to temp file
wget $AUTH_OPT --tries=1 --timeout=10 -q -O $TMPFILE http://$DSLMODEMIP/modemstatus_wanstatus.html
# parse the javascript on the page to get the info we need and print it
cat $TMPFILE | grep 'dslstatus = '| sed -e "s/['; ]//g" | head -n 1 | awk -F '[|/]' '{print "snrdown.value "$5"\nsnrup.value "$6"\nattndown.value "$7"\nattnup.value "$8"\npwrup.value "$29"\npwrdown.value "$30}'
#remove temp file
rm $TMPFILE

190
plugins/router/snmp__juniper Executable file
View file

@ -0,0 +1,190 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright (C) 2014 Johann Schmitz <johann@j-schmitz.net>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Library General Public License as published by
# the Free Software Foundation; version 2 only
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
"""
=head1 NAME
snmp__juniper - Health monitoring plugin for Juniper firewalls.
=head1 CONFIGURATION
Make sure your Juniper device is accessible via SNMP (e.g. via snmpwalk) and the munin-node
has been configured correctly.
=head1 MAGIC MARKERS
#%# family=snmpauto
#%# capabilities=snmpconf
=head1 VERSION
0.0.1
=head1 BUGS
Open a ticket at https://github.com/ercpe/contrib if you find one.
=head1 AUTHOR
Johann Schmitz <johann@j-schmitz.net>
=head1 LICENSE
GPLv2
=cut
"""
import re
import sys
import os
import logging
from pysnmp.entity.rfc3413.oneliner import cmdgen
host = None
port = os.getenv('port', 161)
community = os.getenv('community', None)
debug = bool(os.getenv('MUNIN_DEBUG', os.getenv('DEBUG', 0)))
if debug:
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(levelname)-7s %(message)s')
try:
match = re.search("^(?:|.*\/)snmp_([^_]+)_juniper$", sys.argv[0])
host = match.group(1)
request = match.group(2)
match = re.search("^([^:]+):(\d+)$", host)
if match is not None:
host = match.group(1)
port = match.group(2)
except:
pass
jnxOperatingTable = '1.3.6.1.4.1.2636.3.1.13.1.5'
jnxOperatingTemp = '1.3.6.1.4.1.2636.3.1.13.1.7'
jnxOperatingCPU = '1.3.6.1.4.1.2636.3.1.13.1.8'
jnxOperatingBuffer = '1.3.6.1.4.1.2636.3.1.13.1.11'
class JunOSSnmpClient(object):
def __init__(self, host, port, community):
self.hostname = host
self.transport = cmdgen.UdpTransportTarget((host, int(port)))
self.auth = cmdgen.CommunityData('test-agent', community)
self.gen = cmdgen.CommandGenerator()
def get_devices(self):
errorIndication, errorStatus, errorIndex, varBindTable = self.gen.bulkCmd(
self.auth,
self.transport,
0, 20,
jnxOperatingTable)
# ignoreNonIncreasingOids=True) # only available with pysnmp >= 4.2.4 (?)
if errorIndication:
logging.error("SNMP bulkCmd for devices failed: %s, %s, %s" % (errorIndication, errorStatus, errorIndex))
return {}
devices = {}
for row in varBindTable:
for name, value in row:
if not str(name).startswith(jnxOperatingTable):
continue
if 'Routing Engine' in str(value):
devices[str(name)[len(jnxOperatingTable):]] = re.sub("[^\w]", '_', str(value).replace(' Routing Engine', ''))
return devices
def get_one(self, prefix_oid, suffix):
oid = prefix_oid + suffix
errorIndication, errorStatus, errorIndex, varBindTable = self.gen.getCmd(
self.auth,
self.transport,
oid)
if errorIndication:
logging.error("SNMP getCmd for %s failed: %s, %s, %s" % (oid, errorIndication, errorStatus, errorIndex))
return None
return int(varBindTable[0][1])
def get_data(self):
devs = self.get_devices()
return {
'temp': dict([(name, self.get_one(jnxOperatingTemp, suffix)) for suffix, name in devs.iteritems()]),
'cpu': dict([(name, self.get_one(jnxOperatingCPU, suffix)) for suffix, name in devs.iteritems()]),
'buffer': dict([(name, self.get_one(jnxOperatingBuffer, suffix)) for suffix, name in devs.iteritems()]),
}
def print_config(self):
devices = self.get_devices()
data_def = [
('temp', self.hostname, 'System temperature', '--base 1000', 'System temperature in C', 'system'),
('cpu', self.hostname, 'CPU usage', '--base 1000 -l 0 --upper-limit 100', 'CPU usage in %', 'system'),
('buffer', self.hostname, 'Buffer usage', '--base 1000 -l 0 --upper-limit 100', 'Buffer usage in %', 'system'),
]
for datarow, hostname, title, args, vlabel, category in data_def:
print """multigraph juniper_{datarow}
host_name {hostname}
graph_title {title}
graph_vlabel {vlabel}
graph_args {args}
graph_category {category}
graph_info {title}""".format(datarow=datarow, hostname=hostname, title=title, args=args, vlabel=vlabel, category=category)
for suffix, node in devices.iteritems():
ident = "%s_%s" % (datarow, node)
print """{label}.info {title} on {node}
{label}.label {node}
{label}.type GAUGE
{label}.min 0""".format(title=title, label=ident, node=node)
def execute(self):
data = self.get_data()
for pre, values in data.iteritems():
print "multigraph juniper_%s" % pre
for node, value in values.iteritems():
print "%s_%s.value %s" % (pre, node, value)
c = JunOSSnmpClient(host, port, community)
if "snmpconf" in sys.argv[1:]:
print "require 1.3.6.1.4.1.2636.3.1.13.1.5"
sys.exit(0)
else:
if not (host and port and community):
print "# Bad configuration. Cannot run with Host=%s, port=%s and community=%s" % (host, port, community)
sys.exit(1)
if "config" in sys.argv[1:]:
c.print_config()
else:
c.execute()
# for Munin Plugin Gallery
# graph_category network

229
plugins/router/snmp__juniper_spu Executable file
View file

@ -0,0 +1,229 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright (C) 2014 Johann Schmitz <johann@j-schmitz.net>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Library General Public License as published by
# the Free Software Foundation; version 2 only
#
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
"""
=head1 NAME
snmp__juniper_spu - Network monitoring plugin for the SPU's in Juniper firewalls.
=head1 CONFIGURATION
Make sure your Juniper device is accessible via SNMP (e.g. via snmpwalk) and the munin-node
has been configured correctly.
=head1 MAGIC MARKERS
#%# family=snmpauto
#%# capabilities=snmpconf
=head1 VERSION
0.0.1
=head1 BUGS
Open a ticket at https://github.com/ercpe/contrib if you find one.
=head1 AUTHOR
Johann Schmitz <johann@j-schmitz.net>
=head1 LICENSE
GPLv2
=cut
"""
import re
import sys
import os
import logging
from pysnmp.entity.rfc3413.oneliner import cmdgen
host = None
port = os.getenv('port', 161)
community = os.getenv('community', "public")
debug = bool(os.getenv('MUNIN_DEBUG', os.getenv('DEBUG', 0)))
if debug:
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(levelname)-7s %(message)s')
try:
match = re.search("^(?:|.*\/)snmp_([^_]+)_juniper_spu$", sys.argv[0])
host = match.group(1)
request = match.group(2)
match = re.search("^([^:]+):(\d+)$", host)
if match is not None:
host = match.group(1)
port = match.group(2)
except:
pass
jnxJsSPUMonitoringObjectsTable = '1.3.6.1.4.1.2636.3.39.1.12.1.1'
#jnxJsSPUMonitoringIndex = jnxJsSPUMonitoringObjectsTable + '.1.1'
#jnxJsSPUMonitoringFPCIndex = jnxJsSPUMonitoringObjectsTable + '.1.2'
#jnxJsSPUMonitoringSPUIndex = jnxJsSPUMonitoringObjectsTable + '.1.3'
#jnxJsSPUMonitoringCPUUsage = jnxJsSPUMonitoringObjectsTable + '.1.4'
#jnxJsSPUMonitoringMemoryUsage = jnxJsSPUMonitoringObjectsTable + '.1.5'
jnxJsSPUMonitoringCurrentFlowSession = jnxJsSPUMonitoringObjectsTable + '.1.6'
jnxJsSPUMonitoringMaxFlowSession = jnxJsSPUMonitoringObjectsTable + '.1.7'
jnxJsSPUMonitoringCurrentCPSession = jnxJsSPUMonitoringObjectsTable + '.1.8'
jnxJsSPUMonitoringMaxCPSession = jnxJsSPUMonitoringObjectsTable + '.1.9'
#jnxJsSPUMonitoringNodeIndex = jnxJsSPUMonitoringObjectsTable + '.1.10'
jnxJsSPUMonitoringNodeDescr = jnxJsSPUMonitoringObjectsTable + '.1.11'
jnxJsSPUMonitoringFlowSessIPv4 = jnxJsSPUMonitoringObjectsTable + '.1.12'
jnxJsSPUMonitoringFlowSessIPv6 = jnxJsSPUMonitoringObjectsTable + '.1.13'
jnxJsSPUMonitoringCPSessIPv4 = jnxJsSPUMonitoringObjectsTable + '.1.14'
jnxJsSPUMonitoringCPSessIPv6 = jnxJsSPUMonitoringObjectsTable + '.1.15'
class JunOSSnmpClient(object):
def __init__(self, host, port, community):
self.hostname = host
self.transport = cmdgen.UdpTransportTarget((host, int(port)))
self.auth = cmdgen.CommunityData('test-agent', community)
self.gen = cmdgen.CommandGenerator()
def get_data(self):
errorIndication, errorStatus, errorIndex, varBindTable = self.gen.bulkCmd(
self.auth,
self.transport,
0, 10,
jnxJsSPUMonitoringObjectsTable)
# ignoreNonIncreasingOids=True) # only available with pysnmp >= 4.2.4 (?) and broken anyway
if errorIndication:
logging.error("SNMP bulkCmd for devices failed: %s, %s, %s" % (errorIndication, errorStatus, errorIndex))
return {}
devices = {}
values = {}
for row in varBindTable:
for name, value in row:
if not str(name).startswith(jnxJsSPUMonitoringObjectsTable):
continue
oid = str(name)
nodeid = oid[oid.rindex('.'):]
idx = oid[len(jnxJsSPUMonitoringObjectsTable)+3:]
idx = idx[:idx.index('.')]
if oid.startswith(jnxJsSPUMonitoringNodeDescr):
devices[nodeid] = str(value)
continue
values[oid] = int(value)
return devices, values
def print_config(self):
devices, data = self.get_data()
data_def = [
('flow', self.hostname, 'Flow sessions', '--base 1000', '# of sessions', jnxJsSPUMonitoringMaxFlowSession),
('cp', self.hostname, 'Central point sessions', '--base 1000', '# of sessions', jnxJsSPUMonitoringMaxCPSession),
]
for datarow, hostname, title, args, vlabel, max_prefix in data_def:
print """multigraph juniper_{datarow}
host_name {hostname}
graph_title {title}
graph_vlabel {vlabel}
graph_args {args}
graph_category network
graph_info {title}""".format(datarow=datarow, hostname=hostname, title=title, args=args, vlabel=vlabel)
for suffix, node in devices.iteritems():
ident = "%s_%s" % (datarow, node)
print """{label}.info {title} on {node}
{label}.label {node}
{label}.type GAUGE
{label}.max {max}""".format(title=title, label=ident, node=node, max=data.get(max_prefix + suffix))
for suffix, node in devices.iteritems():
print """
multigraph juniper_{datarow}.{node}
host_name {hostname}
graph_title {title} on {node}
graph_vlabel {vlabel}
graph_args {args}
graph_category network
graph_info {title}
{datarow}V4.info Current IPv4 {datarow} sessions
{datarow}V4.label IPv4
{datarow}V4.draw AREASTACK
{datarow}V4.type GAUGE
{datarow}V6.info Current IPv6 {datarow} sessions
{datarow}V6.label IPv6
{datarow}V6.draw AREASTACK
{datarow}V6.type GAUGE
{datarow}Current.info Current total {datarow} sessions
{datarow}Current.label Total
{datarow}Current.draw LINE1
{datarow}Current.type GAUGE
{datarow}Current.colour 000000
{datarow}Max.info Max. {datarow} sessions supported by the device(s)
{datarow}Max.label Max
{datarow}Max.draw LINE0
{datarow}Max.type GAUGE
""".format(datarow=datarow, hostname=hostname, title=title, args=args, vlabel=vlabel, node=node)
def execute(self):
devices, data = self.get_data()
print "multigraph juniper_flow"
for suffix, node in devices.iteritems():
print "flow_%s.value %s" % (node, data.get(jnxJsSPUMonitoringCurrentFlowSession + suffix, 0))
for suffix, node in devices.iteritems():
print "multigraph juniper_flow.%s" % node
print "flowV4.value %s" % data.get(jnxJsSPUMonitoringFlowSessIPv4 + suffix, 0)
print "flowV6.value %s" % data.get(jnxJsSPUMonitoringFlowSessIPv6 + suffix, 0)
print "flowCurrent.value %s" % data.get(jnxJsSPUMonitoringCurrentFlowSession + suffix, 0)
print "flowMax.value %s" % data.get(jnxJsSPUMonitoringMaxFlowSession + suffix, 0)
print "multigraph juniper_cp"
for suffix, node in devices.iteritems():
print "cp_%s.value %s" % (node, data.get(jnxJsSPUMonitoringCurrentCPSession + suffix, 0))
for suffix, node in devices.iteritems():
print "multigraph juniper_cp.%s" % node
print "cpV4.value %s" % data.get(jnxJsSPUMonitoringCPSessIPv4 + suffix, 0)
print "cpV6.value %s" % data.get(jnxJsSPUMonitoringCPSessIPv6 + suffix, 0)
print "cpCurrent.value %s" % data.get(jnxJsSPUMonitoringCurrentCPSession + suffix, 0)
print "cpMax.value %s" % data.get(jnxJsSPUMonitoringMaxCPSession + suffix, 0)
c = JunOSSnmpClient(host, port, community)
if "snmpconf" in sys.argv[1:]:
print "require %s" % (jnxJsSPUMonitoringObjectsTable, )
sys.exit(0)
else:
if not (host and port and community):
print "# Bad configuration. Cannot run with Host=%s, port=%s and community=%s" % (host, port, community)
sys.exit(1)
if "config" in sys.argv[1:]:
c.print_config()
else:
c.execute()