Skip to content

Instantly share code, notes, and snippets.

@vadirajks
Forked from mo-ya/ec2-ssh
Created August 9, 2016 10:07
Show Gist options
  • Save vadirajks/afb5f6eb4bf3dfad70f039f531b95f88 to your computer and use it in GitHub Desktop.
Save vadirajks/afb5f6eb4bf3dfad70f039f531b95f88 to your computer and use it in GitHub Desktop.
#!/bin/sh
## EC2 automation login tool
#
# Original: http://m.igrs.jp/blog/2013/03/14/ec2-ssh/
# https://gist.github.com/migrs/5157665
# https://gist.github.com/MichinobuMaeda/5545875
#
# Changed by mo-ya (2013-07-06)
#
# - SSH Timeout value can be set by $EC2_SSH_TIMEOUT
# - Default mode is changed to quit. Verbose on/off is switched by $EC2_SSH_VERBOSE
# - If a cache file is not found, the file is created automatically
# - Valid duration of Cache is controlled by $EC2_SSH_CACHE_DAY (default: 1 day)
#
# Changed by mo-ya (2013-06-15)
#
# - Use Cache file
# - Public DNS, Elastic IP Information is stored in a cache file.
# The next access is performed without ec2-api-tools query.
# If the access is failed, Public DNS and Elastic IP are queried by ec2-api-tools,
# and caches are updated.
# - If $1 is undefined, help messages and cache contents are output
# - Verbose Mode is added (controlled by $ec2_ssh_verbose)
#
# Changed by mo-ya (2013-05-20)
#
# - Default user can be set as $EC2_SSH_DEFAULT_USER
# - Default ssh key path can be set as $EC2_SSH_KEY_PATH
# - Some verbose messages are output to STDERR
#
## Settings
set -e
ssh="ssh"
ssh_timeout="2"
ec2din="ec2-describe-instances"
ec2_ssh_host_cache_set="${HOME}/.ec2-ssh.hostcache"
verbose=
cache_day=1
## Post Settings
if [ -n "$EC2_SSH_TIMEOUT" ]; then
ssh_timeout="${EC2_SSH_TIMEOUT}"
fi
ec2_ssh_opt="-o ConnectTimeout=${ssh_timeout}"
if [ -n "$EC2_SSH_KEY_PATH" ]; then
ec2_ssh_opt="${ec2_ssh_opt} -i ${EC2_SSH_KEY_PATH}"
fi
if [ -n "$EC2_SSH_DEFAULT_USER" ]; then
ec2_ssh_user="${EC2_SSH_DEFAULT_USER}@"
fi
if [ -n "$EC2_SSH_CACHE_DAY" ]; then
cache_day="${EC2_SSH_CACHE_DAY}"
fi
if [ -n "$EC2_SSH_VERBOSE" ]; then
verbose="${EC2_SSH_VERBOSE}"
fi
## Functions
vmsg(){
if [ -n "${verbose}" ]; then
echo "$*" >&2
fi
}
msg(){
echo "$*" >&2
}
## Output Help Messages (If any arguments are not found)
if [ $# -lt 1 ]; then
cat <<END_OF_HELP
# [ec2-ssh] Usages
Basic Usage
$ ec2-ssh web1
$ ec2-ssh jonny@web1
Access Same Name Instances (#1, #2 ...)
$ ec2-ssh web#3
Port Fowarding
$ ec2-ssh -L 8080:127.0.0.1:80 web1
Command direct execution
$ ec2-ssh web1 ls -la
$ ec2-ssh web1 tail -f /var/log/nginx/access.log
$ ec2-ssh web1 vmstat 1
$ ec2-ssh web1 -t top
$ ec2-ssh web1 -t sudo service nginx restart
END_OF_HELP
if [ -f "${ec2_ssh_host_cache_set}" ]; then
cat <<END_OF_CACHE
# [ec2-ssh] Cache Lists (in "${ec2_ssh_host_cache_set}")
END_OF_CACHE
cat ${ec2_ssh_host_cache_set}
fi
exit 1
fi
## Display ENVs
if [ -n "$EC2_SSH_HOST_CACHE" ]; then
ec2_ssh_host_cache_set="$EC2_SSH_HOST_CACHE"
fi
vmsg "[ENV]"
vmsg " EC2_SSH_KEY_PATH = $EC2_SSH_KEY_PATH"
vmsg " EC2_SSH_DEFAULT_USER = $EC2_SSH_DEFAULT_USER"
vmsg " EC2_SSH_HOST_CACHE = $ec2_ssh_host_cache_set"
vmsg " EC2_SSH_TIMEOUT = $ssh_timeout"
vmsg " EC2_SSH_CACHE_DAY = $cache_day"
vmsg " EC2_SSH_VERBOSE = $verbose"
## Parse Command line options (host name & number informations)
while [ $# -gt 0 ]; do
case $1 in
-*)
if [ -z "$2" ]; then
break
elif [ "${2:0:1}" == "-" ]; then
args="$args $1"
shift
else
args="$args $1 $2"
shift 2
fi
;;
*)
if [ -n "$1" -a -z "$name" ]; then
name=$1
shift
fi
break
esac
done
if [ "$name" != "${name%\#*}" ]; then
num=${name#*\#}
name=${name%\#*}
fi
[ -z "$num" ] && num=1
if [ "$name" != "${name%@*}" ]; then
user=${name%@*}
name=${name#*@}
fi
## Load EC2 Information from Local Cache
cache_hit=
msg "[Load EC2 Information from Local Cache] ... "
if [ -f "${ec2_ssh_host_cache_set}" ]; then
host=`grep "^${name}#${num}" ${ec2_ssh_host_cache_set} | cut -f2`
reg_date=`grep "^${name}#${num}" ${ec2_ssh_host_cache_set} | cut -f3`
set +e
# for GNU date
valid_date=`date --date "${cache_day} day ago" "+%Y%m%d%H%M%S" 2>/dev/null`
if [ -z "${valid_date}" ]; then
# for BSD date
valid_date=`date -v-${cache_day}d "+%Y%m%d%H%M%S" 2>/dev/null`
fi
set -e
if [ -n "$host" ]; then
cache_old=
if [ -n "${reg_date}" ] && [ -n "${valid_date}" ];then
if [ "${reg_date}" -lt "${valid_date}" ];then
cache_old=1
fi
else
vmsg " WARNING: reg_date or valid_date is not found"
vmsg " reg_date = $reg_date"
vmsg " valid_date = $valid_date"
fi
if [ -z "${cache_old}" ]; then
cache_hit=1
msg " Cache HIT: $name => $host"
else
msg " Cache OLD: older than ${cache_day} day [${reg_date}]: $name => $host"
host=
fi
else
msg " Cache NOT FOUND: host is not found in Caches"
fi
else
msg " Cache file is not found."
fi
yet_connect=1
while [ -n "${yet_connect}" ]; do
## Get EC2 Information from AWS
if [ -z "$host" ]; then
msg "[Get EC2 Information from AWS] ... (wait a minutes)"
q="-F \"tag:Name=$name\""
host=`$ec2din $q --hide-tags | grep ^INSTANCE | cut -f4 | paste -s - | cut -f$num`
if [ -n "$host" ]; then
vmsg "[Target] $host"
else
msg "ec2-ssh: Could not find ec2 instance $name [$num]"
exit 1
fi
fi
## Save host information to cache
if [ -z "$cache_hit" ] ; then
if [ ! -f "${ec2_ssh_host_cache_set}" ]; then
touch ${ec2_ssh_host_cache_set}
fi
vmsg "[Save EC2 Information to Local Cache] ... "
cat ${ec2_ssh_host_cache_set} | grep -v "^${name}#${num}" > ${ec2_ssh_host_cache_set}.$$ | true
cat ${ec2_ssh_host_cache_set}.$$ > ${ec2_ssh_host_cache_set}
rm ${ec2_ssh_host_cache_set}.$$
reg_date=`date "+%Y%m%d%H%M%S"`
echo "${name}#${num} ${host} ${reg_date}" >> ${ec2_ssh_host_cache_set}
vmsg " Cache is updated."
fi
## Access the server
if [ -n "$user" ]; then
ssh_user_set="${user}@"
else
ssh_user_set="${ec2_ssh_user}"
fi
msg "[Connecting EC2] ..."
vmsg $ssh $ec2_ssh_opt $args ${ssh_user_set}$host $@
set +e
$ssh $ec2_ssh_opt $args ${ssh_user_set}$host $@
ssh_stat=$?
set -e
if [ "$ssh_stat" = 0 ]; then
yet_connect=
else
if [ -z "$cache_hit" ]; then
msg "ERROR: Cannot Connect to [Name=$name, PublicDNS=$host]"
msg " Please Check Server Settings."
exit 1
else
msg "WARNING: Cache Info may be obsoleted. Cache is ignored."
host=
cache_hit=
fi
fi
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment