Module: check_mk
Branch: master
Commit: e0f340a916f8eca0a9f49b5a5083a374e689c3f4
URL:
http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=e0f340a916f8ec…
Author: Mathias Kettner <mk(a)mathias-kettner.de>
Date: Tue Apr 19 13:53:42 2016 +0200
3414 New declarator BINARY(...) for OIDs - returning a list of byte values
When declaring OIDs in SNMP based checks you can now include the OID
into <tt>BINARY</tt>. This will then create a list of bytes instead of a
string. E.g. <tt>BINARY('5')</tt> will fetch the end OID 5 and convert
the
string values into lists of bytes, into <tt>[0, 33, 85, 10, 7, 186]</tt>
instead of <tt>'\x00!U\n\x07\xba'</tt>. This allows to tackle a
problem with
the new version 1.2.8 that otherwise automatically interpretes all strings
as UTF-8.
---
.werks/3414 | 16 ++++++++++++++++
ChangeLog | 1 +
checks/if.include | 6 +++++-
checks/if64.include | 2 +-
modules/snmp.py | 45 ++++++++++++++++++++++++++++++---------------
5 files changed, 53 insertions(+), 17 deletions(-)
diff --git a/.werks/3414 b/.werks/3414
new file mode 100644
index 0000000..60fc8bf
--- /dev/null
+++ b/.werks/3414
@@ -0,0 +1,16 @@
+Title: New declarator BINARY(...) for OIDs - returning a list of byte values
+Level: 1
+Component: checks
+Class: feature
+Compatible: compat
+State: unknown
+Version: 1.2.9i1
+Date: 1461066639
+
+When declaring OIDs in SNMP based checks you can now include the OID
+into <tt>BINARY</tt>. This will then create a list of bytes instead of a
+string. E.g. <tt>BINARY('5')</tt> will fetch the end OID 5 and
convert the
+string values into lists of bytes, into <tt>[0, 33, 85, 10, 7, 186]</tt>
+instead of <tt>'\x00!U\n\x07\xba'</tt>. This allows to tackle a
problem with
+the new version 1.2.8 that otherwise automatically interpretes all strings
+as UTF-8.
diff --git a/ChangeLog b/ChangeLog
index 2ad53e3..6cf9fc1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -64,6 +64,7 @@
* 3411 mysql_slave: now max time and related state can be configured if slave-IO and
slave-SQL are not running
* 3412 stulz_temp: now has readable sensor names and discovers all possible sensors
which are connected
NOTE: Please refer to the migration notes!
+ * 3414 New declarator BINARY(...) for OIDs - returning a list of byte values...
* 3073 FIX: windows agent: relative paths to mrpe scripts are now treated as relative
to the agent installation directory...
* 3061 FIX: mk_jolokia: Fixed debugging of the agent plugin
* 3074 FIX: windows agent: fixed incorrect values for 32-bit performance counters
diff --git a/checks/if.include b/checks/if.include
index c99ce37..2a056a5 100644
--- a/checks/if.include
+++ b/checks/if.include
@@ -689,7 +689,11 @@ def check_if_common_single(item, params, info, force_counter_wrap =
False,
if ifPhysAddress:
- mac = ":".join(["%02s" % hex(ord(m))[2:] for m in
ifPhysAddress]).replace(' ', '0')
+ if type(ifPhysAddress) != list:
+ mac_bytes = map(ord, ifPhysAddress)
+ else:
+ mac_bytes = ifPhysAddress
+ mac = ":".join(["%02s" % hex(m)[2:] for m in
mac_bytes]).replace(' ', '0')
infotext += 'MAC: %s, ' % mac
# Check speed settings of interface, but only if speed information
diff --git a/checks/if64.include b/checks/if64.include
index 4f202ec..cfa27d5 100644
--- a/checks/if64.include
+++ b/checks/if64.include
@@ -85,5 +85,5 @@ if64_snmp_end_oids = [
"2.2.1.20", # ifOutErrors 16
"2.2.1.21", # ifOutQLen 17
"31.1.1.1.18", # ifAlias 18
- "2.2.1.6", # ifPhysAddress 19
+ BINARY("2.2.1.6"), # ifPhysAddress 19
]
diff --git a/modules/snmp.py b/modules/snmp.py
index f7815f5..42532b1 100644
--- a/modules/snmp.py
+++ b/modules/snmp.py
@@ -40,6 +40,10 @@ def CACHED_OID(oid):
return "cached", oid
+def BINARY(oid):
+ return "binary", oid
+
+
def strip_snmp_value(value, hex_plain = False):
v = value.strip()
if v.startswith('"'):
@@ -137,7 +141,7 @@ def get_snmp_table(hostname, ip, check_type, oid_info,
use_snmpwalk_cache):
max_len_col = -1
for column in targetcolumns:
- fetchoid = compute_fetch_oid(oid, suboid, column)
+ fetchoid, value_encoding = compute_fetch_oid(oid, suboid, column)
# column may be integer or string like "1.5.4.2.3"
colno += 1
@@ -152,13 +156,13 @@ def get_snmp_table(hostname, ip, check_type, oid_info,
use_snmpwalk_cache):
raise MKGeneralException("Invalid SNMP OID specification in
implementation of check. "
"You can only use one of OID_END, OID_STRING, OID_BIN,
OID_END_BIN and OID_END_OCTET_STRING.")
index_column = colno
- columns.append((fetchoid, []))
+ columns.append((fetchoid, [], "string"))
index_format = column
continue
rowinfo = get_snmpwalk(hostname, ip, check_type, oid, fetchoid, column,
use_snmpwalk_cache)
- columns.append((fetchoid, rowinfo))
+ columns.append((fetchoid, rowinfo, value_encoding))
number_of_rows = len(rowinfo)
if number_of_rows > max_len:
max_len = number_of_rows
@@ -167,7 +171,7 @@ def get_snmp_table(hostname, ip, check_type, oid_info,
use_snmpwalk_cache):
if index_column != -1:
index_rows = []
# Take end-oids of non-index columns as indices
- fetchoid, max_column = columns[max_len_col]
+ fetchoid, max_column, value_encoding = columns[max_len_col]
for o, value in max_column:
if index_format == OID_END:
index_rows.append((o, extract_end_oid(fetchoid, o)))
@@ -180,16 +184,16 @@ def get_snmp_table(hostname, ip, check_type, oid_info,
use_snmpwalk_cache):
else: # OID_END_OCTET_STRING:
index_rows.append((o, oid_to_bin(extract_end_oid(fetchoid, o))[1:]))
- columns[index_column] = fetchoid, index_rows
+ columns[index_column] = fetchoid, index_rows, value_encoding
# prepend suboid to first column
if suboid and columns:
- fetchoid, first_column = columns[0]
+ fetchoid, first_column, value_encoding = columns[0]
new_first_column = []
for o, val in first_column:
new_first_column.append((o, str(suboid) + "." + str(val)))
- columns[0] = fetchoid, new_first_column
+ columns[0] = fetchoid, new_first_column, value_encoding
# Here we have to deal with a nasty problem: Some brain-dead devices
# omit entries in some sub OIDs. This happens e.g. for CISCO 3650
@@ -200,9 +204,9 @@ def get_snmp_table(hostname, ip, check_type, oid_info,
use_snmpwalk_cache):
# From all SNMP data sources (stored walk, classic SNMP, inline SNMP) we
# get normal python strings. But for Check_MK we need unicode strings now.
# Convert them by using the standard Check_MK approach for incoming data
- new_columns = sanitize_snmp_encoding(new_columns)
+ sanitized_columns = sanitize_snmp_encoding(new_columns)
- info += construct_snmp_table_of_rows(new_columns)
+ info += construct_snmp_table_of_rows(sanitized_columns)
return info
@@ -261,6 +265,7 @@ def perform_snmpwalk(hostname, ip, check_type, base_oid, fetchoid):
def compute_fetch_oid(oid, suboid, column):
fetchoid = oid
+ value_encoding = "string"
if suboid:
fetchoid += "." + str(suboid)
@@ -268,15 +273,20 @@ def compute_fetch_oid(oid, suboid, column):
if column != "":
if type(column) == tuple:
fetchoid += "." + str(column[1])
+ if column[0] == "binary":
+ value_encoding = "binary"
else:
fetchoid += "." + str(column)
- return fetchoid
+ return fetchoid, value_encoding
def sanitize_snmp_encoding(columns):
- for index, column in enumerate(columns):
- columns[index] = map(snmp_decode_string, column)
+ for index, (column, value_encoding) in enumerate(columns):
+ if value_encoding == "string":
+ columns[index] = map(snmp_decode_string, column)
+ else:
+ columns[index] = map(snmp_decode_binary, column)
return columns
@@ -284,7 +294,7 @@ def sanitize_snmp_table_columns(columns):
# First compute the complete list of end-oids appearing in the output
# by looping all results and putting the endoids to a flat list
endoids = []
- for fetchoid, column in columns:
+ for fetchoid, column, value_encoding in columns:
for o, value in column:
endoid = extract_end_oid(fetchoid, o)
if endoid not in endoids:
@@ -300,7 +310,7 @@ def sanitize_snmp_table_columns(columns):
# Now fill gaps in columns where some endois are missing
new_columns = []
- for fetchoid, column in columns:
+ for fetchoid, column, value_encoding in columns:
# It might happen that end OIDs are not ordered. Fix the OID sorting to make
# it comparable to the already sorted endoids list. Otherwise we would get
# some mixups when filling gaps
@@ -325,7 +335,7 @@ def sanitize_snmp_table_columns(columns):
while i < len(endoids):
new_column.append("") # (beginoid + '.' +endoids[i],
"") )
i += 1
- new_columns.append(new_column)
+ new_columns.append((new_column, value_encoding))
return new_columns
@@ -540,6 +550,11 @@ def snmp_decode_string(text):
except:
return text.decode('latin1')
+
+def snmp_decode_binary(text):
+ return map(ord, text)
+
+
# .--Classic SNMP--------------------------------------------------------.
# | ____ _ _ ____ _ _ __ __ ____ |
# | / ___| | __ _ ___ ___(_) ___ / ___|| \ | | \/ | _ \ |