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, }