#!/usr/local/bin/cbsd
#v12.1.10
CBSDMODULE="node"
MYARG=""
MYOPTARG="root rsync tryoffline verbose"
EXTHELP="wf_nodescp"
MYDESC="get put file to remove nodes"

ADDHELP="
${H3_COLOR}Description${N0_COLOR}:

Get/put file from/to remove nodes via SSH
Usage:

[verbose=1] node1:remotefile1 localfile1 [ localfile2 node2@:remotefile2 ]


${H3_COLOR}Options${N0_COLOR}:

 ${N2_COLOR}verbose=${N0_COLOR}    - when 0 - add '-q' for scp. 1 - by default.
 ${N2_COLOR}tryoffline=${N0_COLOR} - when 1 - try to fetch inventory when node is offline.
 ${N2_COLOR}rsync=${N0_COLOR}      - when 1 - force to use rsync instead of scp.

${H3_COLOR}Examples${N0_COLOR}:

 # cbsd node mode=add node=10.0.0.7

${H3_COLOR}See also${N0_COLOR}:

 cbsd rexe --help

"


# ToDo:
# Instead of this need one nodescp daemon/services with one lock and which will work on AMQP queue
# where executing
#     % cbsd nodescp XXX YYY
# just add job to queue

verbose=1
root=0
quiet=
rsync=0
tryoffline=0

. ${subrdir}/nc.subr
. ${cbsdinit}
. ${nodes}

getnode()
{
	local _t

	_t=$( echo ${1} | ${GREP_CMD} ":" )

	[ $? -ne 0 ] && return 1

	node=${1%%:*}
	rfile=${1##*:}
}

node_scp()
{
	local node=
	local rfile=
	local rarg=0

	if getnode ${1}; then
		if getnode ${2}; then
			err 1 "${N1_COLOR}Only one remote path${N0_COLOR}"
		fi
		rarg=1
	else
		if getnode ${2}; then
			rarg=2
		fi
	fi

	[ -z "${node}" -o -z "${rfile}" ] && err 1 "${N1_COLOR}specify dst/src node via: ${N2_COLOR}node:path${N0_COLOR}"

	NODEDATA=$( cbsdsqlro nodes "SELECT ip,port,keyfile,rootkeyfile FROM nodelist where nodename='${node}'" )
	if [ -z "${NODEDATA}" ]; then
		${ECHO} "${N1_COLOR}No such node in base: ${N2_COLOR}${node}${N0_COLOR}"
		_all_nodes=$( cbsdsqlro nodes "SELECT nodename FROM nodelist" | ${XARGS_CMD} | ${TR_CMD} " " "," )
		err 1 "${N1_COLOR}available nodes: ${N2_COLOR}${_all_nodes}${N0_COLOR}"
	fi

	sqllist "${NODEDATA}" myip myport keyfile rootkey

	if [ ${tryoffline} -ne 1 ]; then
		if ! check_locktime ${ftmpdir}/shmux_${myip}.lock >/dev/null 2>&1; then
			err 1 "${N1_COLOR}Node is offline${N0_COLOR}"
		fi
	fi

	# optional flags for disable needed
	if [ ${root} -eq 1 -a -r "${rootkey}" ]; then
		[ ${verbose} -eq 1 ] && ${ECHO} "${N1_COLOR}Root key specified and exist, preferred: ${N2_COLOR}${rootkey}${N0_COLOR}"
		key="${rootkey}"
		sshkey_opt="-i ${rootkey}"
		cbsduser="root"
	else
		key="${keyfile}"
		sshkey_opt="-i ${keyfile}"
	fi

	[ ! -r "${key}" ] && sshkey_opt=

	iptype ${myip} >/dev/null 2>&1
	_ret=$?

	case ${_ret} in
		1)
			proto="-4"
			;;
		2)
			proto="-6"
			myip="[${myip}]"
			;;
		*)
			err 1 "${N1_COLOR}nodeaddkey: unknown IP type: ${N2_COLOR}${myip}${N0_COLOR}"
		;;
	esac

	SSHOP="${proto} -C -oBatchMode=yes -oStrictHostKeyChecking=no -oConnectTimeout=5 -oControlPath=${sshdir}/sockets/%r@%h:%p ${quiet} -oPort=${myport} ${sshkey_opt} ${myip}"
	SCPOP="${proto} -C -oBatchMode=yes -oStrictHostKeyChecking=no -oConnectTimeout=5 -oControlPath=${sshdir}/sockets/%r@%h:%p ${quiet} -oPort=${myport} ${sshkey_opt}"

	[ -z "${SCPOP}" -o -z "${myip}" ] && err 1 "${N1_COLOR}No such node ${N2_COLOR}${node}${N1_COLOR} in database or have no ip/scpopt${N0_COLOR}"

	lockname=$( ${miscdir}/cbsd_md5 "${myip}${rfile}" )

	if [ ${rarg} -eq 1 ]; then
		DIR=$( ${DIRNAME_CMD} ${2} )
		[ ! -d "${DIR}" ] && ${MKDIR_CMD} -p ${DIR}

		if [ "${rsync}" = "1" ]; then
			#we have rsync for that
			${LOCKF_CMD} -s -t0 ${ftmpdir}/${lockname}.lock ${RSYNC_CMD} -azzlH -e "${SSH_CMD} ${SCPOP}" ${cbsduser}@${myip}:${rfile} ${2} >${DEBLOG} 2>&1
			err=$?
		else
			#no rsync, just scp
			${LOCKF_CMD} -s -t0 ${ftmpdir}/${lockname}.lock ${SCP_CMD} ${SCPOP} -r ${cbsduser}@${myip}:${rfile} ${2} >${DEBLOG} 2>&1
			err=$?
		fi
	else
		DIR=$( ${DIRNAME_CMD} ${rfile})
		${LOCKF_CMD} -s -t0 ${ftmpdir}/${lockname}.lock ${SSH_CMD} ${SSHOP} -l ${cbsduser} <<EOF
