Created
April 16, 2021 19:58
-
-
Save kennyjwilli/c640f76845451cb145cedaee790d4f9a to your computer and use it in GitHub Desktop.
This file contains 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
(let [invoke (delay @(requiring-resolve 'cs.aws-api/invoke))] | |
(defn fetch-assume-role-creds | |
[sts-client {:keys [role-arn | |
external-id | |
role-session-name]}] | |
(let [role-session-name (or role-session-name "computesoftware") | |
resp (@invoke | |
sts-client {:op :AssumeRole | |
:request (cond-> {:RoleArn role-arn | |
:RoleSessionName role-session-name} | |
external-id | |
(assoc :ExternalId external-id))})] | |
(when (anom/anomaly? resp) | |
(log/info {:tag ::assume-role-anomaly | |
:role-arn role-arn | |
:external-id external-id | |
:anomaly resp})) | |
(if (anom/anomaly? resp) | |
resp | |
(when-let [creds (:Credentials resp)] | |
{:aws/access-key-id (:AccessKeyId creds) | |
:aws/secret-access-key (:SecretAccessKey creds) | |
:aws/session-token (:SessionToken creds) | |
::credentials/ttl (credentials/calculate-ttl creds)}))))) | |
(defn get-source-profile-order | |
[config profile-name {:keys [max-iterations] | |
:or {max-iterations 10}}] | |
(loop [profile-name profile-name | |
sources (list) | |
iter 0] | |
(when (>= iter max-iterations) | |
(throw (ex-info (format "Cannot nest more than %s profiles." max-iterations) | |
{:max-iterations max-iterations}))) | |
(let [profile (get config profile-name) | |
source-profile-name (get profile "source_profile")] | |
(if (nil? source-profile-name) | |
(cons profile sources) | |
(recur source-profile-name (cons profile sources) (inc iter)))))) | |
(let [client (delay @(requiring-resolve 'cs.aws-api/client))] | |
(defn fetch-nested-profiles-creds-map | |
[profiles] | |
(reduce | |
(fn [creds-map [start-profile target-profile]] | |
(let [sts-client (@client | |
(cond-> {:api :sts} | |
(:region start-profile) | |
(assoc :region (:region start-profile)) | |
creds-map | |
(assoc | |
:credentials-provider | |
(reify | |
credentials/CredentialsProvider | |
(fetch [_] creds-map))))) | |
next-creds (fetch-assume-role-creds sts-client | |
{:role-arn (get target-profile "role_arn") | |
:external-id (get target-profile "external_id") | |
:role-session-name (get target-profile "role_session_name")})] | |
next-creds)) | |
nil (partition 2 1 profiles)))) | |
(defn get-credentials-from-profile | |
[f profile-name] | |
(when (.exists f) | |
(try | |
(let [profile (get (config/parse f) profile-name)] | |
(credentials/valid-credentials | |
{:aws/access-key-id (get profile "aws_access_key_id") | |
:aws/secret-access-key (get profile "aws_secret_access_key") | |
:aws/session-token (get profile "aws_session_token")} | |
"aws profiles file")) | |
(catch Throwable _ nil | |
#_(log/error t "Error fetching credentials from aws profiles file"))))) | |
(defn get-credentials-from-assume-role-profile | |
[f profile-name] | |
(when (.exists f) | |
(try | |
(let [config (config/parse f)] | |
(when (get-in config [profile-name "role_arn"]) | |
(let [profiles (get-source-profile-order config profile-name {}) | |
creds (fetch-nested-profiles-creds-map profiles)] | |
(credentials/valid-credentials | |
creds | |
"aws config file")))) | |
(catch Throwable _ nil)))) | |
(defn profile-credentials-provider | |
"Return credentials in an AWS configuration profile. | |
Arguments: | |
profile-name string The name of the profile in the file. (default: default) | |
f File The profile configuration file. (default: ~/.aws/credentials) | |
https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/credentials.html | |
Parsed properties: | |
aws_access_key required | |
aws_secret_access_key required | |
aws_session_token optional | |
Alpha. Subject to change." | |
([] | |
(profile-credentials-provider (or (u/getenv "AWS_PROFILE") | |
(u/getProperty "aws.profile") | |
"default"))) | |
([profile-name] | |
(profile-credentials-provider profile-name | |
{:config-file (or (io/file (u/getenv "AWS_CONFIG_FILE")) | |
(io/file (u/getProperty "user.home") ".aws" "config")) | |
:creds-file (or (io/file (u/getenv "AWS_CREDENTIAL_PROFILES_FILE")) | |
(io/file (u/getProperty "user.home") ".aws" "credentials"))})) | |
([profile-name {:keys [config-file creds-file]}] | |
(credentials/cached-credentials-with-auto-refresh | |
(reify credentials/CredentialsProvider | |
(fetch [_] | |
(or | |
(get-credentials-from-profile creds-file profile-name) | |
(get-credentials-from-assume-role-profile config-file profile-name))))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment