Spellbook v2.0.3 Spellbook View Source
Introduction
Spellbook is an Elixir library providing dynamic hierarchical configurations loading for your application. It is based on the ideas implemented in the Javascript node-config module.
It lets you define a set of default parameters, and extend them for different deployment environments (development, staging, production, etc.) or custom needs (client id, hostname, etc.).
Configurations are stored in default or custom folders containing configuration files and can be overridden and extended by environment variables.
Custom configuration static and dynamic filenames and file formats can be added as needed.
Quick Start
Read the configuration files from the standard <CWD>/config
folder
config = Spellbook.load_config_folder()
Using Spellbook.load_config_folder/0
by default will use the following filename
templates (in the listed order and if they exist) with the {SOMETHING}
template
variables substituted:
<CWD>/config/default.{EXT}
<CWD>/config/default-{INSTANCE}.{EXT}
<CWD>/config/{ENV}.{EXT}
<CWD>/config/{ENV}-{INSTANCE}.{EXT}
<CWD>/config/{SHORT_HOSTNAME}.{EXT}
<CWD>/config/{SHORT_HOSTNAME}-{INSTANCE}.{EXT}
<CWD>/config/{SHORT_HOSTNAME}-{ENV}.{EXT}
<CWD>/config/{SHORT_HOSTNAME}-{ENV}-{INSTANCE}.{EXT}
<CWD>/config/{FULL_HOSTNAME}.{EXT}
<CWD>/config/{FULL_HOSTNAME}-{INSTANCE}.{EXT}
<CWD>/config/{FULL_HOSTNAME}-{ENV}.{EXT}
<CWD>/config/{FULL_HOSTNAME}-{ENV}-{INSTANCE}.{EXT}
<CWD>/config/local.{EXT}
<CWD>/config/local-{INSTANCE}.{EXT}
<CWD>/config/local-{ENV}.{EXT}
<CWD>/config/local-{ENV}-{INSTANCE}.{EXT}
<CWD>/config/custom-env-variables.{EXT}
Spellbook will use the default environment ({ENV}
= dev
) and the full hostname
of the machine the code gets executed on ({FULL_HOSTNAME}
= my-machine.spellbook.domain
).
As the other template variables are not defined, the filenames using them are ignored.
The resulting filenames searched/merged will be:
<CWD>/config/default.json
<CWD>/config/default.yaml
<CWD>/config/dev.json
<CWD>/config/dev.yaml
<CWD>/config/my-machine.spellbook.domain.json
<CWD>/config/my-machine.spellbook.domain.yaml
<CWD>/config/my-machine.spellbook.domain-dev.json
<CWD>/config/my-machine.spellbook.domain-dev.yaml
<CWD>/config/local.json
<CWD>/config/local.yaml
<CWD>/config/local-dev.json
<CWD>/config/local-dev.yaml
<CWD>/config/custom-env-variables.json
<CWD>/config/custom-env-variables.yaml
By default Spellbook supports JSON and YAML file formats.
Read brand's configuration from a specific folder with custom settings for a specific client
config = Spellbook.default_config()
|> Spellbook.add_filename_format("clients/%{brand}.%{ext}")
|> Spellbook.load_config(
folder: "./test/support/brand",
config_filename: "brand-conf",
vars: [instance: "job-processor", brand: "elixir", env: "prod", short_hostname: "worker"]
)
Here we specify a specific folder were to look for the configuration files
(with the folder
option), a custom configuration file name (with the config_filename
option).
The vars
configuration field is used to define the variable values used in
the filename templates.
The Spellbook.default_config/0
function (and the Spellbook.load_config/0
one as well)
configures the Spellbook to search for the following file templates:
./test/support/brand/{CONFIG_FILENAME}.{EXT}
./test/support/brand/{CONFIG_FILENAME}-{INSTANCE}.{EXT}
./test/support/brand/{CONFIG_FILENAME}-{ENV}.{EXT}
./test/support/brand/{CONFIG_FILENAME}-{SHORT_HOSTNAME}-{ENV}-{INSTANCE}.{EXT}
./test/support/brand/{CONFIG_FILENAME}-{FULL_HOSTNAME}-{ENV}-{INSTANCE}.{EXT}
./test/support/brand/clients/{BRAND}.{EXT}
./test/support/brand/custom-env-variables.{EXT}
In this case the searched/merged files will be:
./test/support/brand/brand-conf.json
./test/support/brand/brand-conf.yaml
./test/support/brand/brand-conf-job-processor.json
./test/support/brand/brand-conf-job-processor.yaml
./test/support/brand/brand-conf-prod.json
./test/support/brand/brand-conf-prod.yaml
./test/support/brand/brand-conf-worker-prod-job-processor.json
./test/support/brand/brand-conf-worker-prod-job-processor.yaml
./test/support/brand/brand-conf-worker1.spellbook.domain-prod-job-processor.json
./test/support/brand/brand-conf-worker1.spellbook.domain-prod-job-processor.yaml
./test/support/brand/clients/elixir.json
./test/support/brand/clients/elixir.yaml
./test/support/brand/custom-env-variables.json
./test/support/brand/custom-env-variables.yaml
Get a value out of a Spellbook configuration
A configuration is just a Map.
iex> config = Spellbook.load_config_folder()
%{ "some" => %{ "value" => %{ "from" => %{ "config" => "a value" }}}}
iex> is_map(config) == true
true
You can access the configuration values using the standard language features
iex> value = config["some"]["value"]["from"]["config"]
"a value"
or using the Spellbook.get
method that supports dot notation to access elements
deep down the configuration structure:
iex> value = Spellbook.get(config, "some.value.from.config")
"a value"
Use environment variables in configuration files
Some situations rely heavily on environment variables to configure secrets and
settings best left out of a codebase. Spellbook lets you use map the environment
variable names into your configuration structure using a custom-env-variables.{EXT}
file:
{
"database": {
"username": "DB_USERNAME",
"password": "DB_PASSWORD"
}
}
If the DB_USERNAME
and DB_PASSWORD
environment variable exist, they would
override the values for database.username
and database.password
in the configuration.
Custom environment variables have precedence and override all configuration
files, including local.json
.
Link to this section Summary
Functions
Adds a filename format to the list of templates to be used to generate the list of files to be searched when the configuration is loaded.
Performs a deep merge of a configuration into an application environment.
Performs a deep merge of two maps.
Sets up the default configuration for reading a generic configuration set of files.
Sets up the default configuration for reading a generic configuration set of files.
Sets up the default configuration for reading application configuration from a folder.
Sets up the default configuration for reading application configuration from a folder.
Retrieves a configuration value.
Loads the configuration files from the provided Spellbook.
Creates a Spellbook with the default config folder filenames list and loads them into a configuration map
Creates a Spellbook with the default config folder filenames list and loads them into a configuration map
Creates a Spellbook with the default config filenames list and loads them into a configuration map.
Registers an config file format extension and its parser.
Sets Spellbook options. Option names are atoms.
Sets a variable to be used during filenames list generation using a 2 elements tuple.
Sets a variable to be used during filenames list generation.
Sets some variable to be used during filenames list generation.
Performs a deep substitution of variables used as map values.
Link to this section Functions
Adds a filename format to the list of templates to be used to generate the list of files to be searched when the configuration is loaded.
Filename formats can contain template variables specified using the following interpolation format (%{VARIABLE}
):
"special-%{env}.%{ext}"
"config-%{username}-%{role}.json"
Files are loaded in the order you specify the filename formats.
config = Spellbook.default_config()
|> Spellbook.add_filename_format("clients/%{brand}.%{ext}")
|> Spellbook.add_filename_format(["clients/special/%{brand}-%{version}.%{ext}", "clients/external-%{brand}.%{ext}"])
apply_config_to_application_env(config, config_key, app_name \\ nil, env_key \\ nil)
View SourcePerforms a deep merge of a configuration into an application environment.
Performs a deep merge of two maps.
Examples
iex> Spellbook.deep_merge(%{"a" => %{"b" => "1", "c" => [1,2,3]}}, %{"a" => %{"b" => "X"}})
%{"a" => %{"b" => "X", "c" => [1, 2, 3]}}
Sets up the default configuration for reading a generic configuration set of files.
Accepts a list
Sets up the default configuration for reading a generic configuration set of files.
The valid params
are:
vars
: Keyword or Keyword list of variables to be used in the filenames list generation.options
: map with Spellbook options
The default filename formats are:
<FOLDER>/{CONFIG_FILENAME}.{EXT}
<FOLDER>/{CONFIG_FILENAME}-{INSTANCE}.{EXT}
<FOLDER>/{CONFIG_FILENAME}-{ENV}.{EXT}
<FOLDER>/{CONFIG_FILENAME}-{SHORT_HOSTNAME}-{ENV}-{INSTANCE}.{EXT}
<FOLDER>/{CONFIG_FILENAME}-{FULL_HOSTNAME}-{ENV}-{INSTANCE}.{EXT}
<FOLDER>/custom-env-variables.{EXT}
Sets up the default configuration for reading application configuration from a folder.
Sets up the default configuration for reading application configuration from a folder.
The valid params
are:
vars
: Keyword or Keyword list of variables to be used in the filenames list generation.options
: map with Spellbook options
The default filename formats are:
<CWD>/config/default.{EXT}
<CWD>/config/default-{INSTANCE}.{EXT}
<CWD>/config/{ENV}.{EXT}
<CWD>/config/{ENV}-{INSTANCE}.{EXT}
<CWD>/config/{SHORT_HOSTNAME}.{EXT}
<CWD>/config/{SHORT_HOSTNAME}-{INSTANCE}.{EXT}
<CWD>/config/{SHORT_HOSTNAME}-{ENV}.{EXT}
<CWD>/config/{SHORT_HOSTNAME}-{ENV}-{INSTANCE}.{EXT}
<CWD>/config/{FULL_HOSTNAME}.{EXT}
<CWD>/config/{FULL_HOSTNAME}-{INSTANCE}.{EXT}
<CWD>/config/{FULL_HOSTNAME}-{ENV}.{EXT}
<CWD>/config/{FULL_HOSTNAME}-{ENV}-{INSTANCE}.{EXT}
<CWD>/config/local.{EXT}
<CWD>/config/local-{INSTANCE}.{EXT}
<CWD>/config/local-{ENV}.{EXT}
<CWD>/config/local-{ENV}-{INSTANCE}.{EXT}
<CWD>/config/custom-env-variables.{EXT}
Retrieves a configuration value.
This function supports dot notation, so you can retrieve values from deeply nested keys, like "database.config.password".
Examples
iex> Spellbook.get(%{"a" => %{"b" => "1", "c" => [1,2,3]}}, "a.b")
"1"
load_config(spellbook, params)
View Sourceload_config( spellbook :: %Spellbook{ extensions: term(), filename_formats: term(), options: term(), vars: term() }, params :: maybe_improper_list() ) :: Map.t()
load_config( spellbook :: %Spellbook{ extensions: term(), filename_formats: term(), options: term(), vars: term() }, params :: Map.t() ) :: Map.t()
Loads the configuration files from the provided Spellbook.
Creates a Spellbook with the default config folder filenames list and loads them into a configuration map
Creates a Spellbook with the default config folder filenames list and loads them into a configuration map
Creates a Spellbook with the default config filenames list and loads them into a configuration map.
Registers an config file format extension and its parser.
extensions = %{
"csv" => Crazy.Parser.CSV
}
Spellbook.register_extensions(spellbook, extensions)
Sets Spellbook options. Option names are atoms.
Valid options are:
:folder
: folder where to find the configuration. Defaults to#{Path.join(File.cwd!(), "config")}
.:config_filename
: name of the configuration file, default to"config"
.:ignore_invalid_filename_formats
: defauts totrue
. Set it tofalse
if you want to raise an exception if a file in the generated filenames list is not found.:config
: optional configuration Map or Keyword list to be merged into the final configuration. Takes precedence on everything except the environment variables.
Sets a variable to be used during filenames list generation using a 2 elements tuple.
Sets a variable to be used during filenames list generation.
Sets some variable to be used during filenames list generation.
Performs a deep substitution of variables used as map values.
Examples
iex> Spellbook.substitute_vars(%{"a" => %{"b" => "VAR", "c" => "NOT_A_VAR"}}, %{"VAR" => "spellbook"})
%{"a" => %{"b" => "spellbook", "c" => "NOT_A_VAR"}}