2019-05-28 21:33:02 +08:00
function agp( ) {
2018-10-28 06:21:18 +08:00
echo $AWS_PROFILE
2013-10-09 22:42:28 +08:00
}
2015-09-05 03:18:32 +08:00
2023-03-07 20:33:16 +08:00
function agr( ) {
echo $AWS_REGION
}
2024-02-02 00:11:13 +08:00
# Update state file if enabled
function _aws_update_state( ) {
if [ [ " $AWS_PROFILE_STATE_ENABLED " = = true ] ] ; then
test -d $( dirname ${ AWS_STATE_FILE } ) || exit 1
echo " ${ AWS_PROFILE } ${ AWS_REGION } " > " ${ AWS_STATE_FILE } "
fi
}
function _aws_clear_state( ) {
if [ [ " $AWS_PROFILE_STATE_ENABLED " = = true ] ] ; then
test -d $( dirname ${ AWS_STATE_FILE } ) || exit 1
echo -n > " ${ AWS_STATE_FILE } "
fi
}
2019-05-26 18:31:37 +08:00
# AWS profile selection
2019-05-28 21:33:02 +08:00
function asp( ) {
2020-10-30 05:13:36 +08:00
if [ [ -z " $1 " ] ] ; then
2023-03-15 03:02:54 +08:00
unset AWS_DEFAULT_PROFILE AWS_PROFILE AWS_EB_PROFILE AWS_PROFILE_REGION
2024-02-02 00:11:13 +08:00
_aws_clear_state
2020-10-30 05:13:36 +08:00
echo AWS profile cleared.
return
fi
local -a available_profiles
available_profiles = ( $( aws_profiles) )
if [ [ -z " ${ available_profiles [(r) $1 ] } " ] ] ; then
echo " ${ fg [red] } Profile ' $1 ' not found in ' ${ AWS_CONFIG_FILE :- $HOME /.aws/config } ' " >& 2
echo " Available profiles: ${ (j : , : )available_profiles :- no profiles found } ${ reset_color } " >& 2
return 1
fi
export AWS_DEFAULT_PROFILE = $1
export AWS_PROFILE = $1
export AWS_EB_PROFILE = $1
2021-11-28 04:34:47 +08:00
2023-03-15 03:02:54 +08:00
export AWS_PROFILE_REGION = $( aws configure get region)
2024-02-02 00:11:13 +08:00
_aws_update_state
2021-11-28 04:34:47 +08:00
if [ [ " $2 " = = "login" ] ] ; then
2023-12-27 18:09:23 +08:00
if [ [ -n " $3 " ] ] ; then
aws sso login --sso-session $3
else
aws sso login
fi
2023-12-27 17:59:05 +08:00
elif [ [ " $2 " = = "logout" ] ] ; then
aws sso logout
2021-11-28 04:34:47 +08:00
fi
2020-10-30 05:13:36 +08:00
}
2023-03-07 20:33:16 +08:00
# AWS region selection
function asr( ) {
if [ [ -z " $1 " ] ] ; then
unset AWS_DEFAULT_REGION AWS_REGION
2024-02-02 00:11:13 +08:00
_aws_update_state
2023-03-07 20:33:16 +08:00
echo AWS region cleared.
return
fi
local -a available_regions
available_regions = ( $( aws_regions) )
if [ [ -z " ${ available_regions [(r) $1 ] } " ] ] ; then
echo " ${ fg [red] } Available regions: \n $( aws_regions) "
return 1
fi
export AWS_REGION = $1
export AWS_DEFAULT_REGION = $1
2024-02-02 00:11:13 +08:00
_aws_update_state
2023-03-07 20:33:16 +08:00
}
2020-10-30 05:13:36 +08:00
# AWS profile switch
function acp( ) {
2019-03-25 02:37:07 +08:00
if [ [ -z " $1 " ] ] ; then
2020-11-11 06:20:51 +08:00
unset AWS_DEFAULT_PROFILE AWS_PROFILE AWS_EB_PROFILE
unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN
2019-03-25 02:37:07 +08:00
echo AWS profile cleared.
2019-05-10 23:28:31 +08:00
return
2019-03-25 02:37:07 +08:00
fi
2019-05-10 23:28:31 +08:00
2020-01-30 20:31:33 +08:00
local -a available_profiles
available_profiles = ( $( aws_profiles) )
2019-05-26 18:31:37 +08:00
if [ [ -z " ${ available_profiles [(r) $1 ] } " ] ] ; then
echo " ${ fg [red] } Profile ' $1 ' not found in ' ${ AWS_CONFIG_FILE :- $HOME /.aws/config } ' " >& 2
echo " Available profiles: ${ (j : , : )available_profiles :- no profiles found } ${ reset_color } " >& 2
return 1
fi
2020-11-11 06:20:51 +08:00
local profile = " $1 "
2022-01-19 22:58:34 +08:00
local mfa_token = " $2 "
2020-11-11 06:20:51 +08:00
# Get fallback credentials for if the aws command fails or no command is run
local aws_access_key_id = " $( aws configure get aws_access_key_id --profile $profile ) "
local aws_secret_access_key = " $( aws configure get aws_secret_access_key --profile $profile ) "
local aws_session_token = " $( aws configure get aws_session_token --profile $profile ) "
2020-11-05 05:10:22 +08:00
# First, if the profile has MFA configured, lets get the token and session duration
2020-11-11 06:20:51 +08:00
local mfa_serial = " $( aws configure get mfa_serial --profile $profile ) "
2020-11-20 00:24:09 +08:00
local sess_duration = " $( aws configure get duration_seconds --profile $profile ) "
2020-11-05 05:10:22 +08:00
2020-11-11 06:20:51 +08:00
if [ [ -n " $mfa_serial " ] ] ; then
local -a mfa_opt
2022-01-19 22:58:34 +08:00
if [ [ -z " $mfa_token " ] ] ; then
echo -n " Please enter your MFA token for $mfa_serial : "
read -r mfa_token
fi
2020-11-20 00:24:09 +08:00
if [ [ -z " $sess_duration " ] ] ; then
echo -n "Please enter the session duration in seconds (900-43200; default: 3600, which is the default maximum for a role): "
read -r sess_duration
fi
2020-11-11 06:20:51 +08:00
mfa_opt = ( --serial-number " $mfa_serial " --token-code " $mfa_token " --duration-seconds " ${ sess_duration :- 3600 } " )
2021-07-13 16:05:33 +08:00
fi
2020-11-05 05:10:22 +08:00
2021-07-13 16:05:33 +08:00
# Now see whether we need to just MFA for the current role, or assume a different one
local role_arn = " $( aws configure get role_arn --profile $profile ) "
local sess_name = " $( aws configure get role_session_name --profile $profile ) "
2020-11-05 05:10:22 +08:00
2021-07-13 16:05:33 +08:00
if [ [ -n " $role_arn " ] ] ; then
# Means we need to assume a specified role
aws_command = ( aws sts assume-role --role-arn " $role_arn " " ${ mfa_opt [@] } " )
2020-11-05 05:10:22 +08:00
2021-07-13 16:05:33 +08:00
# Check whether external_id is configured to use while assuming the role
local external_id = " $( aws configure get external_id --profile $profile ) "
if [ [ -n " $external_id " ] ] ; then
aws_command += ( --external-id " $external_id " )
fi
2020-11-11 06:20:51 +08:00
2021-07-13 16:05:33 +08:00
# Get source profile to use to assume role
local source_profile = " $( aws configure get source_profile --profile $profile ) "
if [ [ -z " $sess_name " ] ] ; then
sess_name = " ${ source_profile :- profile } "
2020-11-11 06:20:51 +08:00
fi
2021-07-13 16:05:33 +08:00
aws_command += ( --profile= " ${ source_profile :- profile } " --role-session-name " ${ sess_name } " )
echo " Assuming role $role_arn using profile ${ source_profile :- profile } "
else
# Means we only need to do MFA
aws_command = ( aws sts get-session-token --profile= " $profile " " ${ mfa_opt [@] } " )
echo " Obtaining session token for profile $profile "
fi
# Format output of aws command for easier processing
aws_command += ( --query '[Credentials.AccessKeyId,Credentials.SecretAccessKey,Credentials.SessionToken]' --output text)
# Run the aws command to obtain credentials
local -a credentials
credentials = ( ${ (ps : \t : ) " $( ${ aws_command [@] } ) " } )
if [ [ -n " $credentials " ] ] ; then
aws_access_key_id = " ${ credentials [1] } "
aws_secret_access_key = " ${ credentials [2] } "
aws_session_token = " ${ credentials [3] } "
2020-11-05 05:10:22 +08:00
fi
2020-11-11 06:20:51 +08:00
# Switch to AWS profile
if [ [ -n " ${ aws_access_key_id } " && -n " $aws_secret_access_key " ] ] ; then
export AWS_DEFAULT_PROFILE = " $profile "
export AWS_PROFILE = " $profile "
export AWS_EB_PROFILE = " $profile "
export AWS_ACCESS_KEY_ID = " $aws_access_key_id "
export AWS_SECRET_ACCESS_KEY = " $aws_secret_access_key "
if [ [ -n " $aws_session_token " ] ] ; then
export AWS_SESSION_TOKEN = " $aws_session_token "
else
unset AWS_SESSION_TOKEN
fi
echo " Switched to AWS Profile: $profile "
2020-10-25 05:07:49 +08:00
fi
2013-10-09 22:42:28 +08:00
}
2015-09-05 03:18:32 +08:00
2019-05-28 21:33:02 +08:00
function aws_change_access_key( ) {
2019-05-26 18:31:37 +08:00
if [ [ -z " $1 " ] ] ; then
2019-03-24 03:56:55 +08:00
echo " usage: $0 <profile> "
2014-07-30 20:59:00 +08:00
return 1
fi
2019-03-24 03:56:55 +08:00
2023-04-18 16:36:07 +08:00
local profile = " $1 "
# Get current access key
local original_aws_access_key_id = " $( aws configure get aws_access_key_id --profile $profile ) "
asp " $profile " || return 1
echo "Generating a new access key pair for you now."
if aws --no-cli-pager iam create-access-key; then
echo "Insert the newly generated credentials when asked."
aws --no-cli-pager configure --profile $profile
else
echo "Current access keys:"
aws --no-cli-pager iam list-access-keys
echo " Profile \" ${ profile } \" is currently using the $original_aws_access_key_id key. You can delete an old access key by running \`aws --profile $profile iam delete-access-key --access-key-id AccessKeyId\` "
return 1
fi
2019-03-24 03:56:55 +08:00
2023-04-18 16:36:07 +08:00
read -q " yn?Would you like to disable your previous access key ( ${ original_aws_access_key_id } ) now? "
case $yn in
[ Yy] *)
echo -n " \nDisabling access key ${ original_aws_access_key_id } ... "
2023-05-06 19:40:06 +08:00
if aws --no-cli-pager iam update-access-key --access-key-id ${ original_aws_access_key_id } --status Inactive; then
2023-04-18 16:36:07 +08:00
echo "done."
else
echo " \nFailed to disable ${ original_aws_access_key_id } key. "
fi
; ;
*)
echo ""
; ;
esac
echo " You can now safely delete the old access key by running \`aws --profile $profile iam delete-access-key --access-key-id ${ original_aws_access_key_id } \` "
2020-11-20 00:24:09 +08:00
echo "Your current keys are:"
2023-04-18 16:36:07 +08:00
aws --no-cli-pager iam list-access-keys
2014-07-30 20:59:00 +08:00
}
2023-03-07 20:33:16 +08:00
function aws_regions( ) {
2024-01-31 04:36:18 +08:00
local region
if [ [ $AWS_DEFAULT_REGION ] ] ; then
region = " $AWS_DEFAULT_REGION "
elif [ [ $AWS_REGION ] ] ; then
region = " $AWS_REGION "
else
region = "us-west-1"
fi
2023-03-07 20:33:16 +08:00
if [ [ $AWS_DEFAULT_PROFILE || $AWS_PROFILE ] ] ; then
2024-01-31 04:36:18 +08:00
aws ec2 describe-regions --region $region | grep RegionName | awk -F ':' '{gsub(/"/, "", $2);gsub(/,/, "", $2);gsub(/ /, "", $2); print $2}'
2023-03-07 20:33:16 +08:00
else
echo "You must specify a AWS profile."
fi
}
2019-05-28 21:33:02 +08:00
function aws_profiles( ) {
2023-01-13 21:35:30 +08:00
aws --no-cli-pager configure list-profiles 2> /dev/null && return
2019-05-25 16:24:43 +08:00
[ [ -r " ${ AWS_CONFIG_FILE :- $HOME /.aws/config } " ] ] || return 1
2022-07-13 01:25:27 +08:00
grep --color= never -Eo '\[.*\]' " ${ AWS_CONFIG_FILE :- $HOME /.aws/config } " | sed -E 's/^[[:space:]]*\[(profile)?[[:space:]]*([^[:space:]]+)\][[:space:]]*$/\2/g'
2013-10-09 22:42:28 +08:00
}
2014-08-31 00:20:28 +08:00
2023-03-07 20:33:16 +08:00
function _aws_regions( ) {
reply = ( $( aws_regions) )
}
compctl -K _aws_regions asr
2019-05-28 21:33:02 +08:00
function _aws_profiles( ) {
2019-05-26 18:31:37 +08:00
reply = ( $( aws_profiles) )
}
2020-11-05 05:10:22 +08:00
compctl -K _aws_profiles asp acp aws_change_access_key
2019-03-24 02:52:31 +08:00
2019-03-25 02:37:07 +08:00
# AWS prompt
2019-05-28 21:33:02 +08:00
function aws_prompt_info( ) {
2023-03-21 22:29:48 +08:00
local _aws_to_show
2023-03-28 22:55:53 +08:00
local region = " ${ AWS_REGION :- ${ AWS_DEFAULT_REGION :- $AWS_PROFILE_REGION } } "
2023-04-19 21:46:10 +08:00
2023-05-12 17:42:30 +08:00
if [ [ -n " $AWS_PROFILE " ] ] ; then
2023-04-19 21:46:10 +08:00
_aws_to_show += " ${ ZSH_THEME_AWS_PROFILE_PREFIX = "<aws:" } ${ AWS_PROFILE } ${ ZSH_THEME_AWS_PROFILE_SUFFIX = ">" } "
2023-03-21 22:29:48 +08:00
fi
2023-04-19 21:46:10 +08:00
2023-05-12 17:42:30 +08:00
if [ [ -n " $region " ] ] ; then
[ [ -n " $_aws_to_show " ] ] && _aws_to_show += " ${ ZSH_THEME_AWS_DIVIDER = " " } "
2023-04-19 21:46:10 +08:00
_aws_to_show += " ${ ZSH_THEME_AWS_REGION_PREFIX = "<region:" } ${ region } ${ ZSH_THEME_AWS_REGION_SUFFIX = ">" } "
2023-03-21 22:29:48 +08:00
fi
2023-04-19 21:46:10 +08:00
2023-03-21 22:29:48 +08:00
echo " $_aws_to_show "
2019-03-25 02:37:07 +08:00
}
2020-11-11 06:20:51 +08:00
if [ [ " $SHOW_AWS_PROMPT " != false && " $RPROMPT " != *'$(aws_prompt_info)' * ] ] ; then
2019-04-10 03:07:42 +08:00
RPROMPT = '$(aws_prompt_info)' " $RPROMPT "
2019-03-25 02:37:07 +08:00
fi
2024-02-02 00:11:13 +08:00
if [ [ " $AWS_PROFILE_STATE_ENABLED " = = true ] ] ; then
AWS_STATE_FILE = " ${ AWS_STATE_FILE :- /tmp/.aws_current_profile } "
test -s " ${ AWS_STATE_FILE } " || return
aws_state = ( $( cat $AWS_STATE_FILE ) )
2024-03-26 16:55:16 +08:00
2024-02-02 00:11:13 +08:00
export AWS_DEFAULT_PROFILE = " ${ aws_state [1] } "
export AWS_PROFILE = " $AWS_DEFAULT_PROFILE "
export AWS_EB_PROFILE = " $AWS_DEFAULT_PROFILE "
test -z " ${ aws_state [2] } " && AWS_REGION = $( aws configure get region)
export AWS_REGION = ${ AWS_REGION :- $aws_state [2] }
export AWS_DEFAULT_REGION = " $AWS_REGION "
fi
2019-03-24 02:52:31 +08:00
# Load awscli completions
2020-03-06 00:13:46 +08:00
# AWS CLI v2 comes with its own autocompletion. Check if that is there, otherwise fall back
2020-07-19 01:06:08 +08:00
if command -v aws_completer & > /dev/null; then
2020-10-05 23:20:02 +08:00
autoload -Uz bashcompinit && bashcompinit
2020-03-06 00:13:46 +08:00
complete -C aws_completer aws
else
function _awscli-homebrew-installed( ) {
# check if Homebrew is installed
( ( $+commands[ brew] ) ) || return 1
# speculatively check default brew prefix
if [ -h /usr/local/opt/awscli ] ; then
_brew_prefix = /usr/local/opt/awscli
else
# ok, it is not in the default prefix
# this call to brew is expensive (about 400 ms), so at least let's make it only once
_brew_prefix = $( brew --prefix awscli)
fi
}
# get aws_zsh_completer.sh location from $PATH
_aws_zsh_completer_path = " $commands [aws_zsh_completer.sh] "
# otherwise check common locations
if [ [ -z $_aws_zsh_completer_path ] ] ; then
# Homebrew
if _awscli-homebrew-installed; then
_aws_zsh_completer_path = $_brew_prefix /libexec/bin/aws_zsh_completer.sh
# Ubuntu
elif [ [ -e /usr/share/zsh/vendor-completions/_awscli ] ] ; then
_aws_zsh_completer_path = /usr/share/zsh/vendor-completions/_awscli
2020-03-10 00:07:34 +08:00
# NixOS
elif [ [ -e " ${ commands [aws] : P : h : h } /share/zsh/site-functions/aws_zsh_completer.sh " ] ] ; then
_aws_zsh_completer_path = " ${ commands [aws] : P : h : h } /share/zsh/site-functions/aws_zsh_completer.sh "
2020-03-06 00:13:46 +08:00
# RPM
else
_aws_zsh_completer_path = /usr/share/zsh/site-functions/aws_zsh_completer.sh
fi
2019-03-24 02:52:31 +08:00
fi
2020-03-06 00:13:46 +08:00
[ [ -r $_aws_zsh_completer_path ] ] && source $_aws_zsh_completer_path
unset _aws_zsh_completer_path _brew_prefix
2014-08-31 00:20:28 +08:00
fi
2023-03-07 20:33:16 +08:00