4.7 Jinja2过滤器

这里补充一个重要的概念——Jinja2过滤器,希望大家能够掌握。这是因为Ansible除了使用YAML文件以外,还大量使用Jinja2过滤器。

Jinja2是Python下一个广泛应用的模板引擎,官网地址为http://jinja.pocoo.org ,下面来介绍下Ansible如何使用Jinja2的强大过滤器(Filter)功能。

广告:个人专属 VPN,独立 IP,无限流量,多机房切换,还可以屏蔽广告和恶意软件,每月最低仅 5 美元

1.格式化数据

下面的过滤器会读取template中的数据结构并渲染为不同的格式,这点在调试的时候非常有用:

{{ 变量名

| to_json }}

{{ 变量名

| to_yaml }}

为了便于阅读,可以使用:

{{ 变量名

| to_nice_json }}

{{ 变量名

| to_nice_yaml }}

从格式化数据读入的命令如下:

{{ 变量名

| from_json }}

{{ 变量名

| from_yaml }}

举例如下:

tasks:

- shell: cat /some/path/to/file.json

register: result

- set_fact: myvar="{{ result.stdout | from_json }}"

和条件一起使用的示例如下:

tasks:

- shell: /usr/bin/foo

register: result

ignore_errors: True

- debug: msg="it failed"

when: result|failed

- debug: msg="it changed"

when: result|changed

- debug: msg="it succeeded"

when: result|success

- debug: msg="it was skipped"

when: result|skipped

2.强制定义变量

对于未定义变量,Ansible的默认行为是fail。但你可以将其关闭,命令如下:

{{ 变量名

| mandatory }}

3.未定义变量默认值

Jinja2提供了一个有用的default过滤器,相比于未定义变量时直接fail,这是个更好的方法:

{{ 变量名

| default(5) }}

4.忽略未定义变量和参数

Ansible 1.8之后,可以使用default过滤器忽略未定义的变量和模块参数,命令如下:

- name: touch files with an optional mode

file: dest={{item.path}} state=touch mode={{item.mode|default(omit)}}

with_items:

- path: /tmp/foo

- path: /tmp/bar

- path: /tmp/baz

mode: "0444"

5.list过滤器

这些过滤器可作用在list的所有变量上。获取数字list中最小值的命令如下:

{{ list1 | min }}

获取数字list中最大值的命令如下:

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

6.集合过滤器

集合过滤器自带的函数都可以从集合或列表中返回一个唯一集合。

从list中获取唯一集合的命令如下:

{{ list1 | unique }}

两个list的并集、交集和差集,命令分别如下:

{{ list1 | union(list2) }}

{{ list1 | intersect(list2) }}

{{ list1 | difference(list2) }}

7.随机数过滤器

从list中随机获取一个值,命令如下:

{{ ['a','b','c']|random }} => 'c'

从0到59中获取一个随机数,命令如下:

{{ 59 |random}}

从0到100以步长为10获取随机数,命令如下:

{{ 100 |random(step=10) }} => 70

从1到100以步长为10获取随机数,命令如下:

{{ 100 |random(1, 10) }} => 31

{{ 100 |random(start=1, step=10) }} => 51

8.shuffle过滤器

该过滤器可随机排序已有list,命令如下所示:

{{ ['a','b','c']|shuffle }} => ['c','a','b']

{{ ['a','b','c']|shuffle }} => ['b','c','a']

判断是否为数字,命令如下所示:

{{ myvar | isnan }}

求对数(默认基为e)的命令如下所示:

{{ myvar | log }}

求10的对数,命令如下所示:

{{ myvar | log(10) }}

求次幂的命令如下所示:

{{ myvar | pow(2) }}

{{ myvar | pow(5) }}

求开方的命令如下所示:

{{ myvar | root }}

{{ myvar | root(5) }}

9.IP过滤器

检查是否为有效IP,命令如下所示:

{{ myvar | ipaddr }}

检查某版本是否有有效IP,命令如下所示:

{{ myvar | ipv4 }}

{{ myvar | ipv6 }}

从IP地址提取指定信息,命令如下所示:

{{ '192.0.2.1/24' | ipaddr('address') }}

10.哈希过滤器

使用哈希过滤器,命令如下所示:

{{ 'test1'|hash('sha1') }}

{{ 'test1'|hash('md5') }}

{{ 'test2'|checksum }}

{{ 'passwordsaresecret'|password_hash('sha512') }}

其他有用的过滤器用法如下所示:

获取路径的最后一个名称:

{{ path | basename }}从路径中获取目录名称:

{{ path | dirname }}获取链接的实际路径:

{{ path | realpath }}

使用match或search匹配正则表达式的命令如下所示:

vars:

url: "http://example.com/users/foo/resources/bar"

tasks:

- shell: "msg='matched pattern 1'"

when: url | match("http://example.com/users/.*/resources/.*")

- debug: "msg='matched pattern 2'"

when: url | search("/users/.*/resources/.*")

使用regex_place进行正则替换的命令如下所示:

convert "ansible" to "able"

命令显示结果如下:

{{ 'ansible' | regex_replace('^a.*i(.*)$', 'a\\1') }}

使用convert进行正则替换,命令如下所示:

convert "foobar" to "bar"

命令显示结果如下:

{{ 'foobar' | regex_replace('^f.*o(.*)$', '\\1') }}

在正则中使用regex_escape转义特殊字符,命令如下所示:

convert '^f.*o(.*)$' to '\^f\.\*o\(\.\*\)\$'

命令显示结果如下:

{{ '^f.*o(.*)$' | regex_escape() }}

参考文档

http://docs.ansible.com/ansible/playbooks_filters.html#ip-address-filter 。