2 # -*- encoding: utf-8; py-indent-offset: 4 -*-
3 # +------------------------------------------------------------------+
4 # | ____ _ _ __ __ _ __ |
5 # | / ___| |__ ___ ___| | __ | \/ | |/ / |
6 # | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
7 # | | |___| | | | __/ (__| < | | | | . \ |
8 # | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
10 # | Copyright Mathias Kettner 2016 mk@mathias-kettner.de |
11 # +------------------------------------------------------------------+
13 # This file is part of Check_MK.
14 # The official homepage is at http://mathias-kettner.de/check_mk.
16 # check_mk is free software; you can redistribute it and/or modify it
17 # under the terms of the GNU General Public License as published by
18 # the Free Software Foundation in version 2. check_mk is distributed
19 # in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
20 # out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
21 # PARTICULAR PURPOSE. See the GNU General Public License for more de-
22 # tails. You should have received a copy of the GNU General Public
23 # License along with GNU Make; see the file COPYING. If not, write
24 # to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
25 # Boston, MA 02110-1301 USA.
27 # .1.3.6.1.4.1.1991.1.1.3.3.6.1.1.1 41.4960 C: Normal
28 # .1.3.6.1.4.1.1991.1.1.3.3.6.1.1.2 50.9531 C: Normal
29 # .1.3.6.1.4.1.1991.1.1.3.3.6.1.1.65 49.8007 C: Normal
31 # .1.3.6.1.4.1.1991.1.1.3.3.6.1.2.1 007.9643 dBm: Normal
32 # .1.3.6.1.4.1.1991.1.1.3.3.6.1.2.2 007.5898 dBm: Normal
33 # .1.3.6.1.4.1.1991.1.1.3.3.6.1.2.65 006.9644 dBm: Normal
35 # .1.3.6.1.4.1.1991.1.1.3.3.6.1.3.1 000.6744 dBm: Normal
36 # .1.3.6.1.4.1.1991.1.1.3.3.6.1.3.2 -023.0102 dBm: Low-Alarm
37 # .1.3.6.1.4.1.1991.1.1.3.3.6.1.3.65 -015.6863 dBm: Low-Alarm
40 # .1.3.6.1.4.1.1991.1.1.3.3.9.1.1.1 100GBASE-LR4 CFP2
41 # .1.3.6.1.4.1.1991.1.1.3.3.9.1.1.2 100GBASE-LR4 CFP2
42 # .1.3.6.1.4.1.1991.1.1.3.3.9.1.1.65 100GBASE-LR4 CFP2
44 # .1.3.6.1.4.1.1991.1.1.3.3.9.1.4.1 12-1234567-01
45 # .1.3.6.1.4.1.1991.1.1.3.3.9.1.4.2 12-1234567-01
46 # .1.3.6.1.4.1.1991.1.1.3.3.9.1.4.65 12-1234567-01
48 # .1.3.6.1.4.1.1991.1.1.3.3.9.1.5.1 XXX00000X00X00X
49 # .1.3.6.1.4.1.1991.1.1.3.3.9.1.5.2 XXX000000000XX0
50 # .1.3.6.1.4.1.1991.1.1.3.3.9.1.5.65 XXX0000000000X
53 # .1.3.6.1.4.1.1991.1.1.3.3.10.1.2.1.1 41.5000 C: Normal
54 # .1.3.6.1.4.1.1991.1.1.3.3.10.1.2.1.2 41.4960 C: Normal
55 # .1.3.6.1.4.1.1991.1.1.3.3.10.1.2.1.3 41.4921 C: Normal
56 # .1.3.6.1.4.1.1991.1.1.3.3.10.1.2.1.4 41.5039 C: Normal
57 # .1.3.6.1.4.1.1991.1.1.3.3.10.1.2.2.1 50.9687 C: Normal
58 # .1.3.6.1.4.1.1991.1.1.3.3.10.1.2.2.2 50.9843 C: Normal
59 # .1.3.6.1.4.1.1991.1.1.3.3.10.1.2.2.3 50.9570 C: Normal
60 # .1.3.6.1.4.1.1991.1.1.3.3.10.1.2.2.4 50.9570 C: Normal
61 # .1.3.6.1.4.1.1991.1.1.3.3.10.1.2.65.1 49.7539 C: Normal
62 # .1.3.6.1.4.1.1991.1.1.3.3.10.1.2.65.2 49.7734 C: Normal
63 # .1.3.6.1.4.1.1991.1.1.3.3.10.1.2.65.3 49.7578 C: Normal
64 # .1.3.6.1.4.1.1991.1.1.3.3.10.1.2.65.4 49.7851 C: Normal
66 # .1.3.6.1.4.1.1991.1.1.3.3.10.1.3.1.1 001.9072 dBm: Normal
67 # .1.3.6.1.4.1.1991.1.1.3.3.10.1.3.1.2 002.5098 dBm: Normal
68 # .1.3.6.1.4.1.1991.1.1.3.3.10.1.3.1.3 001.3392 dBm: Normal
69 # .1.3.6.1.4.1.1991.1.1.3.3.10.1.3.1.4 001.9473 dBm: Normal
70 # .1.3.6.1.4.1.1991.1.1.3.3.10.1.3.2.1 001.5615 dBm: Normal
71 # .1.3.6.1.4.1.1991.1.1.3.3.10.1.3.2.2 001.4924 dBm: Normal
72 # .1.3.6.1.4.1.1991.1.1.3.3.10.1.3.2.3 001.6840 dBm: Normal
73 # .1.3.6.1.4.1.1991.1.1.3.3.10.1.3.2.4 001.5421 dBm: Normal
74 # .1.3.6.1.4.1.1991.1.1.3.3.10.1.3.65.1 000.0543 dBm: Normal
75 # .1.3.6.1.4.1.1991.1.1.3.3.10.1.3.65.2 000.6069 dBm: Normal
76 # .1.3.6.1.4.1.1991.1.1.3.3.10.1.3.65.3 001.6307 dBm: Normal
77 # .1.3.6.1.4.1.1991.1.1.3.3.10.1.3.65.4 001.3152 dBm: Normal
79 # .1.3.6.1.4.1.1991.1.1.3.3.10.1.4.1.1 -004.9935 dBm: Normal
80 # .1.3.6.1.4.1.1991.1.1.3.3.10.1.4.1.2 -005.4030 dBm: Normal
81 # .1.3.6.1.4.1.1991.1.1.3.3.10.1.4.1.3 -005.3017 dBm: Normal
82 # .1.3.6.1.4.1.1991.1.1.3.3.10.1.4.1.4 -005.6479 dBm: Normal
83 # .1.3.6.1.4.1.1991.1.1.3.3.10.1.4.2.1 -026.0205 dBm: Low-Alarm
84 # .1.3.6.1.4.1.1991.1.1.3.3.10.1.4.2.2 -214.3647 dBm: Low-Alarm
85 # .1.3.6.1.4.1.1991.1.1.3.3.10.1.4.2.3 -214.3647 dBm: Low-Alarm
86 # .1.3.6.1.4.1.1991.1.1.3.3.10.1.4.2.4 -024.9485 dBm: Low-Alarm
87 # .1.3.6.1.4.1.1991.1.1.3.3.10.1.4.65.1 -021.4266 dBm: Low-Alarm
88 # .1.3.6.1.4.1.1991.1.1.3.3.10.1.4.65.2 -020.3621 dBm: Low-Alarm
89 # .1.3.6.1.4.1.1991.1.1.3.3.10.1.4.65.3 -022.4412 dBm: Low-Alarm
90 # .1.3.6.1.4.1.1991.1.1.3.3.10.1.4.65.4 -021.8045 dBm: Low-Alarm
99 '7': 'lower layer down',
105 def parse_brocade_optical(info
):
106 def parse_value(value_string
):
107 if value_string
== 'N/A' or value_string
.lower() == "not supported":
110 val
, _unit
, status
= value_string
.split()
111 return float(val
), status
115 if_info
, if_data
, if_ids
, lanes
= info
118 for temp
, tx_light
, rx_light
, if_id
in if_data
:
121 'temp': parse_value(temp
),
122 'tx_light': parse_value(tx_light
),
123 'rx_light': parse_value(rx_light
),
126 for if_id
, if_descr
, if_type
, if_operstatus
in if_info
:
128 parsed
[if_id
].update({
129 'port_type': if_type
,
130 'description': if_descr
,
131 'operational_status': if_operstatus
134 # add informational values
135 for media_type
, part
, serial
, if_id
in if_ids
:
137 parsed
[if_id
].update({'type': media_type
, 'part': part
, 'serial': serial
})
140 for temp
, tx_light
, rx_light
, lane
in lanes
:
141 if_id
, lane
= lane
.split('.')
143 parsed
[if_id
].setdefault('lanes', {})\
144 .setdefault(int(lane
), {
145 'temp': parse_value(temp
),
146 'tx_light': parse_value(tx_light
),
147 'rx_light': parse_value(rx_light
),
152 def inventory_brocade_optical(parsed
):
153 settings
= host_extra_conf_merged(host_name(), inventory_if_rules
)
154 porttypes
= set(settings
.get('porttypes', if_inventory_porttypes
))
155 portstates
= settings
.get('portstates', if_inventory_portstates
)
156 match_desc
= settings
.get('match_desc')
159 pad_width
= max([int(len(key
)) for key
in parsed
.keys()])
163 def port_match(name
, what
):
167 if regex(r
).match(name
):
171 for key
, entry
in parsed
.iteritems():
172 if (entry
['port_type'] in porttypes
and entry
['operational_status'] in portstates
and
173 port_match(entry
['description'], match_desc
)):
174 # if pad_width == 0 then "0" * -X == ""
175 yield "0" * (pad_width
- len(key
)) + key
, {}
178 def check_brocade_optical(item
, params
, parsed
):
179 def nagios_state(entry
, key
):
181 if reading
[0] is None:
183 elif params
.get(key
, False):
184 state
= reading
[1].lower()
185 if state
== "normal":
187 if state
.endswith("warn"):
192 def infotext(reading
, title
, unit
):
193 if reading
[0] < -214748.0:
196 reading_text
= "%.1f %s" % (reading
[0], unit
)
197 return "%s %s (%s)" % (title
, reading_text
, reading
[1])
199 item
= item
.lstrip('0')
205 if 'serial' in iface
:
206 add_info
.append('S/N %s' % iface
['serial'])
208 add_info
.append('P/N %s' % iface
['part'])
210 oper_status
= iface
['operational_status']
211 oper_status_readable
= OPER_STATUS_MAP
.get(oper_status
, 'unknown[%s]' % oper_status
)
213 yield 0, '[%s] Operational %s' % (", ".join(add_info
), oper_status_readable
)
215 yield 0, 'Operational %s' % oper_status_readable
218 yield check_temperature(
221 "brocade_optical_%s" % item
,
222 dev_status
=nagios_state(iface
, 'temp'))
224 if 'tx_light' in iface
and iface
['tx_light'][0] is not None:
225 yield nagios_state(iface
, 'tx_light'), infotext(iface
['tx_light'], "TX Light", "dBm"),\
226 [("tx_light", iface
['tx_light'][0])]
228 if 'rx_light' in iface
and iface
['rx_light'][0] is not None:
229 yield nagios_state(iface
, 'rx_light'), infotext(iface
['rx_light'], "RX Light", "dBm"),\
230 [("rx_light", iface
['rx_light'][0])]
232 if 'lanes' in iface
and params
.get('lanes', False):
233 for num
, lane
in iface
['lanes'].iteritems():
234 state
, text
, perf
= check_temperature(
237 "brocade_optical_lane%d_%s" % (num
, item
),
238 dev_status
=nagios_state(lane
, 'temp'))
239 perf
= [("port_%s_%d" % (perf
[0][0], num
), perf
[0][1])]
241 yield state
, "Temperature (Lane %d) %s" % (num
, text
), perf
243 yield state
, None, perf
245 state
= nagios_state(lane
, 'tx_light')
248 infotext(iface
['tx_light'], "TX Light (Lane %d)" % num
, "dBm"),\
249 [("tx_light_%d" % num
, lane
['tx_light'][0])]
251 yield state
, None, [("tx_light_%d" % num
, lane
['tx_light'][0])]
253 state
= nagios_state(lane
, 'rx_light')
256 infotext(iface
['rx_light'], "RX Light (Lane %d)" % num
, "dBm"),\
257 [("rx_light_%d" % num
, lane
['rx_light'][0])]
259 yield state
, None, [("rx_light_%d" % num
, lane
['rx_light'][0])]
262 check_info
['brocade_optical'] = {
263 'parse_function': parse_brocade_optical
,
264 'check_function': check_brocade_optical
,
265 'inventory_function': inventory_brocade_optical
,
266 'service_description': "Interface %s Optical",
269 ".1.3.6.1.2.1.2.2.1",
277 ".1.3.6.1.4.1.1991.1.1.3.3.6.1",
285 ".1.3.6.1.4.1.1991.1.1.3.3.9.1",
293 ".1.3.6.1.4.1.1991.1.1.3.3.10.1",
295 2, # lane temperature
296 3, # lane TX light level
297 4, # lane RX light level
301 'snmp_scan_function': lambda oid
: oid(".1.3.6.1.2.1.1.2.0").startswith(".1.3.6.1.4.1.1991.1."),
302 'has_perfdata': True,
303 'group': "brocade_optical",
304 'includes': ["temperature.include", "if.include"],