Expressions and loops
Expressions, filters, arithmetic and loops in a design.
Expressions
An expression is written in {{ }} inside a YAML string, and can stand for a whole value or part of one:
| Pattern | Example | Gives |
|---|---|---|
| A variable | '{{ variables.site_name }}' | The variable's value |
| The containing object | '{{ parent }}' | The object that holds this one |
| A field of it | '{{ parent.site }}' | That object's site |
| The loop's variable | '{{ loop.i }}' | The current pass of the loop |
| A filter | '{{ loop.i | zeropad }}' | 01, 02 and so on |
| Arithmetic | '{{ loop.i * 2 - 1 }}' | A number worked out per pass |
| A function | "{{ nbd.lookup.endpoint('SW-01', 'Interface', 'eth0') }}" | The object the function finds |
| Part of a value | '{{ variables.rack_name }}-TOR-01' | Text with the value in it |
A function's arguments can hold expressions of their own, which are worked out first. Write the outer string in double quotes so its arguments can be in single quotes, as in the compute rack's cables.
Filters
A filter follows a value after |, one to an expression:
| Filter | Does | Example |
|---|---|---|
zeropad | Pads a number to two digits | 7 becomes 07 |
zeropad(N) | Pads a number to N digits | zeropad(3) makes 7 into 007 |
lower | Lower-cases text | DC1 becomes dc1 |
upper | Upper-cases text | dc1 becomes DC1 |
slugify | Makes a NetBox slug: lower-case letters and digits joined by single hyphens | Store 001 (US-West) becomes store-001-us-west |
Any other filter, or two in one expression, refuses the render.
When an expression can't be worked out
An expression the render can't resolve refuses the render, naming the object and the field: a loop's variable outside its loop, a variable the design doesn't declare, or a chain of filters.
Braces that aren't one of these expressions are text, and NetBox gets them as written. A config template's own {{ device.name }} is text the design means.
Loops
nbd_loop repeats an object, or a group of objects, once per pass:
devices:
- nbd_loop:
over: {start: 1, end: 10}
as: i
infra_type: Device
name: 'SERVER-{{ loop.i | zeropad }}'over takes:
| Form | Passes |
|---|---|
{start: 1, end: 10} | 1 to 10, both included |
3 | 1 to 3 |
[red, green, blue] | Each item, in order |
as names the loop's variable. Inside the loop, with as: i:
| Variable | Is |
|---|---|
loop.i | The pass number, or for a list, the item |
loop.index | The pass, counting from 1 |
loop.index0 | The pass, counting from 0 |
loop.first, loop.last | Whether this is the first or last pass |
loop.length | How many passes there are |
To repeat several objects together, list them under items:
cables:
- nbd_loop:
over: {start: 1, end: 3}
as: i
items:
- infra_type: Cable
label: 'CABLE-A-{{ loop.i }}'
- infra_type: Cable
label: 'CABLE-B-{{ loop.i }}'A loop can also repeat an included design: put design: and template_vars: beside nbd_loop, as the compute rack does for its servers.
A loop's bounds can't come from a variable yet, so a design that loops over the same count in several places repeats it in each.