预计阅读本页时间:-
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 。