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 #TODO Cleanup the whole status text mapping in
28 # ipmi_common.include, ipmi_sensors.include, ipmi
31 def ipmi_ignore_entry(name
, status_txt
, rules
):
32 if status_txt
is None:
34 ignored_sensors
= rules
.get("ignored_sensors", [])
35 ignored_sensorstates
= rules
.get("ignored_sensorstates", [])
36 for cmp_status
in ignored_sensorstates
:
37 if status_txt
.startswith(cmp_status
):
39 for e
in ignored_sensors
:
40 if name
.startswith(e
):
45 def check_ipmi_common(item
, params
, parsed
, what
, status_txt_mapping
):
49 if item
== "Summary" or item
== "Summary FreeIPMI":
50 return check_ipmi_common_summarized(params
, parsed
, status_txt_mapping
)
52 return check_ipmi_common_detailed(item
, params
, parsed
[item
], what
, status_txt_mapping
)
55 def ipmi_common_check_levels(sensorname
, val
, params
):
56 warn_texts
, crit_texts
= [], []
57 for this_sensorname
, levels
in params
.get("numerical_sensor_levels", []):
58 if this_sensorname
== sensorname
and levels
and val
is not None:
59 if levels
.get("lower"):
60 warn
, crit
= levels
["lower"]
63 "%s %s (warn/crit below %s/%s)" % (sensorname
, val
, warn
, crit
))
66 "%s %s (warn/crit below %s/%s)" % (sensorname
, val
, warn
, crit
))
67 if levels
.get("upper"):
68 warn
, crit
= levels
["upper"]
70 crit_texts
.append("%s %s (warn/crit at %s/%s)" % (sensorname
, val
, warn
, crit
))
72 warn_texts
.append("%s %s (warn/crit at %s/%s)" % (sensorname
, val
, warn
, crit
))
74 return warn_texts
, crit_texts
77 def check_ipmi_common_detailed(item
, params
, data
, what
, status_txt_mapping
):
80 status_txt
= data
["status_txt"]
81 crit_low
= data
["crit_low"]
82 warn_low
= data
["warn_low"]
83 warn_high
= data
["warn_high"]
84 crit_high
= data
["crit_high"]
86 # stay compatible with older versions
90 infotext
+= ", %s" % val
95 infotext
+= " %s" % unit
97 if what
== "ipmitool":
98 old_perf_val
= str(val
)
101 perfdata
= [(item
, old_perf_val
, warn_high
, crit_high
)]
103 elif what
== "freeipmi" and \
104 ("temperature" in item
.lower() or "temp" in item
.lower()):
105 # Do not save performance data for FANs. This produces
106 # much data and is - in my opinion - useless.
107 perfdata
= [("value", val
, None, crit_high
)]
111 state
= status_txt_mapping(status_txt
)
113 for ty
, warn
, crit
in [("below", warn_low
, crit_low
), ("at", warn_high
, crit_high
)]:
114 if warn
is not None and crit
is None:
115 warn_texts
.append("warn %s %s" % (ty
, warn
))
116 elif warn
is not None and crit
is not None:
117 crit_texts
.append("warn/crit %s %s/%s" % (ty
, warn
, crit
))
118 elif warn
is None and crit
is not None:
119 crit_texts
.append("crit %s %s" % (ty
, crit
))
121 for wato_status_txt
, wato_status
in params
.get("sensor_states", []):
122 if status_txt
.startswith(wato_status_txt
):
126 these_warn_texts
, these_crit_texts
= ipmi_common_check_levels(item
, val
, params
)
127 warn_texts
+= these_warn_texts
128 crit_texts
+= these_crit_texts
133 levelsinfo
= " (%s)" % ", ".join(crit_texts
)
136 levelsinfo
= " (%s)" % ", ".join(warn_texts
)
138 return state
, "Status: %s%s" % (infotext
, levelsinfo
), perfdata
141 def check_ipmi_common_summarized(params
, parsed
, status_txt_mapping
):
150 for sensorname
, data
in parsed
.items():
153 status_txt
= data
["status_txt"]
155 # Skip datasets which have no valid data (zero value, no unit and state nc)
156 if ipmi_ignore_entry(sensorname
, status_txt
, params
) or \
157 (val
== '0.000' and unit
is None and status_txt
.startswith('nc')):
158 skipped_texts
.append("%s (%s)" % (sensorname
, status_txt
))
161 sensorstate
= status_txt_mapping(status_txt
)
162 for wato_status_txt
, wato_status
in params
.get("sensor_states", []):
163 if status_txt
.startswith(wato_status_txt
):
164 sensorstate
= wato_status
167 these_warn_texts
, these_crit_texts
= ipmi_common_check_levels(sensorname
, val
, params
)
168 warn_texts
+= these_warn_texts
169 crit_texts
+= these_crit_texts
171 infotext
= "%s (%s)" % (sensorname
, status_txt
)
173 warn_texts
.append(infotext
)
174 elif sensorstate
== 2:
175 crit_texts
.append(infotext
)
177 ok_texts
.append(infotext
)
179 states
.append(sensorstate
)
181 if "amb" in sensorname
or "Ambient" in sensorname
:
184 ambient_sum
+= float(val
)
188 if ambient_count
> 0:
189 perfdata
= [("ambient_temp", ambient_sum
/ ambient_count
)]
193 infotexts
= ["%d sensors" % len(parsed
)]
194 for title
, texts
, extrainfo
, text_state
in [("OK", ok_texts
, "", 0),
195 ("WARN", warn_texts
, "(!)", 1),
196 ("CRIT", crit_texts
, "(!!)", 2),
197 ("skipped", skipped_texts
, "", 0)]:
198 if len(parsed
) == len(texts
):
200 infotext
= "%d sensors %s" % (len(parsed
), title
)
202 infotext
+= ": %s%s" % (", ".join(texts
), extrainfo
)
203 infotexts
= [infotext
]
207 infotext
= "%d %s" % (len(texts
), title
)
209 infotext
+= ": %s%s" % (", ".join(texts
), extrainfo
)
210 infotexts
.append(infotext
)
213 states
.append(text_state
)
215 return max(states
), ' - '.join(infotexts
), perfdata