How to upgrade JunOS remotely via NETCONF
In this post I would like to explain how to upgrade JunOS on a router remotely. Imagine that you have dozens of routers and you would like to script it somehow. Below is a script I have written in python. I must say that it really took me some time to comprehend paramiko API but finally I wrote one which does really work. As you might have known, NETCONF is a fantastic protocol by which you can send RPC calls to remote devices. This script opens a netconf channel and sends these command inside this channel.
By using the predefined connection parameters, script opens the netconf channel and sends the command in variable SOFT_ADD which orders the device to fetch the software from JUNOS_URL and then upgrade it.
#!/usr/bin/python # A script which upgrades JunOS remotely import paramiko import socket import time import sys ROUTER_IP='172.16.1.1' USERNAME='root' PASSWORD='root123' JUNOS_URL='http://172.16.1.3/junos-srxsme-11.1R3.5-domestic.tgz' ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy( paramiko.AutoAddPolicy()) CLOSE = """""" SOFT_ADD = """ """ socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM) socket.connect((ROUTER_IP,830)) trans = paramiko.Transport(socket) trans.connect(username=USERNAME, password=PASSWORD) #CREATE CHANNEL FOR DATA COMM ch = trans.open_session() name = ch.set_name('netconf') #Invoke NETCONF ch.invoke_subsystem('netconf') #SEND COMMAND ch.send(SOFT_ADD) #Recieve data returned data = ch.recv(2048) while data: data = ch.recv(1024) print data, #if data.find('') == 0: if data.find('') != -1: #We have reached the end of reply ch.send(CLOSE) ch.close() trans.close() socket.close() """+JUNOS_URL+"""
Lets see this script in action; (because it is still a primitive one expect some errors in output but it does the job)
root@linux:~/sbin/netconf# python junos.py]]>]]> urn:ietf:params:xml:ns:netconf:base:1.0 urn:ietf:params:xml:ns:netconf:capability:candidate:1.0 urn:ietf:params:xml:ns:netconf:capability:confirmed-commit:1.0 urn:ietf:params:xml:ns:netconf:capability:validate:1.0 urn:ietf:params:xml:ns:netconf:capability:url:1.0?protocol=http,ftp,file http://xml.juniper.net/netconf/junos/1.0 http://xml.juniper.net/dmi/system/1.0 31018 ]]>]]> hup 0
Isn’t it cool? You can include multiple routers to ease upgrade operations or anything you want. If you want to do more, you can check paramiko API along with RPC call documentation to extend your scripts and do more stuff with it.
After I have written this post I have noticed that I forgot to mention to enable netconf protocol in JunOS. Here is the command;
junos# set system services netconf ssh junos#commit
Hi,
Check out NCClient, a NETCONF client written in Juniper that, among many other things, hides some of the SSH details of paramiko under a easy-to-use API. Should work very well for the type of tasks you’re looking at.
…and the URL is: http://schmizz.net/ncclient/
…and it’s not written in “Juniper” but “Python”. Even though I’d be very curious to see something written in Juniper.
Hi Carl,
I had taken a look at this client some time ago. To be honest, I am studying python nowadays so I prefer to do the things a bit harder way due to that but I will look into it once again. Thanks for your comment.
Very helpful — I found that terminating the script works better using this stragety:
#Recieve data returned
data = ch.recv(2048)
while data:
data = ch.recv(1024)
print data,
if data.find(”) != -1:
#We have reached the end of reply
ch.send(CLOSE)
Thanks for posting this!
thanks for your contribution too Charles!
Why have you created ssh = paramiko.SSHClient()
Is it really necessary ?
According to paramiko manual it is necessary indeed. If you think it isn’t, I would be happy to hear the reason.
hi,
I’m newbie in python
what script should be added, so it support for multiple router
thanks
You don’t even have to use python to run through multiple routers. You can write a simple bash script which reads a file containing IP addresses and you can pass the argument to this script. It needs a bit modification though.
great article
but please have a look to below 2 links
https://github.com/Juniper/py-junos-eznc
https://techwiki.juniper.net/Automation_Scripting/Junos_OS_PyEZ
Thank you Nitin!
Hi Sir,
Thanks for sharing the script. Does this script also support Juniper Virtual-chassis switches ? If not can you explain how would you do that?
Thanks