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