Current section
Files
Jump to
Current section
Files
lib/loaders/file.ex
defmodule Weave.Loaders.File do
@moduledoc """
This loader will attempt to consume files located within a configured directory.
The directory must be cofigured like one of the following:
```elixir
loaders: [
{Weave.Loaders.File, directories: [
"/run/secrets"
]},
]
```
With the above configuration, any files in the mentioned directories will be
sent to the handler.
Please note, the filenames will be "sanitized" before being sent to the handler.
This means "/run/secrets/my_DB_password" will become "my_db_password"
"""
use Weave.Loader
require Logger
@spec load_configuration_from_directory(binary, atom, list | nil) :: list
@spec load_file(binary, binary, atom) :: :ok
@doc """
You shouldn't call this function youroself. Instead, use a Weave module.
"""
def load_configuration(options: [directories: directories], only: only, handler: handler) do
Logger.debug(fn ->
"Weave - Environment Loader: directories: #{inspect(directories)}, only: #{inspect(only)}, handler: #{
inspect(handler)
}"
end)
Enum.reduce(directories, [], fn directory, acc ->
acc ++ load_configuration_from_directory(directory, handler, only)
end)
end
@doc """
Safety net to provide debug when people don't configure their loaders correctly
"""
def load_configuration(options: options, only: _, handler: _) do
Logger.warn(fn ->
"Weave File Loader called, but wasn't configured with `directories: [binary]`"
end)
Logger.debug(fn -> "options: #{inspect(options)}" end)
[]
end
defp load_configuration_from_directory(directory, handler, accepted_filenames)
when is_binary(directory) and is_atom(handler) do
Logger.info(fn -> "Loading configuration from directory '#{directory}'" end)
directory
|> String.trim_trailing("/")
|> File.ls!()
|> Enum.filter(fn file ->
!File.dir?("#{directory}/#{file}")
end)
|> filter_filenames(accepted_filenames)
|> Enum.map(fn file ->
Logger.info(fn -> "Found File: #{file}" end)
load_file(directory, file, handler)
sanitize(file)
end)
end
defp load_file(file_directory, file_name, handler) do
configuration =
"#{file_directory}/#{file_name}"
|> File.read!()
|> String.trim()
apply_configuration(file_name, configuration, handler)
end
defp filter_filenames(files, nil), do: files
defp filter_filenames(files, accepted_filenames) when is_list(accepted_filenames) do
# Allow variables names to be passed as string or atoms
# by converting everything to strings here
only = Enum.map(accepted_filenames, &sanitize/1)
Enum.filter(files, fn file ->
Logger.debug(fn -> "Checking if #{file} is within our only filter: #{file in only}" end)
file in only
end)
end
end