Last active
February 13, 2019 20:10
-
-
Save blurayne/001fb1b9f00f644047a2c10eb84e5e02 to your computer and use it in GitHub Desktop.
SSH to EC2 using peco and awless
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
### | |
# SSH to AWS EC2 instances using peco and awless | |
# | |
# - Generate a cache of AWS instances | |
# - Open peco to select one or more server and either open ssh or tmux-css | |
# - Does not use `awless ssh` since prefererence on ‘security by obscurity’ | |
# | |
# Dependencies | |
# | |
# https://github.com/peikk0/tmux-cssh | |
# https://github.com/peco/peco | |
# https://github.com/wallix/awless | |
# | |
# Part of bash-raclette | |
# Strict bash scripting | |
set -euo pipefail -o errtrace | |
# Using XDG standards ;) | |
CACHE_PATH="${CACHE_PATH:-$HOME/.cache/rc}" | |
if [[ -z "${AWS_PROFILES:-}" ]]; then | |
echo "$(basename $0): No AWS_PROFILES defined" | |
exit 1 | |
fi | |
IFS=' ' read -r -a awsProfiles <<< "$AWS_PROFILES" | |
# hide up cmd output | |
on_exit_hide_cmd() { | |
echo -e "\r\e[K\r\e[1A" | |
} | |
# output to stdin after run and press return | |
runcmd (){ | |
echo "$@" | perl -e 'ioctl STDOUT, 0x5412, $_ for split //, <>' ; | |
trap on_exit_hide_cmd EXIT | |
} | |
# output to stdin after run | |
writecmd (){ | |
echo "$@" | perl -e 'ioctl STDOUT, 0x5412, $_ for split //, do{ chomp($_ = <>); $_ }' ; | |
trap on_exit_hide_cmd EXIT | |
} | |
cachefile_valid() { | |
local ftime=$(stat -c %Y $1 2>/dev/null) | |
if [[ -z "$ftime" ]]; then | |
return 1 | |
fi | |
# better of with printf here yet trying to be nice to osx's bash3 | |
local now=$(date +%s) | |
if [[ $(( ${ftime} + 3600 + 24 )) -gt ${now} ]]; then | |
return 0; | |
else | |
return 1 | |
fi | |
} | |
update_aws_instance_cache() { | |
local cmd=() | |
local cacheFile | |
local sync=0 | |
if [[ ! -d "$CACHE_PATH" ]]; then | |
mkdir -p "$CACHE_PATH" | |
fi | |
for profile in ${awsProfiles[@]}; do | |
cacheFile="$CACHE_PATH/aws-$profile-instances.list" | |
if ! cachefile_valid $CACHE_PATH/aws-$profile-instances.list 1; then | |
cmd=( | |
awless -p "$profile" list instances \ | |
--columns id,name,state,keypair,privateip,publicip,tags \ | |
--format=csv --sort name --no-headers '|' xargs -I {} echo $profile,{} | |
) | |
( eval ${cmd[@]} > "$cacheFile.new" && mv "$cacheFile.new" "$cacheFile" ) & | |
if [[ -e "$cacheFile" ]]; then | |
# if file is old we background process and continue | |
disown | |
else | |
echo "awless: generating cache for $profile" | |
sync=1 | |
fi | |
fi | |
if [[ "$sync" -eq 1 ]]; then | |
for job in $(jobs -p); do wait $job || ( echo "failure..." && exit 1 ); done | |
fi | |
done | |
} | |
list_aws_instances() { | |
for profile in ${awsProfiles[@]}; do | |
cat "$CACHE_PATH/aws-$profile-instances.list" | |
done | |
} | |
format_aws_instance_csv() { | |
printf "%s\n" "$@" | sed ':a;N;$!ba;s/\n/\n\n---\n/g' | tr ',' '\n' | |
} | |
main() { | |
update_aws_instance_cache | |
IFS=$'\n' instances=($(list_aws_instances | peco --initial-filter Fuzzy --prompt "aws-instance>")) | |
if [[ -z "${instances[*]}" ]]; then | |
return | |
fi | |
format_aws_instance_csv "${instances[@]}" | |
local cmd="ssh" | |
echo "${#instances[@]}" | |
if [[ "${#instances[@]}" -gt 1 ]]; then | |
cmd="tmux-cssh" | |
fi | |
cmd="${cmd} ${@} $(printf "%s\n" "${instances[@]}" | cut -d ',' -f 6 | tr '\n' ' ')" | |
echo | |
echo --- | |
writecmd "${cmd}" | |
} | |
main "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment