通过过滤器处理数据
- 使用方式:
{{数据|过滤器}}
例:
# 简单的例子(将变量myname传给过滤器capitalize):
{{ myname | capitalize }} # capitalize将字符串首字符改为大写
# 复杂一的例子,过滤器处理后的值,可以链式继续传递给后面的过滤器
# 列表[1,4,2,2]通过unique去重后,交给sort排序
{{ [ 1, 4, 2, 2 ] | unique | sort }}
过滤器的本质,实际上是一个函数。前面传过来的数据,将会成为函数的第1个参数。
使用过滤器
检查变量是否已定义
- mandatory:判断某一变量是否已定义,如果未定义,则中止playbook
[student@worktest myansible]$ vim myfilter.yml
---
- name: test filters
hosts: lb_servers
tasks:
- name: my test filter
debug:
msg: "{{my_value | mandatory}}"
# 运行playbook,将会失败
[student@worktest myansible]$ ansible-playbook myfilter.yml
[student@worktest myansible]$ vim myfilter.yml
---
- name: test filters
hosts: lb_servers
vars:
my_value: hello world
tasks:
- name: my test filter
debug:
msg: "{{my_value | mandatory}}"
# 运行playbook,将会正常运行
[student@worktest myansible]$ ansible-playbook myfilter.yml
default:如果一个变量没有定义,则通过赋默认值创建它
[student@worktest myansible]$ vim myfilter.yml
---
- name: test filters
hosts: lb_servers
gather_facts: no
tasks:
- name: my test filter
debug:
msg: "{{username | default('tom')}}"
# 执行,将会输出tom
[student@worktest myansible]$ ansible-playbook myfilter.yml
# 如果变量定义了,但是是空值,可以通过default的额外参数True,为变量赋值
[student@worktest myansible]$ vim myfilter.yml
---
- name: test filters
hosts: lb_servers
gather_facts: no
vars:
username: ""
tasks:
- name: my test filter
debug:
msg: "{{username | default('tom')}}"
# 执行,将会输出""
[student@worktest myansible]$ ansible-playbook myfilter.yml
[student@worktest myansible]$ vim myfilter.yml
---
- name: test filters
hosts: lb_servers
gather_facts: no
vars:
username: ""
tasks:
- name: my test filter
debug:
msg: "{{username | default('tom', True)}}"
# 执行,将会输出tom
[student@worktest myansible]$ ansible-playbook myfilter.yml
执行数学运算
运算符 | 作用 |
---|---|
+ | 加法 |
- | 减法 |
/ | 真正的除法 |
// | 地板除 |
% | 求模(取余) |
* | 乘法 |
** | 幂(乘方) |
操作列表
- max、min、sum用于取最大值、最小值、求和。length求长度,first、last取出第1个值和最后1个值。random随机取出。
[student@worktest myansible]$ vim myfilter.yml
---
- name: test filters
hosts: lb_servers
gather_facts: no
vars:
my_list: [12, 13, 8, 17, 5]
tasks:
- name: my test filter
debug:
msg: |
max: {{my_list | max}}
min: {{my_list | min}}
sum: {{my_list | sum}}
length: {{my_list | length}}
1st: {{my_list | first}}
last: {{my_list | last}}
random: {{my_list | random}}
排序:
- reverse:用于反转
- sort:升序排列
- shuffle:随机打乱顺序
- list:将对象转为列表
[student@worktest myansible]$ vim myfilter.yml
---
- name: test filters
hosts: lb_servers
gather_facts: no
vars:
my_list: [53, 75, 6, 77, 24, 18, 46, 33, 94, 8]
tasks:
- name: my test filter
debug:
msg: |
reverse: {{my_list | reverse}}
# 运行时,将会得到一个对象,不会得到列表
[student@worktest myansible]$ ansible-playbook myfilter.yml
[student@worktest myansible]$ vim myfilter.yml
---
- name: test filters
hosts: lb_servers
gather_facts: no
vars:
my_list: [53, 75, 6, 77, 24, 18, 46, 33, 94, 8]
tasks:
- name: my test filter
debug:
msg: |
reverse: {{my_list | reverse | list}}
# 执行,输出反转后的列表
[student@worktest myansible]$ ansible-playbook myfilter.yml
[student@worktest myansible]$ vim myfilter.yml
---
- name: test filters
hosts: lb_servers
gather_facts: no
vars:
my_list: [53, 75, 6, 77, 24, 18, 46, 33, 94, 8]
tasks:
- name: my test filter
debug:
msg: |
reverse: {{my_list | reverse | list}}
sort: {{my_list | sort | list}}
shuffle: {{ my_list | shuffle}}
- 合并:flatten用于扁平化列表。
[student@worktest myansible]$ vim myfilter.yml
---
- name: test filters
hosts: lb_servers
gather_facts: no
vars:
my_list: [2, [10, [20, 15]], 100]
tasks:
- name: my test filter
debug:
msg: |
flatten: {{my_list | flatten}}
- 将列表作为集合处理。集合不能有重复元素。
- 集合还可以支持交集(取出两个集合中相同的元素)、并集(取出两个集合中全部的元素)、差补(一个集合中有,另一个集合中没有的元素)。
[student@worktest myansible]$ vim myfilter.yml
---
- name: test filters
hosts: lb_servers
gather_facts: no
vars:
my_list: [10, 5, 5, 8, 8, 3, 2, 3, 10]
l1: [10, 20, 30]
l2: [20, 30, 40]
tasks:
- name: my test filter
debug:
msg: |
unique: {{my_list | unique | list}}
union: {{l1 | union(l2)}}
intersect: {{l1 | intersect(l2)}}
difference: {{l1 | difference(l2)}}
操作字典
-
字典的key不能重复。
-
合并字典
[student@worktest myansible]$ vim myfilter.yml
---
- name: test filters
hosts: lb_servers
gather_facts: no
vars:
d1: {'a': 1, 'b': 2}
d2: {'b': 10, 'c': 20}
tasks:
- name: my test filter
debug:
msg: |
combine: {{d1 | combine(d2)}}
- 重构。
[student@worktest myansible]$ vim myfilter.yml
---
- name: test filters
hosts: lb_servers
gather_facts: no
vars:
user1: {'name': 'tom', 'age': 20}
tasks:
- name: my test filter
debug:
msg: |
dict2items: {{user1 | dict2items}}
# 结果是[{'key': 'name', 'value': 'tom'}, {'key': 'age', 'value': 20}]
[student@worktest myansible]$ vim myfilter.yml
---
- name: test filters
hosts: lb_servers
gather_facts: no
vars:
user1: [{'key': 'name', 'value': 'tom'}, {'key': 'age', 'value': 20}]
tasks:
- name: my test filter
debug:
msg: |
items2dict: {{user1 | items2dict}}
# 结果是{'name': 'tom', 'age': 20}
哈希、编码及操作字符串
- 计算数据的哈希值
[student@worktest myansible]$ echo -n 'stud' | sha1sum
93bf429bc427204342799decfccd813efc1f159c -
[student@worktest myansible]$ vim myfilter.yml
---
- name: test filters
hosts: lb_servers
gather_facts: no
vars:
s1: 'stud'
tasks:
- name: my test filter
debug:
msg: |
sha1: {{s1 | hash('sha1')}}
md5: {{s1 | hash('md5')}}
sha256: {{s1 | hash('sha256')}}
sha512: {{s1 | hash('sha512')}}
- 创建用户时,可以通过
password_hash
插件为用户创建密码
[student@worktest myansible]$ vim myfilter.yml
---
- name: test filters
hosts: lb_servers
gather_facts: no
vars:
s1: 'stud'
tasks:
- name: my test filter
debug:
msg: |
password: {{s1 | password_hash('sha512')}}
- base64编码。将可见字符使用6位进行编码,常规的字符编码方案,都是至少8位。所以3个常规字符,是24位,正好对应4个base64编码字符。
[student@worktest myansible]$ echo -n 'a' | base64
YQ==
[student@worktest myansible]$ echo -n 'ab' | base64
YWI=
[student@worktest myansible]$ echo -n 'abc' | base64
YWJj
[student@worktest myansible]$ echo -n 'YWJj' | base64 --decode
abc
[student@worktest myansible]$
[student@worktest myansible]$ echo -n 'YWI=' | base64 --decode
ab
[student@worktest myansible]$ echo -n 'YQ==' | base64 --decode
a
[student@worktest myansible]$ vim myfilter.yml
---
- name: test filters
hosts: lb_servers
gather_facts: no
vars:
s1: 'abc'
b1: 'YWJj'
tasks:
- name: my test filter
debug:
msg: |
str -> base64: {{s1 | b64encode}}
base64 -> str: {{b1 | b64decode}}
格式化文本
- lower:转成小写字母
- upper:转成大写字母
- capitalize:将首字符转成大写
[student@worktest myansible]$ vim myfilter.yml
---
- name: test filters
hosts: lb_servers
gather_facts: no
vars:
s1: 'HELLO'
s2: 'world'
tasks:
- name: my test filter
debug:
msg: |
lower: {{s1 | lower}}
upper: {{s2 | upper}}
capitalize: {{s2 | capitalize}}
-
替换文本
- replace可以实现简单的字符串替换
- regex_search可以使用正则表达式查找
- regex_replace可以使用正则表达式进行查找替换
[student@worktest myansible]$ vim myfilter.yml
---
- name: test filters
hosts: lb_servers
gather_facts: no
vars:
s1: 'marvin, arthur'
tasks:
- name: my test filter
debug:
msg: |
replace: {{s1 | replace('ar', '**')}}
regex_search: {{s1|regex_search('ar\S*r')}}
regex_replace: {{s1|regex_replace('ar(\S*)r', '\1mb')}}
操作JSON数据
- JSON是一种数据表示方式,它是一种独立于语言的数据呈现方式。
# yaml格式数据示例。声明变量hosts。
hosts:
- name: bastion
ip:
- 172.25.250.254
- 172.25.252.1
- name: classroom
ip:
- 172.25.252.254
# 转成python数据类型如下:
hosts = [
{
'name': 'bastion',
'ip': ['172.25.250.254', '172.25.252.1']
},
{
'name': 'classroom',
'ip': ['172.25.252.254']
}
]
- json_query可以把ansible中的数据,转成json格式
[student@worktest myansible]$ vim myfilter.yml
---
- name: test filters
hosts: lb_servers
gather_facts: no
vars:
hosts:
- name: bastion
ip:
- 172.25.250.254
- 172.25.252.1
- name: classroom
ip:
- 172.25.252.254
tasks:
- name: my test filter
debug:
msg: |
json_query: {{hosts|json_query('[*].name')}} {{hosts|json_query('[*].ip')}}
- 需要将yaml转为json,可以使用to_json或
to_nice_json
;反过来,可以使用to_yaml或to_nice_yaml
[student@worktest myansible]$ vim myfilter.yml
---
- name: test filters
hosts: lb_servers
gather_facts: no
vars:
hosts:
- name: bastion
ip:
- 172.25.250.254
- 172.25.252.1
- name: classroom
ip:
- 172.25.252.254
tasks:
- name: my test filter
copy:
dest: /tmp/data.json
content: "{{hosts|to_nice_json}}"
[student@servera ~]$ cat /tmp/data.json
[
{
"ip": [
"172.25.250.254",
"172.25.252.1"
],
"name": "bastion"
},
{
"ip": [
"172.25.252.254"
],
"name": "classroom"
}
]
使用lookup插件
- 可以使用lookup或query实现在Jinja2模板中调用插件,获取外部文件或环境变量中的内容。
# 将/etc/hosts中的内容读取出来,赋值给myhosts变量
[student@worktest myansible]$ vim lookup.yml
---
- name: test lookup
hosts: lb_servers
gather_facts: no
vars:
myhosts: "{{lookup('file', '/etc/hosts')}}"
tasks:
- name: my test lookup
debug:
msg: "{{myhosts}}"
# lookup也可以同时读入多个文件,多个文件的内容将会拼接成一个大字符串
[student@worktest myansible]$ vim lookup.yml
---
- name: test lookup
hosts: lb_servers
gather_facts: no
vars:
myhosts: "{{lookup('file', '/etc/hosts', '/etc/issue')}}"
tasks:
- name: my test lookup
debug:
msg: "{{myhosts}}"
# 如果使用query替代lookup,则每个文件的内容,都成为列表中的一个字符串
[student@worktest myansible]$ vim lookup.yml
---
- name: test lookup
hosts: lb_servers
gather_facts: no
vars:
myhosts: "{{query('file', '/etc/hosts', '/etc/issue')}}"
tasks:
- name: my test lookup
debug:
msg: "{{myhosts}}"
使用template参数
[student@worktest myansible]$ vim myfile.j2
Hello {{name|capitalize}}
[student@worktest myansible]$ vim lookup.yml
---
- name: test lookup
hosts: lb_servers
gather_facts: no
vars:
name: tom
tasks:
- name: my test lookup
debug:
msg: "{{lookup('template', 'myfile.j2')}}"
在控制节点的环境变量中读取内容
[student@worktest myansible]$ vim lookup.yml
---
- name: test lookup
hosts: lb_servers
gather_facts: no
tasks:
- name: my test lookup
debug:
msg: "{{lookup('env', 'HOSTNAME')}}"
获取控制节点的命令输出
- 使用pipe获取的是命令的原始输出样式,使用lines将会把输出切分,各项之间使用逗号分隔。
[student@worktest myansible]$ vim lookup.yml
---
- name: test lookup
hosts: lb_servers
gather_facts: no
tasks:
- name: my test lookup
debug:
msg: "{{lookup('pipe', 'ls -l /home')}}"
[student@worktest myansible]$ vim lookup.yml
---
- name: test lookup
hosts: lb_servers
gather_facts: no
tasks:
- name: my test lookup
debug:
msg: "{{lookup('lines', 'ls -l /home')}}"
处理错误
- 大部分的插件,在运行期间,如果出现错误,将会终止执行。
- lookup允许设置执行其他功能,而不是终止任务。
# my.file不存在,则设置内容为Hello World
[student@worktest myansible]$ vim lookup.yml
---
- name: test lookup
hosts: lb_servers
gather_facts: no
tasks:
- name: my test lookup
debug:
msg: "{{lookup('file', 'my.file', errors='warn') | default('Hello World', true)}}"