diff --git a/puppetboard/core.py b/puppetboard/core.py
index 4d43b7d0..ea8c8f7b 100644
--- a/puppetboard/core.py
+++ b/puppetboard/core.py
@@ -6,6 +6,7 @@
from flask import Flask
from flask_caching import Cache
from flask_apscheduler import APScheduler
+from markupsafe import escape
from pypuppetdb import connect
from puppetboard.utils import (get_or_abort, jsonprint,
@@ -247,3 +248,20 @@ def to_html(message: str) -> str:
r"(file: \1, line: \2)", message)
return message
+
+
+def get_error_html(node_name, source, message, show_error_as):
+
+ # sanitize the data from PuppetDB first,
+ # as we will add some HTML tags in the functions below and don't want these
+ # to be escaped
+ safe_source = escape(source)
+ safe_message = escape(message)
+
+ # enrich the message using HTML
+ if show_error_as == 'friendly':
+ error_html = to_html(get_friendly_error(safe_source, safe_message, node_name))
+ else:
+ error_html = get_raw_error(safe_source, safe_message)
+
+ return error_html
diff --git a/puppetboard/templates/report.html b/puppetboard/templates/report.html
index f2ca19d2..3df36640 100644
--- a/puppetboard/templates/report.html
+++ b/puppetboard/templates/report.html
@@ -108,9 +108,9 @@
Metrics
}
},
{ data: 'level', name: 'level' },
- { data: 'source', name: 'source', visible: false },
+ { data: 'source', name: 'source', visible: false, render: DataTable.render.text() },
{ data: 'tags', name: 'tags', visible: false },
- { data: 'message', name: 'message' },
+ { data: 'message', name: 'message' }, // HTML for this column is sanitized in get_message()
// see also the comment about these columns in reports.py
{ data: 'location', name: 'location', visible: false },
{ data: 'short_location', name: 'short_location' },
@@ -176,10 +176,10 @@ Metrics
"data": events,
'columns': [
- { data: 'resource' },
+ { data: 'resource', render: DataTable.render.text() },
{ data: 'status' },
- { data: 'old' },
- { data: 'new' },
+ { data: 'old', render: DataTable.render.text() },
+ { data: 'new', render: DataTable.render.text() },
],
"ordering": false,
diff --git a/puppetboard/views/failures.py b/puppetboard/views/failures.py
index d31c7b79..63dd4ace 100644
--- a/puppetboard/views/failures.py
+++ b/puppetboard/views/failures.py
@@ -1,8 +1,8 @@
from flask import Response, stream_with_context, abort
from pypuppetdb.QueryBuilder import AndOperator, EqualsOperator
-from puppetboard.core import get_app, get_puppetdb, environments, stream_template, to_html, \
- get_friendly_error, get_raw_error
+from puppetboard.core import get_app, get_puppetdb, environments, \
+ stream_template, get_error_html
from puppetboard.utils import check_env, yield_or_stop
app = get_app()
@@ -55,12 +55,9 @@ def failures(env: str, show_error_as: str):
break
if source and message:
- if show_error_as == 'friendly':
- error = to_html(get_friendly_error(source, message, node.name))
- else:
- error = get_raw_error(source, message)
+ error = get_error_html(node.name, source, message, show_error_as)
else:
- error = to_html(f'Node {node.name} is failing but we could not find the errors')
+ error = f'Node {node.name} is failing but we could not find the errors'
failure = {
'certname': node.name,
diff --git a/puppetboard/views/reports.py b/puppetboard/views/reports.py
index 47dd6d94..05e56733 100644
--- a/puppetboard/views/reports.py
+++ b/puppetboard/views/reports.py
@@ -10,8 +10,8 @@
EqualsOperator, OrOperator,
LessEqualOperator, RegexOperator, GreaterEqualOperator)
-from puppetboard.core import get_app, get_puppetdb, environments, REPORTS_COLUMNS, to_html, \
- get_raw_error, get_friendly_error
+from puppetboard.core import get_app, get_puppetdb, environments, \
+ REPORTS_COLUMNS, get_error_html
from puppetboard.utils import (check_env, get_or_abort)
app = get_app()
@@ -179,12 +179,6 @@ def get_short_location(location: str) -> str:
return location
-def get_message(node_name, log, show_error_as):
- if show_error_as == 'friendly':
- error = to_html(get_friendly_error(log['source'], log['message'], node_name))
- else:
- error = get_raw_error(log['source'], log['message'])
- return error
@app.route('/report//',
@@ -254,7 +248,7 @@ def report(env, node_name, report_id, show_error_as):
'level': log["level"],
'source': log['source'],
'tags': ', '.join(log['tags']),
- 'message': get_message(node_name, log, show_error_as),
+ 'message': get_error_html(node_name, log['source'], log['message'], show_error_as),
'location': get_location(log),
# this could be also done with a different rendered in DataTables,
# - feel free to refactor it into that if you know how