#!/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 ] \ || echo.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 ) ;; ( * ) echo.error "invalid setting for '--use-bastion' (must be 'true' or 'false')" ;; esac ;; ( --force-local-login ) FORCE_LOCAL_LOGIN=true ;; * ) echo.error "unknown argument '$1'" ;; esac [[ $_S -le $# ]] \ && shift $_S \ || echo.error "missing argument for '$1'" \ || shift $# done utils.check-errors --fail ########################################## GET_SSH_ARGS() { remote.config.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.config.get-connection-string $REMOTE_NAME) [ $CONNECTION_STRING ] \ || FAIL 1 'unable to determine connection string' ########################################## LOGIN_SHELL=$(\ remote.config.query-connection-with-fallback \ "$LOGIN_SHELL" \ ".$REMOTE_NAME.shell" \ ".default.shell" \ "zsh" \ ) REMOTE_COMMAND=$(\ remote.config.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.config.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.config.query-connection-with-fallback \ ".sessions.$REMOTE_NAME.bastion.preferred" \ 'false' \ ; ) } local BASTION_HOST [[ $USE_BASTION =~ true ]] && { BASTION_HOST=$(\ remote.config.query-connection-with-fallback \ ".sessions.$REMOTE_NAME.bastion.session" \ ) } [ $BASTION_HOST ] && { echo.debug "REMOTE_COMMAND : $REMOTE_COMMAND" PASSTHROUGH_COMMAND="$(remote.bastion.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 echo.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 echo.debug "ssh ${SSH_ARGS[@]} $CONNECTION_STRING \"$REMOTE_COMMAND\"" ssh ${SSH_ARGS[@]} $CONNECTION_STRING "$REMOTE_COMMAND" }