首页 > 解决方案 > 无法比较从 ansble_devices 事实返回的嵌套字典中键的值

问题描述

团队,我正在尝试比较来自 ansible_devices 变量并陷入语法错误的键值的字符串值。我只想在WHEN满足条件时打印味精。基本上,我只想在分区为 NULL 或其中没有任何值时打印 msg。

我有以下示例输出,我可以检索它,但现在我想将它与一些字符串进行比较,但 values.yml 失败

null_partitions: "{}"
  debug:
    msg: "{{ ansible_hostname }} {{ item }} {{ ansible_devices[item]['partitions'] }}"
  #when: "{{ ansible_devices[item]['partitions'] is defined }}"
  when: "ansible_devices[item]['partitions'] == ansible_devices[item] {{ null_partitions }}"
  with_items: "{{ ansible_devices }}"

输出错误:

 fatal: [node1]: FAILED! => {"msg": "The conditional check 'ansible_devices[item]['partitions'] == ansible_devices[item] {{ null_partitions }}' failed. The error was: template error while templating string: expected token 'end of statement block', got '{'. String: {% if ansible_devices[item]['partitions'] == ansible_devices[item] {} %} True {% else %} False {% endif %}\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 15, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n# As per the warning in your output, 'when' clauses should not be wrapped with curly braces. Also better to use 'inventory_hostname' in this case\n- name: Print device partitions that are defined\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
           },


我评论的输出when如下

ok: [node] => (item=loop3) => {
      "msg": "node1 loop0 {}"
  }

根据评论,我试过了

when: "ansible_devices[item]['partitions'] ==  null_partitions"

输出是

  TASK [local_volume_mount : Print device partitions that are defined] 
skipping: [node] => (item=loop0)

不确定我的模式{}是否在值中定义错误?或者如果任务从字面上寻找null_partitions一个字符串?

标签: ansibleansible-2.xansible-facts

解决方案


"partitions": {}<= 您的结果中的 this不是包含"{}"但为空字典的字符串。

因此,编写子句的正确且安全的方法when是检查变量是否为 amapping以及是否为 0 长度(即没有声明的键)。

when:
  - ansible_devices[item]['partitions'] is mapping
  - ansible_devices[item]['partitions'] | length == 0

关于mapping测试,请参阅https://jinja2docs.readthedocs.io/en/stable/templates.html#list-of-builtin-tests


推荐阅读