
Centralized configuration collection with MikroTiks using Python
What for
With the increase in the number of network nodes and the complexity of their configuration, many probably have a question - and if the piece of iron dies, can I quickly restore work to another? If I can do it manually, then how long will I then catch the little things that I forgot?
The googling process has led to the understanding that there are no ready-made solutions of this kind specifically for this vendor. I did not like what was found in the community - they offered to place backup scripts on the hardware itself and run them on a schedule. In essence, this solved the problem, but if I have several dozen pieces of equipment, clicking on the copy paste for each copy is not Feng Shui.
Fortunately there is a little skill in writing useful things in Python and fantasy.
Fantasy
I’m wondering what I’ll need - a TFTP server, where we will put our economy, * a nix machine (it’s easier to do this than with win), Python on board with the necessary set of libraries. As it turned out later, the TFTP server can be thrown out, you will need FTP.
Try times
I try to solve the problem head-on - I use telnetlib for communication - it does not work. It's strange, because it worked with switches. After thinking it over, I realized that telnet at MikroTik is decorated with all the colors of the rainbow, it means it is strewing with special characters, and filtering them is not included in my plans.
Attempt two
I’m looking at the paramiko library and its component SSHClient - now everything works out - the connection goes through, I can execute the commands and get the result.
Now let's see how the configurations are removed from these really unusual pieces of iron. A common scenario on network equipment is the execution of one command that can send its config to a TFTP server. In the case of MikroTik, this option does not work - it turns out that the backup configuration file is the first thing you need to create:
/system backup save [name=]
After that, the file can already be downloaded somewhere, but as it turned out, this can only be done via FTP, and with HTTP and TFTP it can only merge files. It doesn’t matter, we quickly raise the FTP server with a minimal configuration, which is not difficult for the esteemed readers to google.
/tool fetch address= mode=ftp dst-path= src-path= user= password= upload=yes
And in the end, you need to remove the garbage behind you so as not to sail to the exhaustion of free space on the internal carrier:
/file remove
Result
For a couple of hours, fantasy gave birth to this script:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# for SSH
from paramiko import SSHClient
from paramiko import AutoAddPolicy
# for versioning
import datetime
# for file operations
import os
# for sleep
import time
# versioning
Version = datetime.date.today()
#print "\n" + str(Version)
# hosts array IP1, IP2, IP3
hosts = ( "1.2.3.4", "5.6.7.8" , "9.10.11.12")
# username
users = ( "user1", "user2", "user3")
iterUser = iter(users)
# userpassword
passwords = ( "pass1", "pass2", "pass3" )
iterPassword = iter(passwords)
# FTPD IP
FtpdIP = "13.14.15.16"
# ftp user account
ftpUser = "ftpuser"
ftpPass = "ftppass"
# keep backups for 4 weeks
backtime = datetime.timedelta(weeks=-4)
sshCli = SSHClient()
sshCli.set_missing_host_key_policy(AutoAddPolicy())
print "header done"
# loop host adresses
for host in hosts:
print "\n" + str(host)
# iterate through user-password pairs
user = iterUser.next()
Password = iterPassword.next()
# define operations
CreateLocalBckp = "system backup save name=" + str(host) + "_" + str(Version) + ".backup"
UploadToFtp = "tool fetch address=" + str(FtpdIP) + " mode=ftp dst-path=" + str(host) + "_" + str(Version) + ".backup src-path=" + str(host) + "_" + str(Version)+ ".backup" + " user=" + str(ftpUser) + " password=" + str(ftpPass) + " upload=yes"
RemoveLocalBckp = 'file remove "' + str(host) + "_" + str(Version) + ".backup" + '"'
# try for not to fail the whole script on one error
try:
print "connecting.." + str(host) + "@" + str(user) + ":" + str(Password)
sshCli.connect(str(host), port=2022, username=str(user), password=str(Password))
print "connected.."
# creating local backup
print "creating local backup.. /" + CreateLocalBckp
sshCli.exec_command(CreateLocalBckp)
# sleep after each command because mikrotik can not do it so fast as script executes
time.sleep(2)
print "local backup created.."
# uloading local backup to ftp
print "uploading local backup to ftp.. /" + UploadToFtp
sshCli.exec_command(UploadToFtp)
time.sleep(2)
print "backup uploaded to remote location.."
# removing local backup
time.sleep(2)
print "removing local backup.. /" + RemoveLocalBckp
sshCli.exec_command(RemoveLocalBckp)
time.sleep(2)
print "local backup removed.."
sshCli.close()
# try delete old file (if exists)
try:
os.remove("/tftp/" + str(host) + "_" + str(Version + backtime) +".cfg")
except:
print "Error while trying to delete old backup " + "/tftp/" + str(host) + "_" + str(Version + backtime) +".cfg"
except:
print "Error connecting to host", host
The script will store on our FTP server a set of configuration backups per month with names of the form IP_YYYY-MM-DD.backup
PS: there is a similar creation for the case of 3Com switches and uploading their configurations via telnet to TFTP - if readers are interested, I will definitely publish it.