netbox-community / netbox

The premier source of truth powering network automation. Open source under Apache 2. Try NetBox Cloud free: https://netboxlabs.com/free-netbox-cloud/
http://netboxlabs.com/oss/netbox/
Apache License 2.0
16.25k stars 2.59k forks source link

Config Template unable to dynamically include templates #17490

Open robduffy2010 opened 2 months ago

robduffy2010 commented 2 months ago

Deployment Type

Self-hosted

NetBox Version

v4.0.9

Python Version

3.10

Steps to Reproduce

  1. Create the following template in a data store, as well as child templates in the blocks directory. In this example a template named interface.j2 is located in the blocks/TEST/ directory.
  2. Assign the template to a device
  3. Attempt to render the template

Example of template. This has been tested manually using Jinja2. The configuration blocks referenced are from a plugin.

config system interface {% for config_block in device.site.configblock_set.all() %} {% include "blocks/" + custom_block.name + "/interface.j2" %} {% endfor %} end

Expected Behavior

Expected behaviour is that the template renders and imports the relevant includes.

Observed Behavior

Traceback (most recent call last): File "/opt/netbox/netbox/utilities/jinja2.py", line 26, in get_source template_source = self._template_cache[template] KeyError: 'blocks/TEST/interface.j2'

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "/opt/netbox/netbox/dcim/views.py", line 2060, in get_extra_context rendered_config = config_template.render(context=context_data) File "/opt/netbox/netbox/extras/models/configs.py", line 282, in render output = template.render(**_context) File "/usr/local/lib/python3.10/site-packages/jinja2/environment.py", line 1304, in render self.environment.handle_exception() File "/usr/local/lib/python3.10/site-packages/jinja2/environment.py", line 939, in handle_exception raise rewrite_traceback_stack(source=source) File "block-config.j2", line 49, in top-level template code File "/opt/netbox/netbox/utilities/jinja2.py", line 28, in get_source raise TemplateNotFound(template) jinja2.exceptions.TemplateNotFound: blocks/TEST/interface.j2

DanSheps commented 2 months ago

Tested this and confirmed this does indeed not import the template.

I honestly have no idea what could be going wrong here as most of the jinja rendering happens within jinja itself. This may be an upstream bug but I am not sure.

robduffy2010 commented 2 months ago

Thanks for checking. It's very odd alright. I have unittests on the Gitlab repo which hosts the config template, which renders the templates using some test data. It works perfectly on there.

I had a look at the Netbox code and suspect it might could have something to do with the jinja2 sandbox being used but I'm really not sure. I'll have to do some more testing to emulate it as closely as possible.