Copy files through multiple gateways

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
%d bloggers like this: