#!/bin/bash -e # # sync-router shell scripts to synchronize cisco configuration and DHCP static # lease files with with GIT repository. Operations performed: # - update header of modified DHCP static lease files, upload # them using using scp and add them to the next commit # - restart Cisco DHCP service after updating static lease files # - copy Cisco startup-config using scp and add to next commit # - update IOS image files on the router when checked in to the # repository, update startup-config file accordingly on router # - commit changes to the git repository # # Version 1.1, latest version at: https://gitlab.lindenaar.net/scripts/cisco # # Copyright (c) 2016 Frederik Lindenaar # # This script is free software: you can redistribute and/or modify it under the # terms of version 3 of the GNU General Public License as published by the Free # Software Foundation, or (at your option) any later version of the license. # # This script is distributed in the hope that it will be useful but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along with # this program. If not, visit <http://www.gnu.org/licenses/> to download it. ### Configuration ### router=`basename \`dirname $0 | pwd\`` # name of router - based on directory dhcpfiles=dhcp-\* # list/pattern of dhcp lease files imagefiles=c??00-universalk9-mz.SPA.\* # list/pattern of IOS image files fileto=flash # location of dhcp/IOS files on cisco ### Implementation ### echo updating with $router # Support function to download a file from the router # parameters: $1 - filename to be copied and $2 - (optional) target filename # when no target filename is provided the source file will be downloaded to the # current directory with the same name. Adds downloaded file to git changeset router_file_download() { fromfile=${1?ERROR: at least one filename is required to copy from router} tofile=${2:-$fromfile} filesrc=$fileto if [ "$fromfile" == startup-config ]; then filesrc=nvram fi echo downloading $tofile from router $filesrc scp -q $router:$filesrc:$fromfile $tofile git add $tofile } # Support function to upload a file to the router # parameters: $1 - filename to be copied and $2 - (optional) target filename # when a target filename is provided the source file will be moved to the target # file after uploading and the target file is added to the git changeset router_file_upload() { fromfile=${1?ERROR: at least one filename is required to copy to router} tofile=${2:-$fromfile} filedst=$fileto if [ "$fromfile" == startup-config ]; then filedst=nvram fi echo uploading new/updated $tofile to router $filedst scp -q $fromfile $router:$filedst:$tofile if [ "$fromfile" != "$tofile" ]; then mv $fromfile $tofile git add $tofile fi } # Support function to remove a file from the router # parameters: $1 - filename to be removed router_file_remove() { delfile=${1?ERROR: need a filename to remove from router} echo removing $delfile as it is no longer in the repository ssh -q $router "delete /force $fileto:$delfile" } # Fetch the start-up configuration from the router router_file_download startup-config # Process the DHCP static lease files that have changed git status -s "$dhcpfiles" | while read status filename token newfilename do case $status in \?\?) echo skipping $filename as it is not yet added to the repository ;; D) router_file_remove $filename ;; R) router_file_remove $filename router_file_upload $newfilename ;; A |M) echo updating and uploading modified file $filename head -2 $filename | while read tag value do case $tag in \*time\*) date +"$tag %h %d %Y %l:%M %p" > .$filename.$$.tmp ;; \*version\*) echo $tag $[ $value + 1 ] >> .$filename.$$.tmp ;; *) echo "found unknown entry \"$tag $value\", aborting" exit 1 ;; esac done tail +3 $filename >> .$filename.$$.tmp router_file_upload .$filename.$$.tmp $filename ;; *) echo unsupported git status "$status", aborting exit 1 ;; esac done # Restart the DHCP service on the router if any of the dhcp files changed if git status -s "$dhcpfiles" | egrep -q ^[MAD]; then echo restarting dhcp service cat << EOT | ssh -q $router configure terminal no service dhcp service dhcp exit exit EOT fi # Process the IOS image files that have changed git status -s "$imagefiles" | while read status filename token newfilename do case $status in \?\?) echo skipping $filename as it is not yet added to the repository ;; R) router_file_remove $filename router_file_upload $newfilename ;; D) router_file_remove $filename ;; A |M) router_file_upload $filename ;; *) echo unsupported git status "$status", aborting exit 1 ;; esac done # Update the boot images in the startup-config file if we're updating any images if git status -s "$imagefiles" | egrep -q ^[MADR]; then fgrep -n "boot system $fileto" startup-config | cut -d: -f1 > .startup-config.$$.lines head -$[ `head -1 .startup-config.$$.lines` -1 ] startup-config > .startup-config.$$ git ls-files $imagefiles | sort -r | sed "s/^/boot system $fileto /g" >> .startup-config.$$ tail +$[ `tail -1 .startup-config.$$.lines` +1 ] startup-config >> .startup-config.$$ rm .startup-config.$$.lines router_file_upload .startup-config.$$ startup-config fi # show what has changed in the startup config and commit to the repository git diff --cached startup-config git commit || git reset HEAD startup-config