Saturday, October 14, 2023

Automating Network Configurations with Jinja2 and Python: A Step-by-Step Guide

 In this post, I worked on collecting a code that works with Jinja template.


the nice thing in working with Jinja is that you can have baseline configs that will be used to all devices and also have variables that will be changed according to your need.


for example: in each device which can be a router, you will have:

1. southbound links to switches and let's assume an interface used for this G1/0/48

2. you have NTP servers to be configured on these routers

3. hostnames

4.routing protocol

.......etc.


all these can be variable in Jinja template which we can use along with python to generate configs. and maybe even later we can use to push to network nodes.

this can automate our work, on the longterm this can make our job easier and more consistent.


let's start by making a directory which we can call routers_configs

in this directory we will have three files:

1. jinja file which is our router configs template and it should have the following:

file name is >> cisco_template.j2

as you can see in template below, you can have a complete configuration file ready and change the parts that you want them to be replaced from your CSV file with the {{ variable }} as below>>

hostname {{ router_name }}
ntp server {{ ntp_ip }}
interface loopback 0
ip address {{ ip_address }} 255.255.255.255
router {{ routing_pro }}
int gig {{ int_number }}

2. devices information, which can be a CSV file where you have saved your new devices list and information that you will add to these devices. 

the file can be used as below with comma to separate the rows.

router-bgd, 192.68.1.2, 2.2.2.2, ospf 1, 1/0/48

router-suly, 172.16.1.1, 1.1.1.1, ospf 1, 1/0/48

rtr-erbil, 10.0.0.1, 1.1.1.1, ospf 1, 1/0/48

router-bgd2, 192.68.1.3, 2.2.2.2, ospf 1, 1/0/48

router-suly2, 172.16.1.2, 1.1.1.1, ospf 1, 1/0/48

rtr-erbil2, 10.0.0.2, 1.1.1.1, ospf 1, 1/0/48

3. file is the python code that we will use to render the information in these two files and printout the configs to an external text files for each device. and we will name the file as ciscojinja.py

import csv
from jinja2 import Environment, FileSystemLoader
#these must always added

file_loader = FileSystemLoader('.') #check this directory to find jinja template

#load environment

env = Environment(loader=file_loader)

template = env.get_template('cisco_template.j2') #find the jinja file and get it

with open ('info.csv') as info_source:
csv_file = csv.reader(info_source)
for row in csv_file:
csv_router_name = row[0]
csv_ip = row[1]
csv_ntp_server = row[2]
routing_protocol = row[3]
interface_slot = row[4]
output = template.render(router_name=csv_router_name, ip_address=csv_ip,
ntp_ip=csv_ntp_server,
routing_pro=routing_protocol,
int_number=interface_slot) #these names must be compatible with jinja template names
with open(csv_router_name + '.txt', 'w') as configs:
configs.write(output)






when you run the python code, you will notice that other text files will be generated that contain configuration rendered from the CSV data. check below:














you can copy these and iterate to what else you need. next will be added more jinja templates to specific parts of configs, for example: jinja template for bgp configs only or ospf only or ACL's and prefixes.


Hope this is helpful.






Monday, October 2, 2023

Using Python and Netmiko to Access and Retrieve Palo Alto Firewall Data

In this post, I will be using the python code below to login a my Palo Alto Firewall using NETMIKO.
the code defines two functions that we will use to get the information we need from the Firewall.
note that you can replicate the function to add other (net_connect.send_commands)
then print out, or even more that you can also add more IP addresses 
for example: pan2_ip and pan3_ip then you will only need to use the last two lines of the code:
pan2_ip= get_int(pan2_ip)
print(pan2_ip)
import netmiko

pan_ip= '192.168.1.250'

username='python'
password='python1234'
device_type='paloalto_panos' #this must be one of the types supported by Netmiko
port='22'

#get the system information of the PANOS
def get_info(ip):
net_connect = netmiko.ConnectHandler(ip=ip, device_type=device_type, username=username,password=password, port=port)
return net_connect.send_command('show system info')
pan_info= get_info(pan_ip)
print(pan_info)

#get the IP information of the PANOS
def get_int(ip):
net_connect = netmiko.ConnectHandler(ip=ip, device_type=device_type, username=username,password=password, port=port)
return net_connect.send_command('show interface all')
pan_ip= get_int(pan_ip)
print(pan_ip)
#end

Securing Small Businesses: A Roadmap to Continuity and Confidence

  In an ever-expanding world of cyberspace, the prevalence of cyber-attacks grows daily. Allocating budgetary resources to network and cyber...