Sometimes the best way to learn to do something useful with a scripting language is with a starting point and a real world use case. While I don’t consider myself a Python expert, I can usually figure out how to put things together and get a task accomplished. For this article I challenged myself to create a simple script that performs the following:
- Open a file for a list of devices and credentials
- Log in to each device in the file using the credentials found
- Remove the current NTP server (18.104.22.168)
- Add a new NTP server (22.214.171.124)
- Save the configuration
I am sharing the script below as an example. Note this Python file uses paramiko. Therefore that library needs to be installed (MAC users – sudo pip install paramiko)
import paramiko ####devices.txt format #### username,password,host #### username,password,host qbfile = open("devices.txt", "r") for aline in qbfile: values = aline.split(",") myuser = values mypass = values myhost = values.rstrip() ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(myhost, username=myuser, password=mypass) channel = ssh.invoke_shell() stdin = channel.makefile('wb') stdout = channel.makefile('rb') stdin.write(''' conf t no ntp server 126.96.36.199 ntp server 188.8.131.52 end wr exit ''') print stdout.read() ssh.close() qbfile.close()
cisco,cisco,172.16.1.132 cisco,cisco,172.16.1.133 cisco,cisco,172.16.1.134
Running NTPChange.py yields the following output.
csr1000v-1# csr1000v-1# conf t Enter configuration commands, one per line. End with CNTL/Z. csr1000v-1(config)# no ntp server 184.108.40.206 csr1000v-1(config)# ntp server 220.127.116.11 csr1000v-1(config)# end csr1000v-1# wr Building configuration... [OK] csr1000v-1# exit csr1000v-2# csr1000v-2# conf t Enter configuration commands, one per line. End with CNTL/Z. csr1000v-2(config)# no ntp server 18.104.22.168 csr1000v-2(config)# ntp server 22.214.171.124 csr1000v-2(config)# end csr1000v-2# wr Building configuration... [OK] csr1000v-2# exit csr1000v-3# csr1000v-3# conf t Enter configuration commands, one per line. End with CNTL/Z. csr1000v-3(config)# no ntp server 126.96.36.199 csr1000v-3(config)# ntp server 188.8.131.52 csr1000v-3(config)# end csr1000v-3# wr Building configuration... [OK] csr1000v-3# exit Process finished with exit code 0
Spot checking one of the routers shows that the script functioned as expected.
csr1000v-2#show run | sec ntp ntp server 184.108.40.206 csr1000v-2#
The files created for this example can be downloaded here.
While Python can become very complex and produce very complex functions, it doesn’t necessarily have to be. Specifically, this example shows a non-interactive example where the programmer is assuming the next commands to enter. There is no qualification or validation. My recommendation is to start with simple scripts and thoroughly test in a controlled environment prior to rolling out anything to hundreds (or thousands) of devices. Leveraging Python, and other scripting tools, can dramatically increase an engineer’s efficiency. However it is important to go through a thorough validation process before executing at scale.
Disclaimer: This article includes the independent thoughts, opinions, commentary or technical detail of Paul Stewart. This
may or may does not reflect the position of past, present or future employers.