From 26f8c3aae313bc54dffc8713969013218030d4a7 Mon Sep 17 00:00:00 2001 From: Alexander Haase Date: Wed, 11 Dec 2024 16:28:42 +0100 Subject: [PATCH] Closes 18061: Hide traceback from rendered device config (#18127) * Hide traceback from rendered device config When an exception occurs during device configuration rendering, it usually doesn't contain information about the template being rendered, but rather the trace of how the template was rendered. Since this could confuse users and expose internal server information, it is now hidden. * Improve error message display; replicate changes for VMs --------- Co-authored-by: Jeremy Stretch --- netbox/dcim/views.py | 10 +++--- .../templates/dcim/device/render_config.html | 33 ++++++++++++------- .../virtualmachine/render_config.html | 33 ++++++++++++------- netbox/virtualization/views.py | 10 +++--- 4 files changed, 52 insertions(+), 34 deletions(-) diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index f390be89b..c8474b01d 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -1,5 +1,3 @@ -import traceback - from django.contrib import messages from django.contrib.contenttypes.models import ContentType from django.core.paginator import EmptyPage, PageNotAnInteger @@ -2106,7 +2104,8 @@ class DeviceRenderConfigView(generic.ObjectView): # If a direct export has been requested, return the rendered template content as a # downloadable file. if request.GET.get('export'): - response = HttpResponse(context['rendered_config'], content_type='text') + content = context['rendered_config'] or context['error_message'] + response = HttpResponse(content, content_type='text') filename = f"{instance.name or 'config'}.txt" response['Content-Disposition'] = f'attachment; filename="{filename}"' return response @@ -2124,17 +2123,18 @@ class DeviceRenderConfigView(generic.ObjectView): # Render the config template rendered_config = None + error_message = None if config_template := instance.get_config_template(): try: rendered_config = config_template.render(context=context_data) except TemplateError as e: - messages.error(request, _("An error occurred while rendering the template: {error}").format(error=e)) - rendered_config = traceback.format_exc() + error_message = _("An error occurred while rendering the template: {error}").format(error=e) return { 'config_template': config_template, 'context_data': context_data, 'rendered_config': rendered_config, + 'error_message': error_message, } diff --git a/netbox/templates/dcim/device/render_config.html b/netbox/templates/dcim/device/render_config.html index 785939a83..ab2f1c531 100644 --- a/netbox/templates/dcim/device/render_config.html +++ b/netbox/templates/dcim/device/render_config.html @@ -5,7 +5,7 @@ {% block title %}{{ object }} - {% trans "Config" %}{% endblock %} {% block content %} -
+

{% trans "Config Template" %}

@@ -48,19 +48,28 @@
-
-

- {% trans "Rendered Config" %} - - {% trans "Download" %} - -

- {% if config_template %} -
{{ rendered_config }}
+ {% if config_template %} + {% if rendered_config %} +
+

+ {% trans "Rendered Config" %} + + {% trans "Download" %} + +

+
{{ rendered_config }}
+
{% else %} -
{% trans "No configuration template found" %}
+
+

{% trans "Error rendering template" %}

+ {% trans error_message %} +
{% endif %} -
+ {% else %} +
+ {% trans "No configuration template has been assigned for this device." %} +
+ {% endif %}
{% endblock %} diff --git a/netbox/templates/virtualization/virtualmachine/render_config.html b/netbox/templates/virtualization/virtualmachine/render_config.html index 5e7a0711b..fa6f1723b 100644 --- a/netbox/templates/virtualization/virtualmachine/render_config.html +++ b/netbox/templates/virtualization/virtualmachine/render_config.html @@ -5,7 +5,7 @@ {% block title %}{{ object }} - {% trans "Config" %}{% endblock %} {% block content %} -
+

{% trans "Config Template" %}

@@ -48,19 +48,28 @@
-
-

- {% trans "Rendered Config" %} - - {% trans "Download" %} - -

- {% if config_template %} -
{{ rendered_config }}
+ {% if config_template %} + {% if rendered_config %} +
+

+ {% trans "Rendered Config" %} + + {% trans "Download" %} + +

+
{{ rendered_config }}
+
{% else %} -
{% trans "No configuration template found" %}
+
+

{% trans "Error rendering template" %}

+ {% trans error_message %} +
{% endif %} -
+ {% else %} +
+ {% trans "No configuration template has been assigned for this virtual machine." %} +
+ {% endif %}
{% endblock %} diff --git a/netbox/virtualization/views.py b/netbox/virtualization/views.py index d1d65b1ff..f71d56b19 100644 --- a/netbox/virtualization/views.py +++ b/netbox/virtualization/views.py @@ -1,5 +1,3 @@ -import traceback - from django.contrib import messages from django.db import transaction from django.db.models import Prefetch, Sum @@ -425,7 +423,8 @@ class VirtualMachineRenderConfigView(generic.ObjectView): # If a direct export has been requested, return the rendered template content as a # downloadable file. if request.GET.get('export'): - response = HttpResponse(context['rendered_config'], content_type='text') + content = context['rendered_config'] or context['error_message'] + response = HttpResponse(content, content_type='text') filename = f"{instance.name or 'config'}.txt" response['Content-Disposition'] = f'attachment; filename="{filename}"' return response @@ -443,17 +442,18 @@ class VirtualMachineRenderConfigView(generic.ObjectView): # Render the config template rendered_config = None + error_message = None if config_template := instance.get_config_template(): try: rendered_config = config_template.render(context=context_data) except TemplateError as e: - messages.error(request, _("An error occurred while rendering the template: {error}").format(error=e)) - rendered_config = traceback.format_exc() + error_message = _("An error occurred while rendering the template: {error}").format(error=e) return { 'config_template': config_template, 'context_data': context_data, 'rendered_config': rendered_config, + 'error_message': error_message, }