UNDERSTANDING JINJA - 理解Jinja使用语法

UNDERSTANDING JINJA

Jinja是SLS文件中的默认模板语言。

本文在github上有一份相同的资料,可以按需选择浏览:UNDERSTANDING JINJA

JINJA IN STATES

Jinja在YAML之前进行评定,这意味着它在States运行之前进行评定。

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块仅在未运行FreeBSD的minions上进行计算,第二个块根据os grain更改配置文件的文件名。

编写if-else块会导致非常冗余的状态文件。 在这种情况下,使用pillar或使用先前定义的变量可能更容易:

{% 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文件列表,为每个文件添加状态块。

filter_by函数也可用于根据grain设置变量:

{% set auditd = salt['grains.filter_by']({
'RedHat': { 'package': 'audit' },
'Debian': { 'package': 'auditd' },
}) %}

INCLUDE AND IMPORT

Includes和imports可用于在状态文件之间、文件之间共享那些通用且可重用的状态配置。

{% from 'lib.sls' import test %}

这将从文件lib.sls导入test模板变量或宏,而不是test state元素。 如果包含的文件对grains或其他需要上下文的内容执行检查,则需要将上下文也传递到包含的文件中:

{% from 'lib.sls' import test with context %}

Includes 在使用时必须引用完整路径,如下所示:

spam/eggs.jinja

 {% include 'spam/foobar.jinja' %}

INCLUDING CONTEXT DURING INCLUDE/IMPORT

通过向include/importe指令添加with context,可以将当前上下文传递给执行include/importe的模板。

{% import 'openssl/vars.sls' as ssl with context %}

MACROS

Macros有助于消除冗余代码。 宏作为迷你模板时最有用,用来通过借助一些参数化变量处理重复字符串块。 请注意,从模板块中剥离空格以及包含的块可能是模拟宏的变量返回所必需的。

# 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 %}

这将定义一个宏,它将返回完整包名称的字符串,具体返回值则取决于打包系统的命名约定。 宏的空白将被删除,因此宏将使用空格控件返回一个没有换行符的字符串。

TEMPLATE INHERITANCE

模板继承支持在状态文件和文件中正常使用。 搜索路径从状态树或pillar的根开始。

模板继承(extends)的概念与HTML中比较常见的模板继承是一致的,使用方法也相似。

ERRORS

Saltstack 支持用户使用raise 这个 jinja 函数抛出自定义的错误信息。

{{ raise('Custom Error') }}

当使用包含上述语句的模板时,会引发一个TemplateError异常,导致渲染失败,并显示以下消息:

TemplateError: Custom Error

FILTERS

Saltstack使用下面这些自定义过滤器扩展了内置过滤器。JINJA内置的过滤器大约有几十个,下面又由Salt扩展了几十个,数量确实不少,功能各异。

STRFTIME

将任何与时间相关的对象转换为基于特定时间格式的字符串。 它需要有效的strftime指令。 这可以在Python文档中找到详尽的列表。

{% set curtime = None | strftime() %}

使用隐式的日期需要安装timelib Python模块。

{{ "2002/12/25"|strftime("%y") }}
{{ "1040814000"|strftime("%Y-%m-%d") }}
{{ datetime|strftime("%u") }}
{{ "tomorrow"|strftime }}

SEQUENCE

用于确认解析的数据是sequence格式。

YAML_ENCODE

将单个对象序列化为标准的YAML变量,并具有转义特殊字符所需的任何处理。 这适用于任何标量YAML数据类型:整数,浮点数,时间戳,布尔值,字符串,unicode。 它不适用于序列或maps等multi-objects对象。

{%- 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 }}
zip: {{ zip|yaml_encode }}
zap: {{ zap|yaml_encode }}
{%- endload %}

在上述情况下,{{bar}}{{foo.bar}}应该相同,{{baz}}{{foo.baz}}应该相同。

YAML_DQUOTE

