You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

253 lines
7.8 KiB
Bash

#!/usr/bin/env bash
# vim:ts=4:sts=4:sw=4:et
#
# Author: Hari Sekhon
# Date: 2012-09-01 13:01:11 +0100
#
# https://github.com/harisekhon/bash-tools
#
# License: see accompanying Hari Sekhon LICENSE file
#
# If you're using my code you're welcome to connect with me on LinkedIn and optionally send me feedback to help steer this or other code I publish
#
# https://www.linkedin.com/in/harisekhon
#
# ============================================================================ #
# A W S - A m a z o n W e b S e r v i c e s
# ============================================================================ #
srcdir="${srcdir:-$(dirname "${BASH_SOURCE[0]}")/..}"
# shellcheck disable=SC1090
type add_PATH &>/dev/null || . "$srcdir/.bash.d/paths.sh"
# ==================
# AWS CLI completion
aws_completer="$(type -P aws_completer 2>/dev/null)"
if [ -n "$aws_completer" ]; then
complete -C "$aws_completer" aws
fi
#alias s3='s3cmd'
alias s3='aws s3'
# ==================
# AWLess completion
alias awl=awless
alias assh="awless ssh"
if type -P awless &>/dev/null; then
# standard completion
if ! type _awless_start &>/dev/null; then
eval "$(awless completion bash)"
fi
# make completion work with awl alias above
if ! type _awl_start &>/dev/null; then
eval "$(awless completion bash | sed 's/awless/awl/g')"
fi
fi
# ==================
# JAVA_HOME needs to be set to use EC2 api tools
#[ -x /usr/bin/java ] && export JAVA_HOME=/usr # errors but still works
# Shouldn't be needed any more, all these sorts of tools were unified on awscli
#
# link_latest '/usr/local/ec2-api-tools-*'
#if [ -d /usr/local/ec2-api-tools/bin ]; then
# export EC2_HOME=/usr/local/ec2-api-tools # this should be a link to the unzipped ec2-api-tools-1.6.1.4/
# add_PATH "$EC2_HOME/bin"
#fi
# ============================================================================ #
# ec2dre - ec2-describe-regions - list regions you have access to and put them here
# TODO: pull a more recent list and have aliases/functions auto-generated from that to export
aws_eu(){
export EC2_URL=ec2.eu-west-1.amazonaws.com
}
aws_useast(){
export EC2_URL=ec2.us-east-1.amazonaws.com
}
#aws_eu
# ============================================================================ #
# https://github.com/remind101/assume-role
assume-role(){
#eval "$(command assume-role "$@")"
local output
output="$(command assume-role "$@")"
# shellcheck disable=SC2181
if [ $? -eq 0 ]; then
eval "$output"
fi
}
# ============================================================================ #
aws_get_cred_path(){
local aws_credentials="${AWS_SHARED_CREDENTIALS_FILE:-$HOME/.aws/credentials}"
local aws_config="${AWS_CONFIG_FILE:-$HOME/.aws/config}"
local boto="${BOTO_CONFIG:-$HOME/.boto}"
local credentials_file
if [ -f "$aws_credentials" ]; then
credentials_file="$aws_credentials"
# older boto creds
elif [ -f "$boto" ]; then
credentials_file="$boto"
elif [ -f "$aws_config" ]; then
credentials_file="$aws_config"
else
echo "no credentials found - didn't find $aws_credentials or $boto or $aws_config" 2>/dev/null
return 1
fi
echo "$credentials_file"
}
# this rarely changes so just set it once as initialization instead of passing lots of params
# or re-executing aws_get_cred_path() multiple times in different functions
aws_credentials_file="$(aws_get_cred_path)"
aws_clean_env(){
echo "clearing AWS_* environment variables"
while read -r envvar; do
unset "$envvar"
done < <(env | sed -n '/^AWS_/ s/=.*// p')
}
aws_get_profile_data(){
local profile="$1"
local filename="${2:-$aws_credentials_file}"
sed -n "/[[:space:]]*\\[\\(profile[[:space:]]*\\)*$profile\\]/,/^[[:space:]]*\\[/p" "$filename"
}
aws_profile(){
local profile="${1// }"
if [ -n "$profile" ]; then
if ! [[ "$profile" =~ ^[[:alnum:]_-]+$ ]]; then
echo "invalid profile name given, must be alphanumeric, dashes and underscores allowed"
return 1
fi
local profile_data
profile_data="$(aws_get_profile_data "$profile")"
[ -n "$profile_data" ] ||
profile_data="$(aws_get_profile_data "$profile" "${AWS_CONFIG_FILE:-$HOME/.aws/config}")"
if [ -z "$profile_data" ]; then
echo "profile [$profile] not found in $aws_credentials_file!"
return 1
fi
aws_clean_env
echo "setting aws profile to '$profile'"
export AWS_PROFILE="$profile"
elif [ -n "$AWS_PROFILE" ]; then
echo "$AWS_PROFILE"
else
echo "default (keys not loaded to env)"
fi
}
alias awsprofile=aws_profile
# Storing creds in one place in Boto creds file, pull them straight from there
# if only using new creds, might want to just export AWS_PROFILE instead using aws_profile which provides validation
aws_env(){
local profile="${1:-default}"
# export AWS_ACCESS_KEY
# export AWS_SECRET_KEY
# export AWS_SESSION_TOKEN - for multi-factor authentication
local aws_token=~/.aws/token
aws_profile "$profile" || return 1
# section is checked for existence as part of aws_profile(), will return before here if not valid
local profile_data
profile_data="$(aws_get_profile_data "$profile")"
echo "loading [$profile] creds from $aws_credentials_file"
eval "$(
for key in aws_access_key_id aws_secret_access_key aws_session_token; do
awk -F= "/^[[:space:]]*$key/"'{gsub(/[[:space:]]+/, "", $0); gsub(/_id/, "", $1); gsub(/_secret_access/, "_secret", $1); print "export "toupper($1)"="$2}' <<< "$profile_data"
done
)"
if [ -f "$aws_token" ]; then
echo "sourcing $aws_token"
# shellcheck disable=SC1090
source "$aws_token"
fi
}
alias awsenv=aws_env
aws_envs(){
awk '/^[[:space:]]*\[.+\]/{print $1}' < "$aws_credentials_file" |
sed 's/\[//;s/\]//' |
while read -r profile; do
default=0
if [ "$profile" = "$AWS_PROFILE" ]; then
local default=1
elif [ -z "$AWS_PROFILE" ] &&
[ "$profile" = "default" ]; then
local default=1
fi
if [ "$default" = 1 ]; then
echo -n "* "
else
echo -n " "
fi
echo -n "$profile"
if [ "$default" = 1 ] &&
! env | grep -q '^AWS_SECRET_KEY='; then
echo -n " (keys not loaded to env)"
fi
echo
done
}
alias awsenvs=aws_envs
aws_unenv(){
unset AWS_ACCESS_KEY
unset AWS_SECRET_KEY
unset AWS_SESSION_TOKEN
}
alias awsunenv=aws_unenv
aws_token(){
local output
local token
if [ $# -eq 0 ]; then
echo "usage: aws_token <token_from_mfa_device> [<other_options>]"
return 1
fi
if [ -z "${AWS_MFA_ARN:-}" ]; then
echo "environment variable \$AWS_MFA_ARN not set - you need to"
echo
echo "export AWS_MFA_ARN=arn:aws:iam::<123456789012>:mfa/<user>"
echo
echo "(you might want to put that in your ~/.bashrc.local or similar)"
return 1
fi
#aws sts get-session-token --serial-number arn-of-the-mfa-device --token-code code-from-token
set -x
output="$(aws sts get-session-token --serial-number "$AWS_MFA_ARN" --duration-seconds "${AWS_STS_DURATION_SECS:-129600}" --token-code "$@")"
result=$?
set +x
echo "$output"
if [ $result -ne 0 ]; then
return $result
fi
if type -P jq &>/dev/null; then
token="$(jq -r '.Credentials.SessionToken' <<< "$output")"
else
token-"$(awk -F: '/SessionToken/{print $2}' | sed 's/"//')"
fi
export AWS_SESSION_TOKEN="$token"
echo "exported AWS_SESSION_TOKEN"
echo
echo "export AWS_SESSION_TOKEN=$token" > ~/.aws/token
echo "saved to ~/.aws/token for other shells to source via aws_env()"
echo
echo "you can now use AWS CLI normally"
}
alias awstoken=aws_token