diff --git a/src/aws_credentials_file.erl b/src/aws_credentials_file.erl index dfc47d5..cbd86c1 100644 --- a/src/aws_credentials_file.erl +++ b/src/aws_credentials_file.erl @@ -135,7 +135,29 @@ parse_config_file(Path, Options) -> read_from_profile(File, Profile) -> case maps:get(Profile, File, undefined) of undefined -> {error, {desired_profile_not_found, Profile}}; - Map -> {ok, Map} + Map -> + case maps:is_key(<<"credential_process">>, Map) of + true -> + % Source credentials with an external process + % https://docs.aws.amazon.com/cli/v1/userguide/cli-configure-sourcing-external.html + Process = maps:get(<<"credential_process">>, Map), + Stdout = os:cmd(binary_to_list(Process)), + CredResult = jsx:decode(iolist_to_binary(Stdout)), + CredsMap = maps:from_list(lists:filtermap( + fun + ({<<"AccessKeyId">>, AKI}) -> + {true, {<<"aws_access_key_id">>, AKI}}; + ({<<"SecretAccessKey">>, SAK}) -> + {true, {<<"aws_secret_access_key">>, SAK}}; + ({<<"SessionToken">>, ST}) -> + {true, {<<"aws_session_token">>, ST}}; + (_) -> + false + end, maps:to_list(CredResult))), + {ok, maps:merge(Map, CredsMap)}; + false -> + {ok, Map} + end end. -spec desired_profile(aws_credentials_provider:options()) -> binary(). diff --git a/test/aws_credentials_providers_SUITE.erl b/test/aws_credentials_providers_SUITE.erl index e84acca..5129c88 100644 --- a/test/aws_credentials_providers_SUITE.erl +++ b/test/aws_credentials_providers_SUITE.erl @@ -35,6 +35,7 @@ all() -> , {group, env} , {group, application_env} , {group, ecs} + , {group, credential_process} ]. groups() -> @@ -47,6 +48,7 @@ groups() -> , {env, [], all_testcases()} , {application_env, [], all_testcases()} , {ecs, [], all_testcases()} + , {credential_process, [], all_testcases()} ]. all_testcases() -> @@ -69,6 +71,8 @@ init_per_group(GroupName, Config) -> credential_env -> init_group(credential_env, provider(file), credential_env, Config); profile_env -> init_group(profile_env, provider(file), config_credential, Config); application_env -> init_group(application_env, provider(env), application_env, Config); + credential_process -> + init_group(credential_process, provider(file), credential_process, Config); GroupName -> init_group(GroupName, Config) end. @@ -111,6 +115,9 @@ assert_test(credential_env) -> assert_test(profile_env) -> Provider = provider(file), assert_values(?DUMMY_ACCESS_KEY2, ?DUMMY_SECRET_ACCESS_KEY2, Provider); +assert_test(credential_process) -> + Provider = provider(file), + assert_values(?DUMMY_ACCESS_KEY2, ?DUMMY_SECRET_ACCESS_KEY2, Provider); assert_test(GroupName) -> Provider = provider(GroupName), assert_values(?DUMMY_ACCESS_KEY, ?DUMMY_SECRET_ACCESS_KEY, Provider). @@ -145,6 +152,8 @@ provider_opts(config_credential, Config) -> #{credential_path => ?config(data_dir, Config) ++ "config_credential/"}; provider_opts(credential_env, _Config) -> #{credential_path => os:getenv("HOME")}; +provider_opts(credential_process, Config) -> + #{credential_path => ?config(data_dir, Config) ++ "credential_process/"}; provider_opts(_GroupName, _Config) -> #{}. diff --git a/test/aws_credentials_providers_SUITE_data/credential_process/config b/test/aws_credentials_providers_SUITE_data/credential_process/config new file mode 100644 index 0000000..a8c11c6 --- /dev/null +++ b/test/aws_credentials_providers_SUITE_data/credential_process/config @@ -0,0 +1,2 @@ +[default] +region = us-east-1 diff --git a/test/aws_credentials_providers_SUITE_data/credential_process/credentials b/test/aws_credentials_providers_SUITE_data/credential_process/credentials new file mode 100644 index 0000000..15d2151 --- /dev/null +++ b/test/aws_credentials_providers_SUITE_data/credential_process/credentials @@ -0,0 +1,2 @@ +[default] +credential_process = echo '{"AccessKeyId":"dummy_access_key2", "SecretAccessKey":"dummy_secret_access_key2"}'