使用过滤器处理数据
过滤器允许您将JSON数据转换为YAML数据,分割URL以提取主机名,获取字符串的SHA1哈希值,添加或乘以整数等等。您可以使用此处记录的Ansible特定过滤器来处理您的数据,或者使用Jinja2附带的任何标准过滤器 - 请参阅官方Jinja2模板文档中内置过滤器列表。您还可以使用Python方法来转换数据。您可以创建自定义Ansible过滤器作为插件,尽管我们通常欢迎将新的过滤器添加到ansible-core存储库中,以便每个人都可以使用它们。
因为模板化发生在Ansible控制节点上,**而不是**目标主机上,所以过滤器在控制节点上执行并在本地转换数据。
处理未定义变量
过滤器可以通过提供默认值或使某些变量可选来帮助您管理丢失或未定义的变量。如果您将Ansible配置为忽略大多数未定义变量,则可以使用mandatory
过滤器将某些变量标记为需要值。
提供默认值
您可以使用Jinja2的“default”过滤器直接在模板中为变量提供默认值。这通常比在未定义变量时失败更好的方法。
{{ some_variable | default(5) }}
在上面的示例中,如果变量“some_variable”未定义,Ansible将使用默认值5,而不是引发“未定义变量”错误并失败。如果您在角色中工作,还可以添加角色默认值来定义角色中变量的默认值。要了解有关角色默认值的更多信息,请参阅角色目录结构。
从2.8版本开始,尝试访问Jinja中Undefined值的属性将返回另一个Undefined值,而不是立即抛出错误。这意味着您现在可以简单地在嵌套数据结构中使用带有值的默认值(换句话说,{{ foo.bar.baz | default('DEFAULT') }}
),而无需知道中间值是否已定义。
如果要在变量计算结果为false或空字符串时使用默认值,则必须将第二个参数设置为true
{{ lookup('env', 'MY_USER') | default('admin', true) }}
使变量可选
默认情况下,Ansible要求模板表达式中的所有变量都具有值。但是,您可以使特定模块变量可选。例如,您可能希望使用系统默认值来处理一些项目并控制其他项目的值。要使模块变量可选,请将默认值设置为特殊变量omit
- name: Touch files with an optional mode
ansible.builtin.file:
dest: "{{ item.path }}"
state: touch
mode: "{{ item.mode | default(omit) }}"
loop:
- path: /tmp/foo
- path: /tmp/bar
- path: /tmp/baz
mode: "0444"
在此示例中,文件/tmp/foo
和/tmp/bar
的默认模式由系统的umask决定。Ansible不会为mode
发送值。只有第三个文件/tmp/baz
收到mode=0444选项。
注意
如果您在default(omit)
过滤器之后“链接”其他过滤器,则应执行以下操作:"{{ foo | default(None) | some_filter or omit }}"
。在此示例中,默认None
(Python空值)值将导致后面的过滤器失败,这将触发or omit
逻辑部分。但是,以这种方式使用omit
非常特定于您要链接的后续过滤器,因此如果您这样做,请做好一些反复试验的准备。
定义必填值
如果您将Ansible配置为忽略未定义的变量,则可能需要将某些值定义为必填值。默认情况下,如果您的playbook或命令中的变量未定义,Ansible将失败。您可以通过将DEFAULT_UNDEFINED_VAR_BEHAVIOR设置为false
来配置Ansible以允许未定义的变量。在这种情况下,您可能希望要求定义某些变量。您可以使用
{{ variable | mandatory }}
变量值将按原样使用,但如果变量未定义,则模板评估将引发错误。
一种方便的需要覆盖变量的方法是使用undef()函数为其提供未定义的值。
galaxy_url: "https://galaxy.ansible.com"
galaxy_api_key: "{{ undef(hint='You must specify your Galaxy API key') }}"
定义true/false/null的不同值(三元运算)
您可以创建一个测试,然后定义一个值在测试返回true时使用,另一个值在测试返回false时使用(1.9版新增)。
{{ (status == 'needs_restart') | ternary('restart', 'continue') }}
此外,您可以定义一个值用于true,一个值用于false,以及一个值用于null(2.8版新增)。
{{ enabled | ternary('no shutdown', 'shutdown', omit) }}
管理数据类型
您可能需要了解、更改或设置变量的数据类型。例如,已注册的变量在您的下一个任务需要列表时可能包含字典,或者用户提示在您的剧本需要布尔值时可能返回字符串。使用ansible.builtin.type_debug、ansible.builtin.dict2items和ansible.builtin.items2dict过滤器来管理数据类型。您也可以使用数据类型本身将值强制转换为特定数据类型。
发现数据类型
2.3 版本新增。
如果您不确定变量的底层 Python 类型,可以使用ansible.builtin.type_debug过滤器来显示它。这在需要特定类型变量的调试时非常有用。
{{ myvar | type_debug }}
您应该注意,虽然这看起来像是一个用于检查变量中是否具有正确数据类型的有用过滤器,但您通常应该更倾向于使用类型测试,它允许您测试特定数据类型。
将字符串转换为列表
使用ansible.builtin.split过滤器将字符/字符串分隔的字符串转换为适合循环的项目列表。例如,如果您想用逗号分割字符串变量fruits,您可以使用:
{{ fruits | split(',') }}
字符串数据(应用ansible.builtin.split过滤器之前)
fruits: apple,banana,orange
列表数据(应用ansible.builtin.split过滤器之后)
- apple
- banana
- orange
将字典转换为列表
2.6 版本新增。
使用ansible.builtin.dict2items过滤器将字典转换为适合循环的项目列表。
{{ dict | dict2items }}
字典数据(应用ansible.builtin.dict2items过滤器之前)
tags:
Application: payment
Environment: dev
列表数据(应用ansible.builtin.dict2items过滤器之后)
- key: Application
value: payment
- key: Environment
value: dev
2.8 版本新增。
ansible.builtin.dict2items过滤器是ansible.builtin.items2dict过滤器的反向操作。
如果您想配置键的名称,ansible.builtin.dict2items过滤器接受2个关键字参数。传递key_name
和value_name
参数来配置列表输出中键的名称。
{{ files | dict2items(key_name='file', value_name='path') }}
字典数据(应用ansible.builtin.dict2items过滤器之前)
files:
users: /etc/passwd
groups: /etc/group
列表数据(应用ansible.builtin.dict2items过滤器之后)
- file: users
path: /etc/passwd
- file: groups
path: /etc/group
将列表转换为字典
2.7 版本新增。
使用ansible.builtin.items2dict过滤器将列表转换为字典,并将内容映射到key: value
对。
{{ tags | items2dict }}
列表数据(应用ansible.builtin.items2dict过滤器之前)
tags:
- key: Application
value: payment
- key: Environment
value: dev
字典数据(应用ansible.builtin.items2dict过滤器之后)
Application: payment
Environment: dev
ansible.builtin.items2dict过滤器是ansible.builtin.dict2items过滤器的反向操作。
并非所有列表都使用key
来指定键和value
来指定值。例如:
fruits:
- fruit: apple
color: red
- fruit: pear
color: yellow
- fruit: grapefruit
color: yellow
在此示例中,您必须传递key_name
和value_name
参数来配置转换。例如:
{{ fruits | items2dict(key_name='fruit', value_name='color') }}
如果您不传递这些参数,或者没有为您的列表传递正确的值,您将看到KeyError: key
或KeyError: my_typo
。
强制数据类型
您可以将值强制转换为某些类型。例如,如果您期望从vars_prompt输入“True”,并且您希望 Ansible 将其识别为布尔值而不是字符串:
- ansible.builtin.debug:
msg: test
when: some_string_value | bool
如果您想对事实进行数学比较,并且您希望 Ansible 将其识别为整数而不是字符串:
- shell: echo "only on Red Hat 6, derivatives, and later"
when: ansible_facts['os_family'] == "RedHat" and ansible_facts['lsb']['major_release'] | int >= 6
1.6 版本新增。
数据格式:YAML 和 JSON
您可以使用模板将数据结构在 JSON 或 YAML 格式之间切换,并提供格式化、缩进和加载数据的选项。这些基本过滤器偶尔可用于调试。
{{ some_variable | to_json }}
{{ some_variable | to_yaml }}
有关这些过滤器的文档,请参阅ansible.builtin.to_json和ansible.builtin.to_yaml。
对于易于阅读的输出,您可以使用:
{{ some_variable | to_nice_json }}
{{ some_variable | to_nice_yaml }}
有关这些过滤器的文档,请参阅ansible.builtin.to_nice_json和ansible.builtin.to_nice_yaml。
您可以更改任一格式的缩进:
{{ some_variable | to_nice_json(indent=2) }}
{{ some_variable | to_nice_yaml(indent=8) }}
ansible.builtin.to_yaml和ansible.builtin.to_nice_yaml过滤器使用PyYAML 库,该库具有默认的 80 个字符字符串长度限制。这会导致在第 80 个字符后出现意外换行符(如果第 80 个字符后有空格)。为了避免这种行为并生成长行,请使用width
选项。您必须使用硬编码数字来定义宽度,而不是像float("inf")
这样的结构,因为过滤器不支持代理 Python 函数。例如:
{{ some_variable | to_yaml(indent=8, width=1337) }}
{{ some_variable | to_nice_yaml(indent=8, width=1337) }}
该过滤器支持传递其他 YAML 参数。有关完整列表,请参阅PyYAML 文档中的dump()
。
如果您正在读取一些已格式化的数据:
{{ some_variable | from_json }}
{{ some_variable | from_yaml }}
例如:
tasks:
- name: Register JSON output as a variable
ansible.builtin.shell: cat /some/path/to/file.json
register: result
- name: Set a variable
ansible.builtin.set_fact:
myvar: "{{ result.stdout | from_json }}"
过滤器to_json和Unicode支持
默认情况下,ansible.builtin.to_json和ansible.builtin.to_nice_json会将接收到的数据转换为 ASCII,因此:
{{ 'München'| to_json }}
将返回:
'M\u00fcnchen'
要保留 Unicode 字符,请将参数ensure_ascii=False
传递给过滤器。
{{ 'München'| to_json(ensure_ascii=False) }}
'München'
2.7 版本新增。
为了解析多文档 YAML 字符串,提供了ansible.builtin.from_yaml_all过滤器。ansible.builtin.from_yaml_all过滤器将返回解析的 YAML 文档的生成器。
例如:
tasks:
- name: Register a file content as a variable
ansible.builtin.shell: cat /some/path/to/multidoc-file.yaml
register: result
- name: Print the transformed variable
ansible.builtin.debug:
msg: '{{ item }}'
loop: '{{ result.stdout | from_yaml_all | list }}'
组合和选择数据
您可以组合来自多个来源和类型的數據,并从大型数据结构中选择值,从而精确控制复杂数据。
组合来自多个列表的项目:zip 和 zip_longest
2.3 版本新增。
要获取组合其他列表元素的列表,请使用ansible.builtin.zip
- name: Give me list combo of two lists
ansible.builtin.debug:
msg: "{{ [1,2,3,4,5,6] | zip(['a','b','c','d','e','f']) | list }}"
# => [[1, "a"], [2, "b"], [3, "c"], [4, "d"], [5, "e"], [6, "f"]]
- name: Give me the shortest combo of two lists
ansible.builtin.debug:
msg: "{{ [1,2,3] | zip(['a','b','c','d','e','f']) | list }}"
# => [[1, "a"], [2, "b"], [3, "c"]]
要始终遍历所有列表,请使用ansible.builtin.zip_longest
- name: Give me the longest combo of three lists, fill with X
ansible.builtin.debug:
msg: "{{ [1,2,3] | zip_longest(['a','b','c','d','e','f'], [21, 22, 23], fillvalue='X') | list }}"
# => [[1, "a", 21], [2, "b", 22], [3, "c", 23], ["X", "d", "X"], ["X", "e", "X"], ["X", "f", "X"]]
与上面提到的ansible.builtin.items2dict 过滤器输出类似,这些过滤器可用于构建dict
{{ dict(keys_list | zip(values_list)) }}
列表数据(应用ansible.builtin.zip 过滤器之前)
keys_list:
- one
- two
values_list:
- apple
- orange
字典数据(应用ansible.builtin.zip 过滤器之后)
one: apple
two: orange
组合对象和子元素
2.7 版本新增。
ansible.builtin.subelements 过滤器生成对象及其子元素值的乘积,类似于ansible.builtin.subelements 查询。这允许您指定要在模板中使用的各个子元素。例如,此表达式
{{ users | subelements('groups', skip_missing=True) }}
应用ansible.builtin.subelements 过滤器之前的數據
users:
- name: alice
authorized:
- /tmp/alice/onekey.pub
- /tmp/alice/twokey.pub
groups:
- wheel
- docker
- name: bob
authorized:
- /tmp/bob/id_rsa.pub
groups:
- docker
应用ansible.builtin.subelements 过滤器之后的數據
-
- name: alice
groups:
- wheel
- docker
authorized:
- /tmp/alice/onekey.pub
- /tmp/alice/twokey.pub
- wheel
-
- name: alice
groups:
- wheel
- docker
authorized:
- /tmp/alice/onekey.pub
- /tmp/alice/twokey.pub
- docker
-
- name: bob
authorized:
- /tmp/bob/id_rsa.pub
groups:
- docker
- docker
您可以将转换后的数据与loop
一起使用,以迭代多个对象的相同子元素
- name: Set authorized ssh key, extracting just that data from 'users'
ansible.posix.authorized_key:
user: "{{ item.0.name }}"
key: "{{ lookup('file', item.1) }}"
loop: "{{ users | subelements('authorized') }}"
组合哈希/字典
2.0 版本中的新功能。
ansible.builtin.combine 过滤器允许合并哈希。例如,以下操作将覆盖一个哈希中的键
{{ {'a':1, 'b':2} | combine({'b':3}) }}
生成的哈希将是
{'a':1, 'b':3}
过滤器还可以接受多个参数进行合并
{{ a | combine(b, c, d) }}
{{ [a, b, c, d] | combine }}
在这种情况下,d
中的键将覆盖c
中的键,后者将覆盖b
中的键,依此类推。
该过滤器还接受两个可选参数:recursive
和 list_merge
。
- recursive
是一个布尔值,默认为
False
。ansible.builtin.combine 是否应递归合并嵌套哈希。注意:它**不**依赖于ansible.cfg
中hash_behaviour
设置的值。- list_merge
是一个字符串,其可能的值为
replace
(默认)、keep
、append
、prepend
、append_rp
或prepend_rp
。当要合并的哈希包含数组/列表时,它会修改ansible.builtin.combine 的行为。
default:
a:
x: default
y: default
b: default
c: default
patch:
a:
y: patch
z: patch
b: patch
如果recursive=False
(默认值),则不会合并嵌套哈希
{{ default | combine(patch) }}
这将导致
a:
y: patch
z: patch
b: patch
c: default
如果recursive=True
,则递归进入嵌套哈希并合并它们的键
{{ default | combine(patch, recursive=True) }}
这将导致
a:
x: default
y: patch
z: patch
b: patch
c: default
如果list_merge='replace'
(默认值),则右侧哈希中的数组将“替换”左侧哈希中的数组
default:
a:
- default
patch:
a:
- patch
{{ default | combine(patch) }}
这将导致
a:
- patch
如果list_merge='keep'
,则将保留左侧哈希中的数组
{{ default | combine(patch, list_merge='keep') }}
这将导致
a:
- default
如果list_merge='append'
,则右侧哈希中的数组将附加到左侧哈希中的数组
{{ default | combine(patch, list_merge='append') }}
这将导致
a:
- default
- patch
如果list_merge='prepend'
,则右侧哈希中的数组将添加到左侧哈希中的数组前面
{{ default | combine(patch, list_merge='prepend') }}
这将导致
a:
- patch
- default
如果list_merge='append_rp'
,则右侧哈希中的数组将附加到左侧哈希中的数组。左侧哈希中也出现在右侧哈希相应数组中的数组元素将被删除(“rp”代表“remove present”)。哈希中都不存在的重复元素将被保留
default:
a:
- 1
- 1
- 2
- 3
patch:
a:
- 3
- 4
- 5
- 5
{{ default | combine(patch, list_merge='append_rp') }}
这将导致
a:
- 1
- 1
- 2
- 3
- 4
- 5
- 5
如果list_merge='prepend_rp'
,则行为类似于append_rp
,但右侧哈希中的数组元素将被添加到前面
{{ default | combine(patch, list_merge='prepend_rp') }}
这将导致
a:
- 3
- 4
- 5
- 5
- 1
- 1
- 2
recursive
和 list_merge
可以一起使用
default:
a:
a':
x: default_value
y: default_value
list:
- default_value
b:
- 1
- 1
- 2
- 3
patch:
a:
a':
y: patch_value
z: patch_value
list:
- patch_value
b:
- 3
- 4
- 4
- key: value
{{ default | combine(patch, recursive=True, list_merge='append_rp') }}
这将导致
a:
a':
x: default_value
y: patch_value
z: patch_value
list:
- default_value
- patch_value
b:
- 1
- 1
- 2
- 3
- 4
- 4
- key: value
从数组或哈希表中选择值
2.1 版本中的新功能。
使用extract 过滤器将索引列表映射到容器(哈希或数组)中的值列表
{{ [0,2] | map('extract', ['x','y','z']) | list }}
{{ ['x','y'] | map('extract', {'x': 42, 'y': 31}) | list }}
上述表达式的结果将是
['x', 'z']
[42, 31]
过滤器可以接受另一个参数
{{ groups['x'] | map('extract', hostvars, 'ec2_ip_address') | list }}
这将获取“x”组中的主机列表,在hostvars中查找它们,然后查找结果的ec2_ip_address。“x”组中主机的最终结果是 IP 地址列表。
过滤器的第三个参数也可以是列表,用于在容器内进行递归查找
{{ ['a'] | map('extract', b, ['x','y']) | list }}
这将返回一个包含b['a']['x']['y']值的列表。
组合列表
这组过滤器返回组合列表的列表。
排列
要获取列表的排列
- name: Give me the largest permutations (order matters)
ansible.builtin.debug:
msg: "{{ [1,2,3,4,5] | ansible.builtin.permutations | list }}"
- name: Give me permutations of sets of three
ansible.builtin.debug:
msg: "{{ [1,2,3,4,5] | ansible.builtin.permutations(3) | list }}"
组合
组合始终需要一个集合大小
- name: Give me combinations for sets of two
ansible.builtin.debug:
msg: "{{ [1,2,3,4,5] | ansible.builtin.combinations(2) | list }}"
另请参见zip_filter
乘积
乘积过滤器返回输入可迭代对象的笛卡尔积。这大致相当于生成器表达式中的嵌套 for 循环。
例如
- name: Generate multiple hostnames
ansible.builtin.debug:
msg: "{{ ['foo', 'bar'] | product(['com']) | map('join', '.') | join(',') }}"
这将导致
{ "msg": "foo.com,bar.com" }
选择 JSON 数据:JSON 查询
要从 JSON 格式的复杂数据结构(例如 Ansible facts)中选择单个元素或数据子集,请使用community.general.json_query 过滤器。community.general.json_query 过滤器允许您查询复杂的 JSON 结构并使用循环结构对其进行迭代。
注意
此过滤器已迁移到 community.general 集合。请遵循安装说明安装该集合。
注意
在使用此过滤器之前,必须在 Ansible 控制节点上手动安装 **jmespath** 依赖项。此过滤器基于 **jmespath** 构建,您可以使用相同的语法。有关示例,请参见 jmespath 示例。
考虑以下数据结构
{
"domain": {
"cluster": [
{
"name": "cluster1"
},
{
"name": "cluster2"
}
],
"server": [
{
"name": "server11",
"cluster": "cluster1",
"port": "8080"
},
{
"name": "server12",
"cluster": "cluster1",
"port": "8090"
},
{
"name": "server21",
"cluster": "cluster2",
"port": "9080"
},
{
"name": "server22",
"cluster": "cluster2",
"port": "9090"
}
],
"library": [
{
"name": "lib1",
"target": "cluster1"
},
{
"name": "lib2",
"target": "cluster2"
}
]
}
}
要从此结构中提取所有集群,可以使用以下查询
- name: Display all cluster names
ansible.builtin.debug:
var: item
loop: "{{ domain_definition | community.general.json_query('domain.cluster[*].name') }}"
要提取所有服务器名称
- name: Display all server names
ansible.builtin.debug:
var: item
loop: "{{ domain_definition | community.general.json_query('domain.server[*].name') }}"
要从 cluster1 提取端口
- name: Display all ports from cluster1
ansible.builtin.debug:
var: item
loop: "{{ domain_definition | community.general.json_query(server_name_cluster1_query) }}"
vars:
server_name_cluster1_query: "domain.server[?cluster=='cluster1'].port"
注意
您可以使用变量使查询更易读。
要以逗号分隔的字符串形式打印 cluster1 的端口
- name: Display all ports from cluster1 as a string
ansible.builtin.debug:
msg: "{{ domain_definition | community.general.json_query('domain.server[?cluster==`cluster1`].port') | join(', ') }}"
注意
在上面的示例中,使用反引号引用文字可以避免转义引号并保持可读性。
您可以使用 YAML 单引号转义
- name: Display all ports from cluster1
ansible.builtin.debug:
var: item
loop: "{{ domain_definition | community.general.json_query('domain.server[?cluster==''cluster1''].port') }}"
注意
在 YAML 中,单引号内的单引号转义是通过将单引号加倍来完成的。
要获取包含集群所有端口和名称的哈希映射
- name: Display all server ports and names from cluster1
ansible.builtin.debug:
var: item
loop: "{{ domain_definition | community.general.json_query(server_name_cluster1_query) }}"
vars:
server_name_cluster1_query: "domain.server[?cluster=='cluster1'].{name: name, port: port}"
要提取名称以“server1”开头的所有集群的端口
- name: Display ports from all clusters with the name starting with 'server1'
ansible.builtin.debug:
msg: "{{ domain_definition | to_json | from_json | community.general.json_query(server_name_query) }}"
vars:
server_name_query: "domain.server[?starts_with(name,'server1')].port"
要提取名称包含“server1”的所有集群的端口
- name: Display ports from all clusters with the name containing 'server1'
ansible.builtin.debug:
msg: "{{ domain_definition | to_json | from_json | community.general.json_query(server_name_query) }}"
vars:
server_name_query: "domain.server[?contains(name,'server1')].port"
注意
使用 starts_with
和 contains
时,必须使用 `` to_json | from_json `` 过滤器才能正确解析数据结构。
随机化数据
当您需要随机生成的值时,请使用以下过滤器之一。
随机 MAC 地址
2.6 版本新增。
此过滤器可用于根据字符串前缀生成随机 MAC 地址。
注意
此过滤器已迁移到 community.general 集合。请遵循安装说明安装该集合。
要从以“52:54:00”开头的字符串前缀获取随机 MAC 地址
"{{ '52:54:00' | community.general.random_mac }}"
# => '52:54:00:ef:1c:03'
请注意,如果前缀字符串有任何错误,过滤器将发出错误。
2.9 版中的新增功能。
从 Ansible 2.9 版开始,您还可以从种子初始化随机数生成器以创建随机但幂等的 MAC 地址
"{{ '52:54:00' | community.general.random_mac(seed=inventory_hostname) }}"
随机项目或数字
Ansible 中的 ansible.builtin.random 过滤器是默认 Jinja2 随机过滤器的扩展,可用于从一系列项目中返回随机项目或根据范围生成随机数。
要从列表中获取随机项目
"{{ ['a','b','c'] | random }}"
# => 'c'
要获取 0(包含)到指定整数(不包含)之间的随机数
"{{ 60 | random }} * * * * root /script/from/cron"
# => '21 * * * * root /script/from/cron'
要获取 0 到 100 之间的随机数,但步长为 10
{{ 101 | random(step=10) }}
# => 70
要获取 1 到 100 之间的随机数,但步长为 10
{{ 101 | random(1, 10) }}
# => 31
{{ 101 | random(start=1, step=10) }}
# => 51
您可以从种子初始化随机数生成器以创建随机但幂等的数字
"{{ 60 | random(seed=inventory_hostname) }} * * * * root /script/from/cron"
随机排列列表
ansible.builtin.shuffle 过滤器会随机化现有列表,每次调用都会给出不同的顺序。
要从现有列表中获取随机列表
{{ ['a','b','c'] | shuffle }}
# => ['c','a','b']
{{ ['a','b','c'] | shuffle }}
# => ['b','c','a']
您可以从种子初始化随机排列生成器以生成随机但幂等的顺序
{{ ['a','b','c'] | shuffle(seed=inventory_hostname) }}
# => ['b','a','c']
shuffle 过滤器尽可能返回列表。如果将其与非“列表化”项目一起使用,则过滤器将不执行任何操作。
管理列表变量
您可以搜索列表中的最小值或最大值,或展平多级列表。
要从数字列表中获取最小值
{{ list1 | min }}
2.11 版中的新增功能。
要获取对象列表中的最小值
{{ [{'val': 1}, {'val': 2}] | min(attribute='val') }}
要从数字列表中获取最大值
{{ [3, 4, 2] | max }}
2.11 版中的新增功能。
要获取对象列表中的最大值
{{ [{'val': 1}, {'val': 2}] | max(attribute='val') }}
2.5 版中的新增功能。
展平列表(与 flatten 查找执行的操作相同)
{{ [3, [4, 2] ] | flatten }}
# => [3, 4, 2]
仅展平列表的第一级(类似于 items 查找)
{{ [3, [4, [2]] ] | flatten(levels=1) }}
# => [3, 4, [2]]
2.11 版中的新增功能。
保留列表中的空值,默认情况下,flatten 会移除它们。
{{ [3, None, [4, [2]] ] | flatten(levels=1, skip_nulls=False) }}
# => [3, None, 4, [2]]
从集合或列表中选择(集合论)
您可以从集合或列表中选择或组合项目。
1.4 版中的新增功能。
要从列表中获取唯一集合
# list1: [1, 2, 5, 1, 3, 4, 10]
{{ list1 | unique }}
# => [1, 2, 5, 3, 4, 10]
要获取两个列表的并集
# list1: [1, 2, 5, 1, 3, 4, 10]
# list2: [1, 2, 3, 4, 5, 11, 99]
{{ list1 | union(list2) }}
# => [1, 2, 5, 1, 3, 4, 10, 11, 99]
要获取两个列表的交集(两个列表中所有项目的唯一列表)
# list1: [1, 2, 5, 3, 4, 10]
# list2: [1, 2, 3, 4, 5, 11, 99]
{{ list1 | intersect(list2) }}
# => [1, 2, 5, 3, 4]
要获取两个列表的差集(列表 1 中不存在于列表 2 中的项目)
# list1: [1, 2, 5, 1, 3, 4, 10]
# list2: [1, 2, 3, 4, 5, 11, 99]
{{ list1 | difference(list2) }}
# => [10]
要获取两个列表的对称差集(每个列表独有的项目)
# list1: [1, 2, 5, 1, 3, 4, 10]
# list2: [1, 2, 3, 4, 5, 11, 99]
{{ list1 | symmetric_difference(list2) }}
# => [10, 11, 99]
计算数字(数学)
1.9 版中的新增功能。
您可以使用 Ansible 过滤器计算数字的对数、幂和根。Jinja2 提供其他数学函数,例如 abs() 和 round()。
获取对数(默认为 e)
{{ 8 | log }}
# => 2.0794415416798357
获取以 10 为底的对数
{{ 8 | log(10) }}
# => 0.9030899869919435
给我 2 的幂!(或 5)
{{ 8 | pow(5) }}
# => 32768.0
平方根或 5 次方根
{{ 8 | root }}
# => 2.8284271247461903
{{ 8 | root(5) }}
# => 1.5157165665103982
管理网络交互
这些过滤器可以帮助您完成常见的网络任务。
注意
这些过滤器已迁移到 ansible.utils 集合。请遵循安装说明安装该集合。
IP 地址过滤器
1.9 版中的新增功能。
测试字符串是否为有效的 IP 地址
{{ myvar | ansible.utils.ipaddr }}
您还可以要求特定的 IP 协议版本
{{ myvar | ansible.utils.ipv4 }}
{{ myvar | ansible.utils.ipv6 }}
IP 地址过滤器还可以用于从 IP 地址中提取特定信息。例如,要从 CIDR 获取 IP 地址本身,可以使用
{{ '192.0.2.1/24' | ansible.utils.ipaddr('address') }}
# => 192.0.2.1
有关 ansible.utils.ipaddr 过滤器的更多信息和完整的用法指南,请参见 Ansible.Utils。
网络 CLI 过滤器
2.4 版中的新增功能。
要将网络设备 CLI 命令的输出转换为结构化的 JSON 输出,请使用 ansible.netcommon.parse_cli 过滤器
{{ output | ansible.netcommon.parse_cli('path/to/spec') }}
ansible.netcommon.parse_cli 过滤器将加载规范文件并将命令输出传递到该文件中,返回 JSON 输出。YAML 规范文件定义了如何解析 CLI 输出。
规范文件应为格式正确的 YAML 文件。它定义了如何解析 CLI 输出并返回 JSON 数据。下面是一个有效的规范文件示例,它将解析 show vlan
命令的输出。
---
vars:
vlan:
vlan_id: "{{ item.vlan_id }}"
name: "{{ item.name }}"
enabled: "{{ item.state != 'act/lshut' }}"
state: "{{ item.state }}"
keys:
vlans:
value: "{{ vlan }}"
items: "^(?P<vlan_id>\\d+)\\s+(?P<name>\\w+)\\s+(?P<state>active|act/lshut|suspended)"
state_static:
value: present
上面的规范文件将返回一个 JSON 数据结构,该结构是包含已解析 VLAN 信息的哈希列表。
可以使用 key 和 values 指令将相同的命令解析为哈希。以下是如何使用相同的 show vlan
命令将输出解析为哈希值的一个示例。
---
vars:
vlan:
key: "{{ item.vlan_id }}"
values:
vlan_id: "{{ item.vlan_id }}"
name: "{{ item.name }}"
enabled: "{{ item.state != 'act/lshut' }}"
state: "{{ item.state }}"
keys:
vlans:
value: "{{ vlan }}"
items: "^(?P<vlan_id>\\d+)\\s+(?P<name>\\w+)\\s+(?P<state>active|act/lshut|suspended)"
state_static:
value: present
解析 CLI 命令的另一个常见用例是将大型命令分解为可以解析的块。这可以使用 start_block
和 end_block
指令来完成,将命令分解为可以解析的块。
---
vars:
interface:
name: "{{ item[0].match[0] }}"
state: "{{ item[1].state }}"
mode: "{{ item[2].match[0] }}"
keys:
interfaces:
value: "{{ interface }}"
start_block: "^Ethernet.*$"
end_block: "^$"
items:
- "^(?P<name>Ethernet\\d\\/\\d*)"
- "admin state is (?P<state>.+),"
- "Port mode is (.+)"
上面的示例将 show interface
的输出解析为哈希列表。
网络过滤器还支持使用 TextFSM 库解析 CLI 命令的输出。要使用 TextFSM 解析 CLI 输出,请使用以下过滤器
{{ output.stdout[0] | ansible.netcommon.parse_cli_textfsm('path/to/fsm') }}
使用 TextFSM 过滤器需要安装 TextFSM 库。
网络 XML 过滤器
2.5 版中的新增功能。
要将网络设备命令的 XML 输出转换为结构化的 JSON 输出,请使用 ansible.netcommon.parse_xml 过滤器
{{ output | ansible.netcommon.parse_xml('path/to/spec') }}
ansible.netcommon.parse_xml 过滤器将加载规范文件并将命令输出传递到格式化为 JSON 的文件中。
规范文件应为格式正确的 YAML 文件。它定义了如何解析 XML 输出并返回 JSON 数据。
下面是一个有效的规范文件示例,它将解析 show vlan | display xml
命令的输出。
---
vars:
vlan:
vlan_id: "{{ item.vlan_id }}"
name: "{{ item.name }}"
desc: "{{ item.desc }}"
enabled: "{{ item.state.get('inactive') != 'inactive' }}"
state: "{% if item.state.get('inactive') == 'inactive'%} inactive {% else %} active {% endif %}"
keys:
vlans:
value: "{{ vlan }}"
top: configuration/vlans/vlan
items:
vlan_id: vlan-id
name: name
desc: description
state: ".[@inactive='inactive']"
上面的规范文件将返回一个 JSON 数据结构,该结构是包含已解析 VLAN 信息的哈希列表。
可以使用 key 和 values 指令将相同的命令解析为哈希。以下是如何使用相同的 show vlan | display xml
命令将输出解析为哈希值的一个示例。
---
vars:
vlan:
key: "{{ item.vlan_id }}"
values:
vlan_id: "{{ item.vlan_id }}"
name: "{{ item.name }}"
desc: "{{ item.desc }}"
enabled: "{{ item.state.get('inactive') != 'inactive' }}"
state: "{% if item.state.get('inactive') == 'inactive'%} inactive {% else %} active {% endif %}"
keys:
vlans:
value: "{{ vlan }}"
top: configuration/vlans/vlan
items:
vlan_id: vlan-id
name: name
desc: description
state: ".[@inactive='inactive']"
top
的值是相对于XML根节点的XPath表达式。在下面的示例XML输出中,top
的值为configuration/vlans/vlan
,这是一个相对于根节点(`top
值中的configuration
是最外层的容器节点,vlan
是最内层的容器节点。
items
是一个键值对字典,它将用户定义的名称映射到选择元素的XPath表达式。XPath表达式相对于top
中包含的XPath值。例如,规范文件中的vlan_id
是用户定义的名称,其值vlan-id
是相对于top
中XPath值的相对路径。
可以使用XPath表达式提取XML标签的属性。规范中state
的值是一个XPath表达式,用于获取输出XML中vlan
标签的属性。
<rpc-reply>
<configuration>
<vlans>
<vlan inactive="inactive">
<name>vlan-1</name>
<vlan-id>200</vlan-id>
<description>This is vlan-1</description>
</vlan>
</vlans>
</configuration>
</rpc-reply>
注意
有关支持的XPath表达式的更多信息,请参见XPath 支持。
网络VLAN过滤器
2.8 版本新增。
使用ansible.netcommon.vlan_parser过滤器将VLAN整数的无序列表转换为根据类似IOS的VLAN列表规则排序的整数字符串列表。此列表具有以下属性:
VLAN按升序排列。
三个或更多连续的VLAN用短横线列出。
列表的第一行可以是first_line_len个字符长。
后续列表行可以是other_line_len个字符长。
要排序VLAN列表:
{{ [3003, 3004, 3005, 100, 1688, 3002, 3999] | ansible.netcommon.vlan_parser }}
此示例呈现以下排序列表:
['100,1688,3002-3005,3999']
另一个Jinja模板示例:
{% set parsed_vlans = vlans | ansible.netcommon.vlan_parser %}
switchport trunk allowed vlan {{ parsed_vlans[0] }}
{% for i in range (1, parsed_vlans | count) %}
switchport trunk allowed vlan add {{ parsed_vlans[i] }}
{% endfor %}
这允许在Cisco IOS标记接口上动态生成VLAN列表。您可以存储接口所需确切VLAN的详尽原始列表,然后将其与将实际为配置生成的已解析IOS输出进行比较。
字符串和密码的哈希和加密
1.9 版中的新增功能。
要获取字符串的sha1哈希值:
{{ 'test1' | hash('sha1') }}
# => "b444ac06613fc8d63795be9ad0beaf55011936ac"
要获取字符串的md5哈希值:
{{ 'test1' | hash('md5') }}
# => "5a105e8b9d40e1329780d62ea2265d8a"
获取字符串校验和:
{{ 'test2' | checksum }}
# => "109f4b3c50d7b0df729d299bc6f8e9ef9066971f"
其他哈希(依赖于平台):
{{ 'test2' | hash('blowfish') }}
要获取sha512密码哈希(随机盐):
{{ 'passwordsaresecret' | password_hash('sha512') }}
# => "$6$UIv3676O/ilZzWEE$ktEfFF19NQPF2zyxqxGkAceTnbEgpEKuGBtk6MlU4v2ZorWaVQUMyurgmHCh2Fr4wpmQ/Y.AlXMJkRnIS4RfH/"
要获取具有特定盐的sha256密码哈希:
{{ 'secretpassword' | password_hash('sha256', 'mysecretsalt') }}
# => "$5$mysecretsalt$ReKNyDYjkKNqRVwouShhsEqZ3VOE8eoVO4exihOfvG4"
一种生成每个系统唯一哈希的幂等方法是使用在运行之间一致的盐。
{{ 'secretpassword' | password_hash('sha512', 65534 | random(seed=inventory_hostname) | string) }}
# => "$6$43927$lQxPKz2M2X.NWO.gK.t7phLwOKQMcSq72XxDZQ0XzYV6DlL1OD72h417aj16OnHTGxNzhftXJQBcjbunLEepM0"
可用的哈希类型取决于运行Ansible的控制系统,ansible.builtin.hash依赖于hashlib,ansible.builtin.password_hash依赖于passlib。crypt用作回退,如果未安装passlib
。
2.7 版本新增。
某些哈希类型允许提供rounds参数。
{{ 'secretpassword' | password_hash('sha256', 'mysecretsalt', rounds=10000) }}
# => "$5$rounds=10000$mysecretsalt$Tkm80llAxD4YHll6AgNIztKn0vzAACsuuEfYeGP7tm7"
过滤器`password_hash`产生的结果取决于您是否安装了`passlib`。
为了确保幂等性,请指定`rounds`既不是`crypt`的默认值也不是`passlib`的默认值,对于`crypt`是`5000`,对于`passlib`是可变值(`sha256`为`535000`,`sha512`为`656000`)。
{{ 'secretpassword' | password_hash('sha256', 'mysecretsalt', rounds=5001) }}
# => "$5$rounds=5001$mysecretsalt$wXcTWWXbfcR8er5IVf7NuquLvnUA6s8/qdtOhAZ.xN."
哈希类型“blowfish”(BCrypt)提供了指定BCrypt算法版本的功能。
{{ 'secretpassword' | password_hash('blowfish', '1234567890123456789012', ident='2b') }}
# => "$2b$12$123456789012345678901uuJ4qFdej6xnWjOQT.FStqfdoY8dYUPC"
注意
此参数仅适用于blowfish (BCrypt)。其他哈希类型将简单地忽略此参数。此参数的有效值为:[‘2’,‘2a’,‘2y’,‘2b’]
2.12版本的新增功能。
您还可以使用Ansible ansible.builtin.vault过滤器加密数据。
# simply encrypt my key in a vault
vars:
myvaultedkey: "{{ keyrawdata|vault(passphrase) }}"
- name: save templated vaulted data
template: src=dump_template_data.j2 dest=/some/key/vault.txt
vars:
mysalt: '{{ 2**256|random(seed=inventory_hostname) }}'
template_data: '{{ secretdata|vault(vaultsecret, salt=mysalt) }}'
然后使用unvault过滤器解密它。
# simply decrypt my key from a vault
vars:
mykey: "{{ myvaultedkey|unvault(passphrase) }}"
- name: save templated unvaulted data
template: src=dump_template_data.j2 dest=/some/key/clear.txt
vars:
template_data: '{{ secretdata|unvault(vaultsecret) }}'
操作文本
几个过滤器可用于处理文本,包括URL、文件名和路径名。
向文件添加注释
ansible.builtin.comment过滤器允许您使用各种注释样式从模板中的文本创建文件中的注释。默认情况下,Ansible 使用#
来开始注释行,并在注释文本的上方和下方添加一个空注释行。例如,以下内容:
{{ "Plain style (default)" | comment }}
产生以下输出:
#
# Plain style (default)
#
Ansible 提供了 C (//...
)、C 块 (/*...*/
)、Erlang (%...
) 和 XML (<!--...-->
) 注释样式。
{{ "C style" | comment('c') }}
{{ "C block style" | comment('cblock') }}
{{ "Erlang style" | comment('erlang') }}
{{ "XML style" | comment('xml') }}
您可以定义自定义注释字符。此过滤器:
{{ "My Special Case" | comment(decoration="! ") }}
产生:
!
! My Special Case
!
您可以完全自定义注释样式:
{{ "Custom style" | comment('plain', prefix='#######\n#', postfix='#\n#######\n ###\n #') }}
这将创建以下输出:
#######
#
# Custom style
#
#######
###
#
该过滤器还可以应用于任何Ansible变量。例如,为了使ansible_managed
变量的输出更易读,我们可以在ansible.cfg
文件中将其定义更改为此:
[defaults]
ansible_managed = This file is managed by Ansible.%n
template: {file}
date: %Y-%m-%d %H:%M:%S
user: {uid}
host: {host}
然后使用带有`comment`过滤器的变量:
{{ ansible_managed | comment }}
这将产生以下输出:
#
# This file is managed by Ansible.
#
# template: /home/ansible/env/dev/ansible_managed/roles/role1/templates/test.j2
# date: 2015-09-10 11:02:58
# user: ansible
# host: myhost
#
URL编码变量
urlencode
过滤器使用UTF-8对数据进行引用,以便在URL路径或查询中使用。
{{ 'Trollhättan' | urlencode }}
# => 'Trollh%C3%A4ttan'
拆分URL
2.4 版中的新增功能。
ansible.builtin.urlsplit过滤器从URL中提取片段、主机名、netloc、密码、路径、端口、查询、方案和用户名。没有参数时,返回所有字段的字典。
{{ "http://user:[email protected]:9000/dir/index.html?query=term#fragment" | urlsplit('hostname') }}
# => 'www.acme.com'
{{ "http://user:[email protected]:9000/dir/index.html?query=term#fragment" | urlsplit('netloc') }}
# => 'user:[email protected]:9000'
{{ "http://user:[email protected]:9000/dir/index.html?query=term#fragment" | urlsplit('username') }}
# => 'user'
{{ "http://user:[email protected]:9000/dir/index.html?query=term#fragment" | urlsplit('password') }}
# => 'password'
{{ "http://user:[email protected]:9000/dir/index.html?query=term#fragment" | urlsplit('path') }}
# => '/dir/index.html'
{{ "http://user:[email protected]:9000/dir/index.html?query=term#fragment" | urlsplit('port') }}
# => '9000'
{{ "http://user:[email protected]:9000/dir/index.html?query=term#fragment" | urlsplit('scheme') }}
# => 'http'
{{ "http://user:[email protected]:9000/dir/index.html?query=term#fragment" | urlsplit('query') }}
# => 'query=term'
{{ "http://user:[email protected]:9000/dir/index.html?query=term#fragment" | urlsplit('fragment') }}
# => 'fragment'
{{ "http://user:[email protected]:9000/dir/index.html?query=term#fragment" | urlsplit }}
# =>
# {
# "fragment": "fragment",
# "hostname": "www.acme.com",
# "netloc": "user:[email protected]:9000",
# "password": "password",
# "path": "/dir/index.html",
# "port": 9000,
# "query": "query=term",
# "scheme": "http",
# "username": "user"
# }
使用正则表达式搜索字符串
要使用正则表达式在字符串中搜索或提取字符串的部分,请使用ansible.builtin.regex_search过滤器。
# Extracts the database name from a string
{{ 'server1/database42' | regex_search('database[0-9]+') }}
# => 'database42'
# Example for a case insensitive search in multiline mode
{{ 'foo\nBAR' | regex_search('^bar', multiline=True, ignorecase=True) }}
# => 'BAR'
# Example for a case insensitive search in multiline mode using inline regex flags
{{ 'foo\nBAR' | regex_search('(?im)^bar') }}
# => 'BAR'
# Extracts server and database id from a string
{{ 'server1/database42' | regex_search('server([0-9]+)/database([0-9]+)', '\\1', '\\2') }}
# => ['1', '42']
# Extracts dividend and divisor from a division
{{ '21/42' | regex_search('(?P<dividend>[0-9]+)/(?P<divisor>[0-9]+)', '\\g<dividend>', '\\g<divisor>') }}
# => ['21', '42']
ansible.builtin.regex_search过滤器如果找不到匹配项,则返回空字符串。
{{ 'ansible' | regex_search('foobar') }}
# => ''
注意
ansible.builtin.regex_search过滤器在Jinja表达式中使用时(例如与运算符、其他过滤器等结合使用)返回None
。
{{ 'ansible' | regex_search('foobar') == '' }}
# => False
{{ 'ansible' | regex_search('foobar') is none }}
# => True
这是由于Ansible中某些Jinja内部组件的历史行为和自定义重新实现导致的。如果您希望ansible.builtin.regex_search过滤器在找不到匹配项时始终返回None
,请启用jinja2_native
设置。有关详细信息,请参见为什么regex_search过滤器返回None而不是空字符串?。
要提取字符串中正则表达式匹配的所有匹配项,请使用ansible.builtin.regex_findall过滤器。
# Returns a list of all IPv4 addresses in the string
{{ 'Some DNS servers are 8.8.8.8 and 8.8.4.4' | regex_findall('\\b(?:[0-9]{1,3}\\.){3}[0-9]{1,3}\\b') }}
# => ['8.8.8.8', '8.8.4.4']
# Returns all lines that end with "ar"
{{ 'CAR\ntar\nfoo\nbar\n' | regex_findall('^.ar$', multiline=True, ignorecase=True) }}
# => ['CAR', 'tar', 'bar']
# Returns all lines that end with "ar" using inline regex flags for multiline and ignorecase
{{ 'CAR\ntar\nfoo\nbar\n' | regex_findall('(?im)^.ar$') }}
# => ['CAR', 'tar', 'bar']
要使用正则表达式替换字符串中的文本,请使用ansible.builtin.regex_replace过滤器。
# Convert "ansible" to "able"
{{ 'ansible' | regex_replace('^a.*i(.*)$', 'a\\1') }}
# => 'able'
# Convert "foobar" to "bar"
{{ 'foobar' | regex_replace('^f.*o(.*)$', '\\1') }}
# => 'bar'
# Convert "localhost:80" to "localhost, 80" using named groups
{{ 'localhost:80' | regex_replace('^(?P<host>.+):(?P<port>\\d+)$', '\\g<host>, \\g<port>') }}
# => 'localhost, 80'
# Convert "localhost:80" to "localhost"
{{ 'localhost:80' | regex_replace(':80') }}
# => 'localhost'
# Comment all lines that end with "ar"
{{ 'CAR\ntar\nfoo\nbar\n' | regex_replace('^(.ar)$', '#\\1', multiline=True, ignorecase=True) }}
# => '#CAR\n#tar\nfoo\n#bar\n'
# Comment all lines that end with "ar" using inline regex flags for multiline and ignorecase
{{ 'CAR\ntar\nfoo\nbar\n' | regex_replace('(?im)^(.ar)$', '#\\1') }}
# => '#CAR\n#tar\nfoo\n#bar\n'
注意
如果您想匹配整个字符串并且正在使用*
,请确保始终使用开头/结尾锚点将正则表达式括起来。例如,^(.*)$
将始终只匹配一个结果,而(.*)
在某些Python版本上将匹配整个字符串和结尾的空字符串,这意味着它将进行两次替换。
# add "https://" prefix to each item in a list
GOOD:
{{ hosts | map('regex_replace', '^(.*)$', 'https://\\1') | list }}
{{ hosts | map('regex_replace', '(.+)', 'https://\\1') | list }}
{{ hosts | map('regex_replace', '^', 'https://') | list }}
BAD:
{{ hosts | map('regex_replace', '(.*)', 'https://\\1') | list }}
# append ':80' to each item in a list
GOOD:
{{ hosts | map('regex_replace', '^(.*)$', '\\1:80') | list }}
{{ hosts | map('regex_replace', '(.+)', '\\1:80') | list }}
{{ hosts | map('regex_replace', '$', ':80') | list }}
BAD:
{{ hosts | map('regex_replace', '(.*)', '\\1:80') | list }}
注意
在ansible 2.0之前,如果ansible.builtin.regex_replace过滤器与YAML参数(而不是更简单的“key=value”参数)内的变量一起使用,则需要使用4个反斜杠(\\\\
)而不是2个(\\
)来转义反向引用(例如,\\1
)。
2.0 版本中的新功能。
要转义标准Python正则表达式中的特殊字符,请使用ansible.builtin.regex_escape过滤器(使用默认的re_type='python'
选项)。
# convert '^f.*o(.*)$' to '\^f\.\*o\(\.\*\)\$'
{{ '^f.*o(.*)$' | regex_escape() }}
2.8 版本新增。
要转义POSIX基本正则表达式中的特殊字符,请使用ansible.builtin.regex_escape过滤器以及re_type='posix_basic'
选项。
# convert '^f.*o(.*)$' to '\^f\.\*o(\.\*)\$'
{{ '^f.*o(.*)$' | regex_escape('posix_basic') }}
管理文件名和路径名
要获取文件路径的最后一个名称,例如从“/etc/asdf/foo.txt”中获取“foo.txt”:
{{ path | basename }}
要获取Windows样式文件路径的最后一个名称(2.0版本中的新增功能):
{{ path | win_basename }}
要将Windows驱动器号与文件路径的其余部分分开(2.0版本中的新增功能):
{{ path | win_splitdrive }}
仅获取Windows驱动器号:
{{ path | win_splitdrive | first }}
获取路径中不包含驱动器号的其余部分
{{ path | win_splitdrive | last }}
从路径中获取目录
{{ path | dirname }}
从Windows路径中获取目录(2.0新版本)
{{ path | win_dirname }}
展开包含波浪号(~)字符的路径(1.5版本新增)
{{ path | expanduser }}
展开包含环境变量的路径
{{ path | expandvars }}
注意
expandvars 展开本地变量;在远程路径上使用它可能导致错误。
2.6 版本新增。
获取链接的真实路径(1.8版本新增)
{{ path | realpath }}
获取链接相对于起始点的相对路径(1.7版本新增)
{{ path | relpath('/etc') }}
获取路径或文件名的根和扩展名(2.0新版本)
# with path == 'nginx.conf' the return would be ('nginx', '.conf')
{{ path | splitext }}
ansible.builtin.splitext 过滤器始终返回一对字符串。可以使用 first
和 last
过滤器访问各个组件
# with path == 'nginx.conf' the return would be 'nginx'
{{ path | splitext | first }}
# with path == 'nginx.conf' the return would be '.conf'
{{ path | splitext | last }}
连接一个或多个路径组件
{{ ('/etc', path, 'subdir', file) | path_join }}
2.10版本新增。
操作字符串
为shell使用添加引号
- name: Run a shell command
ansible.builtin.shell: echo {{ string_value | quote }}
将列表连接成字符串
{{ list | join(" ") }}
将字符串分割成列表
{{ csv_string | split(",") }}
2.11 版中的新增功能。
使用Base64编码的字符串
{{ encoded | b64decode }}
{{ decoded | string | b64encode }}
(文档:ansible.builtin.b64encode)
从2.6版本开始,您可以定义要使用的编码类型,默认为 utf-8
{{ encoded | b64decode(encoding='utf-16-le') }}
{{ decoded | string | b64encode(encoding='utf-16-le') }}
(文档:ansible.builtin.b64decode)
注意
string
过滤器仅在Python 2中需要,并确保要编码的文本是unicode字符串。在b64encode之前没有该过滤器,将编码错误的值。
注意
b64decode的返回值是一个字符串。如果您使用b64decode解密二进制blob,然后尝试使用它(例如,使用copy将其写入文件),您很可能会发现您的二进制文件已损坏。如果您需要获取base64编码的二进制文件并将其写入磁盘,最好使用系统base64
命令和shell模块,使用stdin
参数传入编码数据。例如:shell: cmd="base64 --decode > myfile.bin" stdin="{{ encoded }}"
2.6 版本新增。
管理UUID
创建命名空间UUIDv5
{{ string | to_uuid(namespace='11111111-2222-3333-4444-555555555555') }}
2.10版本新增。
使用默认的Ansible命名空间“361E6D51-FAEC-444A-9079-341386DA8E2E”创建命名空间UUIDv5
{{ string | to_uuid }}
1.9 版中的新增功能。
要使用复杂变量列表中每个项目的某个属性,请使用Jinja2 map filter
# get a comma-separated list of the mount points (for example, "/,/mnt/stuff") on a host
{{ ansible_mounts | map(attribute='mount') | join(',') }}
处理日期和时间
要从字符串获取日期对象,请使用to_datetime过滤器
# Get the total amount of seconds between two dates. Default date format is %Y-%m-%d %H:%M:%S but you can pass your own format
{{ (("2016-08-14 20:00:12" | to_datetime) - ("2015-12-25" | to_datetime('%Y-%m-%d'))).total_seconds() }}
# Get remaining seconds after delta has been calculated. NOTE: This does NOT convert years, days, hours, and so on to seconds. For that, use total_seconds()
{{ (("2016-08-14 20:00:12" | to_datetime) - ("2016-08-14 18:00:00" | to_datetime)).seconds }}
# This expression evaluates to "12" and not "132". Delta is 2 hours, 12 seconds
# get amount of days between two dates. This returns only the number of days and discards remaining hours, minutes, and seconds
{{ (("2016-08-14 20:00:12" | to_datetime) - ("2015-12-25" | to_datetime('%Y-%m-%d'))).days }}
注意
有关使用Python日期格式字符串的完整格式代码列表,请参阅python datetime文档。
2.4 版中的新增功能。
要使用字符串格式化日期(如使用shell date命令),请使用“strftime”过滤器
# Display year-month-day
{{ '%Y-%m-%d' | strftime }}
# => "2021-03-19"
# Display hour:min:sec
{{ '%H:%M:%S' | strftime }}
# => "21:51:04"
# Use ansible_date_time.epoch fact
{{ '%Y-%m-%d %H:%M:%S' | strftime(ansible_date_time.epoch) }}
# => "2021-03-19 21:54:09"
# Use arbitrary epoch value
{{ '%Y-%m-%d' | strftime(0) }} # => 1970-01-01
{{ '%Y-%m-%d' | strftime(1441357287) }} # => 2015-09-04
2.13版本新增。
strftime带有一个可选的utc参数,默认为False,这意味着时间为本地时区
{{ '%H:%M:%S' | strftime }} # time now in local timezone
{{ '%H:%M:%S' | strftime(utc=True) }} # time now in UTC
注意
要获取所有字符串可能性,请查看https://docs.pythonlang.cn/3/library/time.html#time.strftime
获取Kubernetes资源名称
注意
这些过滤器已迁移到kubernetes.core集合。请按照安装说明安装该集合。
使用“k8s_config_resource_name”过滤器获取Kubernetes ConfigMap或Secret的名称,包括其哈希值
{{ configmap_resource_definition | kubernetes.core.k8s_config_resource_name }}
然后可以使用它来引用Pod规范中的哈希值
my_secret:
kind: Secret
metadata:
name: my_secret_name
deployment_resource:
kind: Deployment
spec:
template:
spec:
containers:
- envFrom:
- secretRef:
name: {{ my_secret | kubernetes.core.k8s_config_resource_name }}
2.8 版本新增。
另请参阅
- Ansible playbook
剧本简介
- 条件语句
剧本中的条件语句
- 使用变量
关于变量的一切
- 循环
剧本中的循环
- 角色
按角色组织剧本
- 一般提示
剧本提示和技巧
- 沟通
有问题?需要帮助?想分享你的想法?请访问Ansible沟通指南
- Python 3正则表达式操作
如何使用内联正则表达式标志