Byebye
This commit is contained in:
parent
094c4d2274
commit
f63cb92b35
18 changed files with 593 additions and 886 deletions
178
README.md
178
README.md
|
|
@ -1,5 +1,11 @@
|
|||
# JinjaTurtle
|
||||
|
||||
## ABANDONED
|
||||
|
||||
Project is abandoned. To many potential security issues. Please uninstall it. Sorry for wasting your time.
|
||||
|
||||
____
|
||||
|
||||
<div align="center">
|
||||
<img src="https://git.mig5.net/mig5/jinjaturtle/raw/branch/main/jinjaturtle.svg" alt="JinjaTurtle logo" width="240" />
|
||||
</div>
|
||||
|
|
@ -7,15 +13,12 @@
|
|||
JinjaTurtle is a command-line tool that helps turn existing native
|
||||
configuration files into reusable configuration-management templates.
|
||||
|
||||
By default it generates:
|
||||
It generates:
|
||||
|
||||
- a **Jinja2** template; and
|
||||
- an **Ansible defaults YAML** file containing the variables used by that
|
||||
template.
|
||||
|
||||
It can also generate **ERB** templates and **Puppet Hiera-style YAML** data for
|
||||
Puppet workflows.
|
||||
|
||||
JinjaTurtle does not try to replace configuration-management tools. Its job is
|
||||
to speed up the boring first pass: take a real config file, discover the values
|
||||
inside it, replace those values with variables, and write the corresponding
|
||||
|
|
@ -26,8 +29,6 @@ variable data beside the template.
|
|||
JinjaTurtle examines a source config file and keeps the original structure as
|
||||
much as possible.
|
||||
|
||||
For the default Jinja2/Ansible mode:
|
||||
|
||||
1. The config file is parsed.
|
||||
2. Variable names are generated from the config keys and paths.
|
||||
3. Those variable names are prefixed with `--role-name`, which should usually
|
||||
|
|
@ -37,16 +38,6 @@ For the default Jinja2/Ansible mode:
|
|||
5. An Ansible defaults YAML file is generated with those variables and the
|
||||
original values.
|
||||
|
||||
For ERB/Puppet mode:
|
||||
|
||||
1. The same parse/flatten/loop analysis is used.
|
||||
2. An ERB template is generated with Puppet-style instance variables such as
|
||||
`<%= @memory_limit %>`.
|
||||
3. The variables file is written as Puppet Hiera-style data, such as
|
||||
`php::memory_limit: 256M`.
|
||||
4. If `--puppet-class` is supplied, that class name is used as the Hiera
|
||||
namespace while `--role-name` remains the local variable prefix.
|
||||
|
||||
By default, the generated variable data and template are printed to stdout. Use
|
||||
`--defaults-output` and `--template-output` to write them to files.
|
||||
|
||||
|
|
@ -80,78 +71,6 @@ and defaults data like:
|
|||
php_memory_limit: 256M
|
||||
```
|
||||
|
||||
## ERB / Puppet example
|
||||
|
||||
Use `--template-engine erb` when you want Puppet ERB output:
|
||||
|
||||
```shell
|
||||
jinjaturtle php.ini \
|
||||
--role-name php \
|
||||
--template-engine erb \
|
||||
--defaults-output data/common.yaml \
|
||||
--template-output templates/php.ini.erb
|
||||
```
|
||||
|
||||
Given the same source value:
|
||||
|
||||
```ini
|
||||
memory_limit = 256M
|
||||
```
|
||||
|
||||
JinjaTurtle will produce an ERB template value like:
|
||||
|
||||
```erb
|
||||
memory_limit = <%= @memory_limit %>
|
||||
```
|
||||
|
||||
and Hiera-style data like:
|
||||
|
||||
```yaml
|
||||
php::memory_limit: 256M
|
||||
```
|
||||
|
||||
The `--defaults-output` option name is retained for CLI compatibility, but in
|
||||
ERB mode the file is intended to be Puppet Hiera data rather than Ansible role
|
||||
defaults.
|
||||
|
||||
JinjaTurtle does **not** generate Puppet classes or `file` resources. A Puppet
|
||||
module, should still declare the class parameters and call the template, for
|
||||
example with Puppet's `template()` function.
|
||||
|
||||
## Using `--puppet-class`
|
||||
|
||||
Most direct usage can simply use the same value for the role name and Puppet
|
||||
class name:
|
||||
|
||||
```shell
|
||||
jinjaturtle php.ini --role-name php --template-engine erb
|
||||
```
|
||||
|
||||
This creates Hiera keys such as:
|
||||
|
||||
```yaml
|
||||
php::memory_limit: 256M
|
||||
```
|
||||
|
||||
and local ERB variables such as:
|
||||
|
||||
```erb
|
||||
<%= @memory_limit %>
|
||||
```
|
||||
|
||||
For generated systems, it can be useful to make `--role-name` more specific
|
||||
while keeping the Hiera keys under the real Puppet class. For example:
|
||||
|
||||
```shell
|
||||
jinjaturtle php.ini \
|
||||
--role-name php_etc_php_ini \
|
||||
--puppet-class php \
|
||||
--template-engine erb
|
||||
```
|
||||
|
||||
In that case the variable prefix can stay file-specific, while the Hiera data
|
||||
is still written under `php::...`.
|
||||
|
||||
## What sort of config files can it handle?
|
||||
|
||||
JinjaTurtle supports common structured and semi-structured config formats:
|
||||
|
|
@ -176,15 +95,15 @@ homogeneous enough. If it is not confident, it falls back to flattened scalar
|
|||
variables.
|
||||
|
||||
Some very complex files will still need manual cleanup. The goal is to speed up
|
||||
conversion into Jinja2 or ERB templates, not to guarantee a perfect final module
|
||||
without review.
|
||||
conversion into Jinja2 templates, not to guarantee a perfect final role without
|
||||
review.
|
||||
|
||||
## JSON, quoting, and type preservation
|
||||
|
||||
JinjaTurtle tries to preserve rendered config types.
|
||||
|
||||
For JSON, it uses JSON-aware expressions rather than plain string substitution.
|
||||
This avoids generating invalid JSON such as:
|
||||
For JSON, it uses JSON-aware Jinja2 expressions rather than plain string
|
||||
substitution. This avoids generating invalid JSON such as:
|
||||
|
||||
```json
|
||||
{"enabled": True}
|
||||
|
|
@ -196,18 +115,6 @@ when the correct rendered JSON should be:
|
|||
{"enabled": true}
|
||||
```
|
||||
|
||||
In Jinja2 mode this uses Ansible-style JSON filters. In ERB mode it emits Ruby
|
||||
JSON generation where required, for example:
|
||||
|
||||
```erb
|
||||
<% require 'json' -%>
|
||||
{
|
||||
"enabled": <%= JSON.generate(@enabled) %>
|
||||
}
|
||||
```
|
||||
|
||||
That is expected for JSON ERB templates.
|
||||
|
||||
## Can I convert multiple files at once?
|
||||
|
||||
Yes. Pass a directory instead of a single file and JinjaTurtle will convert the
|
||||
|
|
@ -287,8 +194,6 @@ poetry install
|
|||
usage: jinjaturtle [-h] [-r ROLE_NAME] [--recursive]
|
||||
[-f {ini,json,toml,yaml,xml,postfix,systemd,ssh}]
|
||||
[-d DEFAULTS_OUTPUT] [-t TEMPLATE_OUTPUT]
|
||||
[--template-engine {jinja2,erb}]
|
||||
[--puppet-class PUPPET_CLASS]
|
||||
config
|
||||
|
||||
Convert a config file into an Ansible defaults file and Jinja2 template.
|
||||
|
|
@ -301,25 +206,18 @@ positional arguments:
|
|||
options:
|
||||
-h, --help show this help message and exit
|
||||
-r, --role-name ROLE_NAME
|
||||
Role name / variable prefix. In Jinja2 mode this is
|
||||
usually the Ansible role name. In ERB mode it is used
|
||||
as the local variable prefix. Defaults to jinjaturtle.
|
||||
Ansible role name, used as variable prefix. Defaults
|
||||
to jinjaturtle.
|
||||
--recursive When CONFIG is a folder, recurse into subfolders.
|
||||
-f, --format {ini,json,toml,yaml,xml,postfix,systemd,ssh}
|
||||
Force config format instead of auto-detecting from
|
||||
filename.
|
||||
-d, --defaults-output DEFAULTS_OUTPUT
|
||||
Path to write the generated variable YAML. If omitted,
|
||||
it is printed to stdout.
|
||||
Path to write defaults/main.yml. If omitted, defaults
|
||||
YAML is printed to stdout.
|
||||
-t, --template-output TEMPLATE_OUTPUT
|
||||
Path to write the generated config template. If omitted,
|
||||
it is printed to stdout.
|
||||
--template-engine {jinja2,erb}
|
||||
Template syntax to generate. Defaults to jinja2. Use
|
||||
erb for Puppet templates.
|
||||
--puppet-class PUPPET_CLASS
|
||||
Puppet class / Hiera namespace to use with
|
||||
--template-engine erb. Defaults to --role-name.
|
||||
Path to write the generated config template. If
|
||||
omitted, template is printed to stdout.
|
||||
```
|
||||
|
||||
## Additional supported formats
|
||||
|
|
@ -345,43 +243,37 @@ code.
|
|||
Two guarantees matter:
|
||||
|
||||
1. **Values are data, never code.** Every config *value* is replaced with a
|
||||
`{{ variable }}` placeholder in the template, and the original value is stored
|
||||
separately in the defaults/Hiera data. When the template is later rendered,
|
||||
the placeholder prints the value as a literal string; Jinja2 does not
|
||||
recursively render the *contents* of a variable, so a payload sitting inside
|
||||
a value (for example `motd = {{ salt['cmd.run']('id') }}`) is inert.
|
||||
`{{ variable }}` placeholder in the template, and the original value is
|
||||
stored separately in the defaults data. String values in generated defaults
|
||||
are tagged with Ansible's `!unsafe` tag by default, so a payload sitting
|
||||
inside a value (for example `motd = {{ lookup('pipe', 'id') }}`) remains
|
||||
inert even if downstream playbooks accidentally place that value in another
|
||||
templating context.
|
||||
|
||||
2. **Verbatim text is neutralised.** To preserve formatting, JinjaTurtle copies
|
||||
comments, blank lines, headers and any unrecognised lines from the source
|
||||
into the template. Any template metacharacters in that copied text
|
||||
(`{{ }}`, `{% %}`, `{# #}` for Jinja2; `<% %>` for ERB) are escaped so they
|
||||
render as the literal characters the author wrote, rather than executing.
|
||||
into the template. Any Jinja2 metacharacters in that copied text (`{{ }}`,
|
||||
`{% %}`, `{# #}`) are escaped so they render as the literal characters the
|
||||
author wrote, rather than executing.
|
||||
|
||||
### Consumer responsibilities
|
||||
|
||||
The value guarantee above relies on the downstream renderer being single-pass,
|
||||
which is the normal case:
|
||||
Treat generated defaults as untrusted input. JinjaTurtle emits extracted
|
||||
string values with Ansible's `!unsafe` tag, but you should preserve that tag if
|
||||
you merge the generated data into larger defaults files or transform it with
|
||||
other tooling.
|
||||
|
||||
- **Ansible**: rendering a template with `template:`/`ansible.builtin.template`
|
||||
is single-pass. For defence in depth, treat the generated defaults as
|
||||
untrusted input — Ansible already does not re-template variable *contents* by
|
||||
default. If you build your own var structures from this data and pass them
|
||||
through additional templating, mark untrusted values with the `!unsafe` tag so
|
||||
they are never re-evaluated.
|
||||
- **Salt**: use the generated file as a `file.managed` template
|
||||
(`template: jinja`). Do **not** place JinjaTurtle output where Salt would
|
||||
render it a second time as part of SLS/pillar rendering, which is a separate
|
||||
Jinja pass and would re-evaluate any embedded expressions.
|
||||
- **Puppet/ERB**: render with the standard `template()`/`epp()` flow.
|
||||
In short: render JinjaTurtle output exactly once. Do not strip `!unsafe` tags or
|
||||
feed the data back through another templating pass.
|
||||
|
||||
In short: render JinjaTurtle output exactly once. Do not feed it back through
|
||||
another templating pass.
|
||||
Directory mode deliberately ignores symlinks and will not traverse outside the
|
||||
input directory. This prevents a malicious folder tree from smuggling in
|
||||
configuration files through links to unrelated filesystem locations.
|
||||
|
||||
**IMPORTANT**: Always review both the original config files, then the resulting
|
||||
templates generated by JinjaTurtle, before integrating them into your config
|
||||
management system!
|
||||
|
||||
|
||||
## Found a bug, have a suggestion?
|
||||
|
||||
You can e-mail me; see `pyproject.toml` for details. You can also contact me on
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue