Jinja templates - what object properties are available? #12568
-
Hi, Just got started with Jinja templating with the config templates. I'm a little confused as to what I have to work with in terms of various objects. For example, I discovered that Is there any reference for this? |
Beta Was this translation helpful? Give feedback.
Replies: 8 comments 28 replies
-
You can check the code: netbox/netbox/dcim/models/device_components.py Lines 670 to 675 in b7f028f Alternatively you can print all the fields on the model you are working with in
|
Beta Was this translation helpful? Give feedback.
-
Seconding this - I'm having a hard time writing my config templates. How does one get the IP address for an interface (for example)? Is it: {{ interface.address }} or {{ interface.ip_address.address }} or {{ interface.ip_address.value }} or {{ interface.ip_address.ip }} or is it {{ interface.ip_address | first }} I ask in earnest because I genuinely can't tell (even after using nbshell, I'm a little unused to Django, sorry). If someone has any insight, I'd appreciate it. |
Beta Was this translation helpful? Give feedback.
-
I too have just started out on serious template construction and seeking guidance. |
Beta Was this translation helpful? Give feedback.
-
In general, an interface has multiple IP addresses, so you could either get the first one, or all of them. Here's a custom link I use for getting the management IP address of a device (which will be an explicit attribute in NB 3.6):
In nbshell:
Here, |
Beta Was this translation helpful? Give feedback.
-
Firstly, in nbshell there is info on the attributes on an object using e.g.
Secondly, in Python in general, you can get a list of all the property names and method names on an object using
will list everything on that particular interface object - which will be a huge list (it includes all the methods inherited from parent classes, and lots of private methods methods). If you know roughly what you're looking for, you can filter this list. I showed:
That's a list comprehension: it take objects from a list ( In both ways you learn that
you got a message telling you exactly that:
And finally, there's the source code for Interface and IPAddress. On Interface, this gives you:
But that involves getting more into Django internals. |
Beta Was this translation helpful? Give feedback.
-
I don't have a ton to contribute, but I wanted to check back in with my working template so far...hopefully it helps somebody... {%- set vlans = device.site.vlans.all() | list -%}
{%- set interfaces = device.interfaces.all() -%}
{%- set physical = interfaces | selectattr('type', 'ne', 'virtual') | list -%}
{%- set virtual = interfaces | selectattr('type', 'eq', 'virtual') | list -%}
{%- set port_speeds = {
} -%}
{%- for interface in physical -%}
{%- if interface.ip_addresses.first() %}
set interfaces ethernet {{ interface.name }} address {{ interface.ip_addresses.first().address }}
{%- endif %}
{%- if interface.label %}
set interfaces ethernet {{ interface.name }} description {{ interface.label }}
{%- endif %}
{%- if not interface.enabled %}
set interfaces ethernet {{ interface.name }} disable
{%- endif %}
set interfaces ethernet {{ interface.name }} duplex auto
set interfaces ethernet {{ interface.name }} speed {{ port_speeds[interface.speed | string] or 'auto' }}
{%- if interface.mtu %}
set interfaces ethernet {{ interface.name }} mtu {{ interface.mtu }}
{%- endif %}
{%- for vif in virtual | selectattr('parent.id', 'eq', interface.id) | list %}
{% set vlan = vlans | selectattr('id', 'eq', vif.untagged_vlan_id) | first %}
{%- if vif.ip_addresses.first() %}
set interfaces ethernet {{ vif.parent.name }} vif {{ vlan.vid }} address {{ vif.ip_addresses.first().address }}
{%- endif %}
set interfaces ethernet {{ vif.parent.name }} vif {{ vlan.vid }} description {{ vlan.name }}
{%- if vif.mtu %}
set interfaces ethernet {{ vif.parent.name }} vif {{ vlan.vid }} mtu {{ vif.mtu }}
{%- endif %}
{%- endfor %}
{% endfor %} It looks a bit of a wall of text so I'm sure there's a neater way to express that ^ Critique welcome. |
Beta Was this translation helpful? Give feedback.
-
Yeah, the Swagger docs are awesome for listing out every query parameter which is a great reference, but I don't know of an easy way to list all the Django object filters as they are used in Jinja2 templates (or graphql). There are some hints here
https://demo.netbox.dev/static/docs/administration/netbox-shell/
https://docs.djangoproject.com/en/4.2/ref/models/querysets/#id4
which is great, but having a lookup table for reference would be easier instead of having to use my slow brain to find this doc and calculate what the filter should look like for a particular object type.
—
Mark Tinberg ***@***.***>
Division of Information Technology-Network Services
University of Wisconsin-Madison
…________________________________
From: ross-cello ***@***.***>
Sent: Monday, August 21, 2023 2:30 AM
To: netbox-community/netbox ***@***.***>
Cc: Subscribed ***@***.***>
Subject: Re: [netbox-community/netbox] Jinja templates - what object properties are available? (Discussion #12568)
Ugh dammit, I tried permutations of both selectattr("family","equalto",6) and intf.ip_addresses.filter(address__family=4) but didn't get the syntax quite right, ending in failure! Still boils down to an issue of education. Thanks again for delivering.
I'll edit above once I refined. Needed to jig a bit to factor in first loop ip mtu and ip6 enable
{% for intf in device.interfaces.all() %}
!
interface {{ intf.name }}
{%- for ip in intf.ip_addresses.filter(address__family=4) %}
{%- if loop.first %}
ip mtu 1500
ip address {{ ip.address.ip }} {{ ip.address.netmask }}{% else %}
ip address {{ ip.address.ip }} {{ ip.address.netmask }} secondary{% endif %}
{%- else %}
no ip address
{%- endfor %}
{%- for ip in intf.ip_addresses.filter(address__family=6) %}
{%- if loop.first %}
ipv6 enable
ipv6 mtu 1500
ipv6 address {{ ip.address }}{% else %}
ipv6 address {{ ip.address }}{% endif %}
{%- else %}
no ipv6 address
{%- endfor %}
load-interval 30
{% endfor %}
!
I'm okay with that level of duplicity. It actually resembles typical syntax for secondaries. Please go easy on me if you see opportunities to refine futher. XD
—
Reply to this email directly, view it on GitHub<#12568 (reply in thread)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AAS7UMYDPYDQFDD2NPABIJTXWMFBZANCNFSM6AAAAAAX7D5R7A>.
You are receiving this because you are subscribed to this thread.Message ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
This is an amazing thread, thanks to all the fine folks who contributed to this discussion. I was able to get my templates built completely a few weeks after the feature was released (with some help from slack forum) but I've learned a lot by just reading this thread. |
Beta Was this translation helpful? Give feedback.
You can check the code:
netbox/netbox/dcim/models/device_components.py
Lines 670 to 675 in b7f028f
Alternatively you can print all the fields on the model you are working with in
nbshell
:print([f"{f.name} - {type(f).__name__}" for f in Interface._meta.get_fields()])