[PYTHON] Tool to centrally acquire the configuration of Cisco / Juniper router

Overview

I made a tool to centrally acquire the config of the router group. The created tool is published on github. https://github.com/taijiji/ConfigCollector

Motivation made

I made it because I wanted to get the config of the router I manage for all devices at once and manage it with Git.

The original assumption was that I wanted to make a series of processes from [Read router list file]-> [Centralized acquisition of router config]-> [Push to Git remote repository] into a tool, but Git management is Based on the idea that it is better for the operator to do it manually, I cut out only the part to centrally acquire the router config and made it a tool. By focusing only on router config acquisition, the tool itself has become simpler, and as a result, I feel that it has become easier to link with other tools.

Tool installation

I will download it from github.

git clone [email protected]:taijiji/ConfigCollector.git

Change to the downloaded tool directory.

cd ConfigCollector

Install related modules using pip. --If you are not using pip, please install pip in advance.

pip install -r requirements.txt

That's all for preparation.

How to use the tool

For "get_router_config.py", execute the router list information created in JSON format as a command line argument.

python get_router_config.py [json file]

Describe the json file of the router list information as follows. If you write like this, you will get the config via SSH for all routers.

my_router.json


[
    {
        "hostname" : "router1",
        "username" : "user1",
        "password" : "aaabbbccc",
        "ipv4"     : "192.168.0.1",
        "os"       : "JUNOS"
    },
    {
        "hostname" : "router2",
        "username" : "user2",
        "password" : "aaabbbccc",
        "ipv4"     : "192.168.0.2",
        "os"       : "IOS-XR"
    },
    {
        "hostname" : "router3",
        "username" : "user3",
        "password" : "aaabbbccc",
        "ipv4"     : "192.168.0.3",
        "os"       : "IOS"
    }
]

The router OS is intended only for those that can be tested at hand.

What is output

If the tool is executed successfully, the config for each router will be saved under the "router_config" directory. The file name is "Router host name.txt".

The following is the result when executed with the above "my_router.json" file.

$ ls router_config
router1.txt  router2.txt  router3.txt
$ less router_config/router1.txt

show configuration | no-more
## Last commit: 2015-05-01 17:00:00 JST by user1
version 10.x.x;
system {
    host-name router1;
    time-zone Asia/Tokyo;
(snip)

Finally, the administrator manually manages the entire "router_config" directory with [git add]-> [git commit]-> [git push] on Github, Gitlab, etc. to centralize the router config. You can manage the version.

code

I will write the code for your reference. Overall, it's not that difficult.

A module called Exscript is used to get SSH + information to the router. Expect is famous as an SSH tool, but Exscript supports IOS, IOS-XR, JunOS, VRP, etc. in addition to Linux / Unix. It has been. This is convenient because you do not need to parse the router separately when controlling the router.

A file that reads a JSON file and calls a router operation

get_router_config.py


#! /usr/bin/env python
import sys
import traceback
import json

from ssh_router import Router

# Open json input file
try:
    # argument is routers' information with JSON formt.
    input_filename = sys.argv[1]
    input_file = open(input_filename ,'r')
    print 'Reading router info from "' + input_filename + '"...' 
except ( IOError, IndexError):
    print 'Cannot open JSON file.'
    print 'Please use bellow: " python get_router_config [JSON file] " '
    sys.exit()
else:
    router_info_json = input_file.read()
    input_file.close()

# Convert format from json to dictionary_type
try:
    router_info = json.loads(router_info_json)
except ValueError as error:
    print 'JSON format error : '
    print router_info_json
    print error
    sys.exit()

# Login and get config each routers using ssh
for num in range( len(router_info) ):
    router = Router( router_info[num] )
    
    # Login Router
    print 'Accessing router: ' + router_info[num]['hostname'] + '...'
    try:
        router.login()
        router_config = router.get_config()
    except:
        print 'Router login error'
        print router_info[num]
        router.logout()
        sys.exit()

    # Get config of Router
    try:
        router_config = router.get_config()
    except:
        print 'Router get configuration error'
        print router_info[num]
        router.logout()
        sys.exit()
    else:
        router.logout()
    
    # Create output file written config
    try:
        output_filename = 'router_config/' + router_info[num]['hostname'] + '.txt'
        print 'Writing output file "' + output_filename + '"...'
    except AtributeError:
        print 'cannot read dictionary of router_info[' + num + '][hostname]'
        sys.exit()

    try:
        output_file = open ( output_filename, 'w')
    except:
        print 'cannot open "' + output_filename + '"'
        output_file.close
        sys.exit()
    else:
        output_file.write( router_config )
        output_file.close

    print 'Success to create "'  + output_filename + '" !'

Files that make up control over the router

I'm just calling Exscript here.

ssh_router.py


! /usr/bin/env python
# -*- coding: utf-8 -*-

from Exscript.protocols import SSH2
from Exscript.Account import Account

class Router:
    def __init__(self, router_info):
        self.hostname   = router_info['hostname']
        self.username   = router_info['username']
        self.password   = router_info['password']
        self.ipv4           = router_info['ipv4']
        self.os              = router_info['os']

    def login(self):
        self.session = SSH2()
        self.session.connect(self.ipv4)
        self.session.login( Account(name=self.username, password=self.password) )

    def logout(self):
        if self.session :
            self.session.send('exit\r')
            self.session.close()
        else:
            raise AttributeError( 'cannot find a living session.' )

    def get_config(self):
        if( self.os=='IOS-XR' or self.os=='IOS' or self.os=='IOS-XE'):
            self.session.execute('terminal length 0')
            self.session.execute('show running-config')
            result = self.session.response
        elif( self.os == 'JUNOS'):
            self.session.execute('show configuration | no-more')
            result = self.session.response
        else:
            raise ValueError( 'OS is unknown value. Please describe from  JUNOS / IOS / IOS-XE / IOS-XR.' )

        return result

Recommended Posts

Tool to centrally acquire the configuration of Cisco / Juniper router
A tool to convert Juniper config
Supplement to the explanation of vscode
The story of trying to reconnect the client
Script to change the description of fasta
10 methods to improve the accuracy of BERT
How to check the version of Django
The story of adding MeCab to ubuntu 16.04
The story of pep8 changing to pycodestyle
I made a tool to automatically back up the metadata of the Salesforce organization