Jinja2 Basics

The Basic :
Example of a configuration in one script :

import jinja2

dict_variables = {‘key’:  ‘value’, etc…}

template_cfg = ”’
config…{{ .key }}
config…{{ .key }}
config….{{ .key }}
“””
template = jinja2.Template(template_cfg)
print(template.render(dict_variables)

To access :
a key :

{{ dict_name.key }}
Key, Value :
{{ dict_name.items }}

 

Decoupling the jinja2 template from the python script :

import jinja2

dict_vars = {‘peer1_ip’: ‘10.10.10.1’, ‘peer1_as’: ’40’}

#template_file = ‘template.j2’
with open(‘template.j2’) as f:
….bgp_template = f.read()

t = jinja2.Template(bgp_template)
print(t.render(dict_vars))

Adding conditional in template :

Python Script :

import jinja2

network_routes = [‘10.10.10.0/24’, ‘20.20.20.0/24’, ‘30.30.30.0/24’]
bgp_dict = {‘peer1_ip’: ‘10.10.10.1’, ‘peer1_as’: ’20’,’network_routes’: network_routes,’local_as’: ’30’,
‘ipv6_enable’: True, ‘peer1_ipv6’: ‘2001:0db8:85a3:0000:0000:8a2e:0370:7334’}

#template_file = ‘template.j2’
with open(‘template_conditional.j2’) as f:
bgp_template = f.read()

t = jinja2.Template(bgp_template)
print(t.render(bgp_dict))

Template Jinja2 :

feature bgp
router {{ local_as }}
address-family ipv4 unicast
{%- for route in network_routes %}
network {{ route }}
{%- endfor %}
neighbor {{ peer1_ip }} remote-as {{ peer1_as }}
update-source lo0
ebgp-multihop 2
{%- if ipv6_enable %}
address-family ipv6 unicast
neighbor {{ peer1_ipv6 }}
{% endif %}

Using a for Loop the jinja2 template from the python script  for repetitive commands ( example bgp network command ):

Python script :

import jinja2

network_routes = [‘10.10.10.0/24’, ‘20.20.20.0/24’, ‘30.30.30.0/24’]
bgp_dict = {‘peer1_ip’: ‘10.10.10.1’, ‘peer1_as’: ’20’,’network_routes’: network_routes,’local_as’: ’30’}

#template_file = ‘template.j2’
with open(‘template_loop.j2’) as f:
….bgp_template = f.read()

t = jinja2.Template(bgp_template)
print(t.render(bgp_dict))

template_loop.j2  ( the ‘ –  ‘ after the % is to remove the added line done each time its looping )

feature bgp
router {{ local_as }}
….address-family ipv4 unicast
……..{%- for route in network_routes%}
……..network {{ route }}
……..{%- endfor %}
….neighbor {{ peer1_ip }} remote-as {{ peer1_as }}
……..update-source lo0
…….ebgp-multihop 2
…….address-family ipv4 unicast

Using Nested Loop the jinja2 template :

Python Script :

import Jinja2

Dict_var = {
“routers”: {
‘rtr1’: ‘10.10.10.1’,
‘rtr2’: ‘10.10.10.2’,
‘rtr3’: ‘10.10.10.3’,
},

“switches”: {
‘sw1’: ‘10.10.10.4’,
‘sw2’: ‘10.10.10.5’,
‘sw3’: ‘10.10.10.6’,
}

}

Jinja2 Template :

template = ”’

{%- for router_var, ip_addr_var in routers.items() %}
Router : {{ router_var }}  IP : {{ ipadrr_var }}
….{%- for sw_var, ip_addr2_var in switches.items() %}
….Switches : {{ sw_var }}  IP : {{ ip_addr2_var }}
….{%- endfor %}
{%- endfor %}

”’

Reference :
Python for Network Engineers

Leave a Comment