Packages

Weave allows you to configure your application just-in-time (JIT), embracing the 12-Factor manifesto. Weave supports loading configuration from environment variables and files, with prefix and filename filtering. Works great with Kubernetes and Docker Swarm.

Current section

Files

Jump to
weave lib loaders environment.ex
Raw

lib/loaders/environment.ex

defmodule Weave.Loaders.Environment do
@moduledoc """
This loader will utilise the available environment variables to provide configuration. A prefix must be specified.
```elixir
loaders: [
{Weave.Loaders.Environment, prefix: "MY_APP_"},
{Weave.Loaders.Environment, prefix: nil} # Use nil to load all environment variables
]
```
With the above configuration, any environment variables that begin with `MY_APP_` will be sent to the handler. Please note, these will be "sanitized" before being sent to the handler.
This means "MY_APP_NAME" will become "name"
"""
use Weave.Loader
require Logger
@doc """
You shouldn't call this function youroself. Instead, use a Weave module.
"""
def load_configuration(options: [prefix: prefix], only: only, handler: handler) do
Logger.debug(fn ->
"Weave - Environment Loader: prefix: #{prefix}, only: #{inspect(only)}, handler: #{
inspect(handler)
}"
end)
System.get_env()
|> filter_prefix(prefix)
|> filter_only(only)
|> Enum.map(fn {key, value} ->
apply_configuration(key, value, handler)
sanitize(key)
end)
end
@doc """
Safety net to provide debug when people don't configure their loaders correctly
"""
def load_configuration(options: _, only: _, handler: _) do
Logger.warn(fn ->
"Weave Environment Loader called, but wasn't configured with `prefix: nil | binary`"
end)
[]
end
defp filter_prefix(variables, nil), do: variables
defp filter_prefix(variables, prefix) do
require Logger
Logger.debug(fn -> "Filtering prefix: #{prefix}" end)
variables
|> Enum.filter(fn {key, _value} ->
String.starts_with?(key, prefix)
end)
|> Enum.map(fn {key, value} ->
{String.trim_leading(key, prefix), value}
end)
end
defp filter_only(variables, nil), do: variables
defp filter_only(variables, only) do
# Allow variables names to be passed as string
# or atoms by converting everything to strings here
only = Enum.map(only, fn key -> String.downcase(to_string(key)) end)
Enum.filter(variables, fn {key, _} ->
String.downcase(key) in only
end)
end
end