Cleanup config.nodes_of
[check_mk.git] / checks / ipmi_common.include
blob25305d32710468d928e7ec5a202e8cedd2ec7710
1 #!/usr/bin/python
2 # -*- encoding: utf-8; py-indent-offset: 4 -*-
3 # +------------------------------------------------------------------+
4 # | ____ _ _ __ __ _ __ |
5 # | / ___| |__ ___ ___| | __ | \/ | |/ / |
6 # | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
7 # | | |___| | | | __/ (__| < | | | | . \ |
8 # | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
9 # | |
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:
33 return True
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):
38 return True
39 for e in ignored_sensors:
40 if name.startswith(e):
41 return True
42 return False
45 def check_ipmi_common(item, params, parsed, what, status_txt_mapping):
46 if params is None:
47 params = {}
49 if item == "Summary" or item == "Summary FreeIPMI":
50 return check_ipmi_common_summarized(params, parsed, status_txt_mapping)
51 elif item in parsed:
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"]
61 if val < crit:
62 crit_texts.append(
63 "%s %s (warn/crit below %s/%s)" % (sensorname, val, warn, crit))
64 elif val < warn:
65 warn_texts.append(
66 "%s %s (warn/crit below %s/%s)" % (sensorname, val, warn, crit))
67 if levels.get("upper"):
68 warn, crit = levels["upper"]
69 if val >= crit:
70 crit_texts.append("%s %s (warn/crit at %s/%s)" % (sensorname, val, warn, crit))
71 elif val >= warn:
72 warn_texts.append("%s %s (warn/crit at %s/%s)" % (sensorname, val, warn, crit))
73 break
74 return warn_texts, crit_texts
77 def check_ipmi_common_detailed(item, params, data, what, status_txt_mapping):
78 val = data["value"]
79 unit = data["unit"]
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
87 infotext = status_txt
88 perfdata = []
89 if val is not None:
90 infotext += ", %s" % val
91 if unit is not None:
92 if unit == "%":
93 infotext += unit
94 else:
95 infotext += " %s" % unit
97 if what == "ipmitool":
98 old_perf_val = str(val)
99 if unit is not None:
100 old_perf_val += unit
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)]
109 warn_texts = []
110 crit_texts = []
111 state = status_txt_mapping(status_txt)
112 if state:
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):
123 state = wato_status
124 break
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
130 levelsinfo = ""
131 if crit_texts:
132 state = 2
133 levelsinfo = " (%s)" % ", ".join(crit_texts)
134 elif warn_texts:
135 state = 1
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):
142 states = [0]
143 warn_texts = []
144 crit_texts = []
145 ok_texts = []
146 skipped_texts = []
147 ambient_count = 0
148 ambient_sum = 0.0
150 for sensorname, data in parsed.items():
151 val = data["value"]
152 unit = data["unit"]
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))
159 continue
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
165 break
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)
172 if sensorstate == 1:
173 warn_texts.append(infotext)
174 elif sensorstate == 2:
175 crit_texts.append(infotext)
176 else:
177 ok_texts.append(infotext)
179 states.append(sensorstate)
181 if "amb" in sensorname or "Ambient" in sensorname:
182 try:
183 ambient_count += 1
184 ambient_sum += float(val)
185 except:
186 pass
188 if ambient_count > 0:
189 perfdata = [("ambient_temp", ambient_sum / ambient_count)]
190 else:
191 perfdata = []
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):
199 # Everything OK
200 infotext = "%d sensors %s" % (len(parsed), title)
201 if extrainfo:
202 infotext += ": %s%s" % (", ".join(texts), extrainfo)
203 infotexts = [infotext]
204 break
206 elif texts:
207 infotext = "%d %s" % (len(texts), title)
208 if extrainfo:
209 infotext += ": %s%s" % (", ".join(texts), extrainfo)
210 infotexts.append(infotext)
212 if text_state:
213 states.append(text_state)
215 return max(states), ' - '.join(infotexts), perfdata