diff --git a/README.md b/README.md index 85d2094..d3930ea 100644 --- a/README.md +++ b/README.md @@ -14,15 +14,17 @@ License, see [below](#license) sync-router ----------- -Shell scripts used to synchronize the current Cisco startup configuration and -DHCP static lease files with with a GIT repository. This scripts assumes one -(git-managed) subdirectory per router. It performs the following operations when -invoked: +Shell scripts used to synchronize the current Cisco startup configuration, IOS +images and DHCP static lease files with with a GIT repository. This scripts +assumes one (git-managed) subdirectory per router. It performs the following +operations when invoked: + - copy Cisco startup-config using scp and add to next commit + - synchronize the IOS images in the git repository and update the startup- + config accordingly - update the 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 DHCP static lease files - - copy Cisco running-config using scp and add to next commit - commit changes to the git repository I use this script to keep the configuration of my cisco router(s) in a GIT diff --git a/sync-router b/sync-router index ea67de9..cdd9025 100755 --- a/sync-router +++ b/sync-router @@ -6,9 +6,11 @@ # 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.0, latest version at: https://gitlab.lindenaar.net/scripts/cisco +# Version 1.1, latest version at: https://gitlab.lindenaar.net/scripts/cisco # # Copyright (c) 2016 Frederik Lindenaar # @@ -25,22 +27,73 @@ ### Configuration ### router=`basename \`dirname $0 | pwd\`` # name of router - based on directory -syncfiles=dhcp-\* # list/pattern of dhcp lease files -fileto=flash: # location of dhcp lease files on cisco +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 "$syncfiles" | while read status filename +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) - echo removing $filename as it is no longer in the repository - ssh -q $router "delete /force $fileto$filename" + router_file_remove $filename + ;; + R) + router_file_remove $filename + router_file_upload $newfilename ;; A |M|MM) echo updating and uploading modified file $filename @@ -60,9 +113,7 @@ do esac done tail +3 $filename >> .$filename.$$.tmp - scp -q .$filename.$$.tmp $router:$fileto$filename - mv .$filename.$$.tmp $filename - git add $filename + router_file_upload .$filename.$$.tmp $filename ;; *) echo unsupported git status "$status", aborting @@ -72,7 +123,7 @@ do done # Restart the DHCP service on the router if any of the dhcp files changed -if git status -s "$syncfiles" | egrep -q ^[MAD]; then +if git status -s "$dhcpfiles" | egrep -q ^[MAD]; then echo restarting dhcp service cat << EOT | ssh -q $router configure terminal @@ -83,10 +134,42 @@ exit EOT fi -# Fetch the current start-up configuration and add it to the repository -scp -q $router:startup-config . -git diff startup-config -git add startup-config -# and commit the changes (or unadd new configuration when commit is aborted) +# 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