Ansible - 使用过滤器¶
在本章中,您将学习如何使用 Jinja 过滤器转换数据。
目标:在本章中,您将学会如何
转换字典或列表等数据结构;
转换变量。
ansible, jinja, 过滤器
知识:
难度:
阅读时间: 20 分钟
在前几章中,我们已经有机会使用 Jinja 过滤器。
这些用 Python 编写的过滤器允许我们操作和转换 Ansible 变量。
注意
更多信息可以在此处找到。
在本章中,我们将使用以下 playbook 来测试介绍的各种过滤器
- name: Manipulating the data
hosts: localhost
gather_facts: false
vars:
zero: 0
zero_string: "0"
non_zero: 4
true_booleen: True
true_non_booleen: "True"
false_boolean: False
false_non_boolean: "False"
whatever: "It's false!"
user_name: antoine
my_dictionary:
key1: value1
key2: value2
my_simple_list:
- value_list_1
- value_list_2
- value_list_3
my_simple_list_2:
- value_list_3
- value_list_4
- value_list_5
my_list:
- element: element1
value: value1
- element: element2
value: value2
tasks:
- name: Print an integer
debug:
var: zero
注意
以下是您最有可能遇到或需要的过滤器列表,但并非详尽无遗。幸运的是,还有很多其他的。您甚至可以编写自己的过滤器!
Playbook 将按如下方式运行
ansible-playbook play-filter.yml
转换数据¶
数据可以从一种类型转换为另一种类型。
要了解数据的类型(Python 语言中的类型),您必须使用 type_debug
过滤器。
示例
- name: Display the type of a variable
debug:
var: true_boolean|type_debug
这给了我们
TASK [Display the type of a variable] ******************************************************************
ok: [localhost] => {
"true_boolean|type_debug": "bool"
}
可以将整数转换为字符串
- name: Transforming a variable type
debug:
var: zero|string
TASK [Transforming a variable type] ***************************************************************
ok: [localhost] => {
"zero|string": "0"
}
将字符串转换为整数
- name: Transforming a variable type
debug:
var: zero_string|int
或将变量转换为布尔值
- name: Display an integer as a boolean
debug:
var: non_zero | bool
- name: Display a string as a boolean
debug:
var: true_non_boolean | bool
- name: Display a string as a boolean
debug:
var: false_non_boolean | bool
- name: Display a string as a boolean
debug:
var: whatever | bool
字符串可以转换为大写或小写
- name: Lowercase a string of characters
debug:
var: whatever | lower
- name: Upercase a string of characters
debug:
var: whatever | upper
这给了我们
TASK [Lowercase a string of characters] *****************************************************
ok: [localhost] => {
"whatever | lower": "it's false!"
}
TASK [Upercase a string of characters] *****************************************************
ok: [localhost] => {
"whatever | upper": "IT'S FALSE!"
}
replace
过滤器允许您用其他字符替换字符。
在这里,我们删除空格,甚至替换一个单词
- name: Replace a character in a string
debug:
var: whatever | replace(" ", "")
- name: Replace a word in a string
debug:
var: whatever | replace("false", "true")
这给了我们
TASK [Replace a character in a string] *****************************************************
ok: [localhost] => {
"whatever | replace(\" \", \"\")": "It'sfalse!"
}
TASK [Replace a word in a string] *****************************************************
ok: [localhost] => {
"whatever | replace(\"false\", \"true\")": "It's true !"
}
split
过滤器根据一个字符将字符串分割成一个列表
- name: Cutting a string of characters
debug:
var: whatever | split(" ", "")
TASK [Cutting a string of characters] *****************************************************
ok: [localhost] => {
"whatever | split(\" \")": [
"It's",
"false!"
]
}
连接列表元素¶
经常需要将不同元素连接成一个字符串。然后,我们可以指定一个字符或字符串插入到每个元素之间。
- name: Joining elements of a list
debug:
var: my_simple_list|join(",")
- name: Joining elements of a list
debug:
var: my_simple_list|join(" | ")
这给了我们
TASK [Joining elements of a list] *****************************************************************
ok: [localhost] => {
"my_simple_list|join(\",\")": "value_list_1,value_list_2,value_list_3"
}
TASK [Joining elements of a list] *****************************************************************
ok: [localhost] => {
"my_simple_list|join(\" | \")": "value_list_1 | value_list_2 | value_list_3"
}
将字典转换为列表(反之亦然)¶
dict2items
和 itemstodict
过滤器实现起来有点复杂,但经常使用,尤其是在循环中。
请注意,可以指定转换中使用的键名和值名。
- name: Display a dictionary
debug:
var: my_dictionary
- name: Transforming a dictionary into a list
debug:
var: my_dictionary | dict2items
- name: Transforming a dictionary into a list
debug:
var: my_dictionary | dict2items(key_name='key', value_name='value')
- name: Transforming a list into a dictionary
debug:
var: my_list | items2dict(key_name='element', value_name='value')
TASK [Display a dictionary] *************************************************************************
ok: [localhost] => {
"my_dictionary": {
"key1": "value1",
"key2": "value2"
}
}
TASK [Transforming a dictionary into a list] *************************************************************
ok: [localhost] => {
"my_dictionary | dict2items": [
{
"key": "key1",
"value": "value1"
},
{
"key": "key2",
"value": "value2"
}
]
}
TASK [Transforming a dictionary into a list] *************************************************************
ok: [localhost] => {
"my_dictionary | dict2items (key_name = 'key', value_name = 'value')": [
{
"key": "key1",
"value": "value1"
},
{
"key": "key2",
"value": "value2"
}
]
}
TASK [Transforming a list into a dictionary] ************************************************************
ok: [localhost] => {
"my_list | items2dict(key_name='element', value_name='value')": {
"element1": "value1",
"element2": "value2"
}
}
使用列表¶
可以合并或过滤一个或多个列表的数据
- name: Merger of two lists
debug:
var: my_simple_list | union(my_simple_list_2)
ok: [localhost] => {
"my_simple_list | union(my_simple_list_2)": [
"value_list_1",
"value_list_2",
"value_list_3",
"value_list_4",
"value_list_5"
]
}
只保留两个列表的交集(两个列表中都存在的元素)
- name: Merger of two lists
debug:
var: my_simple_list | intersect(my_simple_list_2)
TASK [Merger of two lists] *******************************************************************************
ok: [localhost] => {
"my_simple_list | intersect(my_simple_list_2)": [
"value_list_3"
]
}
反之,只保留差集(第二个列表中不存在的元素)
- name: Merger of two lists
debug:
var: my_simple_list | difference(my_simple_list_2)
TASK [Merger of two lists] *******************************************************************************
ok: [localhost] => {
"my_simple_list | difference(my_simple_list_2)": [
"value_list_1",
"value_list_2",
]
}
如果您的列表包含非唯一值,也可以使用 unique
过滤器对其进行过滤。
- name: Unique value in a list
debug:
var: my_simple_list | unique
JSON/YAML 转换¶
您可能需要导入 JSON 数据(例如,从 API)或以 YAML 或 JSON 格式导出数据。
- name: Display a variable in yaml
debug:
var: my_list | to_nice_yaml(indent=4)
- name: Display a variable in json
debug:
var: my_list | to_nice_json(indent=4)
TASK [Display a variable in yaml] ********************************************************************
ok: [localhost] => {
"my_list | to_nice_yaml(indent=4)": "- element: element1\n value: value1\n- element: element2\n value: value2\n"
}
TASK [Display a variable in json] ********************************************************************
ok: [localhost] => {
"my_list | to_nice_json(indent=4)": "[\n {\n \"element\": \"element1\",\n \"value\": \"value1\"\n },\n {\n \"element\": \"element2\",\n \"value\": \"value2\"\n }\n]"
}
默认值、可选变量、保护变量¶
如果您不为变量提供默认值,或者没有保护好它们,很快就会在 playbook 执行过程中遇到错误。
如果变量不存在,可以使用 default
过滤器将其值替换为另一个值
- name: Default value
debug:
var: variablethatdoesnotexists | default(whatever)
TASK [Default value] ********************************************************************************
ok: [localhost] => {
"variablethatdoesnotexists | default(whatever)": "It's false!"
}
请注意单引号 '
的存在,如果使用 shell
模块,则需要对其进行保护。
- name: Default value
debug:
var: variablethatdoesnotexists | default(whatever| quote)
TASK [Default value] ********************************************************************************
ok: [localhost] => {
"variablethatdoesnotexists | default(whatever|quote)": "'It'\"'\"'s false!'"
}
最后,模块中的可选变量如果不存在,可以使用 default
过滤器中的 omit
关键字来忽略它,这将为您节省运行时错误。
- name: Add a new user
ansible.builtin.user:
name: "{{ user_name }}"
comment: "{{ user_comment | default(omit) }}"
根据另一个值关联一个值(ternary
)¶
有时您需要使用条件来为变量赋值,在这种情况下,通常需要通过 set_fact
步骤。
可以使用 ternary
过滤器来避免这种情况
- name: Default value
debug:
var: (user_name == 'antoine') | ternary('admin', 'normal_user')
TASK [Default value] ********************************************************************************
ok: [localhost] => {
"(user_name == 'antoine') | ternary('admin', 'normal_user')": "admin"
}
其他过滤器¶
{{ 10000 | random }}
: 顾名思义,生成一个随机值。{{ my_simple_list | first }}
: 提取列表的第一个元素。{{ my_simple_list | length }}
: 返回长度(列表或字符串的长度)。{{ ip_list | ansible.netcommon.ipv4 }}
: 只显示 v4 IP。不必细说,如果您需要,有很多专门用于网络的过滤器。{{ user_password | password_hash('sha512') }}
: 生成 sha512 格式的密码哈希。
作者:Antoine Le Morvan
贡献者:Steven Spencer, Ganna Zhyrnova