This article runs through the basics of making a NETCONF connection to an SR OS device and obtaining the running configuration. It will cover a few elements:
This article is not a detailed article on how to use Python and it does not provide details on the only way to or recommended way to communicate with SR OS devices or write Python programs. The article will get you going with a way of automating SR OS in Python.
This article assumes that your system is not behind a proxy.
Element | Version |
---|---|
Linux workstation/server | CentOS 7 |
SR OS device running in Model-Driven mode | 19.7.R1 |
Python | 3.6 |
The default Python interpreter for CentOS 7 is currently Python 2. Python 2 will be end of life in 2020 so this tutorial will use Python 3.
Ensure that the epel-release Yum repository is installed and enabled:
yum install -y epel-release
Now install Python 3.6 and the Python virtual environment package:
yum install -y python36-distro virtualenv
The tools are installed to get started with Python. Python could be run natively, however, it is safer and more flexible to install and run Python in a virtual environment. This allows multiple instances of Python to be easily used on the same machine.
Choose a base directory for this tutorial and change to it. For this tutorial we will use sros-python-101.
mkdir sros-python-101
cd sros-python-101
Create the virtual environment called venv and enter into it with these commands:
virtualenv -p python3 venv
source venv/bin/activate
The prompt will change to include (venv) at the beginning. If you need to leave the virtual environment at any point you can type:
deactivate
Remain in the virtual environment to continue.
In this example, our program will use two libraries:
The argparse library is installed by default with Python so nothing is required for this; however, ncclient does need to be installed into our virtual environment. Install it now:
pip install -U ncclient
For this tutorial, the SR OS devices that we wish to target will be listed in an inventory file. Call this file inventory and enter the details of your device hostnames or IP addresses inside. The following is an example of an inventory file:
172.16.123.1
172.16.123.2
172.16.123.3
172.16.123.4
172.16.123.5
router6
It's time to create the main procedures. Create the sros-python-101.py file containing the following:
#!./venv/bin/python3
## Import the external libraries required
import argparse
from ncclient import manager
from ncclient.xml_ import *
## create_connection
# In: Hostname and Commandline arguments
# Out: NCClient Connection
def create_connection(host, args):
conn = manager.connect(host=host,
port=args.port,
username=args.username,
password=args.password,
hostkey_verify=False,
device_params={'name':'alu'})
return conn
## read_file
# In: filename
# Out: List containing all non-blank lines from filename
def read_file(filename):
f = open(filename, 'r')
output = f.read().splitlines()
output = [ line for line in output if line ]
f.close()
return output
## write_file
# In: filename and contents to be written to the file
# Out: Nothing (returns 0 on completion)
def write_file(filename, contents):
f = open(filename, 'w+')
f.write(contents)
f.close()
return 0
## get_arguments
# In: Nothing
# Out: The command line arguments
def get_arguments():
parser = argparse.ArgumentParser()
parser.add_argument("-i", "--inventory", help="Inventory Filename", required=True)
parser.add_argument("-u", "--username", help="NETCONF SSH Username", required=False, default='admin')
parser.add_argument("-w", "--password", help="NETCONF SSH Password", required=False, default='admin')
parser.add_argument("-p", "--port", help="NETCONF TCP Port", required=False, default=830)
args = parser.parse_args()
return args
### The main procedure. This is a springboard for the individual functions that
### are to be performed
def main():
## Get the commandline arguments
args = get_arguments()
try:
## Read in the inventory filename provided on the command line and receive a list
## of hosts within it
inventory = read_file(args.inventory)
except Exception as error:
print(error)
## For every host in the inventory file perform these actions
for host in inventory:
try:
## Create a NETCONF connection to the host
conn = create_connection(host, args)
## Issue the get-config RPC over our NETCONF connection and receive the running config
config = conn.get_config(source='running')
## Close the NETCONF connection with the host
conn.close_session()
try:
## Write the obtained running configuration (from the data/configure xpath) to a file
write_file(host, to_xml(config.xpath('data/configure')[0]))
except Exception as error:
print(error)
## Provide an on-screen prompt that the program has processed this host
print('Processed',host)
except Exception as error:
print(host,'Error',error)
### Start here. If called directly from the command line then run the main procedure
if __name__ == "__main__":
main()
This is your first Python program to connect to an SR OS model-driven router. It connects to each router in the inventory file in turn using NETCONF, by providing the username and password supplied. It obtains the running configuration of the router and saves this into a file with the filename matching that in the inventory.
Comments are provided within the code as a guide but here is a short explanation of the key elements.
The program starts with the main procedure.
The first thing the program does is obtain command line arguments using the get_arguments procedure. The program requires four inputs:
Next, the program reads the inventory file that was created earlier. The try and except statements allow the program to gracefully handle any error conditions. This returns a list of hosts.
For every host in the list, the program tries to open a NETCONF connection using the create_connection procedure. It passes to this the command line arguments and the hostname/IP from the inventory file and receives in return a NETCONF connection handler.
Using this connection handler the program executes the <get-config> RPC over NETCONF using the conn.get_config(source='running') command to receive the running configuration. This is then loaded into the config variable.
The NETCONF connection to the device is then closed. These are independent functions, meaning that multiple RPCs could be issued over the NETCONF connection before it is closed if this is what is desired.
Finally, the configuration is written to a file with the same name as the hostname/IP address provided in the inventory file. This file is written in XML format.
You can now execute your program directly from the command line; however, to do this we need to change the file permissions to ensure that it is executable.
chmod 0755 sros-python-101.py
If your program is executed with the -h flag, a help screen will be displayed to assist you with the command line arguments.
./sros-python-101.py -h
usage: sros-python-101.py [-h] -i INVENTORY [-u USERNAME] [-w PASSWORD]
[-p PORT]
optional arguments:
-h, --help show this help message and exit
-i INVENTORY, --inventory INVENTORY
Inventory Filename
-u USERNAME, --username USERNAME
NETCONF SSH Username
-w PASSWORD, --password PASSWORD
NETCONF SSH Password
-p PORT, --port PORT NETCONF TCP Port
Now the program can be executed with the command line arguments provided for your environment. In this case, the NETCONF username is netconf and the NETCONF user password is nokia123
./sros-python-101.py -i inventory -u netconf -w nokia123
Processed 172.16.123.1
Processed 172.16.123.2
Processed 172.16.123.3
Processed 172.16.123.4
172.16.123.5 Error Could not open socket to 172.16.123.5:830
router6 Error [Errno -2] Name or service not known
Any errors are handled gracefully and the error message is returned to the screen. In this example the IP address 172.16.123.5 is unreachable and the hostname router6 does not resolve in DNS/local hosts file.
We have covered how to install Python 3 and create a virtual Python environment. We have also covered installing additional Python libraries into this virtual environment.
We created our first Python program in order to obtain the running configuration from a number of devices.