A Python script that generates a Cisco config *. A sample that fills parameters using Jinja2. It seems to be very versatile, so make a note for yourself. If you prepare two config templates including variables and CSV that summarizes the values for variables and execute the script, multiple configs will be output as files.
Template engine for Python. For more information, see Honke.
The name Jinja was chosen because it’s the name of a Japanese temple and temple and template share a similar pronunciation. It is not named after the city in Uganda.
Japanese temples (shrines) have similar pronunciations to templates. (There is a city called Jinja in Uganda, but that's not it)
Make Jinja2 available with pip. Prepare three files and one directory (each explained below).
~ $pip3 list | grep Jinja2
Jinja2 (2.8)
~ $ls
build_templates.py config_template.txt configs inventory.csv
~ $
It's empty.
~ $ls ./configs
~ $
~ $cat inventory.csv
hostName,serialNumber,platformId,site,ipAddress,subnet,username,password,enablepass
Cat01,12345678901,WS-C2960X-48FPD-L,Tokyo,10.10.10.101,255.255.255.0,cisco,C1sco12345,C1$co
Cat02,22345678901,WS-C2960X-48FPD-L,Osaka,10.10.10.102,255.255.255.0,cisco,C1sco12345,C1$co
Cat03,32345678901,WS-C2960X-48FPD-L,Nagoya,10.10.10.103,255.255.255.0,cisco,C1sco12345,C1$co
~ $cat config_template.txt
hostname {{hostName}}
!
enable password {{enablepass}}
!
username {{username}} password 0 {{password}}
no aaa new-model
!
int vlan 1
ip address {{ipAddress}} {{subnet}}
!
end
As already referenced in the variables section, Ansible uses Jinja2 templating to enable dynamic expressions and access to variables.
build_templates.py
# -*- coding: utf-8 -*-
import jinja2
import csv
CONFIGS_DIR= "./configs/"
DEVICES="./inventory.csv"
TEMPLATE="./config_template.txt"
def build_templates(template_file, devices):
templateLoader = jinja2.FileSystemLoader('./')
templateEnv = jinja2.Environment(loader=templateLoader)
template = templateEnv.get_template(template_file)
f = open(devices, 'rt')
try:
reader = csv.DictReader(f)
for dict_row in reader:
outputText = template.render(dict_row)
config_filename = CONFIGS_DIR + dict_row['hostName'] + '-' + dict_row['site'] + '-config'
with open(config_filename, 'w') as config_file:
config_file.write(outputText)
print("Config generation: %s" % config_filename)
finally:
f.close()
if __name__ == "__main__":
build_templates(TEMPLATE, DEVICES)
--Read line by line (device by device) from CSV file with Python dictionary (csv.DictReader) --Variable completion (template.render (dict_row)) to template and output --Loop as many as the number of devices (for dict_row in reader) ――The way to write Jinja2 is written separately, but it seems that you can write even one as follows.
Quote
import os
import jinja2
def render(tpl_path, context):
path, filename = os.path.split(tpl_path)
return jinja2.Environment(
loader=jinja2.FileSystemLoader(path or './')
).get_template(filename).render(context)
~ $python3 build_templates.py
Config generation: ./configs/Cat01-Tokyo-config
Config generation: ./configs/Cat02-Osaka-config
Config generation: ./configs/Cat03-Nagoya-config
~ $
~ $ls ./configs/
Cat01-Tokyo-config Cat02-Osaka-config Cat03-Nagoya-config
~ $
~ $cat ./configs/Cat01-Tokyo-config
hostname Cat01
!
enable password C1$co
!
username cisco password 0 C1sco12345
no aaa new-model
!
int vlan 1
ip address 10.10.10.101 255.255.255.0
!
end
~ $
~ $
~ $cat ./configs/Cat02-Osaka-config
hostname Cat02
!
enable password C1$co
!
username cisco password 0 C1sco12345
no aaa new-model
!
int vlan 1
ip address 10.10.10.102 255.255.255.0
!
end
~ $
~ $
it is a good feeling. It seems that it can be used for other purposes.
Usage of csv.DictReader ... Easy-to-understand explanation of CSV parsing CiscoDevNet / apic-em-samples-aradford ... It's messy, but it contains a lot.
Recommended Posts