[ ! -d "${DIR}" ] && ${MKDIR_CMD} -p "${DIR}"
EOF
		if [ "${rsync}" = "1" ]; then
			#we have rsync for that
			${LOCKF_CMD} -s -t0 ${ftmpdir}/${lockname}.lock ${RSYNC_CMD} -azzlH -e "${SSH_CMD} ${SCPOP}" ${1} ${cbsduser}@${myip}:${rfile} >${DEBLOG} 2>&1
			err=$?
		else
			#no rsync, just scp
			${LOCKF_CMD} -s -t0 ${ftmpdir}/${lockname}.lock scp ${SCPOP} -r ${1} ${cbsduser}@${myip}:${rfile} >${DEBLOG} 2>&1
			err=$?
		fi
	fi

	return ${err}
}

### MAIN ###
_args=

# trim special args from "$*"
for i in $*; do
	prefix5=$( substr --pos=0 --len=5 --str="${i}" )
	prefix6=$( substr --pos=0 --len=6 --str="${i}" )
	prefix8=$( substr --pos=0 --len=8 --str="${i}" )
	prefix11=$( substr --pos=0 --len=11 --str="${i}" )

	[ "${prefix5}" = "root=" ] && continue
	[ "${prefix6}" = "rsync=" ] && continue
	[ "${prefix8}" = "verbose=" ] && continue
	[ "${prefix11}" = "tryoffline=" ] && continue

	if [ -n "${_args}" ]; then
		_args="${_args} ${i}"
	else
		_args="${i}"
	fi
done

if [ "${verbose}" = "0" ]; then
	quiet="-q"
fi

node_scp ${_args}
_ret=$?

case ${_ret} in
	0)
		true
		;;
	*)
		case ${err} in
			255)
				${ECHO} "${N1_COLOR}${CBSD_APP}: make sure you have ${N2_COLOR}~cbsd/.ssh/authorized_keys${N1_COLOR} (copy of ~cbsd/.ssh/id_rsa.pub) on: ${N2_COLOR}${myip}${N0_COLOR}:"
				${ECHO} "cp -a ~cbsd/.ssh/id_rsa.pub ~cbsd/.ssh/authorized_keys"
				;;
		esac
		[ -r "${DEBLOG}" ] && ${CAT_CMD} ${DEBLOG}
		;;
esac

exit ${err}
