Stefan Lieberth

Network Consultant / Solution Architect

 

 

 

Devops is great opportunity to drive network provisioning and network operations into new areas.

 

YAML is in my view the best method to store configuration data in a vendor independent human readable format. From readability perspective YAML is by far better than XML or JSON.

 

Based on the blogs form Jeremy Schulman,  Matt Oswald and  Sreenivas Makam I did a small exercise with an abstract YAML configuration data, This abstract YAML configuration is converted into a python data structure.

The Jinja2 rendering machine uses the python data structure and vendor specific templates to create into Cisco or Juniper configurations.

 

The code below is python3 based. Therefor there are minor differences to the above mentioned blogs, which use python2

 

 

 

Please the below the python script, which includes  the YAML data and the Jinja2 templates:

 

from jinja2 import Template

from pprint import pprint

import yaml

 

YAML data as string

yamlConfig = """---

hostname: thisTestSystem

ntpServers:

  - 10.1.1.1

  - 11.1.1.1"""

 

load YAML data into a python data structure configDict.

configDict = yaml.safe_load(yamlConfig)

 

JINJA2 template for Cisco, which uses  the information from the python data structure.

ciscoTemplateString = """hostname {{ config['hostname'] }}

{%- for server in config['ntpServers'] %}

ntp server {{ server }}

{%- endfor %}"""

 

instantiate the Jinja2 template object with the Cisco template and render the template using the configData.

ciscoTemplate = Template(ciscoTemplateString)

print (ciscoTemplate.render(config=configDict))

 

 

JINJA2 template for Juniper,

juniperTemplateString = """set system hostname {{ config['hostname'] }}

{%- for server in config['ntpServers'] %}

set system ntp-server {{ server }}

{%- endfor %}"""

 

instantiate the Jinja2 template object with the Juniper template and render the template using the configData.

juniperTemplate = Template(juniperTemplateString)

print (juniperTemplate.render(config=configDict))

 

 

 

Output (with some addional print statements:

########################yaml Config#########################

---

hostname: thisTestSystem

ntpServers:

  - 10.1.1.1

  - 11.1.1.1

............................................................

#####################loaded config Dict#####################

{'hostname': 'thisTestSystem', 'ntpServers': ['10.1.1.1', '11.1.1.1']}

............................................................

###################cisco jinja2 template####################

hostname {{ config['hostname'] }}

{%- for server in config['ntpServers'] %}

ntp server {{ server }}

{%- endfor %}

............................................................

####################cisco config snippet####################

hostname thisTestSystem

ntp server 10.1.1.1

ntp server 11.1.1.1

............................................................

##################juniper jinja2 template###################

set system hostname {{ config['hostname'] }}

{%- for server in config['ntpServers'] %}

set system ntp-server {{ server }}

{%- endfor %}

............................................................

###################juniper config snippet###################

set system hostname thisTestSystem

set system ntp-server 10.1.1.1

set system ntp-server 11.1.1.1

............................................................