Check in of configuration files to a Gitlab server

Table of contents

  1. Introduction
  2. Check in part for Gitlab
  3. Handling of multiple sites
  4. Compare and track of changes
  5. Source code on Github

Related posts

Introduction

I’m planning a small blog post series about Cisco configuration backup with Netbox and Gitlab.

My idea is to “control” which devices are backed up by Netbox with Device Type, Site, IPv4 address and Status (“Active”).

Based on above information the script should then login with SSH to the devices, send a couple of commands like banner, wr mem, copy run scp to start a file transfer to save the configuration on a SCP host temporary directory.

The configuration files are then checked in into a GitLab repository so it’s easy to track and compare configuration files.

To outline the idea, I made the drawing shown below.

Concept Cisco configuration backup with Netbox and Gitlab

Check in part for Gitlab

To check in the configuration files the script uses a for-loop to go through the devices. The for-loop does some IPv4 cleanup (remove the subnet bits) and checks for the device role.

If there is in the /tmp folder a configuration file, the script authenticate against the Gitlab server.

  • If Gitlab does not have the configuration file, the script needs to call the create action.

  • If there is already a configuration file, then the script needs to use the update action.

The try/except block for the create and update action is creating its data in JSON. This JSON data is then committed to the Gitlab server project.


    # Get the devices from Netbox
    devices = getDevicesFromNetbox()

    # Use a for-loop to go through the devices and check in the configuration files
    for i in range(0, len(devices)):

      # Split list
      role = str(devices[i][0])
      location = str(devices[i][1])
      hostname = str(devices[i][2])
      ipv4 = str(devices[i][3])[:len(str(devices[i][3]))-3]
      status = str(devices[i][4])

      # If device is active and has a primary IPv4 address (ssh connect action)
      if status == "Active" and ipv4 != "N":

        # role is a switch
          if role == "switch":
            cliCiscoSwitch()
          # role is a wlc
          elif role == "wificontroller":
            cliCiscoWirelessController()
          # role is a firewall
          elif role == "wanfirewall":
            cliCiscoAsaFirewall()

      # handle list from netbox if device is missing ipv4 or if
      # device status is set to something else than active
      else:
        print ("WARN: device not set to active or IP missing")

      # If device is active and has primary IPv4 address (open file action)
      if status == "Active" and ipv4 != "N":
        # open config file and read it into a string variable
        try:
          content = open('/tmp/' + hostname + '.cfg').read()
        except:
          print ("ERROR: Cannot open file: " + hostname + ".cfg")

        urllib3.disable_warnings()
        requests.packages.urllib3.disable_warnings()
        gl = gitlab.Gitlab(gitlab_url, ssl_verify=False, private_token=gitlab_token)
        # authenticate
        gl.auth()
        # get gitlab project
        project = gl.projects.get(project_id)

        # try with a commit create if file does not exist on gitlab project
        try:
          data_create = {
            'branch': 'master',
            'commit_message': 'Initial commit of config file on ' + today + ' by backup2git',
            'actions': [
              {
                'action': 'create',
                 'file_path': location + '/' + hostname + '.cfg',
                 'content': open('/tmp/' + hostname + '.cfg').read(),
              }
            ]
          }
        except:
          print ("Cannot build commit create JSON")
          pass
        # If file exists, use commit update to check in new version of file
        try:
          data_update = {
            'branch': 'master',
            'commit_message': 'Update of config file on ' + today + ' by backup2git',
            'actions': [
              {
                'action': 'update',
                'file_path': location + '/' + hostname + '.cfg',
                'content': open('/tmp/' + hostname + '.cfg').read(),
              }
            ]
          }
        except:
          print ("Cannot build commit update JSON")
          pass

Handling of multiple sites

To handle multiple sites (in my case I moved from Germany to New Hampshire, after five years in the USA back to Germany and then within Germany), the Gitlab project uses different directories matching the Sites in Netbox.

Screenshot: Sites in Gitlab project

As shown in the screenshot below, the configuration files are stored in the sites directory. Please note that if a configuration file did not exist, the comment would change to Initial commit of config file.

Screenshot: Configuration files in Gitlab project

Compare and track of changes

The nice thing and benefit of having Cisco configuration files on a Gitlab server is that I can now compare and track changes in the configuration below.

Screenshot: Changes in configuration file

Source code on Github

The source code of the script is now available on my Github account at sthierolf / network-automation-scripts / backup2git.py