Module: check_mk
Branch: master
Commit: 74386d1e60e1d14032f48e10995055cfbeafe858
URL:
http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=74386d1e60e1d1…
Author: Moritz Kiemer <mo(a)mathias-kettner.de>
Date: Tue Oct 23 09:09:18 2018 +0200
docker.include: Properly parse values with unescaped commas
Change-Id: I47f3154a456b6ab16d24bdd87cb40182ab6909be
---
checks/docker.include | 24 +++++++++++++++++-----
tests/unit/checks/test_docker_parse_node_images.py | 3 ++-
2 files changed, 21 insertions(+), 6 deletions(-)
diff --git a/checks/docker.include b/checks/docker.include
index 87eb4cd..3b23b69 100644
--- a/checks/docker.include
+++ b/checks/docker.include
@@ -200,7 +200,8 @@ def _get_json_list(info):
json_list.append(json.loads(' '.join(row)))
except ValueError:
pass
- return json_list
+ # some buggy docker commands produce empty output
+ return [element for element in json_list if element]
def parse_docker_subsection_images(info):
@@ -255,10 +256,24 @@ def _split_subsections(info):
if row[0].startswith('[[[') and row[0].endswith(']]]'):
subname = row[0].strip('[]')
continue
- subsections.setdefault(subname, []).append(row)
+ subsections.setdefault(subname, []).append(row)
return subsections
+def parse_docker_messed_up_labels(string):
+ '''yield key value pairs
+
+ 'string' is in the format "key1=value1,key2=value2,...", but there
+ may be unescaped commas in the values.
+ '''
+ def toggle_key_value():
+ for chunk in string.split('='):
+ for item in chunk.rsplit(',', 1):
+ yield item
+ toggler = toggle_key_value()
+ return dict(zip(toggler, toggler))
+
+
def parse_docker_node_images(info):
subsections = _split_subsections(info)
images = parse_docker_subsection_images(subsections.get("images", []))
@@ -285,7 +300,7 @@ def parse_docker_node_images(info):
for image_id, labels in image_labels.iteritems():
image = images.get(_docker_trunc_id(image_id))
if image is not None and labels is not None:
- image["__labels__"].update(labels)
+ image["__labels__"].update(labels)
mapping = {(i['Repository'], i['Tag']): i['ID']
for i in images.itervalues()}
@@ -298,8 +313,7 @@ def parse_docker_node_images(info):
labels = c.get("Labels")
if isinstance(labels, (str, unicode)):
- lab = (p.split("=", 1) for p in labels.split(","))
- c["Labels"] = dict(lab)
+ c["Labels"] = parse_docker_messed_up_labels(labels)
return {"images": images, "containers": containers}
diff --git a/tests/unit/checks/test_docker_parse_node_images.py
b/tests/unit/checks/test_docker_parse_node_images.py
index 5b5dd7b..4cd1318 100644
--- a/tests/unit/checks/test_docker_parse_node_images.py
+++ b/tests/unit/checks/test_docker_parse_node_images.py
@@ -264,7 +264,7 @@ INFO1 = [
'{"Command":"\\"/usr/sbin/init\\"","CreatedAt":"2018-10-12',
'11:13:24', '+0200',
'CEST","ID":"f1641e401237","Image":"local/c7-systemd-httpd","Labels":"org.label-schema.build-date=20180804,org.label-schema.license=GPLv2,org.label-schema.name=CentOS',
'Base',
-
'Image,org.label-schema.schema-version=1.0,org.label-schema.vendor=CentOS","LocalVolumes":"0","Mounts":"/sys/fs/cgroup","Names":"sad_stonebraker","Networks":"bridge","Ports":"0.0.0.0:8080-\u003e80/tcp","RunningFor":"5',
+ 'Image,org.label-schema.schema-version=1.0,funny.value.with.commas=This',
'is', 'really,', 'really',
'stupid.,org.label-schema.vendor=CentOS","LocalVolumes":"0","Mounts":"/sys/fs/cgroup","Names":"sad_stonebraker","Networks":"bridge","Ports":"0.0.0.0:8080-\u003e80/tcp","RunningFor":"5',
'hours',
'ago","Size":"0B","Status":"Up',
'5', 'hours"}'
],
[
@@ -1212,6 +1212,7 @@ EXPECTED_CONTAINERS1 = {
u'org.label-schema.build-date': u'20180804',
u'org.label-schema.license': u'GPLv2',
u'org.label-schema.name': u'CentOS Base Image',
+ u'funny.value.with.commas': u'This is really, really
stupid.',
u'org.label-schema.schema-version': u'1.0',
u'org.label-schema.vendor': u'CentOS'
},