Skip to main content

j2ipaddr

Jinja2 filters for IP addresses, the easy way

Why

On networking and network automation, we need to extract info about IP addresses as a combination of two values:

  • a host address
  • a subnet mask

For 10.10.10.5/24, the host address is 10.10.10.5 and the subnet mask is 255.255.255.0, and its prefix length is 24.

There is additional information we can infer from this single item, as its network address, broadcast address.

Useful data for network engineers are wildcards or hostmasks, network size, class, type, and so on.

Jinja2 provides several integrated filters to work with, however it can be complicated to use complex data types.

Ansible provides a way to work this on its ansible.utils.ipaddr collection.

However, probably you won't need the entire Ansible package just to be able to use it.

This package intends to provide a set of filters and handler to the Python 3 netaddr module, on a way that is hopefully easy and lightweight to use.

What

Included filters are the following. IPv4 and IPv6 are supported. Every filter returns a str, except ip_prefixlen and ip_network_hosts_size which return an int. Surrounding whitespace in the input is ignored.

ip_address(addr)

Returns an IP address for a combination of IP address and subnet mask

ip_address('10.10.10.5/24')
> 10.10.10.5
{{ '10.10.10.5/24' | ip_address }}
> 10.10.10.5

ip_prefixlen(addr)

Returns a prefix length for a combination of IP address and subnet mask

ip_prefixlen('10.10.10.5/24')
> 24
{{ '10.10.10.5/24' | ip_prefixlen }}
> 24

Returns an int.

ip_netmask(addr)

Returns a subnet mask for a combination of IP address and subnet mask

ip_netmask('10.10.10.5/24')
> 255.255.255.0
{{ '10.10.10.5/24' | ip_netmask }}
> 255.255.255.0

ip_hostmask(addr)

Returns a wildcard or hostmask for a combination of IP address and subnet mask

ip_hostmask('10.10.10.5/24')
> 0.0.0.255
{{ '10.10.10.5/24' | ip_hostmask }}
> 0.0.0.255

ip_wildcard(addr)

Alias for ip_hostmask(addr)

ip_wildcard('10.10.10.5/24')
> 0.0.0.255
{{ '10.10.10.5/24' | ip_wildcard }}
> 0.0.0.255

ip_network(addr)

Returns a network address for a combination of IP address and subnet mask

ip_network('10.10.10.5/24')
> 10.10.10.0
{{ '10.10.10.5/24' | ip_network }}
> 10.10.10.0

ip_broadcast(addr)

Returns a broadcast address for a combination of IP address and subnet mask

ip_broadcast('10.10.10.5/24')
> 10.10.10.255
{{ '10.10.10.5/24' | ip_broadcast }}
> 10.10.10.255

Returns None when there is no broadcast address: IPv6, /31 and /32. Jinja2 renders None as the text "None", so guard it with {% if %} or | default('') if those can show up.

ip_network_hosts_size(addr)

Returns the number of usable hosts for a combination of IP address and subnet mask

ip_network_hosts_size('10.10.10.5/24')
> 254
{{ '10.10.10.5/24' | ip_network_hosts_size }}
> 254

Returns an int. The network and broadcast addresses are not counted. /31 gives 2 (RFC 3021) and /32 gives 1.

ip_network_first(addr)

Returns the first usable address in network for a combination of IP address and subnet mask

ip_network_first('10.10.10.5/24')
> 10.10.10.1
{{ '10.10.10.5/24' | ip_network_first }}
> 10.10.10.1

For /31 and /32 there is nothing to skip, so it returns the first address of the network.

ip_network_last(addr)

Returns the last usable address in network for a combination of IP address and subnet mask

ip_network_last('10.10.10.5/24')
> 10.10.10.254
{{ '10.10.10.5/24' | ip_network_last }}
> 10.10.10.254

For /31 and /32 there is nothing to skip, so it returns the last address of the network.

Invalid input

An input that is not a valid IP address or network (including None or an undefined variable) raises netaddr.AddrFormatError with a message that shows the offending value:

invalid IP address or network: '10.0.0.300/24' (expected something like '10.10.10.5/24')

How

Simply install with pip.

pip install j2ipaddr

To insert the filters on your Jinja2 processor, simply use the following syntax. The filter name can be changed by adjusting the dict key name.

import jinja2
from j2ipaddr import filters
jinja2.filters.FILTERS['ip_prefixlen'] = filters.ip_prefixlen

Or, probably an easier way, use the following one-liner to load all the filters into your Jinja2 filters

import jinja2
from j2ipaddr import filters
jinja2.filters.FILTERS.update(filters.load_all())

On your templates, you can do this as an example:

Variables

host:
  interfaces:
    Te1/0/1:
      ipv4_addresses:
        - 10.10.10.5/24

Template

router ospf 10
  network {{ host.interfaces.Te1/0/1.ipv4_addresses[0] | ip_network }} {{ host.interfaces.Te1/0/1.ipv4_addresses[0] | ip_wildcard }} area 0.0.0.0

The output would looks like this:

router ospf 10
  network 10.10.10.0 0.0.0.255 area 0.0.0.0

Metadata

Release files for j2ipaddr 1.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for j2ipaddr 1.1.1
File Size Uploaded Provenance Actions
j2ipaddr-1.1.1.tar.gz 16.4 kB Without provenance Details for j2ipaddr-1.1.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for j2ipaddr 1.1.1
File Interpreter ABI Platform Actions
j2ipaddr-1.1.1-py3-none-any.whl Python 3 none any Details for j2ipaddr-1.1.1-py3-none-any.whl

Total release size: 33.2 kB

Release files / j2ipaddr-1.1.1.tar.gz

Download URL j2ipaddr-1.1.1.tar.gz
Size 16.4 kB
Tags Source
SHA-256 checksum
How to use checksums
2116ae29de9071bd461cdc30c26005098cc91a8dd42f06e331196679f73aa5a1
BLAKE2b-256 checksum
How to use checksums
afd4bafb1d985de3bc8f8447538276e9442bcc40bc81dab9a41b5d69329d651f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.25

Release files / j2ipaddr-1.1.1-py3-none-any.whl

Download URL j2ipaddr-1.1.1-py3-none-any.whl
Size 16.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
867e312f99621baf48a983893cddf2dd924bd78deaf2f9773114ef9fe24a58d4
BLAKE2b-256 checksum
How to use checksums
2ac4a827bb7bc8d5e185589dbe3791ca3eb3e3f9f5dd4175e1daf8cd9dda26cb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.25

Security for j2ipaddr 1.1.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page