Network Automation Project – Part 1
Hi everyboy, today I want to share with you a project I’ve worked on during the past days. For this project I’ve been inspired by the Facebook NetEng team who created the #netengcode facebook group after a presentation a NANOG where they performed a tutorial on Network Automation and, specifically, on how they developed an auto-remedation tool. Beside all the really interesting contents, the tool was developed using DB interaction using Python. Since I’ve never done anything like this, I’ve decided to make some practice coding a little project.
As I said, I’ve been inspired by their work and code, and my project contains some lines of theirs (limited to some db.py’s lines). Anyway, let’s start 🙂
[The whole project code can be found on GitHub, here]
SCENARIO
As usually, the network is built using GNS3 with VirtualBox.
The devices are minimally configured with the essentials to provide basic connectivity and SSH access to the user gabriele.
THE TOOL
The project directory is composed by several files:
gabriele@gabriele-VirtualBox:~/Desktop/project$ ls bgp.py network_automation_project.py db.py push.py devices.txt interfaces.py
The network_automation_project.py file is the main file that we will be execute. An high level description of the project is:
- The user define a list of devices to be added inside the network using the devices.txt text file.
- The “python network_automation_project.py [-u username -p password -f textfile]” command is executed.
- The tool will ask for any missing parameters and then will start to parse devices.txt data inside a sqlite database.
- The tool will ask the user some facts about the network (interface names and addresses and BGP informations).
- The tool will store those additional information inside the db.
- The tool will generate the proper configuration based on the data provided.
- The tool will push the configuration to the devices.
In this stage the project is executed as dry run, but I’d like to add some multithreding function.
THE DB
As I said, the db is a sqlite one. I’ve defined 3 tables: devices, interfaces and neighbors.
DEVICES_SCHEMA = (''' CREATE TABLE devices ( router_id TEXT PRIMARY KEY, hostname TEXT, vendor TEXT, ports INT, as_number INT, ip_address TEXT, configured DEFAULT 0) ''') NEIGHBORS_SCHEMA = (''' CREATE TABLE neighbors ( router_id TEXT PRIMARY KEY, neighbors_list TEXT) ''') INTERFACES_SCHEMA = (''' CREATE TABLE interfaces ( router_id TEXT PRIMARY KEY, interface TEXT) ''')
RUN IT!
Let’s see what happens if we run it.
..$ python network_automation_project.py -u gabriele -p projectme10 -f devices.txt BUILDING DB { "1.1.1.1": { "as_number": "10", "hostname": "Router1", "ip_address": "172.16.1.1", "ports_number": "12", "vendor": "Cisco" }, "2.2.2.2": { "as_number": "20", "hostname": "Router2", "ip_address": "172.16.2.2", "ports_number": "36", "vendor": "Cisco" } }
As you can see, I’ve executed the tool with the options -u -p -f so that it will run directly without asking any missing information first.
The devices.txt file appears as follows:
1.1.1.1;Router1;Cisco;12;10;172.16.1.1; 2.2.2.2;Router2;Cisco;36;20;172.16.2.2;
The format is router_id;hostname;vendor,number_of_ports;as_number;ip_address_to_ssh;
After that all the parameters are parsed, the tool will start building and populating the database.
If everything goes well, then we can start to configure our ports.. [CLICK IMAGES TO ENLARGE]
The tool informs me I can configure up to 12 ports and ask me how many ports I whish to configure right now. I choose 2 ports and then I have to enter the information required. To make sure the user will insert a valid IP address I’ve used the netaddr Python module. All the data is then stored inside the db.
Then we enters the BGP configuration phase..
After this, the tool starts to generate the proper configuration command based on the data stored inside the db. Then, the configuration is pushed into the devices using the netmiko Python API and, lastly, all the running configuration is saved in a text file with the format hostname_configuration.txt
Now it’s the time to configure the other device as well.
After that, let’s verify eveything has gone fine issuing a “show bgp” command on Router2:
It seems good. R2 now it’s named Router2 and all the BGP information are received correctly. In addition to this, we can also examine the 2 new created text files: Router1_configuration.txt and Router2_configuration.txt.
GOING FURTHER
The project is not finished yet and I’d like to add some more functionalities and fix some problems as well. Specifically, I’d like to:
- Improve DB interaction, since sometimes some error occurs when data is already stored.
- Add some multivendor support, As you can see from the actual code, I’ve included some function to generate Juniper configurations, but I leaved them blank.
- Add some multithreading behaviour.
- Add some “service” like traffic draining.
Finding some other guy who wish to contribute would be great. So if you’re interested or if you have some hints please reach out 😀
I hope you will find this post interesting. Any comments are more than welcome 🙂
Again, the whole project code can be found here
P.S.
I’ve started contributing to other network automation project on github. I think this is a great way to learn and understand things better. By now I’ve only pushed few lines of code to the netcli_to_dict project, which is “a collection of scripts that provide samples of how to iterate through the output of an executed command and return a dictionary, or a list of dictionaries, based on information could be useful in various automation projects.”
P.P.S
Few days ago I went to Taormina with my girlfriend. We spent some great time together dining and walking through the beautiful streets of that little city. Then, I saw the “I have a dream…” wall, where everyone can write something. So I decided to take the chunk and write “NETENG INTERN 2016”. Who knows.. 🙂
P.P.P.S
For those wondering, I’m not an a**hole and so I’ve written something romantic for my girlfriend before writing the above thing 😀