Jinja加载工具为jinja模板提供了一个更强大的后端
在state文件中Jinja最基本的用法是使用控制结构包装条件或冗余state元素:
{% 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
在这个例子中,第一个if块将会判断minions非运行在FreeBSD, 第二个块基于 os grain改变文件名。
编写 if-else 块可以加载冗余的state文件。这种情况下,使用 pillars ,或使用一个预定义的变量将会变得更加容易。
{% 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 %}
使用一个模板设定的变量, for循环 将会遍历MOTD列表中的文件并更新,为每个文件添加一个state块。
Includes和imports__ 可在state文件之间共享,重用state配置。
{% from 'lib.sls' import test %}
这个范例将会从 lib.sls
文件导入 test
模板变量或宏,并不是 test
state元素。 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:
{% from 'lib.sls' import test with context %}
宏 有助于消除冗余代码,however stripping whitespace from the template block, as well as contained blocks, may be necessary to emulate a variable return from the macro.
# init.sls
{% from 'lib.sls' import pythonpkg with context %}
python-virtualenv:
pkg.installed:
- name: {{ pythonpkg('virtualenv') }}
python-fabric:
pkg.installed:
- name: {{ pythonpkg('fabric') }}
# 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 works fine from state files and files. The search path starts at the root of the state tree or pillar.
Saltstack extends builtin filters with these custom filters:
Converts any time related object into a time based string. It requires a valid strftime directives. An exhaustive list can be found in the official Python documentation.
{% set curtime = None | strftime() %}
Fuzzy dates require the timelib Python module is installed.
{{ "2002/12/25"|strftime("%y") }}
{{ "1040814000"|strftime("%Y-%m-%d") }}
{{ datetime|strftime("%u") }}
{{ "tomorrow"|strftime }}
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.
{%- 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.
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.
{%- 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_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
).Jinja 可以以同样的方式用于被管理的文件:
# redis.sls
/etc/redis/redis.conf:
file.managed:
- source: salt://redis.conf
- template: jinja
- context:
bind: 127.0.0.1
# lib.sls
{% set port = 6379 %}
# 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.
注解
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.
The Jinja renderer provides a shorthand lookup syntax for the salt
dictionary of execution function.
2014.7.0 新版功能.
# The following two function calls are equivalent.
{{ salt['cmd.run']('whoami') }}
{{ salt.cmd.run('whoami') }}
The show_full_context
function can be used to output all variables present
in the current Jinja context.
2014.7.0 新版功能.
Context is: {{ show_full_context() }}
salt.utils.jinja.
SerializerExtension
(environment)¶Yaml和Json处理。
Format filters
Allows jsonifying or yamlifying any data structure. For example, this dataset:
data = {
'foo': True,
'bar': 42,
'baz': [1, 2, 3],
'qux': 2.0
}
yaml = {{ data|yaml }}
json = {{ data|json }}
python = {{ data|python }}
will be rendered as:
yaml = {bar: 42, baz: [1, 2, 3], foo: true, qux: 2.0}
json = {"baz": [1, 2, 3], "foo": true, "bar": 42, "qux": 2.0}
python = {'bar': 42, 'baz': [1, 2, 3], 'foo': True, 'qux': 2.0}
The yaml filter takes an optional flow_style parameter to control the default-flow-style parameter of the YAML dumper.
{{ data|yaml(False) }}
will be rendered as:
bar: 42
baz:
- 1
- 2
- 3
foo: true
qux: 2.0
Load filters
Strings and variables can be deserialized with load_yaml and load_json tags and filters. It allows one to manipulate data directly in templates, easily:
{%- set yaml_src = "{foo: it works}"|load_yaml %}
{%- set json_src = "{'bar': 'for real'}"|load_json %}
Dude, {{ yaml_src.foo }} {{ json_src.bar }}!
will be rendered as:
Dude, it works for real!
Load tags
Salt implements import_yaml
and import_json
tags. They work like
the import tag, except that the document is also deserialized.
Syntaxes are {% load_yaml as [VARIABLE] %}[YOUR DATA]{% endload %}
and {% load_json as [VARIABLE] %}[YOUR DATA]{% endload %}
For example:
{% load_yaml as yaml_src %}
foo: it works
{% endload %}
{% load_json as json_src %}
{
"bar": "for real"
}
{% endload %}
Dude, {{ yaml_src.foo }} {{ json_src.bar }}!
will be rendered as:
Dude, it works for real!
Import tags
External files can be imported and made available as a Jinja variable.
{% import_yaml "myfile.yml" as myfile %}
{% import_json "defaults.json" as defaults %}
{% import_text "completeworksofshakespeare.txt" as poems %}
Catalog
import_*
and load_*
tags will automatically expose their
target variable to import. This feature makes catalog of data to
handle.
for example:
# doc1.sls
{% load_yaml as var1 %}
foo: it works
{% endload %}
{% load_yaml as var2 %}
bar: for real
{% endload %}
# doc2.sls
{% from "doc1.sls" import var1, var2 as local2 %}
{{ var1.foo }} {{ local2.bar }}