Juniper Config Backup on GITLAB

Hi All

In this blog, we will see how we can take the backup of router configs and push it to gitlab for version control.

We will take Juniper routers here for example and build the script in Python and run our task as a cronjob on CentOS 7 to automatically backup the configs onto GITLAB.
We will use power of Git here to store the differentials in configs and we can see the differences in Gitlab UI.

So let’s see how we can achieve it.
Before starting with config backup, let’s build the device store on which we will be running the script or in other words backup will be running. For this we are storing the values in YAML file http://yaml.org/ as dictionary. You can either store the values as list or Dictionary in YAML. You can use json also to store the same data instead of YAML.

Yaml file (.yml)
---
# Add devices here in form Hostname: 'ip address'
  Manchester_MX10003: '10.198.206.3'
  Glasgow_MX10003: '10.198.206.6'
  London_MX104: '10.198.206.9'
  Leeds_MX104: '10.198.206.12'
  Bristol_MX104: '10.198.206.15'

Above are the file contents, where we are storing the data as Key, Value pair where Key is hostname of device and Values are its IP Addresses.

Now our data store is done, we can start with Juniper PYez (https://www.juniper.net/documentation/en_US/junos-pyez/topics/concept/junos-pyez-overview.html) to get the configs first.

We will be importing the Pyez modules, set the .yml input file location and run ‘for’ loop on our dictionary. We will store the backup config files as .txt file with hostnames as Title for easy accessibility. Don’t forget to import yaml module as we will be working on yaml file.

from jnpr.junos import Device
from jnpr.junos.exception import ConnectError
import yaml

input_file = '/home/sun/gitlab/device_list.yml'

for key, value in yaml.load(open(input_file)).items():

    dev_username = test
    dev_password = test
    dev = Device(host=value, user=dev_username, passwd=dev_password, port='830')

    try:
        dev.open()
    except ConnectError as err:
        print ("Cannot connect to device: {0}".format(err))
        sys.exit(1)
    except Exception as err:
        print (err)
        sys.exit(1)

    config = str(dev.cli("show configuration | no-more", warning=False))

    #####Create/Write to Config to File

    file_name = key + '.txt'


   dev.close()

That was pretty simple. Let me know if you have any issues. Now let’s work out how to push it to GIT.

We will be using the subprocess module to do this work for us where we will be running series of commands in serial to put the files across the gitlab. You are starting by going into particular directory which is your starting git project directory. You are looking at each branch within your git project using ‘git branch’ command and then checking out a particular branch on which you to work or store the data. In our case it’s Core_Network. Once you have moved to that, you can move into other specific folders and ‘mv’ your backup .txt files into this folder.

Once that is done, you will use git commands, like ‘git add –all’ to add all files as part of staging. ‘git commit –m “some description”’ to commit the files and then use ‘git push’ to push them to remote gitlab server.

Code will be:

from subprocess import PIPE
from subprocess import Popen
import sys
import os
import yaml
cmds =['cd /home/sun/gitlab/athena-test', 'git branch', 'ls -l', 'git checkout " Core_Network"', 'cd "Core Network"', 'cd "Device backups"', 'mv /home/sun/gitlab/*.txt /home/sun/gitlab/athena-test/"Core Network"/"Device backups"/', 'git add --all', 'git commit -m "Updated config files"', 'git push' ]
encoding = 'utf8'
p = Popen('/bin/sh', stdin=PIPE, stdout=PIPE, stderr=PIPE)
for cmd in cmds:
p.stdin.write(cmd + "\n")
p.stdin.close()
#print p.stdout.read()
print "Push to GitLab Completed"

One main thing you have to keep in mind is that you won’t be able to push the files until unless you have some remote servers configured under your server.

For example, mine is below where I have removed certain values and replaced them with xxx, yyy and ip address.. xxx is username, yyy is password and hostname  is gitlab server address.

sun@ $ git remote -v
origin https://xxx:yyy@<hostname>/athena-test.git (fetch)
origin https://xxx:yyy@<hostname>/athena-test.git (push)

Let’s see this in action by changing the config on one of the router.

write@re0.Manchester.MX10003.uk> edit
Entering configuration mode

write@re0.Manchester.MX10003.uk# run show configuration system services ssh
root-login allow;
protocol-version v2;
max-sessions-per-connection 32;
connection-limit 20;
rate-limit 10;

[edit]
write@re0.Manchester.MX10003.uk# set system services ssh connection-limit 10

[edit]
write@re0.Manchester.MX10003.uk# show | compare
[edit system services ssh]
- connection-limit 20;
+ connection-limit 10;

[edit]
write@re0.Manchester.MX10003.uk# commit
commit complete

Run the script now from CentOS Server

sun@ pwd

/home/sun/gitlab

sun@ $ python git_config_backup.py

Successfully Collected Configuration from Device: Bristol_MX104

Successfully Collected Configuration from Device: Manchester_MX10003

Successfully Collected Configuration from Device: Glasgow_MX10003

Successfully Collected Configuration from Device: London_MX104

Successfully Collected Configuration from Device: Leeds_MX104

Push to GitLab Completed

 

You can see config was pushed and if we see the gitlab, it’s clearly showing the difference from the previous backup it had. Red one is one that is removed and Green one is what has been added.

So you can use this utility as version control of your configs and once you are happy with the configs you can push them to master for production use 🙂

 

Gitlab
GitLab side by side comparison

 

One last thing, if you have to run this as a cronjob on Centos, just edit the crontab file using ‘crontab –e’ and add the path to the script and at what particular time you want to run and that’s all.

I hope you liked this blog. Let me know if you have any queries.

 

Regards

Mohit

Leave a comment