fcb6fa78a1304f9a8eff2a7563658de04a13d499

Author
Maksym <maksyms@users.noreply.github.com>
Committer
GitHub <noreply@github.com>
Date

Message

aws: add role delegation and MFA support as per IAM Best Practices (#8419)

* Added role delegation support and MFA support as per IAM Best Practices

* fix: grep with color enabled breaks profile parsing

* fix: compatible with MacOS basic sed

* docs: Added jq as a dependency

* feat: added variable session duration, if the role to be assumed permits it.

* bug: incorrect assigment for session length

* fix: profile extraction failed with some versions of sed

Fixed the issue that resulted from merging upstream changes to allow "." in the profile name

* fix: broken profile parsing when profile name contains "@"

Diff

  1diff --git a/plugins/aws/README.md b/plugins/aws/README.md
  2index 57c3b54acddf726fb7c7790f1855ac5403a21a85..4ceb71425639c251e8f1b2f5a2a84b3788c2ba1d 100644
  3--- a/plugins/aws/README.md
  4+++ b/plugins/aws/README.md
  5@@ -3,7 +3,7 @@
  6 This plugin provides completion support for [awscli](https://docs.aws.amazon.com/cli/latest/reference/index.html)
  7 and a few utilities to manage AWS profiles and display them in the prompt.
  8 
  9-To use it, add `aws` to the plugins array in your zshrc file.
 10+To use it, make sure [jq](https://stedolan.github.io/jq/download/) is installed, and add `aws` to the plugins array in your zshrc file.
 11 
 12 ```zsh
 13 plugins=(... aws)
 14diff --git a/plugins/aws/aws.plugin.zsh b/plugins/aws/aws.plugin.zsh
 15index 7994963c323552ddd0c8ad7c2c6c65f9dc6790fd..8a68bf0d88d2af9e95ac81a4cb9160896a77594b 100644
 16--- a/plugins/aws/aws.plugin.zsh
 17+++ b/plugins/aws/aws.plugin.zsh
 18@@ -5,7 +5,7 @@ function agp() {
 19 # AWS profile selection
 20 function asp() {
 21   if [[ -z "$1" ]]; then
 22-    unset AWS_DEFAULT_PROFILE AWS_PROFILE AWS_EB_PROFILE
 23+    unset AWS_DEFAULT_PROFILE AWS_PROFILE AWS_EB_PROFILE AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN
 24     echo AWS profile cleared.
 25     return
 26   fi
 27@@ -18,9 +18,61 @@ function asp() {
 28     return 1
 29   fi
 30 
 31-  export AWS_DEFAULT_PROFILE=$1
 32-  export AWS_PROFILE=$1
 33-  export AWS_EB_PROFILE=$1
 34+  local exists="$(aws configure get aws_access_key_id --profile $1)"
 35+  local role_arn="$(aws configure get role_arn --profile $1)"
 36+  local aws_access_key_id=""
 37+  local aws_secret_access_key=""
 38+  local aws_session_token=""
 39+  if [[ -n $exists || -n $role_arn ]]; then
 40+    if [[ -n $role_arn ]]; then
 41+      local mfa_serial="$(aws configure get mfa_serial --profile $1)"
 42+      local mfa_token=""
 43+      local mfa_opt=""
 44+      if [[ -n $mfa_serial ]]; then
 45+        echo "Please enter your MFA token for $mfa_serial:"
 46+        read mfa_token
 47+        echo "Please enter the session duration in seconds (900-43200; default: 3600, which is the default maximum for a role):"
 48+        read sess_duration
 49+        if [[ -z $sess_duration ]]; then
 50+          sess_duration = 3600
 51+        fi
 52+        mfa_opt="--serial-number $mfa_serial --token-code $mfa_token --duration-seconds $sess_duration"
 53+      fi
 54+
 55+      local ext_id="$(aws configure get external_id --profile $1)"
 56+      local extid_opt=""
 57+      if [[ -n $ext_id ]]; then
 58+        extid_opt="--external-id $ext_id"
 59+      fi
 60+
 61+      local profile=$1
 62+      local source_profile="$(aws configure get source_profile --profile $1)"
 63+      if [[ -n $source_profile ]]; then
 64+        profile=$source_profile
 65+      fi
 66+
 67+      echo "Assuming role $role_arn using profile $profile"
 68+      local assume_cmd=(aws sts assume-role "--profile=$profile" "--role-arn $role_arn" "--role-session-name "$profile"" "$mfa_opt" "$extid_opt")
 69+      local JSON="$(eval ${assume_cmd[@]})"
 70+
 71+      aws_access_key_id="$(echo $JSON | jq -r '.Credentials.AccessKeyId')"
 72+      aws_secret_access_key="$(echo $JSON | jq -r '.Credentials.SecretAccessKey')"
 73+      aws_session_token="$(echo $JSON | jq -r '.Credentials.SessionToken')"
 74+    else
 75+      aws_access_key_id="$(aws configure get aws_access_key_id --profile $1)"
 76+      aws_secret_access_key="$(aws configure get aws_secret_access_key --profile $1)"
 77+      aws_session_token=""
 78+    fi
 79+
 80+    export AWS_DEFAULT_PROFILE=$1
 81+    export AWS_PROFILE=$1
 82+    export AWS_EB_PROFILE=$1
 83+    export AWS_ACCESS_KEY_ID=$aws_access_key_id
 84+    export AWS_SECRET_ACCESS_KEY=$aws_secret_access_key
 85+    [[ -z "$aws_session_token" ]] && unset AWS_SESSION_TOKEN || export AWS_SESSION_TOKEN=$aws_session_token
 86+
 87+    echo "Switched to AWS Profile: $1";
 88+  fi
 89 }
 90 
 91 function aws_change_access_key() {
 92@@ -41,7 +93,7 @@ function aws_change_access_key() {
 93 
 94 function aws_profiles() {
 95   [[ -r "${AWS_CONFIG_FILE:-$HOME/.aws/config}" ]] || return 1
 96-  grep '\[profile' "${AWS_CONFIG_FILE:-$HOME/.aws/config}"|sed -e 's/.*profile \([a-zA-Z0-9@_\.-]*\).*/\1/'
 97+  grep --color=never -Eo '\[.*\]' "${AWS_CONFIG_FILE:-$HOME/.aws/config}" | sed -E 's/^[[:space:]]*\[(profile)?[[:space:]]*([-_[:alnum:]\.@]+)\][[:space:]]*$/\2/g'
 98 }
 99 
100 function _aws_profiles() {