将字符串序列化为正确转义的YAML双引号字符串。 当字符串的内容未知并且可能包含需要保留的引号或unicode时,这很有用。 生成的字符串将包含在一对双引号内。

{%- 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 %}

在上面的例子中{{ bar }}and {{ foo.bar }}应该是相同的, {{ baz }}{{ foo.baz }} 应该是相同的。如果无法保证变量内容是字符串,那么最好使用yaml_encode来处理所有YAML标量类型。

YAML_SQUOTE

yaml_dquote过滤器类似,但使用单引号。 请注意,YAML仅允许双引号内的特殊转义,因此yaml_squote几乎没有用处(即您可能想要使用yaml_encodeyaml_dquote)。

TO_BOOL

New in version 2017.7.0.

返回一个数据的bool逻辑值。

Example:

{{ 'yes' | to_bool }}
{{ 'true' | to_bool }}
{{ 1 | to_bool }}
{{ 'no' | to_bool }}

将被渲染为:

True
True
True
False

EXACTLY_N_TRUE

New in version 2017.7.0.

测试一个可迭代的数据集中是否有N个值为 “truthy” 的内容项 (不是 None, False, 也不是 0)。

Example:

{{ ['yes', 0, False, 'True'] | exactly_n_true(2) }}

返回:

True

EXACTLY_ONE_TRUE

New in version 2017.7.0.

测试迭代的数据集中是否有一个项目值是属于“truthy”(既不是None,也不是0,也不是0)。

Example:

{{ ['yes', False, 0, None] | exactly_one_true }}

返回:

True

QUOTE

New in version 2017.7.0.

将文本用引号括起来。

REGEX_SEARCH

New in version 2017.7.0.

扫描字符串,查找此正则表达式产生匹配的位置。 如果找不到匹配项,则返回None

Example:

{{ 'abcdefabcdef' | regex_search('BC(.*)', ignorecase=True) }}

Returns:

('defabcdef',)

REGEX_MATCH

New in version 2017.7.0.

如果字符串开头的零个或多个字符与此正则表达式匹配,否则返回None

Example:

{{ 'abcdefabcdef' | regex_match('BC(.*)', ignorecase=True) }}

返回:

None

REGEX_REPLACE

New in version 2017.7.0.

搜索模式并替换为一个字符序列。

Example:

{% set my_text = 'yes, this is a TEST' %}
{{ my_text | regex_replace(' ([a-z])', '__\\1', ignorecase=True) }}

返回:

yes,__this__is__a__TEST

UUID

New in version 2017.7.0.

返回一个 UUID格式的值。

Example:

{{ 'random' | uuid }}

返回:

3652b285-26ad-588e-a5dc-c2ee65edc804

IS_LIST

New in version 2017.7.0.

判断一个对象是否是list类型。

Example:

{{ [1, 2, 3] | is_list }}

返回:

True

IS_ITER

New in version 2017.7.0.

判断一个对象是否是可迭代的类型。

Example:

{{ [1, 2, 3] | is_iter }}

返回:

True

MIN

New in version 2017.7.0.

返回一个列表中的最小值。

Example:

{{ [1, 2, 3] | min }}

返回:

1

MAX

New in version 2017.7.0.

返回一个列表中的最大值。

Example:

{{ [1, 2, 3] | max }}

返回:

3

AVG

New in version 2017.7.0.

返回一个列表中所有项的平均值。

Example:

{{ [1, 2, 3] | avg }}

返回:

2

UNION

New in version 2017.7.0.

返回两个list的并集。

Example:

{{ [1, 2, 3] | union([2, 3, 4]) | join(', ') }}

返回:

1, 2, 3, 4

INTERSECT

New in version 2017.7.0.

返回两个列表交集。

Example:

{{ [1, 2, 3] | intersect([2, 3, 4]) | join(', ') }}

返回:

2, 3

DIFFERENCE

New in version 2017.7.0.

返回两个list的差集(从第一个看第二个,找差别)。

Example:

