在Ansible Playbook中,如何从字典列表中选择键=key的字典。

huangapple go评论80阅读模式
英文:

How to select dictionary from list of dictionaries where key = value in ansible playbook

问题

以下是您需要的翻译部分:

我已经看到了一些其他与我的需求相似的问题,但是,我仍然难以弄清楚如何从这个JSON中获取我需要的确切信息。这是我的Ansible调试任务:

  1. - debug:
  2. msg: "{{ foreman_environments.stdout }}"

这是输出:

> ok: [127.0.0.1] => {
"msg": "[{'id': 12, 'name': 'CDE', 'label': 'CDE', 'permissions': {'readable': True}}, {'id': 7, 'name': 'QA3', 'label': 'QA3', 'permissions': {'readable': True}}, {'id': 4, 'name': 'Library', 'label': 'Library', 'permissions': {'readable': True}}, {'id': 6, 'name': 'Development', 'label': 'Development', 'permissions': {'readable': True}}, {'id': 8, 'name': 'Production', 'label': 'Production', 'permissions': {'readable': True}}]"
}

我需要捕获'名字'键等于x的'id'值。在这个确切的情况下,我想要获取QA3的'id',但我可能也需要捕获其他环境的'id'。因此,我需要取得这个环境列表,并返回name == some name的'id'值。然后,我需要在包含所有其他版本的不同列表中搜索该'id'。

这是我尝试过的内容:

  1. - debug:
  2. msg: "{{ foreman_environments.stdout |
  3. selectattr('name', 'equalto', 'QA3') |
  4. list | last | to_json }}"

这是我得到的输出:

> {"msg": "The task includes an option with an undefined variable. The error was: 'str object' has no attribute 'name'\n\nThe error appears to be in '/opt/git/ci_cd_ansible/playbook_publish_foreman_view.yml': line 36, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n - debug:\n ^ here\n"}

我想要注册结果,然后使用已注册的结果来执行相同的操作,但针对不同的数据集。有人可以帮助我理解我漏掉了什么吗?

编辑:

我已经改变了我的方法来使用

  1. "{{ foreman_environments.stdout |
  2. selectattr('name', 'equalto', 'QA3') }}"

并返回一个生成器对象。然而,如果我尝试将其转换为列表,我会收到错误消息:

> fatal: [127.0.0.1]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'str object' has no attribute 'name'\n\nThe error appears to be in '/opt/git/ci_cd_ansible/playbook_publish_foreman_view.yml': line 36, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n - debug:\n ^ here\n"}

英文:

I've seen a few other questions that are similar to my need, however, I'm still having a hard time figuring out how I need to get exactly what I need from this JSON. Here's my Ansible debug task:

  1. - debug:
  2. msg: "{{ foreman_environments.stdout }}"

and here's the output:

> ok: [127.0.0.1] => {
"msg": "[{'id': 12, 'name': 'CDE', 'label': 'CDE', 'permissions': {'readable': True}}, {'id': 7, 'name': 'QA3', 'label': 'QA3', 'permissions': {'readable': True}}, {'id': 4, 'name': 'Library', 'label': 'Library', 'permissions': {'readable': True}}, {'id': 6, 'name': 'Development', 'label': 'Development', 'permissions': {'readable': True}}, {'id': 8, 'name': 'Production', 'label': 'Production', 'permissions': {'readable': True}}]"
}

I need to capture the 'id' value where the 'name' key equals x. In this exact case, I want to get the 'id' of QA3, but I might need to capture the 'id' of other environments as well. So I need to take this list of environments and return the value of 'id' where name == some name. Then I need to search for that 'id' in a different list that contains all the other versions.

Here's what I've tried:

  1. - debug:
  2. msg: "{{ foreman_environments.stdout |
  3. selectattr('name', 'equalto', 'QA3') |
  4. list | last | to_json }}"

and here's the output I get:

> {"msg": "The task includes an option with an undefined variable. The error was: 'str object' has no attribute 'name'\n\nThe error appears to be in '/opt/git/ci_cd_ansible/playbook_publish_foreman_view.yml': line 36, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n - debug:\n ^ here\n"}

I want to register the result and then use that registered result to functionally do this same thing but against a different set of data. Can someone help me understand what I'm missing?

EDIT:

I've changed my method to use

  1. "{{ foreman_environments.stdout |
  2. selectattr('name', 'equalto', 'QA3') }}"

and that returns a generator object. If I try to translate that to a list, though, I get an error:

> fatal: [127.0.0.1]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'str object' has no attribute 'name'\n\nThe error appears to be in '/opt/git/ci_cd_ansible/playbook_publish_foreman_view.yml': line 36, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n - debug:\n ^ here\n"}

