mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-07 19:22:14 +09:00
feat(config): read secrets from NAME_FILE variables (#1421)
Co-authored-by: Hampus <[email protected]>
This commit is contained in:
@@ -70,6 +70,21 @@ else
|
||||
rm -f "$node_name_file"
|
||||
fi
|
||||
|
||||
case "${FLUXER_ERLANG_COOKIE_FILE:-}" in
|
||||
*[![:space:]]*)
|
||||
case "${FLUXER_ERLANG_COOKIE:-}" in
|
||||
*[![:space:]]*)
|
||||
echo 'FLUXER_ERLANG_COOKIE and FLUXER_ERLANG_COOKIE_FILE are both set, set only one.' >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
if ! FLUXER_ERLANG_COOKIE="$(cat -- "$FLUXER_ERLANG_COOKIE_FILE")"; then
|
||||
echo "FLUXER_ERLANG_COOKIE_FILE could not read $FLUXER_ERLANG_COOKIE_FILE." >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -z "${FLUXER_ERLANG_COOKIE:-}" ]; then
|
||||
echo 'FLUXER_ERLANG_COOKIE is required.' >&2
|
||||
exit 1
|
||||
|
||||
@@ -18,4 +18,8 @@ if [ -r "$node_name_file" ]; then
|
||||
FLUXER_ERLANG_NODE_NAME="$(cat "$node_name_file")"
|
||||
export FLUXER_ERLANG_NODE_NAME
|
||||
fi
|
||||
if [ -r "${FLUXER_ERLANG_COOKIE_FILE:-}" ] && [ -z "$(printf '%s' "${FLUXER_ERLANG_COOKIE:-}" | tr -d '[:space:]')" ]; then
|
||||
FLUXER_ERLANG_COOKIE="$(cat "$FLUXER_ERLANG_COOKIE_FILE")"
|
||||
export FLUXER_ERLANG_COOKIE
|
||||
fi
|
||||
exec "$script_dir/fluxer_gateway.real" "$@"
|
||||
|
||||
@@ -305,11 +305,44 @@ env_string(Name, Default) ->
|
||||
|
||||
-spec env_value(string()) -> string() | undefined.
|
||||
env_value(Name) ->
|
||||
Value = non_blank_env(Name),
|
||||
FileName = Name ++ "_FILE",
|
||||
case non_blank_env(FileName) of
|
||||
undefined -> Value;
|
||||
Path when Value =:= undefined -> read_env_file(FileName, Path);
|
||||
_ -> erlang:error({ambiguous_env, Name, FileName})
|
||||
end.
|
||||
|
||||
-spec non_blank_env(string()) -> string() | undefined.
|
||||
non_blank_env(Name) ->
|
||||
case os:getenv(Name) of
|
||||
false -> undefined;
|
||||
Value -> non_blank(Value)
|
||||
end.
|
||||
|
||||
-spec read_env_file(string(), string()) -> string() | undefined.
|
||||
read_env_file(FileName, Path) ->
|
||||
case file:read_file(Path) of
|
||||
{ok, Contents} -> env_file_value(FileName, Path, strip_newline(Contents));
|
||||
{error, Reason} -> erlang:error({unreadable_env_file, FileName, Path, Reason})
|
||||
end.
|
||||
|
||||
-spec env_file_value(string(), string(), binary()) -> string() | undefined.
|
||||
env_file_value(FileName, Path, Contents) ->
|
||||
case unicode:characters_to_list(Contents) of
|
||||
Value when is_list(Value) -> non_blank(Value);
|
||||
_ -> erlang:error({invalid_env_file, FileName, Path})
|
||||
end.
|
||||
|
||||
-spec strip_newline(binary()) -> binary().
|
||||
strip_newline(Contents) ->
|
||||
Size = byte_size(Contents),
|
||||
case Contents of
|
||||
<<Rest:(Size - 2)/binary, "\r\n">> -> Rest;
|
||||
<<Rest:(Size - 1)/binary, "\n">> -> Rest;
|
||||
_ -> Contents
|
||||
end.
|
||||
|
||||
-spec non_blank(string()) -> string() | undefined.
|
||||
non_blank(Value) ->
|
||||
case string:trim(Value) of
|
||||
|
||||
@@ -272,6 +272,64 @@ public_endpoints_defaults_test() ->
|
||||
?assertEqual(undefined, maps:get(media_proxy_endpoint, Config)),
|
||||
?assertEqual(<<"http://localhost:8088">>, maps:get(static_cdn_endpoint, Config)).
|
||||
|
||||
env_value_reads_name_file_test() ->
|
||||
with_env_file(<<"from-file\r\n">>, fun(Path) ->
|
||||
with_envs(
|
||||
[{"FLUXER_GATEWAY_TEST_SECRET", ""}, {"FLUXER_GATEWAY_TEST_SECRET_FILE", Path}],
|
||||
fun() ->
|
||||
?assertEqual(
|
||||
"from-file", fluxer_gateway_config:env_value("FLUXER_GATEWAY_TEST_SECRET")
|
||||
)
|
||||
end
|
||||
)
|
||||
end).
|
||||
|
||||
env_value_trims_only_one_newline_test() ->
|
||||
with_env_file(<<"line1\nline2\n\n">>, fun(Path) ->
|
||||
with_env("FLUXER_GATEWAY_TEST_SECRET_FILE", Path, fun() ->
|
||||
?assertEqual(
|
||||
"line1\nline2\n", fluxer_gateway_config:env_value("FLUXER_GATEWAY_TEST_SECRET")
|
||||
)
|
||||
end)
|
||||
end).
|
||||
|
||||
env_value_rejects_name_and_name_file_test() ->
|
||||
with_envs(
|
||||
[
|
||||
{"FLUXER_GATEWAY_TEST_SECRET", "direct"},
|
||||
{"FLUXER_GATEWAY_TEST_SECRET_FILE", "/run/secrets/x"}
|
||||
],
|
||||
fun() ->
|
||||
?assertError(
|
||||
{ambiguous_env, "FLUXER_GATEWAY_TEST_SECRET",
|
||||
"FLUXER_GATEWAY_TEST_SECRET_FILE"},
|
||||
fluxer_gateway_config:env_value("FLUXER_GATEWAY_TEST_SECRET")
|
||||
)
|
||||
end
|
||||
).
|
||||
|
||||
env_value_rejects_missing_name_file_test() ->
|
||||
Path = "/nonexistent/fluxer-gateway-test-secret",
|
||||
with_env("FLUXER_GATEWAY_TEST_SECRET_FILE", Path, fun() ->
|
||||
?assertError(
|
||||
{unreadable_env_file, "FLUXER_GATEWAY_TEST_SECRET_FILE", Path, enoent},
|
||||
fluxer_gateway_config:env_value("FLUXER_GATEWAY_TEST_SECRET")
|
||||
)
|
||||
end).
|
||||
|
||||
with_env_file(Contents, Fun) ->
|
||||
Path = filename:join(
|
||||
filename:basedir(user_cache, "fluxer_gateway_tests"),
|
||||
integer_to_list(erlang:unique_integer([positive]))
|
||||
),
|
||||
ok = filelib:ensure_dir(Path),
|
||||
ok = file:write_file(Path, Contents),
|
||||
try
|
||||
Fun(Path)
|
||||
after
|
||||
file:delete(Path)
|
||||
end.
|
||||
|
||||
with_envs([], Fun) ->
|
||||
Fun();
|
||||
with_envs([{Name, Value} | Rest], Fun) ->
|
||||
|
||||
Reference in New Issue
Block a user