]> src.twobees.de Git - dotfiles.git/blob - stow/oh-my-zsh/.oh-my-zsh/plugins/aws/aws.plugin.zsh
...
[dotfiles.git] / stow / oh-my-zsh / .oh-my-zsh / plugins / aws / aws.plugin.zsh
1 function agp() {
2   echo $AWS_PROFILE
3 }
4
5 # AWS profile selection
6 function asp() {
7   if [[ -z "$1" ]]; then
8     unset AWS_DEFAULT_PROFILE AWS_PROFILE AWS_EB_PROFILE
9     echo AWS profile cleared.
10     return
11   fi
12
13   local -a available_profiles
14   available_profiles=($(aws_profiles))
15   if [[ -z "${available_profiles[(r)$1]}" ]]; then
16     echo "${fg[red]}Profile '$1' not found in '${AWS_CONFIG_FILE:-$HOME/.aws/config}'" >&2
17     echo "Available profiles: ${(j:, :)available_profiles:-no profiles found}${reset_color}" >&2
18     return 1
19   fi
20
21   export AWS_DEFAULT_PROFILE=$1
22   export AWS_PROFILE=$1
23   export AWS_EB_PROFILE=$1
24
25   if [[ "$2" == "login" ]]; then
26     aws sso login
27   fi
28 }
29
30 # AWS profile switch
31 function acp() {
32   if [[ -z "$1" ]]; then
33     unset AWS_DEFAULT_PROFILE AWS_PROFILE AWS_EB_PROFILE
34     unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN
35     echo AWS profile cleared.
36     return
37   fi
38
39   local -a available_profiles
40   available_profiles=($(aws_profiles))
41   if [[ -z "${available_profiles[(r)$1]}" ]]; then
42     echo "${fg[red]}Profile '$1' not found in '${AWS_CONFIG_FILE:-$HOME/.aws/config}'" >&2
43     echo "Available profiles: ${(j:, :)available_profiles:-no profiles found}${reset_color}" >&2
44     return 1
45   fi
46
47   local profile="$1"
48   local mfa_token="$2"
49
50   # Get fallback credentials for if the aws command fails or no command is run
51   local aws_access_key_id="$(aws configure get aws_access_key_id --profile $profile)"
52   local aws_secret_access_key="$(aws configure get aws_secret_access_key --profile $profile)"
53   local aws_session_token="$(aws configure get aws_session_token --profile $profile)"
54
55
56   # First, if the profile has MFA configured, lets get the token and session duration
57   local mfa_serial="$(aws configure get mfa_serial --profile $profile)"
58   local sess_duration="$(aws configure get duration_seconds --profile $profile)"
59
60   if [[ -n "$mfa_serial" ]]; then
61     local -a mfa_opt
62     if [[ -z "$mfa_token" ]]; then
63       echo -n "Please enter your MFA token for $mfa_serial: "
64       read -r mfa_token
65     fi
66     if [[ -z "$sess_duration" ]]; then
67       echo -n "Please enter the session duration in seconds (900-43200; default: 3600, which is the default maximum for a role): "
68       read -r sess_duration
69     fi
70     mfa_opt=(--serial-number "$mfa_serial" --token-code "$mfa_token" --duration-seconds "${sess_duration:-3600}")
71   fi
72
73   # Now see whether we need to just MFA for the current role, or assume a different one
74   local role_arn="$(aws configure get role_arn --profile $profile)"
75   local sess_name="$(aws configure get role_session_name --profile $profile)"
76
77   if [[ -n "$role_arn" ]]; then
78     # Means we need to assume a specified role
79     aws_command=(aws sts assume-role --role-arn "$role_arn" "${mfa_opt[@]}")
80
81     # Check whether external_id is configured to use while assuming the role
82     local external_id="$(aws configure get external_id --profile $profile)"
83     if [[ -n "$external_id" ]]; then
84       aws_command+=(--external-id "$external_id")
85     fi
86
87     # Get source profile to use to assume role
88     local source_profile="$(aws configure get source_profile --profile $profile)"
89     if [[ -z "$sess_name" ]]; then
90       sess_name="${source_profile:-profile}"
91     fi
92     aws_command+=(--profile="${source_profile:-profile}" --role-session-name "${sess_name}")
93
94     echo "Assuming role $role_arn using profile ${source_profile:-profile}"
95   else
96     # Means we only need to do MFA
97     aws_command=(aws sts get-session-token --profile="$profile" "${mfa_opt[@]}")
98     echo "Obtaining session token for profile $profile"
99   fi
100
101   # Format output of aws command for easier processing
102   aws_command+=(--query '[Credentials.AccessKeyId,Credentials.SecretAccessKey,Credentials.SessionToken]' --output text)
103
104   # Run the aws command to obtain credentials
105   local -a credentials
106   credentials=(${(ps:\t:)"$(${aws_command[@]})"})
107
108   if [[ -n "$credentials" ]]; then
109     aws_access_key_id="${credentials[1]}"
110     aws_secret_access_key="${credentials[2]}"
111     aws_session_token="${credentials[3]}"
112   fi
113
114   # Switch to AWS profile
115   if [[ -n "${aws_access_key_id}" && -n "$aws_secret_access_key" ]]; then
116     export AWS_DEFAULT_PROFILE="$profile"
117     export AWS_PROFILE="$profile"
118     export AWS_EB_PROFILE="$profile"
119     export AWS_ACCESS_KEY_ID="$aws_access_key_id"
120     export AWS_SECRET_ACCESS_KEY="$aws_secret_access_key"
121
122     if [[ -n "$aws_session_token" ]]; then
123       export AWS_SESSION_TOKEN="$aws_session_token"
124     else
125       unset AWS_SESSION_TOKEN
126     fi
127
128     echo "Switched to AWS Profile: $profile"
129   fi
130 }
131
132 function aws_change_access_key() {
133   if [[ -z "$1" ]]; then
134     echo "usage: $0 <profile>"
135     return 1
136   fi
137
138   echo "Insert the credentials when asked."
139   asp "$1" || return 1
140   AWS_PAGER="" aws iam create-access-key
141   AWS_PAGER="" aws configure --profile "$1"
142
143   echo "You can now safely delete the old access key running \`aws iam delete-access-key --access-key-id ID\`"
144   echo "Your current keys are:"
145   AWS_PAGER="" aws iam list-access-keys
146 }
147
148 function aws_profiles() {
149   [[ -r "${AWS_CONFIG_FILE:-$HOME/.aws/config}" ]] || return 1
150   grep --color=never -Eo '\[.*\]' "${AWS_CONFIG_FILE:-$HOME/.aws/config}" | sed -E 's/^[[:space:]]*\[(profile)?[[:space:]]*([^[:space:]]+)\][[:space:]]*$/\2/g'
151 }
152
153 function _aws_profiles() {
154   reply=($(aws_profiles))
155 }
156 compctl -K _aws_profiles asp acp aws_change_access_key
157
158 # AWS prompt
159 function aws_prompt_info() {
160   [[ -n "$AWS_PROFILE" ]] || return
161   echo "${ZSH_THEME_AWS_PREFIX=<aws:}${AWS_PROFILE:gs/%/%%}${ZSH_THEME_AWS_SUFFIX=>}"
162 }
163
164 if [[ "$SHOW_AWS_PROMPT" != false && "$RPROMPT" != *'$(aws_prompt_info)'* ]]; then
165   RPROMPT='$(aws_prompt_info)'"$RPROMPT"
166 fi
167
168
169 # Load awscli completions
170
171 # AWS CLI v2 comes with its own autocompletion. Check if that is there, otherwise fall back
172 if command -v aws_completer &> /dev/null; then
173   autoload -Uz bashcompinit && bashcompinit
174   complete -C aws_completer aws
175 else
176   function _awscli-homebrew-installed() {
177     # check if Homebrew is installed
178     (( $+commands[brew] )) || return 1
179
180     # speculatively check default brew prefix
181     if [ -h /usr/local/opt/awscli ]; then
182       _brew_prefix=/usr/local/opt/awscli
183     else
184       # ok, it is not in the default prefix
185       # this call to brew is expensive (about 400 ms), so at least let's make it only once
186       _brew_prefix=$(brew --prefix awscli)
187     fi
188   }
189
190   # get aws_zsh_completer.sh location from $PATH
191   _aws_zsh_completer_path="$commands[aws_zsh_completer.sh]"
192
193   # otherwise check common locations
194   if [[ -z $_aws_zsh_completer_path ]]; then
195     # Homebrew
196     if _awscli-homebrew-installed; then
197       _aws_zsh_completer_path=$_brew_prefix/libexec/bin/aws_zsh_completer.sh
198     # Ubuntu
199     elif [[ -e /usr/share/zsh/vendor-completions/_awscli ]]; then
200       _aws_zsh_completer_path=/usr/share/zsh/vendor-completions/_awscli
201     # NixOS
202     elif [[ -e "${commands[aws]:P:h:h}/share/zsh/site-functions/aws_zsh_completer.sh" ]]; then
203       _aws_zsh_completer_path="${commands[aws]:P:h:h}/share/zsh/site-functions/aws_zsh_completer.sh"
204     # RPM
205     else
206       _aws_zsh_completer_path=/usr/share/zsh/site-functions/aws_zsh_completer.sh
207     fi
208   fi
209
210   [[ -r $_aws_zsh_completer_path ]] && source $_aws_zsh_completer_path
211   unset _aws_zsh_completer_path _brew_prefix
212 fi