Copy files through multiple gateways

Script to copy files over multiple gateways

This will be used if the destination server is only accessible through another server/multiple servers

Example: 
We want to move a website folder from server A to server D, but server C is the only server who has access to server D, and server A only has direct access to server B.
In order to have access to server D we need to connect from server A to server B, and from server B to server C.
The requirement of the script is that ssh keys are added between all servers.

How to use

./scp-files.sh "192.168.0.10 someUser" 3 \"192.168.0.3 gwuser1 192.168.0.4 gwuser1 192.168.0.5 gwuser3" "/tmp/website.tar.bz2" "/var/www/"
– the main script called scp-files.sh
#!/bin/bash

hasGateways=false
#$1 = final server details
#$2 = gatewayCount
#$3 = gateways details
#$4 = file/folder to copy
#$5 = final destination on the server
#check if we have arguments
if (($# == 0))
    then
        echo "1:Usage $0 \"serverUrl serverUser\" gatewaysCount \"gateway1Url gateway1User gateway2Url gateway2User\" \"pathToFilesToSend\" \"destinationPathOnTheFinalServer\""
        exit 1
else
    #test if we have 2 arguments and the second one is a number
    if (($#>=2))
        then
            re='^[0-9]+$'
            if ! [[ $2 =~ $re ]] ;
                then
                   echo "1:The second argument needs to be a number"
                   exit 1
            fi
    fi
    #if we have 2 arguments and the second one is higher than 0 we need the third argument to be present
    if (($#==2)) && (($2>0))
        then
            echo "1:Please provide the $2 gateway(s) configuration"
            exit 1
    fi
    if (($2==0))
        then
            hasGateways=false
    fi
    #set the gateways var, this will be used to create the scp command
    if (($#>=3)) && (($2>0))
        then
        hasGateways=true
    fi
fi

server=$1
gatewayCount=$2
gateways=$3

IFS=' ' read -a serverConfiguration <<< "$server"

if ((${#serverConfiguration[@]}!=2))
    then
    echo "1: The provided server configuration is invalid"
    exit 1
fi

if $hasGateways
    then
        IFS=' ' read -a gatewayConfigurations <<< "$gateways"
        if ((${#gatewayConfigurations[@]}!=$gatewayCount*2))
            then
                echo "1:The provided gateways configuration is invalid"
                exit 1
        fi
fi


timestamp() {
  date +"%Y%m%d%H%M%S%N"
}


newGatewayString=""
deleteFirstGateway(){
    for index in ${!gatewayConfigurations[*]}
        do
            if (($index>1))
                then
                gatewayDataNew=${gatewayConfigurations[$index]}
                if [ ! -z "${newGatewayString}" ];
                    then
                        newGatewayString="${newGatewayString} ${gatewayDataNew}"
                else
                        newGatewayString="${gatewayDataNew}"
                fi


            fi
    done
}
archiveName="$(timestamp).tar.bz2"

scriptExecDirectory=$(dirname $0)
cp $scriptExecDirectory/gateway-script.sh /tmp/gateway-script.sh
if [ -d $4 ]
    then
       eval "cd $4 && tar -cvjf /tmp/${archiveName} * 2>/tmp/tarError 1>/dev/null"
       if [[ -s /tmp/tarError ]];
            then
            echo "1:Failed to create tar archive from $4"
            exit 1
       fi
else
    parentDirNameFor=`dirname $4`
    fileNameForTar=`basename $4`
    eval "cd $parentDirNameFor && tar -cvjf /tmp/${archiveName} $fileNameForTar 2>/tmp/tarError 1>/dev/null"
    if [[ -s /tmp/tarError ]];
        then
        echo "1:Failed to create tar archive from $4"
        exit 1
    fi
fi
if $hasGateways
    then
    gatewayData="${gatewayConfigurations[1]}@${gatewayConfigurations[0]}"
    newGatewayCount=`expr $gatewayCount - 1`
    deleteFirstGateway
    eval "scp /tmp/${archiveName} ${gatewayData}:/tmp/ 2>/tmp/scpError 1>/dev/null"
    if [[ -s /tmp/scpError ]] ;
        then
            echo "1:There was an error during the SCP function for the archive. Please check the /tmp/scpError file";
            exit 1
    else
        cd $scriptExecDirectory
        eval "scp /tmp/gateway-script.sh ${gatewayData}:/tmp/ 2>/tmp/scpError 1>/dev/null"
        if [[ -s /tmp/scpError ]];
            then
                echo "1:There was an error during the SCP function for the gateway script. Please check the /tmp/scpError file";
                exit 1
        else
            ssh $gatewayData 'chmod +x /tmp/gateway-script.sh' 2>/tmp/sshError 1>/dev/null
            if [[ -s /tmp/sshError ]];
                then
                    echo "1:There was an error during the SSH function chown +x. Please check the /tmp/sshError file";
                    exit 1
            else
                ssh $gatewayData 'bash' "/tmp/gateway-script.sh" "\"$1\" $newGatewayCount \"${newGatewayString}\" \"${archiveName}\" \"$5\"" 2>/tmp/sshError 1>/tmp/sshOutput
                if [[ -s /tmp/sshError ]] || [[ -s /tmp/sshOutput ]];
                    then
                        echo "1:There was an error during the SSH function for gateway-script execution. Please check the /tmp/sshError or /tmp/sshOutput file";
                        exit 1
                else
                    echo "0"
                    exit 0
                fi
            fi
        fi
    fi
else
    serverInfo="${serverConfiguration[1]}@${serverConfiguration[0]}"
    eval "scp /tmp/$archiveName $serverInfo:/tmp/ 2>scpError 1>/dev/null"
    destinationPath=$5
    if [[ -s /tmp/scpError ]] ;
        then
            echo "1:Error copying the archive to the final server. Please check /tmp/scpError"
            exit 1
    else

        if [[ ! -d  $destinationPath ]];
            then
            ssh $serverInfo "mkdir -p \"$destinationPath\"" 2>/tmp/sshError 1>/tmp/sshOutput
        fi
        if [[ -s /tmp/sshError ]];
        then
            echo "1:Failed to create $destinationPath on $serverConfiguration"
            exit 1
        else
            ssh $serverInfo "tar -xvjf /tmp/$archiveName -C \"$destinationPath\"" 2>/tmp/tarError 1>/tmp/tarOutput
            if [[ -s /tmp/tarError ]];
                then
                echo "1:Failed to extract tar archive from $archiveName to $destinationPath on $serverConfiguration"
                exit 1
            else
                echo "0"
                exit 0
            fi
        fi
    fi
fi
the second script called gateway-script.sh
#!/bin/bash

hasGateways=false
#$1 = final server details
#$2 = gatewayCount
#$3 = gateways details
#$4 = file/folder to copy
#$5 = final destination on the server
#check if we have arguments
if (($# == 0))
    then
        echo "1:Usage $0 \"serverUrl serverUser\" gatewaysCount \"gateway1Url gateway1User gateway2Url gateway2User\" \"pathToFilesToSend\" \"destinationPathOnTheFinalServer\""
        exit 1
else
    #test if we have 2 arguments and the second one is a number
    if (($#>=2))
        then
            re='^[0-9]+$'
            if ! [[ $2 =~ $re ]] ;
                then
                   echo "1:The second argument needs to be a number"
                   exit 1
            fi
    fi
    #if we have 2 arguments and the second one is higher than 0 we need the third argument to be present
    if (($#==2)) && (($2>0))
        then
            echo "1:Please provide the $2 gateway(s) configuration"
            exit 1
    fi
    if (($2==0)) || (($2=="0"))
        then
            hasGateways=false
    fi
    #set the gateways var, this will be used to create the scp command
    if (($#>=3)) && (($2>0))
        then
        hasGateways=true
    fi
fi

server=$1
gatewayCount=$2
gateways=$3


IFS=' ' read -a serverConfiguration <<< "$server"

if ((${#serverConfiguration[@]}!=2))
    then
    echo "1: The provided server configuration is invalid"
    exit 1
fi

if $hasGateways
    then
        IFS=' ' read -a gatewayConfigurations <<< "$gateways"
        if ((${#gatewayConfigurations[@]}!=$gatewayCount*2))
            then
                echo "1:The provided gateways configuration is invalid"
                exit 1
        fi
fi

newGatewayString=""
deleteFirstGateway(){
    for index in ${!gatewayConfigurations[*]}
        do
            if (($index>1))
                then
                gatewayDataNew=${gatewayConfigurations[$index]}
                if [ ! -z "${newGatewayString}" ];
                    then
                        newGatewayString="${newGatewayString} ${gatewayDataNew}"
                else
                        newGatewayString="${gatewayDataNew}"
                fi
            fi
    done
}

archiveName="${4}"


if $hasGateways && (($2!=0))
    then
        gatewayData="${gatewayConfigurations[1]}@${gatewayConfigurations[0]}"
        newGatewayCount=`expr $gatewayCount - 1`
        deleteFirstGateway
        eval "scp /tmp/${archiveName} ${gatewayData}:/tmp/ 2>/tmp/scpError 1>/dev/null"
        if [[ -s /tmp/scpError ]] ;
            then
                echo "1:There was an error during the SCP function for the archive. Please check the /tmp/scpError file";
                exit 1
        else
            eval "scp /tmp/gateway-script.sh ${gatewayData}:/tmp/ 2>/tmp/scpError 1>/dev/null"
            if [[ -s /tmp/scpError ]];
                then
                    echo "1:There was an error during the SCP function for the gateway script. Please check the /tmp/scpError file";
                    exit 1
            else
                ssh $gatewayData 'chmod +x /tmp/gateway-script.sh' 2>/tmp/sshError 1>/dev/null
                if [[ -s /tmp/sshError ]];
                    then
                        echo "1:There was an error during the SSH function chown +x. Please check the /tmp/sshError file";
                        exit 1
                else
                    ssh $gatewayData 'bash' "/tmp/gateway-script.sh" "\"$1\" $newGatewayCount \"${newGatewayString}\" \"${archiveName}\" \"$5\"" 2>/tmp/sshError 1>/dev/null
                    if [[ -s /tmp/sshError ]];
                        then
                            echo "1:There was an error during the SSH function for gateway-script execution. Please check the /tmp/sshError file";
                            exit 1
                    else
                        exit 0
                    fi
                fi
            fi
        fi
else
    serverInfo="${serverConfiguration[1]}@${serverConfiguration[0]}"
    eval "scp /tmp/$archiveName $serverInfo:/tmp/ 2>scpError 1>/dev/null"
    destinationPath=$5
    if [[ -s /tmp/scpError ]] ;
        then
            echo "1:Error copying the archive to the final server. Please check /tmp/scpError"
            exit 1
    else

        if [[ ! -d  $destinationPath ]];
            then
            ssh $serverInfo "mkdir -p \"$destinationPath\"" 2>/tmp/sshError 1>/tmp/sshOutput
        fi
        if [[ -s /tmp/sshError ]];
        then
            echo "1:Failed to create $destinationPath on $serverConfiguration"
            exit 1
        else
            ssh $serverInfo "tar -xvjf /tmp/${archiveName} -C \"$destinationPath\"" 2>/tmp/tarError 1>/tmp/tarOutput
            if [[ -s /tmp/tarError ]];
                then
                echo "1:Failed to extract tar archive from $archiveName to $destinationPath on $serverConfiguration"
                exit 1
            else
                echo "0"
                exit 0
            fi
        fi
    fi
fi