当条件循环时在 ansible 中搜索字符串 [英] search a string in ansible when condition over loop
问题描述
团队,我想在 sda
设备上循环,只排除 loop
设备,所以我试图比较字符串的一部分,如果它存在于来自 ansible_devices 项的键中变量并陷入语法错误.
Team, I want to loop on sda
devices only excluding loop
devices so I am trying to compare a part of string if it exists in key that is from ansible_devices item variable and stuck at syntax error.
我只想在 WHEN
条件满足时打印 msg.基本上,当键中有子字符串 loop
时,我只想打印 msg.
I want to print msg only on WHEN
condition Is met. basically, I want to only msg print when there is substring loop
in the key.
我有以下示例输出,我能够检索它,但现在我想将它与某个字符串进行比较但失败,如任务中标记的 #fails
I have below sample output and I am able to retrieve it but now I want to compare it with some string but failing, as marked #fails
in task
values.yml
loop_device: "loop"
task.yaml
debug:
msg: "{{ ansible_hostname }} {{ item }} {{ ansible_devices[item]['partitions'] }}"
when:
- "not ansible_devices[item] is search('loop')" #fails
- ansible_devices[item]['partitions'] is mapping #works
- ansible_devices[item]['partitions'] | length == 0 #works
with_items: "{{ ansible_devices }}"
输出错误:
TASK [local_volume_mount : Print device partitions that are defined using mapping] ***
17:14:23 Tuesday 27 April 2021
17:14:23 fatal: [node1]: FAILED! => {"msg": "The conditional check 'not ansible_devices[item] is search('loop')' failed. The error was: Unexpected templating type error occurred on ({% if not ansible_devices[item] is search('loop') %} True {% else %} False {% endif %}): expected string or bytes-like object\n\nThe error appears to be in '/ansible-managed/jenkins-slave/slave0/workspace/run_ansible_playbook/k8s/baremetal/roles/local_volume_mount/tasks/main.yml': line 24, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n- name: Print device partitions that are defined using mapping\n ^ here\n"}
示例 ansible_Devices
如下
ok: [node1] => {
"ansible_devices": {
"loop0": {
"holders": [],
"host": "",
"links": {
"ids": [],
"labels": [],
"masters": [],
"uuids": []
},
"model": null,
"partitions": {},
"removable": "0",
"rotational": "1",
"sas_address": null,
"sas_device_handle": null,
"scheduler_mode": "none",
"sectors": "0",
"sectorsize": "512",
"size": "0.00 Bytes",
"support_discard": "0",
"vendor": null,
"virtual": 1
},
"sda2": {
"holders": [],
"host": "",
"links": {
"ids": [],
"labels": [],
"masters": [],
"uuids": []
},
"model": null,
"partitions": {},
"removable": "0",
"rotational": "1",
"sas_address": null,
"sas_device_handle": null,
"scheduler_mode": "none",
"sectors": "0",
"sectorsize": "512",
"size": "0.00 Bytes",
"support_discard": "0",
"vendor": null,
"virtual": 1
},
输出仍在打印循环设备
ok: [node1] => (item=loop0) => {
"msg": "node1 loop0 {}"
}
ok: [node1] => (item=loop0) => {
"msg": "node1 sda2 {}"
}
我什至尝试过以下组合
- '"loop" not in ansible_devices[item]'
- ansible_devices[item] is not match("loop")
- ansible_devices[item] is not search("loop")
尝试了下面的答案 1
- debug: after entering loop efficient
msg: "{{ ansible_hostname }} {{ item.key }} {{ item.value.partitions }}"
when:
- item.key is not search('loop')
- item.value.partitions is mapping
- item.value.partitions | length == 0
loop: "{{ ansible_devices | dict2items }}"
with_dict: "{{ ansible_devices }}"
带有 dict2items 的 Answer1 的错误输出
error output for Answer1 with dict2items
ERROR! Syntax Error while loading YAML.
mapping values are not allowed here
The error appears to be in '/ansible-managed/jenkins-slave/slave0/workspace/run_ansible_playbook/k8s/baremetal/roles/local_volume_mount/tasks/main.yml': line 25, column 8, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
- debug: after entering loop efficient
msg: "{{ ansible_hostname }} {{ item.key }} {{ item.value.partitions }}"
^ here
We could be wrong, but this one looks like it might be an issue with
missing quotes. Always quote template expression brackets when they
start a value. For instance:
with_items:
- {{ foo }}
Should be written as:
with_items:
- "{{ foo }}"
推荐答案
快速修复 =>item is not search('loop')
由于您在 dict 上使用 with_items
,因此循环中仅返回其键的列表.因此 item
是您要搜索的键.
Since you use with_items
on a dict, only the list of its keys is returned in the loop. Thus item
is the key you want to search on.
同时,还有一种更有效的方法来循环字典,它会返回一个包含键和值的元素.
Meanwhile, there is a much more efficient way to loop over your dictionaries which will return an element containing both the key and the value.
- 历史语法:
with_dict: "{{ ansible_devices }}"
- 新语法:
loop: "{{ ansible_devices |dict2items }}"
参见:https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html
在您的情况下,这将给出:
in your case this would give:
- debug:
msg: "{{ ansible_hostname }} {{ item.key }} {{ item.value.partitions }}"
when:
- item.key is not search('loop')
- item.value.partitions is mapping
- item.value.partitions | length == 0
loop: "{{ ansible_devices | dict2items }}"
我们实际上可以更进一步,在我们开始循环之前从字典中过滤掉大部分元素.我们仍然需要检查 when 子句中的长度,因为这在过滤过程中不容易计算
We can actually go a step further and filter out most of the elements from the dict before we even start to loop. We still need to check the length in a when clause as this can't be calculated easily during filtering
- debug:
msg: "{{ ansible_hostname }} {{ item.key }} {{ item.value.partitions }}"
when: item.value.partitions | length == 0
loop: >-
{{
ansible_devices
| dict2items
| rejectattr('key', 'search', 'loop')
| selectattr('value.partition', 'mapping')
| list
}}
这篇关于当条件循环时在 ansible 中搜索字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!