将jinja2 for循环转换为列表



我目前在Ansible中有一个jinja2 for循环的问题。我想提取任何可用的windows更新的title

我试着用这个返回结果:

- win_updates:
category_names: "{{ win_update_categories }}"
state: searched
register: available_updates
- debug: msg="{{ available_updates }}"
- debug:
msg: "{{ item['title'] }}"
with_items: " {{ available_updates['updates'] }}"

我得到了这个:

"msg": "available_updates = {'updates': {'74f56410-a048-4c27-91de-5f09600944c7': {'categories': ['Definition Updates', 'Microsoft Defender Antivirus'], 'title': 'Update for Microsoft Defender Antivirus antimalware platform - KB4052623 (Version 4.18.2107.4)', 'id': '74f56410-a048-4c27-91de-5f09600944c7', 'installed': False, 'kb': ['4052623']}, '7b31e2cf-c6b0-434e-9420-97c6fe756573': {'categories': ['Security Updates', 'Windows Server 2019'], 'title': '2021-08 Cumulative Update for Windows Server 2019 for x64-based Systems (KB5005030)', 'id': '7b31e2cf-c6b0-434e-9420-97c6fe756573', 'installed': False, 'kb': ['5005030']}}, 'found_update_count': 2, 'changed': False, 'reboot_required': False, 'installed_update_count': 0, 'filtered_updates': {}, 'failed': False}"
ok: [172.16.1.1] => (item=74f56410-a048-4c27-91de-5f09600944c7) => {
"msg": "<built-in method title of AnsibleUnsafeText object at 0x7f1f9a4bec80>"
}
ok: [172.16.1.1] => (item=7b31e2cf-c6b0-434e-9420-97c6fe756573) => {
"msg": "<built-in method title of AnsibleUnsafeText object at 0x7f1f9a4bef90>"
}

你可以看到title是被编码的或者类似的东西

所以,我做了一些搜索,找到了这个解决方案,使用jinja2和for循环来获取更新的标题。

- win_updates:
category_names: "{{ win_update_categories }}"
state: searched
register: available_updates
- set_fact:
available_updates_title: >-
"{% for update in available_updates.updates.values() %}
{{ update.title }}
{% endfor %}"
- debug:
msg: "{{ available_updates_title }}"

我得到了这个:

"msg": "  Update for Microsoft Defender Antivirus antimalware platform - KB4052623 (Version 4.18.2107.4)n  2021-08 Cumulative Update for Windows Server 2019 for x64-based Systems (KB5005030)n"

它工作正常,但我想创建一个可供每个服务器的标题列表,而jinja2 for loop创建一行标题。

所以我的问题是我如何将jinja2的输出转换为一个可以用Ansible迭代的列表?

任何帮助将不胜感激!提前感谢

很抱歉我对你的数据不存在的评论。同时,对你的变量进行简单的调试,不需要任何额外的字符,例如

- debug:
var: available_updates

会给出一个更容易读的结果,并从一开始就消除了可能的混乱:

ok: [localhost] => {
"available_updates": {
"changed": false,
"failed": false,
"filtered_updates": {},
"found_update_count": 2,
"installed_update_count": 0,
"reboot_required": false,
"updates": {
"74f56410-a048-4c27-91de-5f09600944c7": {
"categories": [
"Definition Updates",
"Microsoft Defender Antivirus"
],
"id": "74f56410-a048-4c27-91de-5f09600944c7",
"installed": false,
"kb": [
"4052623"
],
"title": "Update for Microsoft Defender Antivirus antimalware platform - KB4052623 (Version 4.18.2107.4)"
},
"7b31e2cf-c6b0-434e-9420-97c6fe756573": {
"categories": [
"Security Updates",
"Windows Server 2019"
],
"id": "7b31e2cf-c6b0-434e-9420-97c6fe756573",
"installed": false,
"kb": [
"5005030"
],
"title": "2021-08 Cumulative Update for Windows Server 2019 for x64-based Systems (KB5005030)"
}
}
}
}

现在很明显,available_updates.updates是一个字典,键是更新的id,对应的值包含了每次更新的所有细节。

在第一个注释中提取更新title的一般在线程序想法仍然是好的,除了我们需要在应用映射过滤器提取属性之前将字典转换为列表。这可以使用dict上的.values()方法(如示例中所示)或使用dict2items过滤器来完成。下面的剧本演示了两种可能的方法

---
- name: Extract list of elements from dict
hosts: localhost
gather_facts: false
vars:
# Your orig var on a single line for legigility
available_updates: {'updates':{'74f56410-a048-4c27-91de-5f09600944c7':{'categories':['Definition Updates','Microsoft Defender Antivirus'],'title':'Update for Microsoft Defender Antivirus antimalware platform - KB4052623 (Version 4.18.2107.4)','id':'74f56410-a048-4c27-91de-5f09600944c7','installed':False,'kb':['4052623']},'7b31e2cf-c6b0-434e-9420-97c6fe756573':{'categories':['Security Updates','Windows Server 2019'],'title':'2021-08 Cumulative Update for Windows Server 2019 for x64-based Systems (KB5005030)','id':'7b31e2cf-c6b0-434e-9420-97c6fe756573','installed':False,'kb':['5005030']}},'found_update_count':2,'changed':False,'reboot_required':False,'installed_update_count':0,'filtered_updates':{},'failed':False}
# Equivalent var definitions
title_list_using_values_method: >-
{{ available_updates.updates.values() | map(attribute='title') }}
title_list_using_dict2items_filter: >-
{{ available_updates.updates | dict2items | map(attribute='value.title') }}
tasks:
- name: "Show the original var (use -v to display)"
debug:
var: available_updates
verbosity: 1
- name: "Show result with both definitions"
debug:
var: "title_list_using_{{ flavor }}"
loop:
- values_method
- dict2items_filter
loop_control:
loop_var: flavor

并给出:

PLAY [Extract list of elements from dict] *****************************************************************************
TASK [Show the original var (use -v to display)] *****************************************************************************
skipping: [localhost]
TASK [Show result with both definitions] *****************************************************************************
ok: [localhost] => (item=values_method) => {
"ansible_loop_var": "flavor",
"flavor": "values_method",
"title_list_using_values_method": [
"Update for Microsoft Defender Antivirus antimalware platform - KB4052623 (Version 4.18.2107.4)",
"2021-08 Cumulative Update for Windows Server 2019 for x64-based Systems (KB5005030)"
]
}
ok: [localhost] => (item=dict2items_filter) => {
"ansible_loop_var": "flavor",
"flavor": "dict2items_filter",
"title_list_using_dict2items_filter": [
"Update for Microsoft Defender Antivirus antimalware platform - KB4052623 (Version 4.18.2107.4)",
"2021-08 Cumulative Update for Windows Server 2019 for x64-based Systems (KB5005030)"
]
}
PLAY RECAP *****************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0

我有一个类似的问题,我用这样的方法解决了它:

available_updates['updates'].categories

available_updates['updates']['categories']

最新更新