Current section
Files
Jump to
Current section
Files
lib/aws_ssm_provider.ex
defmodule AwsSsmProvider do
@moduledoc """
Populate run time application variables from a file produced by a call to AWS SSM
"""
use Mix.Releases.Config.Provider
# def start([config_path]) do
def init([config_path]) do
# Helper which expands paths to absolute form
# and expands env vars in the path of the form `${VAR}`
# to their value in the system environment
{:ok, config_path} = Provider.expand_path(config_path)
# All applications are already loaded at this point
if File.exists?(config_path) do
{:ok, lines} = File.read(config_path)
json = Jason.decode!(lines)
set_vars(json)
else
:ok
end
end
defp set_vars([]), do: nil
defp set_vars([head | tail]) do
val = translate_values(head["Value"])
key_list = String.split(head["Name"], "/", trim: true)
atom_key_list = Enum.map(key_list, fn x -> String.to_atom(x) end)
persist(val, atom_key_list)
set_vars(tail)
end
defp persist(val, [_env, _project, app, head_key | [:FromSystem]]) do
Application.put_env(app, head_key, System.get_env(val))
end
defp persist(val, [_env, _project, app, head_key | [:Integer]]) do
Application.put_env(app, head_key, elem(Integer.parse(val), 0))
end
defp persist(val, [_env, _project, app, head_key | []]) do
Application.put_env(app, head_key, val)
end
defp persist(val, [_env, _project, app, head_key | tail_keys]) do
app_vars = Application.get_env(app, head_key) || []
Application.put_env(app, head_key, get_nested_vars(app_vars, tail_keys, val))
end
defp persist(_val, _), do: nil
defp get_nested_vars(parent_vars, [head], value) do
[{head, value} | parent_vars]
end
defp get_nested_vars(parent_vars, key_list, value) do
parent_vars = parent_vars
[head | tail] = key_list
nested_case(tail, [{head, value} | parent_vars])
end
defp nested_case([:FromSystem], [{head, value} | parent_vars]) do
[{head, System.get_env(value)} | parent_vars]
end
defp nested_case([:Integer], [{head, value} | parent_vars]) do
[{head, elem(Integer.parse(value), 0)} | parent_vars]
end
defp nested_case(tail, [{head, value} | parent_vars]) do
curr_vars = parent_vars[head] || []
[{head, get_nested_vars(curr_vars, tail, value)} | parent_vars]
end
defp translate_values(v) do
Map.get(translations(), v, v)
end
defp translations do
%{
"true" => true,
"false" => false
}
end
end