root / plugins / router / snmp__juniper_spu @ a7139bca
Historique | Voir | Annoter | Télécharger (7,41 ko)
| 1 | a7139bca | Lars Kruse | #!/usr/bin/env python |
|---|---|---|---|
| 2 | f52a7ea9 | Johann Schmitz | # -*- coding: utf-8 -*- |
| 3 | |||
| 4 | # Copyright (C) 2014 Johann Schmitz <johann@j-schmitz.net> |
||
| 5 | # |
||
| 6 | # This program is free software; you can redistribute it and/or modify |
||
| 7 | # it under the terms of the GNU Library General Public License as published by |
||
| 8 | # the Free Software Foundation; version 2 only |
||
| 9 | # |
||
| 10 | # This program is distributed in the hope that it will be useful, |
||
| 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
| 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
| 13 | # GNU Library General Public License for more details. |
||
| 14 | # |
||
| 15 | # You should have received a copy of the GNU Library General Public License |
||
| 16 | # along with this program; if not, write to the Free Software |
||
| 17 | # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
||
| 18 | # |
||
| 19 | |||
| 20 | """ |
||
| 21 | =head1 NAME |
||
| 22 | |||
| 23 | snmp__juniper_spu - Network monitoring plugin for the SPU's in Juniper firewalls. |
||
| 24 | |||
| 25 | =head1 CONFIGURATION |
||
| 26 | |||
| 27 | Make sure your Juniper device is accessible via SNMP (e.g. via snmpwalk) and the munin-node |
||
| 28 | has been configured correctly. |
||
| 29 | |||
| 30 | =head1 MAGIC MARKERS |
||
| 31 | |||
| 32 | #%# family=snmpauto |
||
| 33 | #%# capabilities=snmpconf |
||
| 34 | |||
| 35 | =head1 VERSION |
||
| 36 | |||
| 37 | 0.0.1 |
||
| 38 | |||
| 39 | =head1 BUGS |
||
| 40 | |||
| 41 | Open a ticket at https://github.com/ercpe/contrib if you find one. |
||
| 42 | |||
| 43 | =head1 AUTHOR |
||
| 44 | |||
| 45 | Johann Schmitz <johann@j-schmitz.net> |
||
| 46 | |||
| 47 | =head1 LICENSE |
||
| 48 | |||
| 49 | GPLv2 |
||
| 50 | |||
| 51 | =cut |
||
| 52 | """ |
||
| 53 | |||
| 54 | import re |
||
| 55 | import sys |
||
| 56 | import os |
||
| 57 | import logging |
||
| 58 | |||
| 59 | from pysnmp.entity.rfc3413.oneliner import cmdgen |
||
| 60 | |||
| 61 | host = None |
||
| 62 | port = os.getenv('port', 161)
|
||
| 63 | community = os.getenv('community', "public")
|
||
| 64 | |||
| 65 | debug = bool(os.getenv('MUNIN_DEBUG', os.getenv('DEBUG', 0)))
|
||
| 66 | |||
| 67 | if debug: |
||
| 68 | logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(levelname)-7s %(message)s') |
||
| 69 | |||
| 70 | try: |
||
| 71 | match = re.search("^(?:|.*\/)snmp_([^_]+)_juniper_spu$", sys.argv[0])
|
||
| 72 | host = match.group(1) |
||
| 73 | request = match.group(2) |
||
| 74 | match = re.search("^([^:]+):(\d+)$", host)
|
||
| 75 | if match is not None: |
||
| 76 | host = match.group(1) |
||
| 77 | port = match.group(2) |
||
| 78 | except: |
||
| 79 | pass |
||
| 80 | |||
| 81 | jnxJsSPUMonitoringObjectsTable = '1.3.6.1.4.1.2636.3.39.1.12.1.1' |
||
| 82 | #jnxJsSPUMonitoringIndex = jnxJsSPUMonitoringObjectsTable + '.1.1' |
||
| 83 | #jnxJsSPUMonitoringFPCIndex = jnxJsSPUMonitoringObjectsTable + '.1.2' |
||
| 84 | #jnxJsSPUMonitoringSPUIndex = jnxJsSPUMonitoringObjectsTable + '.1.3' |
||
| 85 | #jnxJsSPUMonitoringCPUUsage = jnxJsSPUMonitoringObjectsTable + '.1.4' |
||
| 86 | #jnxJsSPUMonitoringMemoryUsage = jnxJsSPUMonitoringObjectsTable + '.1.5' |
||
| 87 | jnxJsSPUMonitoringCurrentFlowSession = jnxJsSPUMonitoringObjectsTable + '.1.6' |
||
| 88 | jnxJsSPUMonitoringMaxFlowSession = jnxJsSPUMonitoringObjectsTable + '.1.7' |
||
| 89 | jnxJsSPUMonitoringCurrentCPSession = jnxJsSPUMonitoringObjectsTable + '.1.8' |
||
| 90 | jnxJsSPUMonitoringMaxCPSession = jnxJsSPUMonitoringObjectsTable + '.1.9' |
||
| 91 | #jnxJsSPUMonitoringNodeIndex = jnxJsSPUMonitoringObjectsTable + '.1.10' |
||
| 92 | jnxJsSPUMonitoringNodeDescr = jnxJsSPUMonitoringObjectsTable + '.1.11' |
||
| 93 | jnxJsSPUMonitoringFlowSessIPv4 = jnxJsSPUMonitoringObjectsTable + '.1.12' |
||
| 94 | jnxJsSPUMonitoringFlowSessIPv6 = jnxJsSPUMonitoringObjectsTable + '.1.13' |
||
| 95 | jnxJsSPUMonitoringCPSessIPv4 = jnxJsSPUMonitoringObjectsTable + '.1.14' |
||
| 96 | jnxJsSPUMonitoringCPSessIPv6 = jnxJsSPUMonitoringObjectsTable + '.1.15' |
||
| 97 | |||
| 98 | class JunOSSnmpClient(object): |
||
| 99 | |||
| 100 | def __init__(self, host, port, community): |
||
| 101 | self.hostname = host |
||
| 102 | self.transport = cmdgen.UdpTransportTarget((host, int(port))) |
||
| 103 | self.auth = cmdgen.CommunityData('test-agent', community)
|
||
| 104 | self.gen = cmdgen.CommandGenerator() |
||
| 105 | |||
| 106 | def get_data(self): |
||
| 107 | errorIndication, errorStatus, errorIndex, varBindTable = self.gen.bulkCmd( |
||
| 108 | self.auth, |
||
| 109 | self.transport, |
||
| 110 | 0, 10, |
||
| 111 | jnxJsSPUMonitoringObjectsTable) |
||
| 112 | # ignoreNonIncreasingOids=True) # only available with pysnmp >= 4.2.4 (?) and broken anyway |
||
| 113 | |||
| 114 | if errorIndication: |
||
| 115 | logging.error("SNMP bulkCmd for devices failed: %s, %s, %s" % (errorIndication, errorStatus, errorIndex))
|
||
| 116 | return {}
|
||
| 117 | |||
| 118 | devices = {}
|
||
| 119 | values = {}
|
||
| 120 | for row in varBindTable: |
||
| 121 | for name, value in row: |
||
| 122 | if not str(name).startswith(jnxJsSPUMonitoringObjectsTable): |
||
| 123 | continue |
||
| 124 | |||
| 125 | oid = str(name) |
||
| 126 | |||
| 127 | nodeid = oid[oid.rindex('.'):]
|
||
| 128 | |||
| 129 | idx = oid[len(jnxJsSPUMonitoringObjectsTable)+3:] |
||
| 130 | idx = idx[:idx.index('.')]
|
||
| 131 | |||
| 132 | if oid.startswith(jnxJsSPUMonitoringNodeDescr): |
||
| 133 | devices[nodeid] = str(value) |
||
| 134 | continue |
||
| 135 | |||
| 136 | values[oid] = int(value) |
||
| 137 | return devices, values |
||
| 138 | |||
| 139 | def print_config(self): |
||
| 140 | devices, data = self.get_data() |
||
| 141 | |||
| 142 | data_def = [ |
||
| 143 | ('flow', self.hostname, 'Flow sessions', '--base 1000', '# of sessions', jnxJsSPUMonitoringMaxFlowSession),
|
||
| 144 | ('cp', self.hostname, 'Central point sessions', '--base 1000', '# of sessions', jnxJsSPUMonitoringMaxCPSession),
|
||
| 145 | ] |
||
| 146 | |||
| 147 | for datarow, hostname, title, args, vlabel, max_prefix in data_def: |
||
| 148 | print """multigraph juniper_{datarow}
|
||
| 149 | host_name {hostname}
|
||
| 150 | graph_title {title}
|
||
| 151 | graph_vlabel {vlabel}
|
||
| 152 | graph_args {args}
|
||
| 153 | graph_category network |
||
| 154 | graph_info {title}""".format(datarow=datarow, hostname=hostname, title=title, args=args, vlabel=vlabel)
|
||
| 155 | |||
| 156 | for suffix, node in devices.iteritems(): |
||
| 157 | ident = "%s_%s" % (datarow, node) |
||
| 158 | print """{label}.info {title} on {node}
|
||
| 159 | {label}.label {node}
|
||
| 160 | {label}.type GAUGE
|
||
| 161 | {label}.max {max}""".format(title=title, label=ident, node=node, max=data.get(max_prefix + suffix))
|
||
| 162 | |||
| 163 | for suffix, node in devices.iteritems(): |
||
| 164 | print """ |
||
| 165 | multigraph juniper_{datarow}.{node}
|
||
| 166 | host_name {hostname}
|
||
| 167 | 785dab37 | Johann Schmitz | graph_title {title} on {node}
|
| 168 | f52a7ea9 | Johann Schmitz | graph_vlabel {vlabel}
|
| 169 | graph_args {args}
|
||
| 170 | graph_category network |
||
| 171 | graph_info {title}
|
||
| 172 | {datarow}V4.info Current IPv4 {datarow} sessions
|
||
| 173 | {datarow}V4.label IPv4
|
||
| 174 | {datarow}V4.draw AREASTACK
|
||
| 175 | {datarow}V4.type GAUGE
|
||
| 176 | {datarow}V6.info Current IPv6 {datarow} sessions
|
||
| 177 | {datarow}V6.label IPv6
|
||
| 178 | {datarow}V6.draw AREASTACK
|
||
| 179 | {datarow}V6.type GAUGE
|
||
| 180 | {datarow}Current.info Current total {datarow} sessions
|
||
| 181 | {datarow}Current.label Total
|
||
| 182 | {datarow}Current.draw LINE1
|
||
| 183 | {datarow}Current.type GAUGE
|
||
| 184 | {datarow}Current.colour 000000
|
||
| 185 | {datarow}Max.info Max. {datarow} sessions supported by the device(s)
|
||
| 186 | {datarow}Max.label Max
|
||
| 187 | {datarow}Max.draw LINE0
|
||
| 188 | {datarow}Max.type GAUGE
|
||
| 189 | """.format(datarow=datarow, hostname=hostname, title=title, args=args, vlabel=vlabel, node=node) |
||
| 190 | |||
| 191 | def execute(self): |
||
| 192 | devices, data = self.get_data() |
||
| 193 | |||
| 194 | print "multigraph juniper_flow" |
||
| 195 | for suffix, node in devices.iteritems(): |
||
| 196 | print "flow_%s.value %s" % (node, data.get(jnxJsSPUMonitoringCurrentFlowSession + suffix, 0)) |
||
| 197 | |||
| 198 | ae30c597 | Johann Schmitz | for suffix, node in devices.iteritems(): |
| 199 | f52a7ea9 | Johann Schmitz | print "multigraph juniper_flow.%s" % node |
| 200 | print "flowV4.value %s" % data.get(jnxJsSPUMonitoringFlowSessIPv4 + suffix, 0) |
||
| 201 | print "flowV6.value %s" % data.get(jnxJsSPUMonitoringFlowSessIPv6 + suffix, 0) |
||
| 202 | print "flowCurrent.value %s" % data.get(jnxJsSPUMonitoringCurrentFlowSession + suffix, 0) |
||
| 203 | print "flowMax.value %s" % data.get(jnxJsSPUMonitoringMaxFlowSession + suffix, 0) |
||
| 204 | |||
| 205 | print "multigraph juniper_cp" |
||
| 206 | for suffix, node in devices.iteritems(): |
||
| 207 | print "cp_%s.value %s" % (node, data.get(jnxJsSPUMonitoringCurrentCPSession + suffix, 0)) |
||
| 208 | |||
| 209 | ae30c597 | Johann Schmitz | for suffix, node in devices.iteritems(): |
| 210 | f52a7ea9 | Johann Schmitz | print "multigraph juniper_cp.%s" % node |
| 211 | print "cpV4.value %s" % data.get(jnxJsSPUMonitoringCPSessIPv4 + suffix, 0) |
||
| 212 | print "cpV6.value %s" % data.get(jnxJsSPUMonitoringCPSessIPv6 + suffix, 0) |
||
| 213 | print "cpCurrent.value %s" % data.get(jnxJsSPUMonitoringCurrentCPSession + suffix, 0) |
||
| 214 | print "cpMax.value %s" % data.get(jnxJsSPUMonitoringMaxCPSession + suffix, 0) |
||
| 215 | |||
| 216 | c = JunOSSnmpClient(host, port, community) |
||
| 217 | |||
| 218 | if "snmpconf" in sys.argv[1:]: |
||
| 219 | print "require %s" % (jnxJsSPUMonitoringObjectsTable, ) |
||
| 220 | sys.exit(0) |
||
| 221 | else: |
||
| 222 | if not (host and port and community): |
||
| 223 | print "# Bad configuration. Cannot run with Host=%s, port=%s and community=%s" % (host, port, community) |
||
| 224 | sys.exit(1) |
||
| 225 | 17f78427 | Lars Kruse | |
| 226 | f52a7ea9 | Johann Schmitz | if "config" in sys.argv[1:]: |
| 227 | c.print_config() |
||
| 228 | else: |
||
| 229 | c.execute() |
