-module(aws@internal@providers@process).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/aws/internal/providers/process.gleam").
-export([fetch/2]).
-export_type([process_credentials/0, error/0, raw_output/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(
" Credential-process provider. Runs an external command and reads JSON\n"
" credentials from its standard output, per the AWS CLI's\n"
" `credential_process` spec.\n"
"\n"
" Expected output:\n"
" {\n"
" \"Version\": 1,\n"
" \"AccessKeyId\": \"...\",\n"
" \"SecretAccessKey\": \"...\",\n"
" \"SessionToken\": \"...\", // optional\n"
" \"Expiration\": \"ISO 8601 Z\" // optional; absent = non-expiring\n"
" }\n"
).
-type process_credentials() :: {process_credentials,
binary(),
binary(),
gleam@option:option(binary()),
gleam@option:option(integer())}.
-type error() :: {launch_failed, binary()} | {bad_output, binary()}.
-type raw_output() :: {raw_output,
integer(),
binary(),
binary(),
gleam@option:option(binary()),
gleam@option:option(binary())}.
-file("src/aws/internal/providers/process.gleam", 119).
-spec raw_decoder() -> gleam@dynamic@decode:decoder(raw_output()).
raw_decoder() ->
gleam@dynamic@decode:field(
<<"Version"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_int/1},
fun(Version) ->
gleam@dynamic@decode:field(
<<"AccessKeyId"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Access_key_id) ->
gleam@dynamic@decode:field(
<<"SecretAccessKey"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Secret_access_key) ->
gleam@dynamic@decode:then(
gleam@dynamic@decode:optionally_at(
[<<"SessionToken"/utf8>>],
none,
gleam@dynamic@decode:map(
{decoder,
fun gleam@dynamic@decode:decode_string/1},
fun(Field@0) -> {some, Field@0} end
)
),
fun(Session_token) ->
gleam@dynamic@decode:then(
gleam@dynamic@decode:optionally_at(
[<<"Expiration"/utf8>>],
none,
gleam@dynamic@decode:map(
{decoder,
fun gleam@dynamic@decode:decode_string/1},
fun(Field@0) -> {some, Field@0} end
)
),
fun(Expiration) ->
gleam@dynamic@decode:success(
{raw_output,
Version,
Access_key_id,
Secret_access_key,
Session_token,
Expiration}
)
end
)
end
)
end
)
end
)
end
).
-file("src/aws/internal/providers/process.gleam", 142).
-spec decode_credentials(bitstring()) -> {ok, process_credentials()} |
{error, error()}.
decode_credentials(Stdout) ->
gleam@result:'try'(
begin
_pipe = gleam@bit_array:to_string(Stdout),
gleam@result:replace_error(
_pipe,
{bad_output, <<"non-utf8 stdout"/utf8>>}
)
end,
fun(Text) ->
gleam@result:'try'(
begin
_pipe@1 = gleam@json:parse(Text, raw_decoder()),
gleam@result:map_error(
_pipe@1,
fun(_) ->
{bad_output,
<<"stdout is not the expected credential_process JSON"/utf8>>}
end
)
end,
fun(Raw) -> case erlang:element(2, Raw) of
1 ->
Expires_at = case erlang:element(6, Raw) of
{some, Ts} ->
case aws_ffi:parse_iso8601(Ts) of
{ok, T} ->
{some, T};
{error, _} ->
none
end;
none ->
none
end,
{ok,
{process_credentials,
erlang:element(3, Raw),
erlang:element(4, Raw),
erlang:element(5, Raw),
Expires_at}};
Other ->
{error,
{bad_output,
<<"unsupported credential_process Version "/utf8,
(erlang:integer_to_binary(Other))/binary>>}}
end end
)
end
).
-file("src/aws/internal/providers/process.gleam", 100).
-spec do_reverse(list(HLW), list(HLW)) -> list(HLW).
do_reverse(Xs, Acc) ->
case Xs of
[] ->
Acc;
[H | T] ->
do_reverse(T, [H | Acc])
end.
-file("src/aws/internal/providers/process.gleam", 96).
-spec list_reverse(list(HLT)) -> list(HLT).
list_reverse(Xs) ->
do_reverse(Xs, []).
-file("src/aws/internal/providers/process.gleam", 85).
-spec do_filter(list(HLP), fun((HLP) -> boolean()), list(HLP)) -> list(HLP).
do_filter(Xs, Keep, Acc) ->
case Xs of
[] ->
list_reverse(Acc);
[H | T] ->
case Keep(H) of
true ->
do_filter(T, Keep, [H | Acc]);
false ->
do_filter(T, Keep, Acc)
end
end.
-file("src/aws/internal/providers/process.gleam", 81).
-spec list_filter(list(HLM), fun((HLM) -> boolean())) -> list(HLM).
list_filter(Xs, Keep) ->
do_filter(Xs, Keep, []).
-file("src/aws/internal/providers/process.gleam", 70).
-spec split_command(binary()) -> {ok, {binary(), list(binary())}} | {error, nil}.
split_command(Command) ->
Parts = begin
_pipe = Command,
_pipe@1 = gleam@string:split(_pipe, <<" "/utf8>>),
list_filter(_pipe@1, fun(S) -> S /= <<""/utf8>> end)
end,
case Parts of
[] ->
{error, nil};
[Program | Args] ->
{ok, {Program, Args}}
end.
-file("src/aws/internal/providers/process.gleam", 45).
?DOC(
" Run the given command line and decode its stdout as credential-process\n"
" JSON. `command` is the verbatim string from `credential_process`; we\n"
" split it on whitespace into program + arguments before launch.\n"
).
-spec fetch(
fun((binary(), list(binary())) -> {ok, {integer(), bitstring()}} |
{error, nil}),
binary()
) -> {ok, process_credentials()} | {error, error()}.
fetch(Runner, Command) ->
gleam@result:'try'(
begin
_pipe = split_command(Command),
gleam@result:replace_error(
_pipe,
{launch_failed, <<"empty credential_process command"/utf8>>}
)
end,
fun(_use0) ->
{Program, Args} = _use0,
gleam@result:'try'(
begin
_pipe@1 = Runner(Program, Args),
gleam@result:replace_error(
_pipe@1,
{launch_failed,
<<<<"could not run '"/utf8, Program/binary>>/binary,
"'"/utf8>>}
)
end,
fun(_use0@1) ->
{Exit, Stdout} = _use0@1,
case Exit of
0 ->
decode_credentials(Stdout);
Code ->
{error,
{bad_output,
<<"credential_process exited with status "/utf8,
(erlang:integer_to_binary(Code))/binary>>}}
end
end
)
end
).