#!/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" }