答案1

得分: 1

以下是翻译好的部分:

  1. id_qa3: "{{ (content_views.resources[0].environments |
  2. selectattr('name', 'equalto', 'QA3') |
  3. list | first)['id'] }}"

Trying to use .stdout I think is what messed me up. Something about that output format just wasn't working as expected. I just used the original JSON output and filtered it down to the same chunk then selectattr() worked as expected. I also had to figure out that the parentheses needed to go around the entire statement, but inside of the {{}} in order to get the ['id'] to work.

英文:

Here's the answer I was looking for:

  1. id_qa3: "{{ (content_views.resources[0].environments |
  2. selectattr('name', 'equalto', 'QA3') |
  3. list | first)['id'] }}"

Trying to use .stdout I think is what messed me up. Something about that output format just wasn't working as expected. I just used the original JSON output and filtered it down to the same chunk then selectattr() worked as expected. I also had to figure out that the parentheses needed to go around the entire statement, but inside of the {{}} in order to get the ['id'] to work.

答案2

得分: 1

The filter json_query 产生相同的结果

  1. id_qa3: "{{ foreman_environments.stdout|
  2. json_query('[?name == `QA3`].id')|
  3. first }}"

用于测试的完整playbook示例

  1. shell> cat pb.yml
  2. - hosts: all
  3. vars:
  4. foreman_environments:
  5. stdout:
  6. - id: 12
  7. label: CDE
  8. name: CDE
  9. permissions: {readable: true}
  10. - id: 7
  11. label: QA3
  12. name: QA3
  13. permissions: {readable: true}
  14. - id: 4
  15. label: Library
  16. name: Library
  17. permissions: {readable: true}
  18. - id: 6
  19. label: Development
  20. name: Development
  21. permissions: {readable: true}
  22. - id: 8
  23. label: Production
  24. name: Production
  25. permissions: {readable: true}
  26. id_qa3_a: "{{ foreman_environments.stdout|
  27. json_query('[?name == `QA3`].id')|
  28. first }}"
  29. id_qa3_b: "{{ (foreman_environments.stdout|
  30. selectattr('name', '==', 'QA3')|
  31. first).id }}"
  32. tasks:
  33. - debug:
  34. var: id_qa3_a
  35. - debug:
  36. var: id_qa3_b

产生

  1. shell> ansible-playbook pb.yml -l test_11
  2. PLAY [all] ************************************************************************************
  3. TASK [debug] **********************************************************************************
  4. ok: [test_11] =>
  5. id_qa3_a: '7'
  6. TASK [debug] **********************************************************************************
  7. ok: [test_11] =>
  8. id_qa3_b: '7'
  9. PLAY RECAP ************************************************************************************
  10. test_11: ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

英文:

The filter json_query gives the same result

  1. id_qa3: "{{ foreman_environments.stdout|
  2. json_query('[?name == `QA3`].id')|
  3. first }}"

<hr>

<sup>

Example of a complete playbook for testing

  1. shell&gt; cat pb.yml
  2. - hosts: all
  3. vars:
  4. foreman_environments:
  5. stdout:
  6. - id: 12
  7. label: CDE
  8. name: CDE
  9. permissions: {readable: true}
  10. - id: 7
  11. label: QA3
  12. name: QA3
  13. permissions: {readable: true}
  14. - id: 4
  15. label: Library
  16. name: Library
  17. permissions: {readable: true}
  18. - id: 6
  19. label: Development
  20. name: Development
  21. permissions: {readable: true}
  22. - id: 8
  23. label: Production
  24. name: Production
  25. permissions: {readable: true}
  26. id_qa3_a: &quot;{{ foreman_environments.stdout|
  27. json_query(&#39;[?name == `QA3`].id&#39;)|
  28. first }}&quot;
  29. id_qa3_b: &quot;{{ (foreman_environments.stdout|
  30. selectattr(&#39;name&#39;, &#39;==&#39;, &#39;QA3&#39;)|
  31. first).id }}&quot;
  32. tasks:
  33. - debug:
  34. var: id_qa3_a
  35. - debug:
  36. var: id_qa3_b

gives

  1. shell&gt; ansible-playbook pb.yml -l test_11
  2. PLAY [all] ************************************************************************************
  3. TASK [debug] **********************************************************************************
  4. ok: [test_11] =&gt;
  5. id_qa3_a: &#39;7&#39;
  6. TASK [debug] **********************************************************************************
  7. ok: [test_11] =&gt;
  8. id_qa3_b: &#39;7&#39;
  9. PLAY RECAP ************************************************************************************
  10. test_11: ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

</sup>

huangapple
  • 本文由 发表于 2023年5月18日 02:16:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/76275097.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定