mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Merge pull request #33995 from jacobhammons/doc-fixes
Understanding Jinja topic, Jinja doc issues.
This commit is contained in:
commit
1132bc5d0b
29 changed files with 465 additions and 382 deletions
|
@ -1,8 +1,8 @@
|
|||
.. _all-salt.auth:
|
||||
|
||||
=================================
|
||||
Full list of builtin auth modules
|
||||
=================================
|
||||
============
|
||||
auth modules
|
||||
============
|
||||
|
||||
.. currentmodule:: salt.auth
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
.. _all-salt.beacons:
|
||||
|
||||
===================================
|
||||
Full list of builtin beacon modules
|
||||
===================================
|
||||
==============
|
||||
beacon modules
|
||||
==============
|
||||
|
||||
.. currentmodule:: salt.beacons
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
.. _all-salt.engines:
|
||||
|
||||
===================================
|
||||
Full list of builtin engine modules
|
||||
===================================
|
||||
==============
|
||||
engine modules
|
||||
==============
|
||||
|
||||
.. currentmodule:: salt.engines
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
.. _all-salt.fileserver:
|
||||
|
||||
=======================================
|
||||
Full list of builtin fileserver modules
|
||||
=======================================
|
||||
==================
|
||||
fileserver modules
|
||||
==================
|
||||
|
||||
.. currentmodule:: salt.fileserver
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
.. _all-salt.grains:
|
||||
|
||||
===================================
|
||||
Full list of builtin grains modules
|
||||
===================================
|
||||
==============
|
||||
grains modules
|
||||
==============
|
||||
|
||||
.. currentmodule:: salt.grains
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
.. _all-salt_modules:
|
||||
|
||||
======================================
|
||||
Full list of builtin execution modules
|
||||
======================================
|
||||
=================
|
||||
execution modules
|
||||
=================
|
||||
|
||||
.. admonition:: Virtual modules
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
.. _all-netapi-modules:
|
||||
|
||||
===========================
|
||||
Full list of netapi modules
|
||||
===========================
|
||||
==============
|
||||
netapi modules
|
||||
==============
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
.. _all-salt.output:
|
||||
|
||||
===================================
|
||||
Full list of builtin output modules
|
||||
===================================
|
||||
==============
|
||||
output modules
|
||||
==============
|
||||
|
||||
Follow one of the below links for further information and examples
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
.. _all-salt.pillars:
|
||||
|
||||
===================================
|
||||
Full list of builtin pillar modules
|
||||
===================================
|
||||
==============
|
||||
pillar modules
|
||||
==============
|
||||
|
||||
.. currentmodule:: salt.pillar
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
.. _all-salt.proxy:
|
||||
|
||||
==================================
|
||||
Full list of builtin proxy modules
|
||||
==================================
|
||||
=============
|
||||
proxy modules
|
||||
=============
|
||||
|
||||
.. currentmodule:: salt.proxy
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
.. _all-salt.queues:
|
||||
|
||||
===========================
|
||||
Full list of builtin queues
|
||||
===========================
|
||||
=============
|
||||
queue modules
|
||||
=============
|
||||
|
||||
.. currentmodule:: salt.queues
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
.. _all-salt.renderers:
|
||||
|
||||
=====================================
|
||||
Full list of builtin renderer modules
|
||||
=====================================
|
||||
================
|
||||
renderer modules
|
||||
================
|
||||
|
||||
.. currentmodule:: salt.renderers
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
.. _all-salt.returners:
|
||||
|
||||
=====================================
|
||||
Full list of builtin returner modules
|
||||
=====================================
|
||||
================
|
||||
returner modules
|
||||
================
|
||||
|
||||
.. currentmodule:: salt.returners
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
.. _all-salt.roster:
|
||||
|
||||
===================================
|
||||
Full list of builtin roster modules
|
||||
===================================
|
||||
==============
|
||||
roster modules
|
||||
==============
|
||||
|
||||
.. currentmodule:: salt.roster
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
.. _all-salt.runners:
|
||||
|
||||
===========================
|
||||
Full list of runner modules
|
||||
===========================
|
||||
==============
|
||||
runner modules
|
||||
==============
|
||||
|
||||
.. currentmodule:: salt.runners
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
.. _all-salt.sdb:
|
||||
|
||||
================================
|
||||
Full list of builtin sdb modules
|
||||
================================
|
||||
===========
|
||||
sdb modules
|
||||
===========
|
||||
|
||||
.. currentmodule:: salt.sdb
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
.. _all-salt.serializers:
|
||||
|
||||
================================
|
||||
Full list of builtin serializers
|
||||
================================
|
||||
==================
|
||||
serializer modules
|
||||
==================
|
||||
|
||||
.. currentmodule:: salt.serializers
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
.. _all-salt.states:
|
||||
|
||||
==================================
|
||||
Full list of builtin state modules
|
||||
==================================
|
||||
=============
|
||||
state modules
|
||||
=============
|
||||
|
||||
.. currentmodule:: salt.states
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
.. _all-salt.thorium:
|
||||
|
||||
====================================
|
||||
Full list of builtin thorium modules
|
||||
====================================
|
||||
===============
|
||||
thorium modules
|
||||
===============
|
||||
|
||||
.. currentmodule:: salt.thorium
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
.. _all-salt.tops:
|
||||
|
||||
========================================
|
||||
Full list of builtin master tops modules
|
||||
========================================
|
||||
===================
|
||||
master tops modules
|
||||
===================
|
||||
|
||||
.. currentmodule:: salt.tops
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
.. _all-salt.wheel:
|
||||
|
||||
==================================
|
||||
Full list of builtin wheel modules
|
||||
==================================
|
||||
=============
|
||||
wheel modules
|
||||
=============
|
||||
|
||||
.. currentmodule:: salt.wheel
|
||||
|
||||
|
|
364
doc/topics/jinja/index.rst
Normal file
364
doc/topics/jinja/index.rst
Normal file
|
@ -0,0 +1,364 @@
|
|||
.. _jinja:
|
||||
|
||||
===================
|
||||
Understanding Jinja
|
||||
===================
|
||||
|
||||
`Jinja <http://jinja.pocoo.org/docs/>`_ is the default templating language
|
||||
in SLS files.
|
||||
|
||||
Jinja in States
|
||||
===============
|
||||
|
||||
.. _Jinja: http://jinja.pocoo.org/docs/templates/
|
||||
|
||||
Jinja is evaluated before YAML, which means it is evaluated before the States
|
||||
are run.
|
||||
|
||||
The most basic usage of Jinja in state files is using control structures to
|
||||
wrap conditional or redundant state elements:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
{% if grains['os'] != 'FreeBSD' %}
|
||||
tcsh:
|
||||
pkg:
|
||||
- installed
|
||||
{% endif %}
|
||||
|
||||
motd:
|
||||
file.managed:
|
||||
{% if grains['os'] == 'FreeBSD' %}
|
||||
- name: /etc/motd
|
||||
{% elif grains['os'] == 'Debian' %}
|
||||
- name: /etc/motd.tail
|
||||
{% endif %}
|
||||
- source: salt://motd
|
||||
|
||||
In this example, the first if block will only be evaluated on minions that
|
||||
aren't running FreeBSD, and the second block changes the file name based on the
|
||||
*os* grain.
|
||||
|
||||
Writing **if-else** blocks can lead to very redundant state files however. In
|
||||
this case, using :doc:`pillars</topics/pillar/index>`, or using a previously
|
||||
defined variable might be easier:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
{% set motd = ['/etc/motd'] %}
|
||||
{% if grains['os'] == 'Debian' %}
|
||||
{% set motd = ['/etc/motd.tail', '/var/run/motd'] %}
|
||||
{% endif %}
|
||||
|
||||
{% for motdfile in motd %}
|
||||
{{ motdfile }}:
|
||||
file.managed:
|
||||
- source: salt://motd
|
||||
{% endfor %}
|
||||
|
||||
Using a variable set by the template, the `for loop`_ will iterate over the
|
||||
list of MOTD files to update, adding a state block for each file.
|
||||
|
||||
The filter_by function can also be used to set variables based on grains:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
{% set auditd = salt['grains.filter_by']({
|
||||
'RedHat': { 'package': 'audit' },
|
||||
'Debian': { 'package': 'auditd' },
|
||||
}) %}
|
||||
|
||||
.. _`for loop`: http://jinja.pocoo.org/docs/templates/#for
|
||||
|
||||
Include and Import
|
||||
==================
|
||||
|
||||
Includes and imports_ can be used to share common, reusable state configuration
|
||||
between state files and between files.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
{% from 'lib.sls' import test %}
|
||||
|
||||
This would import the ``test`` template variable or macro, not the ``test``
|
||||
state element, from the file ``lib.sls``. In the case that the included file
|
||||
performs checks again grains, or something else that requires context, passing
|
||||
the context into the included file is required:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
{% from 'lib.sls' import test with context %}
|
||||
|
||||
Including Context During Include/Import
|
||||
---------------------------------------
|
||||
|
||||
By adding ``with context`` to the include/import directive, the
|
||||
current context can be passed to an included/imported template.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
{% import 'openssl/vars.sls' as ssl with context %}
|
||||
|
||||
|
||||
.. _imports: http://jinja.pocoo.org/docs/templates/#import
|
||||
|
||||
Macros
|
||||
======
|
||||
|
||||
Macros_ are helpful for eliminating redundant code. Macros are most useful as
|
||||
mini-templates to repeat blocks of strings with a few parameterized variables.
|
||||
Be aware that stripping whitespace from the template block, as well as
|
||||
contained blocks, may be necessary to emulate a variable return from the macro.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
# init.sls
|
||||
{% from 'lib.sls' import pythonpkg with context %}
|
||||
|
||||
python-virtualenv:
|
||||
pkg.installed:
|
||||
- name: {{ pythonpkg('virtualenv') }}
|
||||
|
||||
python-fabric:
|
||||
pkg.installed:
|
||||
- name: {{ pythonpkg('fabric') }}
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
# lib.sls
|
||||
{% macro pythonpkg(pkg) -%}
|
||||
{%- if grains['os'] == 'FreeBSD' -%}
|
||||
py27-{{ pkg }}
|
||||
{%- elif grains['os'] == 'Debian' -%}
|
||||
python-{{ pkg }}
|
||||
{%- endif -%}
|
||||
{%- endmacro %}
|
||||
|
||||
This would define a macro_ that would return a string of the full package name,
|
||||
depending on the packaging system's naming convention. The whitespace of the
|
||||
macro was eliminated, so that the macro would return a string without line
|
||||
breaks, using `whitespace control`_.
|
||||
|
||||
Template Inheritance
|
||||
====================
|
||||
|
||||
`Template inheritance`_ works fine from state files and files. The search path
|
||||
starts at the root of the state tree or pillar.
|
||||
|
||||
.. _`Template inheritance`: http://jinja.pocoo.org/docs/templates/#template-inheritance
|
||||
.. _`Macros`: http://jinja.pocoo.org/docs/templates/#macros
|
||||
.. _`macro`: http://jinja.pocoo.org/docs/templates/#macros
|
||||
.. _`whitespace control`: http://jinja.pocoo.org/docs/templates/#whitespace-control
|
||||
|
||||
Filters
|
||||
=======
|
||||
|
||||
Saltstack extends `builtin filters`_ with these custom filters:
|
||||
|
||||
strftime
|
||||
Converts any time related object into a time based string. It requires a
|
||||
valid :ref:`strftime directives <python2:strftime-strptime-behavior>`. An
|
||||
:ref:`exhaustive list <python2:strftime-strptime-behavior>` can be found in
|
||||
the official Python documentation.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
{% set curtime = None | strftime() %}
|
||||
|
||||
Fuzzy dates require the `timelib`_ Python module is installed.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
{{ "2002/12/25"|strftime("%y") }}
|
||||
{{ "1040814000"|strftime("%Y-%m-%d") }}
|
||||
{{ datetime|strftime("%u") }}
|
||||
{{ "tomorrow"|strftime }}
|
||||
|
||||
sequence
|
||||
Ensure that parsed data is a sequence.
|
||||
|
||||
yaml_encode
|
||||
Serializes a single object into a YAML scalar with any necessary
|
||||
handling for escaping special characters. This will work for any
|
||||
scalar YAML data type: ints, floats, timestamps, booleans, strings,
|
||||
unicode. It will *not* work for multi-objects such as sequences or
|
||||
maps.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
{%- set bar = 7 %}
|
||||
{%- set baz = none %}
|
||||
{%- set zip = true %}
|
||||
{%- set zap = 'The word of the day is "salty"' %}
|
||||
|
||||
{%- load_yaml as foo %}
|
||||
bar: {{ bar|yaml_encode }}
|
||||
baz: {{ baz|yaml_encode }}
|
||||
baz: {{ zip|yaml_encode }}
|
||||
baz: {{ zap|yaml_encode }}
|
||||
{%- endload %}
|
||||
|
||||
In the above case ``{{ bar }}`` and ``{{ foo.bar }}`` should be
|
||||
identical and ``{{ baz }}`` and ``{{ foo.baz }}`` should be
|
||||
identical.
|
||||
|
||||
yaml_dquote
|
||||
Serializes a string into a properly-escaped YAML double-quoted
|
||||
string. This is useful when the contents of a string are unknown
|
||||
and may contain quotes or unicode that needs to be preserved. The
|
||||
resulting string will be emitted with opening and closing double
|
||||
quotes.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
{%- set bar = '"The quick brown fox . . ."' %}
|
||||
{%- set baz = 'The word of the day is "salty".' %}
|
||||
|
||||
{%- load_yaml as foo %}
|
||||
bar: {{ bar|yaml_dquote }}
|
||||
baz: {{ baz|yaml_dquote }}
|
||||
{%- endload %}
|
||||
|
||||
In the above case ``{{ bar }}`` and ``{{ foo.bar }}`` should be
|
||||
identical and ``{{ baz }}`` and ``{{ foo.baz }}`` should be
|
||||
identical. If variable contents are not guaranteed to be a string
|
||||
then it is better to use ``yaml_encode`` which handles all YAML
|
||||
scalar types.
|
||||
|
||||
yaml_squote
|
||||
Similar to the ``yaml_dquote`` filter but with single quotes. Note
|
||||
that YAML only allows special escapes inside double quotes so
|
||||
``yaml_squote`` is not nearly as useful (viz. you likely want to
|
||||
use ``yaml_encode`` or ``yaml_dquote``).
|
||||
|
||||
.. _`builtin filters`: http://jinja.pocoo.org/docs/templates/#builtin-filters
|
||||
.. _`timelib`: https://github.com/pediapress/timelib/
|
||||
|
||||
Jinja in Files
|
||||
==============
|
||||
|
||||
Jinja_ can be used in the same way in managed files:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
# redis.sls
|
||||
/etc/redis/redis.conf:
|
||||
file.managed:
|
||||
- source: salt://redis.conf
|
||||
- template: jinja
|
||||
- context:
|
||||
bind: 127.0.0.1
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
# lib.sls
|
||||
{% set port = 6379 %}
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
# redis.conf
|
||||
{% from 'lib.sls' import port with context %}
|
||||
port {{ port }}
|
||||
bind {{ bind }}
|
||||
|
||||
As an example, configuration was pulled from the file context and from an
|
||||
external template file.
|
||||
|
||||
.. note::
|
||||
|
||||
Macros and variables can be shared across templates. They should not be
|
||||
starting with one or more underscores, and should be managed by one of the
|
||||
following tags: `macro`, `set`, `load_yaml`, `load_json`, `import_yaml` and
|
||||
`import_json`.
|
||||
|
||||
Escaping Jinja
|
||||
==============
|
||||
|
||||
Occasionally, it may be necessary to escape Jinja syntax. There are two ways to
|
||||
to do this in Jinja. One is escaping individual variables or strings and the
|
||||
other is to escape entire blocks.
|
||||
|
||||
To escape a string commonly used in Jinja syntax such as ``{{``, you can use the
|
||||
following syntax:
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
{{ '{{' }}
|
||||
|
||||
For larger blocks that contain Jinja syntax that needs to be escaped, you can use
|
||||
raw blocks:
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
{% raw %}
|
||||
some text that contains jinja characters that need to be escaped
|
||||
{% endraw %}
|
||||
|
||||
See the `Escaping`_ section of Jinja's documentation to learn more.
|
||||
|
||||
A real-word example of needing to use raw tags to escape a larger block of code
|
||||
is when using ``file.managed`` with the ``contents_pillar`` option to manage
|
||||
files that contain something like consul-template, which shares a syntax subset
|
||||
with Jinja. Raw blocks are necessary here because the Jinja in the pillar would
|
||||
be rendered before the file.managed is ever called, so the Jinja syntax must be
|
||||
escaped:
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
{% raw %}
|
||||
- contents_pillar: |
|
||||
job "example-job" {
|
||||
<snipped>
|
||||
task "example" {
|
||||
driver = "docker"
|
||||
|
||||
config {
|
||||
image = "docker-registry.service.consul:5000/example-job:{{key "nomad/jobs/example-job/version"}}"
|
||||
<snipped>
|
||||
{% endraw %}
|
||||
|
||||
.. _`Escaping`: http://jinja.pocoo.org/docs/dev/templates/#escaping
|
||||
|
||||
Calling Salt Functions
|
||||
======================
|
||||
|
||||
The Jinja renderer provides a shorthand lookup syntax for the ``salt``
|
||||
dictionary of :term:`execution function <Execution Function>`.
|
||||
|
||||
.. versionadded:: 2014.7.0
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
# The following two function calls are equivalent.
|
||||
{{ salt['cmd.run']('whoami') }}
|
||||
{{ salt.cmd.run('whoami') }}
|
||||
|
||||
Debugging
|
||||
=========
|
||||
|
||||
The ``show_full_context`` function can be used to output all variables present
|
||||
in the current Jinja context.
|
||||
|
||||
.. versionadded:: 2014.7.0
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
Context is: {{ show_full_context() }}
|
||||
|
||||
Custom Execution Modules
|
||||
========================
|
||||
|
||||
Custom execution modules can be used to supplement or replace complex Jinja. Many
|
||||
tasks that require complex looping and logic are trivial when using Python
|
||||
in a Salt execution module. Salt execution modules are easy to write and
|
||||
distribute to Salt minions.
|
||||
|
||||
:ref:`Writing Execution Modules <writing-execution-modules>`
|
||||
|
||||
Functions in custom execution modules are available in the Salt execution
|
||||
module dictionary just like the built-in execution modules:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
{{ salt['my_custom_module.my_custom_function']() }}
|
||||
|
|
@ -52,7 +52,7 @@ To match a nodegroup on the CLI, use the ``-N`` command-line option:
|
|||
|
||||
.. note::
|
||||
|
||||
The ``N@`` classifier cannot be used in compound mathes within the CLI or
|
||||
The ``N@`` classifier cannot be used in compound matches within the CLI or
|
||||
:term:`top file`, it is only recognized in the :conf_master:`nodegroups`
|
||||
master config file parameter.
|
||||
|
||||
|
|
|
@ -324,11 +324,14 @@ specified list, notice the nested pillar dict:
|
|||
|
||||
salt '*' state.apply edit.vim pillar='{"pkgs": {"vim": "telnet"}}'
|
||||
|
||||
This will attempt to install telnet on your minions, feel free to
|
||||
uninstall the package or replace telnet value with anything else.
|
||||
|
||||
.. note::
|
||||
|
||||
This will attempt to install telnet on your minions, feel free to
|
||||
uninstall the package or replace telnet value with anything else.
|
||||
|
||||
Be aware that when sending sensitive data via pillar on the command-line
|
||||
that the publication containing that data will be received by all minions
|
||||
and will not be restricted to the targeted minions. This may represent
|
||||
a security concern in some cases.
|
||||
|
||||
More On Pillar
|
||||
==============
|
||||
|
|
|
@ -14,6 +14,7 @@ This section describes the fundamental components and concepts that you need to
|
|||
../ref/runners/index
|
||||
engines/index
|
||||
yaml/index
|
||||
jinja/index
|
||||
troubleshooting/index
|
||||
../faq
|
||||
best_practices
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
.. _yaml:
|
||||
|
||||
==================
|
||||
Understanding YAML
|
||||
==================
|
||||
|
||||
|
@ -107,4 +110,10 @@ Learning More
|
|||
One easy way to learn more about how YAML gets rendered into Python data structures is
|
||||
to use an online YAML parser to see the Python output.
|
||||
|
||||
One excellent choice for experimenting with YAML parsing is: http://yaml-online-parser.appspot.com/
|
||||
One excellent choice for experimenting with YAML parsing is: http://yaml-online-parser.appspot.com/
|
||||
|
||||
Templating
|
||||
----------
|
||||
Jinja statements and expressions are allowed by default in SLS files. See
|
||||
:ref:`Understanding Jinja <jinja>`.
|
||||
|
||||
|
|
|
@ -247,6 +247,22 @@ command sent to minions as well as a runner function on the master::
|
|||
.. |200| replace:: success
|
||||
.. |401| replace:: authentication required
|
||||
.. |406| replace:: requested Content-Type not available
|
||||
|
||||
A Note About Curl
|
||||
=================
|
||||
|
||||
When sending passwords and data that might need to be urlencoded, you must set
|
||||
the ``-d`` flag to indicate the content type, and the ``--data-urlencode`` flag
|
||||
to urlencode the input.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
curl -ksi http://localhost:8000/login \\
|
||||
-H "Accept: application/json" \\
|
||||
-d username='myapiuser' \\
|
||||
--data-urlencode password='1234+' \\
|
||||
-d eauth='pam'
|
||||
|
||||
'''
|
||||
# We need a custom pylintrc here...
|
||||
# pylint: disable=W0212,E1101,C0103,R0201,W0221,W0613
|
||||
|
|
|
@ -2,319 +2,7 @@
|
|||
'''
|
||||
Jinja loading utils to enable a more powerful backend for jinja templates
|
||||
|
||||
Jinja in States
|
||||
===============
|
||||
|
||||
.. _Jinja: http://jinja.pocoo.org/docs/templates/
|
||||
|
||||
The most basic usage of Jinja in state files is using control structures to
|
||||
wrap conditional or redundant state elements:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
{% if grains['os'] != 'FreeBSD' %}
|
||||
tcsh:
|
||||
pkg:
|
||||
- installed
|
||||
{% endif %}
|
||||
|
||||
motd:
|
||||
file.managed:
|
||||
{% if grains['os'] == 'FreeBSD' %}
|
||||
- name: /etc/motd
|
||||
{% elif grains['os'] == 'Debian' %}
|
||||
- name: /etc/motd.tail
|
||||
{% endif %}
|
||||
- source: salt://motd
|
||||
|
||||
In this example, the first if block will only be evaluated on minions that
|
||||
aren't running FreeBSD, and the second block changes the file name based on the
|
||||
*os* grain.
|
||||
|
||||
Writing **if-else** blocks can lead to very redundant state files however. In
|
||||
this case, using :doc:`pillars</topics/pillar/index>`, or using a previously
|
||||
defined variable might be easier:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
{% set motd = ['/etc/motd'] %}
|
||||
{% if grains['os'] == 'Debian' %}
|
||||
{% set motd = ['/etc/motd.tail', '/var/run/motd'] %}
|
||||
{% endif %}
|
||||
|
||||
{% for motdfile in motd %}
|
||||
{{ motdfile }}:
|
||||
file.managed:
|
||||
- source: salt://motd
|
||||
{% endfor %}
|
||||
|
||||
Using a variable set by the template, the `for loop`_ will iterate over the
|
||||
list of MOTD files to update, adding a state block for each file.
|
||||
|
||||
.. _`for loop`: http://jinja.pocoo.org/docs/templates/#for
|
||||
|
||||
Include and Import
|
||||
==================
|
||||
|
||||
Includes and imports_ can be used to share common, reusable state configuration
|
||||
between state files and between files.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
{% from 'lib.sls' import test %}
|
||||
|
||||
This would import the ``test`` template variable or macro, not the ``test``
|
||||
state element, from the file ``lib.sls``. In the case that the included file
|
||||
performs checks again grains, or something else that requires context, passing
|
||||
the context into the included file is required:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
{% from 'lib.sls' import test with context %}
|
||||
|
||||
.. _imports: http://jinja.pocoo.org/docs/templates/#import
|
||||
|
||||
Macros
|
||||
======
|
||||
|
||||
Macros_ are helpful for eliminating redundant code, however stripping whitespace
|
||||
from the template block, as well as contained blocks, may be necessary to
|
||||
emulate a variable return from the macro.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
# init.sls
|
||||
{% from 'lib.sls' import pythonpkg with context %}
|
||||
|
||||
python-virtualenv:
|
||||
pkg.installed:
|
||||
- name: {{ pythonpkg('virtualenv') }}
|
||||
|
||||
python-fabric:
|
||||
pkg.installed:
|
||||
- name: {{ pythonpkg('fabric') }}
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
# lib.sls
|
||||
{% macro pythonpkg(pkg) -%}
|
||||
{%- if grains['os'] == 'FreeBSD' -%}
|
||||
py27-{{ pkg }}
|
||||
{%- elif grains['os'] == 'Debian' -%}
|
||||
python-{{ pkg }}
|
||||
{%- endif -%}
|
||||
{%- endmacro %}
|
||||
|
||||
This would define a macro_ that would return a string of the full package name,
|
||||
depending on the packaging system's naming convention. The whitespace of the
|
||||
macro was eliminated, so that the macro would return a string without line
|
||||
breaks, using `whitespace control`_.
|
||||
|
||||
Template Inheritance
|
||||
====================
|
||||
|
||||
`Template inheritance`_ works fine from state files and files. The search path
|
||||
starts at the root of the state tree or pillar.
|
||||
|
||||
.. _`Template inheritance`: http://jinja.pocoo.org/docs/templates/#template-inheritance
|
||||
.. _`Macros`: http://jinja.pocoo.org/docs/templates/#macros
|
||||
.. _`macro`: http://jinja.pocoo.org/docs/templates/#macros
|
||||
.. _`whitespace control`: http://jinja.pocoo.org/docs/templates/#whitespace-control
|
||||
|
||||
Filters
|
||||
=======
|
||||
|
||||
Saltstack extends `builtin filters`_ with these custom filters:
|
||||
|
||||
strftime
|
||||
Converts any time related object into a time based string. It requires a
|
||||
valid :ref:`strftime directives <python2:strftime-strptime-behavior>`. An
|
||||
:ref:`exhaustive list <python2:strftime-strptime-behavior>` can be found in
|
||||
the official Python documentation.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
{% set curtime = None | strftime() %}
|
||||
|
||||
Fuzzy dates require the `timelib`_ Python module is installed.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
{{ "2002/12/25"|strftime("%y") }}
|
||||
{{ "1040814000"|strftime("%Y-%m-%d") }}
|
||||
{{ datetime|strftime("%u") }}
|
||||
{{ "tomorrow"|strftime }}
|
||||
|
||||
sequence
|
||||
Ensure that parsed data is a sequence.
|
||||
|
||||
yaml_encode
|
||||
Serializes a single object into a YAML scalar with any necessary
|
||||
handling for escaping special characters. This will work for any
|
||||
scalar YAML data type: ints, floats, timestamps, booleans, strings,
|
||||
unicode. It will *not* work for multi-objects such as sequences or
|
||||
maps.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
{%- set bar = 7 %}
|
||||
{%- set baz = none %}
|
||||
{%- set zip = true %}
|
||||
{%- set zap = 'The word of the day is "salty"' %}
|
||||
|
||||
{%- load_yaml as foo %}
|
||||
bar: {{ bar|yaml_encode }}
|
||||
baz: {{ baz|yaml_encode }}
|
||||
baz: {{ zip|yaml_encode }}
|
||||
baz: {{ zap|yaml_encode }}
|
||||
{%- endload %}
|
||||
|
||||
In the above case ``{{ bar }}`` and ``{{ foo.bar }}`` should be
|
||||
identical and ``{{ baz }}`` and ``{{ foo.baz }}`` should be
|
||||
identical.
|
||||
|
||||
yaml_dquote
|
||||
Serializes a string into a properly-escaped YAML double-quoted
|
||||
string. This is useful when the contents of a string are unknown
|
||||
and may contain quotes or unicode that needs to be preserved. The
|
||||
resulting string will be emitted with opening and closing double
|
||||
quotes.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
{%- set bar = '"The quick brown fox . . ."' %}
|
||||
{%- set baz = 'The word of the day is "salty".' %}
|
||||
|
||||
{%- load_yaml as foo %}
|
||||
bar: {{ bar|yaml_dquote }}
|
||||
baz: {{ baz|yaml_dquote }}
|
||||
{%- endload %}
|
||||
|
||||
In the above case ``{{ bar }}`` and ``{{ foo.bar }}`` should be
|
||||
identical and ``{{ baz }}`` and ``{{ foo.baz }}`` should be
|
||||
identical. If variable contents are not guaranteed to be a string
|
||||
then it is better to use ``yaml_encode`` which handles all YAML
|
||||
scalar types.
|
||||
|
||||
yaml_squote
|
||||
Similar to the ``yaml_dquote`` filter but with single quotes. Note
|
||||
that YAML only allows special escapes inside double quotes so
|
||||
``yaml_squote`` is not nearly as useful (viz. you likely want to
|
||||
use ``yaml_encode`` or ``yaml_dquote``).
|
||||
|
||||
.. _`builtin filters`: http://jinja.pocoo.org/docs/templates/#builtin-filters
|
||||
.. _`timelib`: https://github.com/pediapress/timelib/
|
||||
|
||||
Jinja in Files
|
||||
==============
|
||||
|
||||
Jinja_ can be used in the same way in managed files:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
# redis.sls
|
||||
/etc/redis/redis.conf:
|
||||
file.managed:
|
||||
- source: salt://redis.conf
|
||||
- template: jinja
|
||||
- context:
|
||||
bind: 127.0.0.1
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
# lib.sls
|
||||
{% set port = 6379 %}
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
# redis.conf
|
||||
{% from 'lib.sls' import port with context %}
|
||||
port {{ port }}
|
||||
bind {{ bind }}
|
||||
|
||||
As an example, configuration was pulled from the file context and from an
|
||||
external template file.
|
||||
|
||||
.. note::
|
||||
|
||||
Macros and variables can be shared across templates. They should not be
|
||||
starting with one or more underscores, and should be managed by one of the
|
||||
following tags: `macro`, `set`, `load_yaml`, `load_json`, `import_yaml` and
|
||||
`import_json`.
|
||||
|
||||
Escaping Jinja
|
||||
==============
|
||||
|
||||
Occasionally, it may be necessary to escape Jinja syntax. There are two ways to
|
||||
to do this in Jinja. One is escaping individual variables or strings and the
|
||||
other is to escape entire blocks.
|
||||
|
||||
To escape a string commonly used in Jinja syntax such as ``{{``, you can use the
|
||||
following syntax:
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
{{ '{{' }}
|
||||
|
||||
For larger blocks that contain Jinja syntax that needs to be escaped, you can use
|
||||
raw blocks:
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
{% raw %]
|
||||
some text that contains jinja characters that need to be escaped
|
||||
{% endraw %}
|
||||
|
||||
See the `Escaping`_ section of Jinja's documentation to learn more.
|
||||
|
||||
A real-word example of needing to use raw tags to escape a larger block of code
|
||||
is when using ``file.managed`` with the ``contents_pillar`` option to manage
|
||||
files that contain something like consul-template, which shares a syntax subset
|
||||
with Jinja. Raw blocks are necessary here because the Jinja in the pillar would
|
||||
be rendered before the file.managed is ever called, so the Jinja syntax must be
|
||||
escaped:
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
{% raw %}
|
||||
- contents_pillar: |
|
||||
job "example-job" {
|
||||
<snipped>
|
||||
task "example" {
|
||||
driver = "docker"
|
||||
|
||||
config {
|
||||
image = "docker-registry.service.consul:5000/example-job:{{key "nomad/jobs/example-job/version"}}"
|
||||
<snipped>
|
||||
{% endraw %}
|
||||
|
||||
.. _`Escaping`: http://jinja.pocoo.org/docs/dev/templates/#escaping
|
||||
|
||||
Calling Salt Functions
|
||||
======================
|
||||
|
||||
The Jinja renderer provides a shorthand lookup syntax for the ``salt``
|
||||
dictionary of :term:`execution function <Execution Function>`.
|
||||
|
||||
.. versionadded:: 2014.7.0
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
# The following two function calls are equivalent.
|
||||
{{ salt['cmd.run']('whoami') }}
|
||||
{{ salt.cmd.run('whoami') }}
|
||||
|
||||
Debugging
|
||||
=========
|
||||
|
||||
The ``show_full_context`` function can be used to output all variables present
|
||||
in the current Jinja context.
|
||||
|
||||
.. versionadded:: 2014.7.0
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
Context is: {{ show_full_context() }}
|
||||
For Jinja usage information see :ref:`Understanding Jinja <jinja>`.
|
||||
'''
|
||||
|
||||
# Import python libs
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
YAML Renderer for Salt
|
||||
|
||||
For YAML usage information see :ref:`Understanding YAML <yaml>`.
|
||||
'''
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
|
Loading…
Add table
Reference in a new issue