Projet

Général

Profil

Paste
Télécharger au format
Statistiques
| Branche: | Révision:

root / plugins / router / snmp__juniper @ 7cf2dda9

Historique | Voir | Annoter | Télécharger (5,86 ko)

1
#!/usr/bin/env python3
2
"""
3
=head1 NAME
4

    
5
snmp__juniper - Health monitoring plugin for 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
Copyright (C) 2014 Johann Schmitz <johann@j-schmitz.net>
23

    
24

    
25
=head1 LICENSE
26

    
27
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

    
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', None)
61

    
62
debug = bool(os.getenv('MUNIN_DEBUG', os.getenv('DEBUG', 0)))
63

    
64
if debug:
65
    logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(levelname)-7s %(message)s')
66

    
67
try:
68
    match = re.search(r"^(?:|.*/)snmp_([^_]+)_juniper$", 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

    
78
jnxOperatingTable = '1.3.6.1.4.1.2636.3.1.13.1.5'
79

    
80
jnxOperatingTemp = '1.3.6.1.4.1.2636.3.1.13.1.7'
81
jnxOperatingCPU = '1.3.6.1.4.1.2636.3.1.13.1.8'
82
jnxOperatingBuffer = '1.3.6.1.4.1.2636.3.1.13.1.11'
83

    
84

    
85
class JunOSSnmpClient(object):
86
    def __init__(self, host, port, community):
87
        self.hostname = host
88
        self.transport = cmdgen.UdpTransportTarget((host, int(port)))
89
        self.auth = cmdgen.CommunityData('test-agent', community)
90
        self.gen = cmdgen.CommandGenerator()
91

    
92
    def get_devices(self):
93
        errorIndication, errorStatus, errorIndex, varBindTable = self.gen.bulkCmd(
94
            self.auth,
95
            self.transport,
96
            0, 20,
97
            jnxOperatingTable)
98
        # the following line is only available with pysnmp >= 4.2.4 (?)
99
        # ignoreNonIncreasingOids=True)
100

    
101
        if errorIndication:
102
            logging.error("SNMP bulkCmd for devices failed: %s, %s, %s"
103
                          % (errorIndication, errorStatus, errorIndex))
104
            return {}
105

    
106
        devices = {}
107
        for row in varBindTable:
108
            for name, value in row:
109
                if not str(name).startswith(jnxOperatingTable):
110
                    continue
111

    
112
                if 'Routing Engine' in str(value):
113
                    devices[str(name)[len(jnxOperatingTable):]] = re.sub(
114
                        r"[^\w]", '_', str(value).replace(' Routing Engine', ''))
115
        return devices
116

    
117
    def get_one(self, prefix_oid, suffix):
118
        oid = prefix_oid + suffix
119
        errorIndication, errorStatus, errorIndex, varBindTable = self.gen.getCmd(
120
            self.auth,
121
            self.transport,
122
            oid)
123

    
124
        if errorIndication:
125
            logging.error("SNMP getCmd for %s failed: %s, %s, %s"
126
                          % (oid, errorIndication, errorStatus, errorIndex))
127
            return None
128

    
129
        return int(varBindTable[0][1])
130

    
131
    def get_data(self):
132
        devs = self.get_devices()
133

    
134
        return {
135
            'temp': dict([(name, self.get_one(jnxOperatingTemp, suffix))
136
                          for suffix, name in devs.items()]),
137
            'cpu': dict([(name, self.get_one(jnxOperatingCPU, suffix))
138
                         for suffix, name in devs.items()]),
139
            'buffer': dict([(name, self.get_one(jnxOperatingBuffer, suffix))
140
                            for suffix, name in devs.items()]),
141
        }
142

    
143
    def print_config(self):
144
        devices = self.get_devices()
145

    
146
        data_def = [
147
            ('temp', self.hostname, 'System temperature', '--base 1000',
148
             'System temperature in C'),
149
            ('cpu', self.hostname, 'CPU usage', '--base 1000 -l 0 --upper-limit 100',
150
             'CPU usage in %'),
151
            ('buffer', self.hostname, 'Buffer usage', '--base 1000 -l 0 --upper-limit 100',
152
             'Buffer usage in %'),
153
        ]
154

    
155
        for datarow, hostname, title, args, vlabel in data_def:
156
            print("""multigraph juniper_{datarow}
157
host_name {hostname}
158
graph_title {title}
159
graph_vlabel {vlabel}
160
graph_args {args}
161
graph_category fw
162
graph_info {title}""".format(datarow=datarow, hostname=hostname, title=title, args=args,
163
                             vlabel=vlabel))
164

    
165
            for suffix, node in devices.items():
166
                ident = "%s_%s" % (datarow, node)
167
                print("""{label}.info {title} on {node}
168
{label}.label {node}
169
{label}.type GAUGE
170
{label}.min 0""".format(title=title, label=ident, node=node))
171

    
172
    def execute(self):
173
        data = self.get_data()
174

    
175
        for pre, values in data.items():
176
            print("multigraph juniper_%s" % pre)
177
            for node, value in values.items():
178
                print("%s_%s.value %s" % (pre, node, value))
179

    
180

    
181
c = JunOSSnmpClient(host, port, community)
182

    
183

    
184
if "snmpconf" in sys.argv[1:]:
185
    print("require 1.3.6.1.4.1.2636.3.1.13.1.5")
186
    sys.exit(0)
187
else:
188
    if not (host and port and community):
189
        print("# Bad configuration. Cannot run with Host=%s, port=%s and community=%s"
190
              % (host, port, community), file=sys.stderr)
191
        sys.exit(1)
192

    
193
    if "config" in sys.argv[1:]:
194
        c.print_config()
195
    else:
196
        c.execute()