python (jinja2) templates for network automation

Post on 17-Jul-2015

285 Views

Category:

Technology

3 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Python Templates for Network Automation

Rick Sherman

VulgarPython.com

What are templates and why use them?

A template is a text document where some or all of the content is automatically generated.

Templates are text files in the format you already work with.

Data is stored separated and automatically loaded.

Easily re-used and shared.

Quick Example – Configuration file

system {host-name tp8;name-server 192.168.5.68;domain-name shermdog.com;backup-router 192.168.71.254;root-authentication {

encrypted-password "$1$hKWBk3fAgDHF/"; ## Secret data

}}

Below is an example of a Junos configuration. The configuration data is highlighted in blue.

Quick configuration template

system {host-name {{ host_name }};name-server {{ dns_server }};domain-name {{ domain_name }};backup-router {{ backup_router }};root-authentication {

encrypted-password "{{ root_password }}"; ## Secret data

}}

Here is a Jinja2 template. The configuration bits have been replaced with variables. This allows us to separate the “how” from the “what”.

Template data source

---host_name: tp8dns_server: 192.168.5.68domain_name: shermdog.combackup_router: 192.168.71.254root_password: $1$hKWBk3fb$/

The data used to fill in the variables can come from a variety of sources such as Python dict, CSV, JSON, YAML, even databases. Here is an example of using YAML.

Templates are reusable text filesTemplates are enhanced text files in the format you already

work with.

They are easily reused, shared and modified because the configuration syntax (“how”) is separated from the

configuration data (“what”).

So why Jinja2?

• Prevalent in the DevOps / NetOps community

• Supported by Ansible and SaltStack

• Vast amounts of information published

• Easy to debug

• Line numbers of exceptions directly point to the

correct line in the template.

• Template inheritance

• Allows you to build a base “skeleton” template that

contains all the common elements of your site and

defines blocks that child templates can override.

• Execution is very fast

Jinja2 Template BasicsVariables are delimited by {{ … }} and expressions

(conditionals, loops, macros, blocks) by {% … %}

system {

host-name {{ host_name }};

name-server {

{% for dns_server in dns %}

{{ dns_server }};

{% endfor %}

}

}

If Statements

Template:

user {{ user.name }} {

authentication {

{% if user.passwd %}

encrypted-password "{{ user.passwd }}";

{% elif user.key %}

ssh-rsa "{{ user.key }}";

{% endif %}

}

}

If Statements

Rendered:

user rick {

authentication {

encrypted-password "$1$wDeov1";

}

}

For Loops

Template:

{% for interface_name in core_interfaces %}

{{ interface_name }} {

output-traffic-control-profile CORE-MAP;

}

{% endfor %}

For LoopsRendered:

xe-4/1/0 {

output-traffic-control-profile CORE-MAP;

}

xe-4/2/0 {

output-traffic-control-profile CORE-MAP;

}

xe-4/3/0 {

output-traffic-control-profile CORE-MAP;

}

Filters

Template:

{% for interface_name in core_interfaces %}

{{ interface_name }} {

description “{{ desc|upper }}”;

}

{% endfor %}

Jinja2 can programmatically manipulate data directly in the template. The library includes a large amount of built in filters such as default value, upper/lower, replace, etc.http://jinja.pocoo.org/docs/dev/templates/#builtin-filters

Filters

Rendered:

xe-4/1/0 {

description “UPSTREAM CON”;

}

xe-4/2/0 {

description “DOWNSTREAM CON”;

}

xe-4/3/0 {

description “MIRROR PORT”;

}

Include

Template:

system {

{% include “login.j2” %}

{% include “services.j2” %}

}

Jinja2 templates are able to directly include the content of files (such as ssh keys) and other templates.

This allows you to split a configuration into multiple pieces.

Include

Rendered:

system {

login {

user rick {

class super-user;

}

services {

ssh;

}

}

Block (Template Inheritance)

Jinja2 provides a very powerful mechanism of template inheritance.

Template inheritance allows you to build a base template that contains all the common elements / defaults of your configuration and defines blocks that child templates can override.

This provides great flexibility in generating base templates and selectively changing sections based on things like role or location.

Block – Parent Template

services {ssh;

{% block dhcp %}dhcp {

pool 0.0.0.0/0;}

{% endblock dhcp %}}

Here is a parent template that has wrapped the dhcpconfiguration in a block named ‘dhcp’.

The configuration listed inside of this block is the default value used if not overridden by a child template.

Block – Child Template

{% extends "parent.j2" %}

{% block dhcp %}

dhcp {

pool 10.0.0.0/24 {

domain-name shermdog.com;

}

}

{% endblock dhcp %}

Here is a child template that contains the ‘dhcp’ block. Because it extends the parent template, the dhcpconfiguration inside of the block will override the parents value.

Block – Rendered template

Rendered:

services {

ssh;

dhcp {

pool 10.0.0.0/24 {

domain-name shermdog.com;

}

}

}

Use templates for configurations!

You will have reusable templates that are easily shared, version controlled, and updated!

top related