195 lines
4.9 KiB
Bash
Executable File
195 lines
4.9 KiB
Bash
Executable File
#!/bin/zsh
|
|
use bastion --group remote
|
|
use config --group remote
|
|
#####################################################################
|
|
|
|
USAGE__options="
|
|
-c, --command override configured remote command
|
|
-s, --shell override configured remote login shell
|
|
-t, --type one of the following connection types:
|
|
- ssh (default) simple ssh execution
|
|
- xserver ssh connection with remote-xserver settings
|
|
- tmux connect directly to configured, remote tmux session
|
|
|
|
--no-rc disable loading the login RC for 'sh -c' commands
|
|
--no-tty don't request a tty connection
|
|
|
|
--force-local-login force login through ssh when working with localhost
|
|
|
|
--use-bastion true / false override for bastion preference
|
|
(default: session.name.bastion.preferred or 'false')
|
|
"
|
|
|
|
USAGE__description="
|
|
Connection / bastion wrapper for $REMOTE__TARGET. To configure,
|
|
use 'scwrypts remote configure'
|
|
"
|
|
|
|
|
|
#####################################################################
|
|
|
|
MAIN() {
|
|
[ $REMOTE__TARGET ] \
|
|
|| ERROR 'missing REMOTE__TARGET context; this must be run through scwrypts' \
|
|
|| return 1
|
|
|
|
local CONNECTION_TYPE=ssh
|
|
local REMOTE_NAME=$REMOTE__TARGET
|
|
local REMOTE_COMMAND LOGIN_SHELL
|
|
local LOAD_RC=true
|
|
local USE_TTY=true
|
|
local FORCE_LOCAL_LOGIN=false
|
|
local USE_BASTION
|
|
|
|
while [[ $# -gt 0 ]]
|
|
do
|
|
local _S=1
|
|
case $1 in
|
|
-t | --type ) ((_S+=1)); CONNECTION_TYPE=$2 ;;
|
|
-c | --command ) ((_S+=1)); REMOTE_COMMAND=$2 ;;
|
|
-s | --shell ) ((_S+=1)); LOGIN_SHELL=$2 ;;
|
|
|
|
--no-rc ) LOAD_RC=false ;;
|
|
--no-tty ) USE_TTY=false ;;
|
|
|
|
--use-bastion )
|
|
((_S+=1))
|
|
USE_BASTION=$2
|
|
case $USE_BASTION in
|
|
true | false ) ;;
|
|
* ) ERROR "invalid setting for '--use-bastion' (must be 'true' or 'false')" ;;
|
|
esac
|
|
;;
|
|
|
|
--force-local-login ) FORCE_LOCAL_LOGIN=true ;;
|
|
|
|
* ) ERROR "unknown argument '$1'" ;;
|
|
esac
|
|
[[ $_S -le $# ]] \
|
|
&& shift $_S \
|
|
|| ERROR "missing argument for '$1'" \
|
|
|| shift $#
|
|
done
|
|
|
|
CHECK_ERRORS
|
|
|
|
##########################################
|
|
|
|
GET_SSH_ARGS() {
|
|
REMOTE__GET_SSH_ARGS \
|
|
--type $CONNECTION_TYPE \
|
|
--use-tty $USE_TTY \
|
|
$REMOTE_NAME \
|
|
;
|
|
}
|
|
|
|
GET_SSH_ARGS >/dev/null \
|
|
&& local SSH_ARGS=($(GET_SSH_ARGS)) \
|
|
|| FAIL 1 'unable to load ssh args; aborting'
|
|
|
|
##########################################
|
|
|
|
local CONNECTION_STRING=$(REMOTE__GET_CONNECTION_STRING $REMOTE_NAME)
|
|
[ $CONNECTION_STRING ] \
|
|
|| FAIL 1 'unable to determine connection string'
|
|
|
|
##########################################
|
|
|
|
LOGIN_SHELL=$(\
|
|
REMOTE__QUERY_CONNECTION_WITH_FALLBACK \
|
|
"$LOGIN_SHELL" \
|
|
".$REMOTE_NAME.shell" \
|
|
".default.shell" \
|
|
"zsh" \
|
|
)
|
|
|
|
REMOTE_COMMAND=$(\
|
|
REMOTE__QUERY_CONNECTION_WITH_FALLBACK \
|
|
"$REMOTE_COMMAND" \
|
|
".sessions.$REMOTE_NAME.$CONNECTION_TYPE.command" \
|
|
".sessions.$REMOTE_NAME.command" \
|
|
".default.$CONNECTION_TYPE.command" \
|
|
".default.command" \
|
|
)
|
|
|
|
[ $REMOTE_COMMAND ] || {
|
|
case $CONNECTION_TYPE in
|
|
tmux )
|
|
local TMUX_SESSION_NAME=$(
|
|
REMOTE__QUERY_CONNECTION_WITH_FALLBACK \
|
|
".sessions.$REMOTE_NAME.tmux.session" \
|
|
".default.tmux.session" \
|
|
"wryn" \
|
|
)
|
|
local TMUX_ARGS=()
|
|
|
|
locale charmap 2>/dev/null | grep -qi 'UTF-8' \
|
|
&& TMUX_ARGS+=(-u)
|
|
|
|
REMOTE_COMMAND="tmux ${TMUX_ARGS[@]} new-session -As $TMUX_SESSION_NAME"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
#####################################################################
|
|
|
|
[ $USE_BASTION ] || {
|
|
USE_BASTION=$(\
|
|
REMOTE__QUERY_CONNECTION_WITH_FALLBACK \
|
|
".sessions.$REMOTE_NAME.bastion.preferred" \
|
|
'false' \
|
|
;
|
|
)
|
|
}
|
|
|
|
local BASTION_HOST
|
|
[[ $USE_BASTION =~ true ]] && {
|
|
BASTION_HOST=$(\
|
|
REMOTE__QUERY_CONNECTION_WITH_FALLBACK \
|
|
".sessions.$REMOTE_NAME.bastion.session" \
|
|
)
|
|
}
|
|
|
|
|
|
[ $BASTION_HOST ] && {
|
|
DEBUG "REMOTE_COMMAND : $REMOTE_COMMAND"
|
|
PASSTHROUGH_COMMAND="$(GET_PASSTHROUGH_PREFIX) connect $REMOTE_NAME --"
|
|
[ "$REMOTE_COMMAND" ] && PASSTHROUGH_COMMAND+=" -c $(printf "%q " "$REMOTE_COMMAND")"
|
|
|
|
BASTION_TARGET=$REMOTE_NAME REMOTE__TARGET=$BASTION_HOST MAIN --command "$PASSTHROUGH_COMMAND"
|
|
return $?
|
|
}
|
|
|
|
##########################################
|
|
|
|
[ $REMOTE_COMMAND ] && [[ $LOAD_RC =~ true ]] && {
|
|
REMOTE_COMMAND="$LOGIN_SHELL -l -c 'source ~/.$(basename $LOGIN_SHELL)rc &>/dev/null; $REMOTE_COMMAND'"
|
|
}
|
|
|
|
[ ! $REMOTE_COMMAND ] && {
|
|
[[ $LOAD_RC =~ true ]] \
|
|
&& REMOTE_COMMAND="$LOGIN_SHELL -l" \
|
|
|| REMOTE_COMMAND="$LOGIN_SHELL"
|
|
}
|
|
|
|
[ $BASTION_TARGET ] && CONNECTION_TYPE=bastion
|
|
|
|
DEBUG "
|
|
attempting execution:
|
|
netpath : $(hostnamectl --static) -> $([ $BASTION_TARGET ] && echo "$BASTION_TARGET -> ")$REMOTE_NAME
|
|
type : $CONNECTION_TYPE
|
|
connection : $REMOTE_NAME
|
|
command : \"$REMOTE_COMMAND\"
|
|
"
|
|
|
|
case $CONNECTION_STRING in
|
|
localhost | $USER@localhost )
|
|
eval "cd; $REMOTE_COMMAND"
|
|
return $?
|
|
;;
|
|
esac
|
|
|
|
DEBUG "ssh ${SSH_ARGS[@]} $CONNECTION_STRING \"$REMOTE_COMMAND\""
|
|
ssh ${SSH_ARGS[@]} $CONNECTION_STRING "$REMOTE_COMMAND"
|
|
}
|