当条件循环时在 ansible 中搜索字符串 [英] search a string in ansible when condition over loop

查看:32
本文介绍了当条件循环时在 ansible 中搜索字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

团队,我想在 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