First of all, thank you for this magnificent plugin as it allows me to manage my intenal DNS seamlessly from Netbox.
I'm using Netbox v3.1.6 in a k8s cluster with a customized image in which I've installed the plugin. Everything is working great functionally and both forward as reverse records are being correctly updated in my Powerdns server.
I have however encountered an error after adding an extra DNS name to a Netbox IP object (both through the frontend as admin panel). The extra record is added correctly in the database and is being pushed to the DNS, however, whenever such an extra DNS name is added, when I open the IP address details in the Netbox frontend, I encountered following error:
I'm not a dev myself and have no experience with Django but decided to do some digging and came to the conclusion the inc/table.html template was expecting a different table class as it was looking for missing attributes.
After some trial and error, I got results after one change to tables.py line 33, replacing:
class PrefixTable(BaseTable):
with:
class PrefixTable(tables.Table):
I'm lacking test data to determine if this is a bug or related to wrong configuration on my side (although all Netbox settings are on default and no other plugins are installed). So I was wondering other users experience the same issue and this is something that needs fixing.
Environment:
Request Method: GET
Request URL: http://xxxx/ipam/ip-addresses/7/
Django Version: 3.2.11
Python Version: 3.9.7
Installed Applications:
['django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.humanize',
'corsheaders',
'debug_toolbar',
'graphiql_debug_toolbar',
'django_filters',
'django_tables2',
'django_prometheus',
'graphene_django',
'mptt',
'rest_framework',
'social_django',
'taggit',
'timezone_field',
'circuits',
'dcim',
'ipam',
'extras',
'tenancy',
'users',
'utilities',
'virtualization',
'wireless',
'django_rq',
'drf_yasg',
'netbox_ddns.NetBoxDDNSConfig']
Installed Middleware:
['graphiql_debug_toolbar.middleware.DebugToolbarMiddleware',
'django_prometheus.middleware.PrometheusBeforeMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware',
'netbox.middleware.ExceptionHandlingMiddleware',
'netbox.middleware.RemoteUserMiddleware',
'netbox.middleware.LoginRequiredMiddleware',
'netbox.middleware.DynamicConfigMiddleware',
'netbox.middleware.APIVersionMiddleware',
'netbox.middleware.ObjectChangeMiddleware',
'django_prometheus.middleware.PrometheusAfterMiddleware']
Template error:
In template /app/netbox/netbox/templates/inc/table.html, error at line 20
for linkify=True, '9' must have a method get_absolute_url
10 : {% else %}
11 : <th {{ column.attrs.th.as_html }}>{{ column.header }}</th>
12 : {% endif %}
13 : {% endfor %}
14 : </tr>
15 : </thead>
16 : {% endif %}
17 : <tbody>
18 : {% for row in table.page.object_list|default:table.rows %}
19 : <tr {{ row.attrs.as_html }}>
20 : {% for column, cell in row.items %}
21 : <td {{ column.attrs.td.as_html }}>{{ cell }}</td>
22 : {% endfor %}
23 : </tr>
24 : {% empty %}
25 : {% if table.empty_text %}
26 : <tr>
27 : <td colspan="{{ table.columns|length }}" class="text-center text-muted">— {{ table.empty_text }} —</td>
28 : </tr>
29 : {% endif %}
30 : {% endfor %}
Traceback (most recent call last):
File "/usr/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/usr/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/lib/python3.9/site-packages/django/views/generic/base.py", line 70, in view
return self.dispatch(request, *args, **kwargs)
File "/app/netbox/netbox/./utilities/views.py", line 93, in dispatch
return super().dispatch(request, *args, **kwargs)
File "/usr/lib/python3.9/site-packages/django/views/generic/base.py", line 98, in dispatch
return handler(request, *args, **kwargs)
File "/app/netbox/netbox/./netbox/views/generic.py", line 71, in get
return render(request, self.get_template_name(), {
File "/usr/lib/python3.9/site-packages/django/shortcuts.py", line 19, in render
content = loader.render_to_string(template_name, context, request, using=using)
File "/usr/lib/python3.9/site-packages/django/template/loader.py", line 62, in render_to_string
return template.render(context, request)
File "/usr/lib/python3.9/site-packages/django/template/backends/django.py", line 61, in render
return self.template.render(context)
File "/usr/lib/python3.9/site-packages/django/template/base.py", line 170, in render
return self._render(context)
File "/usr/lib/python3.9/site-packages/django/test/utils.py", line 100, in instrumented_test_render
return self.nodelist.render(context)
File "/usr/lib/python3.9/site-packages/django/template/base.py", line 938, in render
bit = node.render_annotated(context)
File "/usr/lib/python3.9/site-packages/django/template/base.py", line 905, in render_annotated
return self.render(context)
File "/usr/lib/python3.9/site-packages/django/template/loader_tags.py", line 150, in render
return compiled_parent._render(context)
File "/usr/lib/python3.9/site-packages/django/test/utils.py", line 100, in instrumented_test_render
return self.nodelist.render(context)
File "/usr/lib/python3.9/site-packages/django/template/base.py", line 938, in render
bit = node.render_annotated(context)
File "/usr/lib/python3.9/site-packages/django/template/base.py", line 905, in render_annotated
return self.render(context)
File "/usr/lib/python3.9/site-packages/django/template/loader_tags.py", line 150, in render
return compiled_parent._render(context)
File "/usr/lib/python3.9/site-packages/django/test/utils.py", line 100, in instrumented_test_render
return self.nodelist.render(context)
File "/usr/lib/python3.9/site-packages/django/template/base.py", line 938, in render
bit = node.render_annotated(context)
File "/usr/lib/python3.9/site-packages/django/template/base.py", line 905, in render_annotated
return self.render(context)
File "/usr/lib/python3.9/site-packages/django/template/loader_tags.py", line 150, in render
return compiled_parent._render(context)
File "/usr/lib/python3.9/site-packages/django/test/utils.py", line 100, in instrumented_test_render
return self.nodelist.render(context)
File "/usr/lib/python3.9/site-packages/django/template/base.py", line 938, in render
bit = node.render_annotated(context)
File "/usr/lib/python3.9/site-packages/django/template/base.py", line 905, in render_annotated
return self.render(context)
File "/usr/lib/python3.9/site-packages/django/template/loader_tags.py", line 62, in render
result = block.nodelist.render(context)
File "/usr/lib/python3.9/site-packages/django/template/base.py", line 938, in render
bit = node.render_annotated(context)
File "/usr/lib/python3.9/site-packages/django/template/base.py", line 905, in render_annotated
return self.render(context)
File "/usr/lib/python3.9/site-packages/django/template/loader_tags.py", line 62, in render
result = block.nodelist.render(context)
File "/usr/lib/python3.9/site-packages/django/template/base.py", line 938, in render
bit = node.render_annotated(context)
File "/usr/lib/python3.9/site-packages/django/template/base.py", line 905, in render_annotated
return self.render(context)
File "/usr/lib/python3.9/site-packages/django/template/loader_tags.py", line 62, in render
result = block.nodelist.render(context)
File "/usr/lib/python3.9/site-packages/django/template/base.py", line 938, in render
bit = node.render_annotated(context)
File "/usr/lib/python3.9/site-packages/django/template/base.py", line 905, in render_annotated
return self.render(context)
File "/usr/lib/python3.9/site-packages/django/template/library.py", line 192, in render
output = self.func(*resolved_args, **resolved_kwargs)
File "/app/netbox/netbox/./extras/templatetags/plugins.py", line 59, in plugin_left_page
return _get_registered_content(obj, 'left_page', context)
File "/app/netbox/netbox/./extras/templatetags/plugins.py", line 40, in _get_registered_content
content = getattr(instance, method)()
File "/usr/lib/python3.9/site-packages/netbox_ddns/template_content.py", line 30, in left_page
self.render('netbox_ddns/ipaddress/dns_extra.html', {
File "/app/netbox/netbox/./extras/plugins/__init__.py", line 134, in render
return get_template(template_name).render({**self.context, **extra_context})
File "/usr/lib/python3.9/site-packages/django/template/backends/django.py", line 61, in render
return self.template.render(context)
File "/usr/lib/python3.9/site-packages/django/template/base.py", line 170, in render
return self._render(context)
File "/usr/lib/python3.9/site-packages/django/test/utils.py", line 100, in instrumented_test_render
return self.nodelist.render(context)
File "/usr/lib/python3.9/site-packages/django/template/base.py", line 938, in render
bit = node.render_annotated(context)
File "/usr/lib/python3.9/site-packages/django/template/base.py", line 905, in render_annotated
return self.render(context)
File "/usr/lib/python3.9/site-packages/django/template/defaulttags.py", line 312, in render
return nodelist.render(context)
File "/usr/lib/python3.9/site-packages/django/template/base.py", line 938, in render
bit = node.render_annotated(context)
File "/usr/lib/python3.9/site-packages/django/template/base.py", line 905, in render_annotated
return self.render(context)
File "/usr/lib/python3.9/site-packages/django_tables2/templatetags/django_tables2.py", line 167, in render
return template.render(context={"table": table}, request=request)
File "/usr/lib/python3.9/site-packages/django/template/backends/django.py", line 61, in render
return self.template.render(context)
File "/usr/lib/python3.9/site-packages/django/template/base.py", line 170, in render
return self._render(context)
File "/usr/lib/python3.9/site-packages/django/test/utils.py", line 100, in instrumented_test_render
return self.nodelist.render(context)
File "/usr/lib/python3.9/site-packages/django/template/base.py", line 938, in render
bit = node.render_annotated(context)
File "/usr/lib/python3.9/site-packages/django/template/base.py", line 905, in render_annotated
return self.render(context)
File "/usr/lib/python3.9/site-packages/django/template/defaulttags.py", line 211, in render
nodelist.append(node.render_annotated(context))
File "/usr/lib/python3.9/site-packages/django/template/base.py", line 905, in render_annotated
return self.render(context)
File "/usr/lib/python3.9/site-packages/django/template/defaulttags.py", line 167, in render
values = list(values)
File "/usr/lib/python3.9/site-packages/django_tables2/rows.py", line 244, in items
column.current_value = self.get_cell(column.name)
File "/usr/lib/python3.9/site-packages/django_tables2/rows.py", line 197, in get_cell
return self._get_and_render_with(
File "/usr/lib/python3.9/site-packages/django_tables2/rows.py", line 173, in _get_and_render_with
return render_func(bound_column, value)
File "/usr/lib/python3.9/site-packages/django_tables2/rows.py", line 208, in _call_render
return bound_column.link(content, **render_kwargs) if bound_column.link else content
File "/usr/lib/python3.9/site-packages/django_tables2/columns/base.py", line 152, in __call__
attrs = self.get_attrs(**kwargs)
File "/usr/lib/python3.9/site-packages/django_tables2/columns/base.py", line 147, in get_attrs
attrs["href"] = self.compose_url(**kwargs)
File "/usr/lib/python3.9/site-packages/django_tables2/columns/base.py", line 114, in compose_url
raise TypeError(
Exception Type: TypeError at /ipam/ip-addresses/7/
Exception Value: for linkify=True, '9' must have a method get_absolute_url