使用过滤器和插件转换数据
使用过滤器处理变量
变量类型
Ansible将运行时数据存储在变量中。 变量值的内容定义了确切的数据类型。
一些值类型包括:
-
Strings (字符序列)
-
Numbers(数字值)
-
Booleans(真/假值)
-
Dates(ISO-8601日历日期)
-
Null(将变量值定义为null)
-
Lists or Arrays (值的排序集合)
-
Dictionaries (键值对的集合)
Strings
字符串是字符序列,Ansible中的默认数据类型。 字符串不需要用引号或双引号引起来。 Ansible忽略未加引号字符串结尾的空格。
my_string: Those are the contents of the string
YAML格式允许您定义多行字符串。 使用管道运算符(|)保留换行符,或使用大于运算符(>)抑制换行符。
string_with_breaks: |
This string
has several
line breaks
string_without_breaks: >
This string will not
contain any line breaks.
Separated lines are joined
by a space character.
Numbers
当变量内容符合数字时,Ansible(准确地说是YAML)将解析字符串并生成一个整数或浮点数。
•Integers 包含十进制字符,并可选地以+或-号开头。
answer: 42
•float, 如果在整数值中包含小数点。
float_answer: 42.0
•科学记数法还可用于编写大整数或浮点数。
scientific_answer: 0.42e+2
•十六进制数字以0x开头,之后仅是十六进制字符。 以下示例值为十六进制数2A(十进制为42)
hex_answer: 0x2A
•如果将数字放在引号中,则将其视为字符串。
float_answer: "42"
Booleans
布尔值包含yes,no,y,n,on,off,true或false字符串。 值不区分大小写,但是Jinja2文档建议您使用小写形式以保持一致性。
become_root: false
Date
如果字符串符合ISO-8601标准,则Ansible会将字符串转换为日期类型的值。
my_date_time: 2019-05-30T21:15:32.42+02:00
my_simple_date: 2019-05-30
Null
特殊值null和~字符将变量值定义为null。
---
- name: Debug Play
hosts: servera
gather_facts: no
vars:
myname: null
myage: ~
mysex:
tasks:
- name: Debug
debug:
#var: myname
#var: myage
msg: >
myname is {
{ myname }};
myage is {
{ myage }};
mysex is {
{ mysex }}.
测试结果:null作为普通字符串赋值。
Lists or Arrays
列表,也称为数组,是值的排序集合。 列表是数据收集和循环的基本结构。 将列表以逗号分隔的值序列形式写在方括号中,或者每行一个元素,并以破折号(-)开头。
以下示例是等效的:
my_list: ['Douglas', 'Marvin', 'Arthur']
my_list:
- Douglas
- Marvin
- Arthur
像大多数编程语言中的数组一样,您可以使用从0开始的索引号来访问列表的特定元素:
---
- name: Debug Play
hosts: servera
gather_facts: no
vars:
my_list: ['Douglas', 'Marvin', 'Arthur']
tasks:
- name: Debug
debug:
var: my_list[1]
- name: Confirm that the second list element is "Marvin"
assert:
that:
- my_list[1] == 'Marvin'
Dictionaries
字典在其他上下文中也称为映射或哈希,它们是将字符串键链接到值以进行直接访问的结构。 像列表一样,字典可以单行或跨行编写:
my_dict: {
Douglas: Human, Marvin: Robot, Arthur: Human }
my_dict:
Douglas: Human
Marvin: Robot
Arthur: Human
通过其键访问字典中的项,在字典名称后立即提供该项,并用方括号括起来:
---
- name: Debug Play
hosts: servera
gather_facts: no
vars:
my_dict:
Douglas: Human
Marvin: Robot
Arthur: Human
tasks:
- name: Debug
debug:
var: my_dict['Marvin']
- name: Confirm my_dict key "Marvin"
assert:
that:
- my_dict['Marvin'] == 'Robot'
您还可以使用语法my_dict.Marvin访问词典条目my_dict [‘Marvin’]。 但是,不建议使用这种点符号,因为它可能会与Python字典的属性和方法的保留名称冲突。
更多信息,请参见https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html#creating-valid-variable-names。
使用过滤器处理数据
过滤器允许您处理变量的值,对其进行转换或使用它来计算新值以便提取信息。 要应用过滤器,请在变量名称后加上竖线(|)以及要应用的过滤器名称。 某些过滤器可能需要括号中的可选参数或选项。 您可以在单个表达式中链接多个过滤器。
过滤器不会更改变量中存储的值。 Jinja2表达式只是处理该值并使用结果。
Ansible和Jinja2的官方提供的额过滤器参考:
https://jinja.palletsprojects.com/en/2.10.x/templates/#builtin-filters
使用过滤器处理数据
https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html
过滤器有很多,包括Jinja2的标准过滤器,和Red Hat Ansible Engine提供的其他过滤器。本节只概述了部分过滤器。
内置过滤器清单
检查变量是否定义
mandatory
ansible默认情况下引用未定义的变量,则失败并中止执行Ansible Playbook。为了避免这种情况,可以设置在ansible.cfg的defaults块中设置error_on_undefined_vars为false,忽略未定义变量。
[defaults]
error_on_undefined_vars=false
......
---
- name: test mandatory
hosts: servera
tasks:
- name: show value
debug:
msg: "{
{ my_key }}"
在忽略未定义变量情况下,我们又需要部分变量必须定义,则失败并中止执行Ansible Playbook。可以使用mandatory插件实现。
---
- name: test mandatory
hosts: servera
tasks:
- name: show value
debug:
msg: "{
{ my_key | mandatory }}"
default
{
{ my_value | default("laoma") }}
- 如果变量未定义,则此过滤器会将其设置为括号中指定的值。
- 如果变量已定义,则此过滤器不会对变量结果处理。
{
{ my_value | default("laoma", True) }}
- 如果变量未定义,定义一个空值或定义False值,则此过滤器会将其设置为括号中指定的值。其他情况,过滤器不会对变量结果处理。
示例:
---
- name: test filter
hosts: servera
gather_facts: false
vars:
#myname: laowang
#myname: False
#myname:
tasks:
- name: Show myname
debug:
msg: "{
{ myname | default('laoma') }}"
#msg: "{
{ myname | default('laoma', True) }}"
default过滤器也可以使用特殊值omit。
- 如果变量没有值,则使用该变量的选项无效。
- 如果变量有值,将使用该变量的选项生效。
示例:
---
- name: test filter
hosts: servera
gather_facts: false
vars:
#primary_group: wheel
tasks:
- name: Ensure user jonfoo exists.
user:
name: jonfoo
group: "{
{ primary_group | default(omit) }}"
执行数学计算
Jinja2提供了许多可以对数字进行运算的数学过滤器。 您还可以对数字执行一些基本的数学计算:
| OPERATOR | PURPOSE |
|---|---|
| + | Add two numbers |
| - | Subtract two numbers |
| / | Perform floating point division |
| // | Perform integer division |
| % | Get the remainder of integer division |
| * | Multiply two numbers |
| ** | Raise the left number to the power of the right number |
[student@workstation laoma]$ ansible servera -m debug -a 'msg="{
{ ( 4 + 6 * 2 ) // 2 -3 }}"'
servera | SUCCESS => {
"msg": "5"
}
[student@workstation laoma]$ ansible servera -m debug -a 'msg="{
{ ( 4 ** 3 ) % 5 / 3 }}"'
servera | SUCCESS => {
"msg": "1.3333333333333333"
}
还有许多过滤器可以对数字执行数学运算,例如abs和round。
[student@workstation laoma]$ ansible servera -m debug -a 'msg="{
{ -1764 | abs }}"'
localhost | SUCCESS => {
"msg": "1764"
}
[student@workstation laoma]$ ansible servera -m debug -a 'msg="{
{ 1764.64 |int }}"'
servera | SUCCESS => {
"msg": "1764"
}
[student@workstation laoma]$ ansible servera -m debug -a 'msg="{
{ 1764.64 | round }}"'
servera | SUCCESS => {
"msg": "1765.0"
}
在某些情况下,您可能首先需要使用int过滤器将该值转换为整数,还可以使用float过滤器将其转换为float。
例如,以下Jinja2表达式将一个小时数添加到当前小时数,该小时数作为事实收集并存储为字符串而不是整数:
---
- name: Debug Play
hosts: servera
tasks:
- name: Debug
debug:
msg: "{
{ ansible_facts['date_time']['hour'] + '1' }}"
#msg: "{
{ ( ansible_facts['date_time']['hour'] | int ) + 1 }}"
操作列表
您可以使用许多过滤器来分析和处理列表。 如果列表由数字组成,则可以使用max,min或sum来查找所有列表项的最大数字,最小数字和总和。
---
- name: Debug Play
hosts: servera
gather_facts: no
tasks:
- name: debug variables
debug:
msg: >
sum: "{
{ [2, 4, 6, 8, 10, 12] | sum }}"
min: "{
{ [2, 4, 6, 8, 10, 12] | min }}"
max: "{
{ [2, 4, 6, 8, 10, 12] | max }}"
- name: All three of these assertions are true
assert:
that:
- "{
{ [ 2, 4, 6, 8, 10, 12 ] | sum }} is eq( 42 )"
- "{
{ [ 2, 4, 6, 8, 10, 12 ] | min }} is eq( 2 )"
- "{
{ [ 2, 4, 6, 8, 10, 12 ] | max }} is eq( 12 )"
可以获得有关列表内容的信息,例如first、last、length、random。
---
- name: Debug Play
hosts: servera
gather_facts: no
tasks:
- name: debug variables
debug:
msg: >
length: "{
{ [2, 4, 6, 8, 10, 12] | length }}"
first: "{
{ [2, 4, 6, 8, 10, 12] | first }}"
last: "{
{ [2, 4, 6, 8, 10, 12] | last }}"
random: "{
{ [2, 4, 6, 8, 10, 12] | random }}"
- name: All three of these assertions are true
assert:
that:
- "{
{ [ 2, 4, 6, 8, 10, 12 ] | length }} is eq( 6 )"
- "{
{ [ 2, 4, 6, 8, 10, 12 ] | first }} is eq( 2 )"
- "{
{ [ 2, 4, 6, 8, 10, 12 ] | last }} is eq( 12 )"
修改列表元素的顺序
列表可以通过几种方式重新排序。
- sort 过滤器,返回一个自然排序的列表。
- revert 过滤器,返回一个顺序与原始顺序相反的列表。
- shuffle 过滤器,返回一个随机排序的列表。
---
- name: Debug Play
hosts: servera
gather_facts: no
tasks:
- name: debug variables
debug:
msg: >
reverse: {
{ [ 2, 4, 6, 8, 10 ] | reverse | list }}
sort: {
{ [ 4, 8, 10, 6, 2 ] | sort | list }}
shuffle: {
{ [ 4, 8, 10, 6, 2 ] | shuffle | list }}
- name: reversing and sorting lists
assert:
that:
- "{
{ [ 2, 4, 6, 8, 10 ] | reverse | list }} is eq( [ 10, 8, 6, 4, 2] )"
- "{
{ [ 4, 8, 10, 6, 2 ] | sort | list }} is eq( [ 2, 4, 6, 8, 10 ] )"
有时需要将多个列表合并为一个列表。
flatten过滤器以递归方式获取输入列表值中的任何内部列表,并将内部值添加到外部列表中。

最低0.47元/天 解锁文章
1218

被折叠的 条评论
为什么被折叠?



