config_ninja
Config Ninja 🥷
Similar to confd
, manage your system configuration files by populating Jinja2 templates with data from a remote provider.
Installation
config-ninja
is installed using the official installer or with pip
/ pipx
. If your system supports systemd
, you can then enable config-ninja
as a systemd
service.
Official Installer
The recommended way to install config-ninja
is with the official installer:
curl -sSL https://config-ninja.github.io/config-ninja/install.py | python3 -
To view available installation options, run the installer with the --help
flag:
curl -sSL https://config-ninja.github.io/config-ninja/install.py | python3 - --help
usage: install [-h] [--version VERSION] [--pre] [--uninstall] [--force] [--path PATH] [--backends BACKENDS]
Installs the latest (or given) version of config-ninja
options:
-h, --help show this help message and exit
--version VERSION install named version
--pre allow pre-release versions to be installed
--uninstall uninstall config-ninja
--force respond 'yes' to confirmation prompts; overwrite existing installations
--path PATH install config-ninja to this directory
--backends BACKENDS comma-separated list of package extras to install, or 'none' to install no backends
With pip
/ pipx
Alternatively, use pip
/ pipx
to install [all available backends] (or choose a specific one):
pip install 'config-ninja[all]'
Enable the systemd
Service
After installing config-ninja
, enable it as a systemd
service for the current user:
# omit '--user' to install the agent at the system level
config-ninja self install --user
How It Works
To demonstrate how the mechanics work locally:
create a settings file for
config-ninja
:cat <<EOF >config-ninja-settings.yaml CONFIG_NINJA_OBJECTS: example-0: dest: format: json path: ./.local/settings.json source: backend: local format: toml init: kwargs: path: ./.local/config.toml EOF
start
config-ninja
inmonitor
mode:config-ninja monitor
in a separate shell, create the
config.toml
:cat <<EOF >./.local/config.toml [example-0] a = "first value" b = "second value EOF
Inspect the
settings.json
file created byconfig-ninja
:cat ./.local/settings.json
{ "example-0": { "a": "first value", "b": "second value" } }
Make changes to the data in
config.toml
, andconfig-ninja
will updatesettings.json
accordingly:cat <<EOF >>./.local/config.toml [example-1] c = "third value" d = "fourth value EOF cat ./.local/settings.json
{ "example-0": { "a": "first value", "b": "second value" }, "example-1": { "c": "third value", "d": "fourth value" } }
Chances are, you'll want to update the
config-ninja-settings.yaml
file to use a remote backend (instead oflocal
). See config_ninja.contrib for a list of supported config providers.
Configuration Architecture
The config-ninja
agent monitors the backend source for changes. When the source data is changed, the agent updates the local configuration file with the new data:
sequenceDiagram loop polling config-ninja->>backend: query for changes end backend->>+config-ninja: [backend changed] fetch config config-ninja->>-filesystem: write updated configuration file
Navigation
config_ninja.contrib
for supported backends:config_ninja.cli
for commands and CLI documentationconfig_ninja.systemd
forsystemd
integration
1""".. include:: ../../README.md 2 3# Navigation 4- `config_ninja.contrib` for supported backends: 5 - `config_ninja.contrib.appconfig` 6 - `config_ninja.contrib.local` 7- `config_ninja.cli` for commands and CLI documentation 8- `config_ninja.systemd` for `systemd` integration 9""" # noqa: D415 10 11from __future__ import annotations 12 13__version__ = '1.3.0.post50+cc272a7' 14 15from pathlib import Path 16 17from pyspry import Settings 18 19__all__ = ['DEFAULT_SETTINGS_PATHS', 'load_settings', 'resolve_settings_path'] 20 21DEFAULT_SETTINGS_PATHS = [ 22 Path.cwd() / 'config-ninja-settings.yaml', 23 Path.home() / 'config-ninja-settings.yaml', 24 Path('/etc/config-ninja/settings.yaml'), 25] 26"""Check each of these locations for `config-ninja`_'s settings file. 27 28The following locations are checked (ordered by priority): 29 301. `./config-ninja-settings.yaml` 312. `~/config-ninja-settings.yaml` 323. `/etc/config-ninja/settings.yaml` 33 34.. _config-ninja: https://bryant-finney.github.io/config-ninja/config_ninja.html 35""" 36 37SETTINGS_PREFIX = 'CONFIG_NINJA' 38 39 40def load_settings(path: Path) -> Settings: 41 """Load the settings from the given path.""" 42 return Settings.load(path, SETTINGS_PREFIX) 43 44 45def resolve_settings_path() -> Path: 46 """Return the first path in `DEFAULT_SETTINGS_PATHS` that exists.""" 47 for path in DEFAULT_SETTINGS_PATHS: 48 if path.is_file(): 49 return path 50 51 raise FileNotFoundError('Could not find config-ninja settings', DEFAULT_SETTINGS_PATHS)
Check each of these locations for config-ninja's settings file.
The following locations are checked (ordered by priority):
./config-ninja-settings.yaml
~/config-ninja-settings.yaml
/etc/config-ninja/settings.yaml
41def load_settings(path: Path) -> Settings: 42 """Load the settings from the given path.""" 43 return Settings.load(path, SETTINGS_PREFIX)
Load the settings from the given path.
46def resolve_settings_path() -> Path: 47 """Return the first path in `DEFAULT_SETTINGS_PATHS` that exists.""" 48 for path in DEFAULT_SETTINGS_PATHS: 49 if path.is_file(): 50 return path 51 52 raise FileNotFoundError('Could not find config-ninja settings', DEFAULT_SETTINGS_PATHS)
Return the first path in DEFAULT_SETTINGS_PATHS
that exists.