{{ [1, 2, 3] | difference([2, 3, 4]) | join(', ') }}
Returns:

1


### SYMMETRIC_DIFFERENCE
*New in version 2017.7.0.*

返回两个列表的对称差异。

Example:
```jinja
{{ [1, 2, 3] | symmetric_difference([2, 3, 4]) | join(', ') }}

返回:

1, 4

IS_SORTED

New in version 2017.7.0.

判断一个迭代类型对象是否已排序。

Example:

{{ [1, 2, 3] | is_sorted }}

返回:

True

COMPARE_LISTS

New in version 2017.7.0.

比较两个列表,并返回一个差异结果的字典。

Example:

{{ [1, 2, 3] | compare_lists([1, 2, 4]) }}

返回:

{'new': 4, 'old': 3}

COMPARE_DICTS

New in version 2017.7.0.

比较两个字典类型数据,并返回一个包含差异结果的字典。

Example:

{{ {'a': 'b'} | compare_lists({'a': 'c'}) }}

返回:

{'a': {'new': 'c', 'old': 'b'}}

IS_HEX

New in version 2017.7.0.

如果值为十六进制,则返回True。

Example:

{{ '0xabcd' | is_hex }}
{{ 'xyzt' | is_hex }}

返回:

True
False

CONTAINS_WHITESPACE

New in version 2017.7.0.

如果值包含空格,则返回True。

Example:

{{ 'abcd' | contains_whitespace }}
{{ 'ab cd' | contains_whitespace }}

返回:

False
True

SUBSTRING_IN_LIST

New in version 2017.7.0.

如果在字符串值列表中找到子字符串,则返回True。

Example:

{{ 'abcd' | substring_in_list(['this', 'is', 'an abcd example']) }}

返回:

True

CHECK_WHITELIST_BLACKLIST

New in version 2017.7.0.

检查白名单和/或黑名单,查看值是否与之匹配。

此过滤器可以单独与白名单或黑名单一起使用,也可以同时传递给白名单和黑名单。

如果单独使用白名单,则仅针对白名单检查值成员资格。 如果找到该值,则该函数返回True。 否则,它返回False。

如果单独使用黑名单,则仅根据黑名单检查值成员资格。 如果找到该值,则该函数返回False。 否则,它返回True。

如果同时提供白名单和黑名单,则首先检查黑名单中的值成员资格。 如果在黑名单中找不到该值,则检查白名单。 如果在白名单中找不到该值,则该函数返回False。

白名单的示例:

{{ 5 | check_whitelist_blacklist(whitelist=[5, 6, 7]) }}

返回:

True

黑名单的示例:

{{ 5 | check_whitelist_blacklist(blacklist=[5, 6, 7]) }}

返回:

False

DATE_FORMAT

New in version 2017.7.0.

将unix时间戳转换为人易读的字符串。

Example:

{{ 1457456400 | date_format }}
{{ 1457456400 | date_format('%d.%m.%Y %H:%M') }}

返回:

2017-03-08
08.03.2017 17:00

TO_NUM

New in version 2017.7.0.

New in version 2018.3.0: Renamed from str_to_num to to_num.

将字符串转换为其对应的数值。

Example:

{{ '5' | to_num }}

返回:

5

TO_BYTES

New in version 2017.7.0.

将字符串类型对象转换为字节。

Example:

{{ 'wall of text' | to_bytes }}

注意:使用默认渲染器jinja|yaml时,此选项可能会产生不利影响。 这是因为YAML需要对特殊字符进行适当处理。 有关详细信息,请参阅YAML Idiosyncracies文档中有关YAML ASCII支持的部分。

JSON_ENCODE_LIST

New in version 2017.7.0.

New in version 2018.3.0:从json_decode_list重命名为json_encode_list。 当您编码某些内容时,您会得到字节,当您解码时,您将获得您的语言环境的编码(通常是unicode类型)。 此过滤器在添加时使用的名称不正确。 在Neon 版本中,将支持json_decode_list

Deprecated since version 2018.3.3,2019.2.0: tojson过滤器完成了此过滤器的设计,使该过滤器变得多余。

递归地将列表的所有字符串元素编码为字节。

Example:

{{ [1, 2, 3] | json_encode_list }}

返回:

[1, 2, 3]

JSON_ENCODE_DICT

New in version 2017.7.0.

New in version 2018.3.0: 从json_decode_dict重命名为json_encode_dict。 当您编码某些内容时,您会得到字节,当您解码时,您将获得您的语言环境的编码(通常是unicode类型)。 此过滤器在添加时使用的名称不正确。 在Neon发行版本中,将支持json_decode_dict

Deprecated since version 2018.3.3,2019.2.0:tojson过滤器完成了此过滤器的设计,使该过滤器变得多余。

递归地将字典中的所有字符串项编码为字节。

Example:

假定pillar['foo'] 包含 {u'a': u'\u0414'}, 并且你本地的字符集是 en_US.UTF-8:

{{ pillar['foo'] | json_encode_dict }}

返回:

{'a': '\xd0\x94'}

TOJSON

New in version 2018.3.3,2019.2.0.

将数据结构转储到JSON。

添加此过滤器是为安装了版本低于2.9的Jinja版本的主机提供此功能支持。 如果安装了Jinja 2.9或更新版本,则将使用过滤器的上游版本。 有关更多信息,请参阅upstream docs

RANDOM_HASH

New in version 2017.7.0.

New in version 2018.3.0: 从rand_str重命名为random_hash,以更准确地描述过滤器的功能。 rand_str将被支持到Neon版本发布之前。

生成一个1和传递给过滤器的数字之间的随机数,然后对其进行哈希处理。 默认的哈希类型是由minion的hash_type配置选项指定的哈希类型,但是可以将备用哈希类型作为参数传递给过滤器。

Example:

{% set num_range = 99999999 %}
{{ num_range | random_hash }}
{{ num_range | random_hash('sha512') }}

返回:

43ec517d68b6edd3015b3edc9a11367b
d94a45acd81f8e3107d237dbc0d5d195f6a52a0d188bc0284c0763ece1eac9f9496fb6a531a296074c87b3540398dace1222b42e150e67c9301383fde3d66ae5

MD5

New in version 2017.7.0.

返回字符串的md5摘要。

Example:

{{ 'random' | md5 }}

返回:

7ddf32e17a6ac5ce04a8ecbf782ca509

SHA256

New in version 2017.7.0.

返回字符串的sha256摘要。

Example:

{{ 'random' | sha256 }}

返回:

a441b15fe9a3cf56661190a0b93b9dec7d04127288cc87250967cf3b52894d11

SHA512

New in version 2017.7.0.

返回字符串的sha512摘要。

Example:

{{ 'random' | sha512 }}

返回:

811a90e1c8e86c7b4c0eef5b2c0bf0ec1b19c4b1b5a242e6455be93787cb473cb7bc9b0fdeb960d00d5c6881c2094dd63c5c900ce9057255e2a4e271fc25fef1

BASE64_ENCODE

New in version 2017.7.0.

返回字符串的base64编码。

Example:

{{ 'random' | base64_encode }}

返回:

cmFuZG9t

BASE64_DECODE

New in version 2017.7.0.

解码一段使用base64编码的数据。

{{ 'Z2V0IHNhbHRlZA==' | base64_decode }}

返回:

get salted

HMAC

New in version 2017.7.0.

针对字符串/共享密钥验证hmac签名。 返回一个布尔值。

Example:

{{ 'get salted' | hmac('shared secret', 'eBWf9bstXg+NiP5AOwppB5HMvZiYMPzEM9W5YMm/AmQ=') }}

返回:

True

HTTP_QUERY

New in version 2017.7.0.

根据URL返回一个HTTP回复对象。

Example:

{{ 'http://jsonplaceholder.typicode.com/posts/1' | http_query }}

返回:

{
  'body': '{
    "userId": 1,
    "id": 1,
    "title": "sunt aut facere repellat provident occaecati excepturi option reprehenderit",
    "body": "quia et suscipit\\nsuscipit recusandae consequuntur expedita et cum\\nreprehenderit molestiae ut ut quas totam\\nnostrum rerum est autem sunt rem eveniet architecto"
  }'
}

TRAVERSE

New in version 2018.3.3.

将使用冒号分隔的目标字符串转换为字典或列表类型。 如果此值存在,则目标’foo:bar:0’将返回数据[‘foo’][‘bar’][0],否则将返回提供的默认值。

Example:

{{ {'a1': {'b1': {'c1': 'foo'}}, 'a2': 'bar'} | traverse('a1:b1', 'default') }}

返回:

{'c1': 'foo'}
{{ {'a1': {'b1': {'c1': 'foo'}}, 'a2': 'bar'} | traverse('a2:b2', 'default') }}

返回:

'default'

NETWORKING FILTERS

Salt支持使用以下网络相关的过滤器。

IS_IP

New in version 2017.7.0.

如果字符串是有效的IP地址,则返回True。

{{ '192.168.0.1' | is_ip }}

该过滤器还提供了以下可用的选项:

  • global
  • link-local
  • loopback
  • multicast
  • private
  • public
  • reserved
  • site-local
  • unspecified

Example - 测试一个字符串是否是有效的loopback IP地址。

{{ '192.168.0.1' | is_ip(options='loopback') }}

IS_IPV4

New in version 2017.7.0.

如果字符串是有效的IPv4地址,则返回。 支持与is_ip相同的选项。

{{ '192.168.0.1' | is_ipv4 }}

IS_IPV6

New in version 2017.7.0.

如果字符串是有效的IPv6地址,则返回。 支持与is_ip相同的选项。

{{ 'fe80::' | is_ipv6 }}

IPADDR

New in version 2017.7.0.

从一个给定的列表,仅返回有效的IP条目。 支持与is_ip相同的选项。 该列表还可以包含IP接口/网络。

Example:

{{ ['192.168.0.1', 'foo', 'bar', 'fe80::'] | ipaddr }}

返回:

['192.168.0.1', 'fe80::']

IPV4

New in version 2017.7.0.

Example:

{{ ['192.168.0.1', 'foo', 'bar', 'fe80::'] | ipv4 }}

返回:

['192.168.0.1']

IPV6

New in version 2017.7.0.

从列表中,仅返回有效的IPv6条目。 支持与is_ip相同的选项。 该列表还可以包含IP接口/网络。

Example:

{{ ['192.168.0.1', 'foo', 'bar', 'fe80::'] | ipv6 }}

返回:

['fe80::']

NETWORK_HOSTS

New in version 2017.7.0.

返回属于给定网络中的主机列表。 此实用程序适用于IPv4和IPv6。

注:使用大型IPv6网络运行此命令时,该命令将花费很长时间来收集所有主机。

Example:

{{ '192.168.0.1/30' | network_hosts }}

返回:

['192.168.0.1', '192.168.0.2']

NETWORK_SIZE

New in version 2017.7.0.

返回网络的大小。 此实用程序适用于IPv4和IPv6。

Example:

{{ '192.168.0.1/8' | network_size }}

返回:

16777216

GEN_MAC

New in version 2017.7.0.

使用定义的OUI前缀生成MAC地址。

常见的前缀 prefixes:

  • 00:16:3E – Xen
  • 00:18:51 – OpenVZ
  • 00:50:56 – VMware (manually generated)
  • 52:54:00 – QEMU/KVM
  • AC:DE:48 – PRIVATE

Example:

{{ '00:50' | gen_mac }}

返回:

00:50:71:52:1C

MAC_STR_TO_BYTES

New in version 2017.7.0.

将表示有效MAC地址的字符串转换为字节。

Example:

{{ '00:11:22:33:44:55' | mac_str_to_bytes }}

注:使用默认渲染器jinja|yaml时,此选项可能会产生不利影响。 这是因为YAML需要对特殊字符进行适当处理。 有关详细信息,请参阅YAML Idiosyncracies文档中有关YAML ASCII支持的部分。

DNS_CHECK

New in version 2017.7.0.

返回由dns解析的ip,但不要在失败时退出,只引发异常。 遵从系统对IPv4/6地址解析的偏好。

Example:

{{ 'www.google.com' | dns_check(port=443) }}

返回:

'172.217.3.196'

FILE FILTERS

IS_TEXT_FILE

New in version 2017.7.0.

如果文件是文本则返回。

使用启发式方法通过从文件中读取单个字节块来猜测给定文件是文本还是二进制文件。 如果块中超过30%的字符是非文本的,或者块中有NUL(‘x00’)字节,则假设这是一个二进制文件。

Example:

{{ '/etc/salt/master' | is_text_file }}

返回:

True

IS_BINARY_FILE

New in version 2017.7.0.

如果文件是二进制文件则返回。

检测文件是否为二进制文件,返回bool。 如果文件是二进制,则返回True;如果文件不是,则返回False;如果文件不可用,则返回None。

Example:

{{ '/etc/salt/master' | is_binary_file }}

返回:

False

IS_EMPTY_FILE

New in version 2017.7.0.

如果一个文件为空,则返回True。

Example:

{{ '/etc/salt/master' | is_empty_file }}

返回:

False

FILE_HASHSUM

New in version 2017.7.0.

返回文件的哈希摘要。

Example:

{{ '/etc/salt/master' | file_hashsum }}

返回:

02d4ef135514934759634f10079653252c7ad594ea97bd385480c532bca0fdda

LIST_FILES

New in version 2017.7.0.

返回特定路径下的递归文件列表。

Example:

{{ '/etc/salt/' | list_files | join('\n') }}

返回:

/etc/salt/master
/etc/salt/proxy
/etc/salt/minion
/etc/salt/pillar/top.sls
/etc/salt/pillar/device1.sls

PATH_JOIN

New in version 2017.7.0.

加入绝对路径。

Example:

{{ '/etc/salt/' | path_join('pillar', 'device1.sls') }}

返回:

/etc/salt/pillar/device1.sls

WHICH

New in version 2017.7.0.

是对/usr/bin/which的一个Python克隆。

Example:

{{ 'salt-master' | which }}

返回:

/usr/local/salt/virtualenv/bin/salt-master

TESTS

Saltstack使用下面这些自定义测试扩展了内置测试功能函数:

EQUALTO

测试两个值之间的相等性。

可以直接在if语句中使用:

{% if 1 is equalto(1) %}
    < statements >
{% endif %}

If子句的计算结果为True

或者使用selectattr过滤器:

{{ [{'value': 1}, {'value': 2} , {'value': 3}] | selectattr('value', 'equalto', 3) | list }}

返回:

[{'value': 3}]

MATCH

测试字符串是否与作为参数传递的正则表达式匹配。

可以直接在if语句中使用:

{% if 'a' is match('[a-b]') %}
    < statements >
{% endif %}

上面语句的测试结果为True

或者使用selectattr过滤器:

{{ [{'value': 'a'}, {'value': 'b'}, {'value': 'c'}] | selectattr('value', 'match', '[b-e]') | list }}

返回:

[{'value': 'b'}, {'value': 'c'}]

Test支持其他可选参数:ignorecase,multiline

ESCAPE FILTERS

REGEX_ESCAPE

New in version 2017.7.0.

允许转义字符串,以便可以通过其他函数按字面解释它们。
Example:

regex_escape = {{ 'https://example.com?foo=bar%20baz' | regex_escape }}

将被渲染为:

regex_escape = https\:\/\/example\.com\?foo\=bar\%20baz

SET THEORY FILTERS

UNIQUE

New in version 2017.7.0.

使用Jinja过滤器执行设置数学运算。

返回:

unique = {{ ['foo', 'foo', 'bar'] | unique }}

将被渲染为:

unique = ['foo', 'bar']

JINJA IN FILES

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 }}

例如,配置文件redis.conf是从文件上下文和外部模板文件中提取的。

注意:宏和变量可以跨模板共享。 它们不应该以一个或多个下划线开头,并且应该由以下标记之一管理:macro,set,load_yaml,load_json,import_yaml和import_json。

ESCAPING JINJA

偶尔,可能有必要避免Jinja语法生效。 在Jinja有两种方法可以做到这一点。 一个是转义单个变量或字符串,另一个是转义整个块。

要转义Jinja语法中常用的字符串,例如{{,您可以使用以下语法:

{{ '{{' }}

对于包含需要转义的Jinja语法的较大块,可以使用raw blocks

{% raw %}
    some text that contains jinja characters that need to be escaped
{% endraw %}

有关详细信息,请参阅Jinja文档的Escaping部分。

需要使用原始标记来转义更大代码块的真实单词示例是使用带有contents_pillar选项的file.managed来管理包含像consul-template的文件,该文件与Jinja共享语法子集。 这里需要原始块,因为pillar中的Jinja将在调用file.managed之前呈现,因此必须转义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 %}

CALLING SALT FUNCTIONS

Jinja渲染器为执行函数的salt字典提供了一种简写语法。

New in version 2014.7.0.

# The following two function calls are equivalent.
{{ salt['cmd.run']('whoami') }}
{{ salt.cmd.run('whoami') }}

DEBUGGING

show_full_context函数可用于输出当前Jinja上下文中存在的所有变量。

New in version 2014.7.0.

Context is: {{ show_full_context()|yaml(False) }}

LOGS

New in version 2017.7.0.

在Salt中,可以使用日志调试复杂的Jinja模板。 例如,拨打电话:

{%- do salt.log.error('testing jinja logging') -%}

将在minion日志中插入以下消息:

2017-02-01 01:24:40,728 [salt.module.logmod][ERROR   ][3779] testing jinja logging

PYTHON METHODS

jinja的一个强大功能只在官方jinja文档中暗示过,你可以使用变量类型的本地python方法。 这里是一份关于字符串变量方法的python文档。

{% set hostname,domain = grains.id.partition('.')[::2] %}{{ hostname }}
{% set strings = grains.id.split('-') %}{{ strings[0] }}

CUSTOM EXECUTION MODULES

自定义执行模块可用于补充或替换复杂的Jinja。 在Salt执行模块中使用Python时,许多需要复杂循环和逻辑的任务都是微不足道的。 Salt执行模块易于编写并分发给Salt minions。

Salt执行模块字典中也提供了自定义执行模块中的函数,就像内置执行模块一样:

{{ salt['my_custom_module.my_custom_function']() }}

CUSTOM JINJA FILTERS

鉴于Jinja模板中的所有执行模块都可用,可以将前一步骤中的工作内容自定义为模块,并将其用作Jinja过滤器。 但请注意,仍然无法通过管道进入下一个处理步骤。

例如,不是这样:

{{ my_variable | my_jinja_filter }}

用户需要在一个扩展模块下定义my_jinja_filter函数,比如my_filters,并用作:

{{ salt.my_filters.my_jinja_filter(my_variable) }}

这样做最大的好处是您可以访问数千个现有功能函数,例如:

使用dnsutil获取特定地址的DNS AAAA记录:

{{ salt.dnsutil.AAAA('www.google.com') }}

获取一个 Redis hash的值:

{{ salt.redis.hget('foo_hash', 'bar_field') }}

使用NAPALM route功能获取到达 0.0.0.0/0 的路由:

{{ salt.route.show('0.0.0.0/0') }}

猜你喜欢

转载自blog.csdn.net/watermelonbig/article/details/92762322