我有这两个列表:
"list": [
{
"DEVICE_NAME": "uscx001.net",
"IMPLEMENTATION": "system\nInterface range Gi1/10/0/42 to Gi1/10/0/45 Gi2/10/0/32 to Gi2/10/0/34\ndefault\nport link-mode bridge\ndescription *::HP-HSP::Available::::\nport access vlan 999\nshutdown\nreturn\nsave force",
"POST_CHECK": "dis inter brief | inc 1/10/0/4[2345]|2/10/0/3[234]",
"PRE_CHECK": "dis inter brief | inc 1/10/0/4[2345]|2/10/0/3[234]",
"NO": "1"
},
{
"DEVICE_NAME": "uscx002.net",
"IMPLEMENTATION": "system\nInterface range Gi1/9/0/9 to Gi1/9/0/12 Gi2/9/0/9 to Gi2/9/0/11\ndefault\nport link-mode bridge\ndescription *::HP-HSP::Available::::\nport access vlan 999\nshutdown\nreturn\nsave force",
"POST_CHECK": "dis inter brief | inc 1/9/0/9|1/9/0/1[012]|2/9/0/9|2/9/0/1[01]",
"PRE_CHECK": "dis inter brief | inc 1/9/0/9|1/9/0/1[012]|2/9/0/9|2/9/0/1[01]",
"NO": "2"
}
]
和
"json": {
"offset": 0,
"limit": 1000,
"search": {},
"filter_op": "and",
"total": 701,
"fields": [
"ID",
"Name",
"PluginKey"
],
"data": [
{
"ID": 54,
"Name": "inet-fw.lab.net",
"PluginKey": "checkpoint_gaia"
},
{
"ID": 2558,
"Name": "uscx001.net",
"PluginKey": "hp_aseries_alt_2"
},
{
"ID": 2559,
"Name": "uscx002.net",
"PluginKey": "hp_aseries_alt_2"
},
{
"ID": 2560,
"Name": "test1.net",
"PluginKey": "hp_aseries_alt_2"
}
]
}
目的是创建一个新列表,其中将包含第一个列表以及第二个列表中找到的设备的附加信息 ID 和 PluginKey,因此它将如下所示:
"list2": [
{
"DEVICE_NAME": "uscx001.net",
"IMPLEMENTATION": "system\nInterface range Gi1/10/0/42 to Gi1/10/0/45 Gi2/10/0/32 to Gi2/10/0/34\ndefault\nport link-mode bridge\ndescription *::HP-HSP::Available::::\nport access vlan 999\nshutdown\nreturn\nsave force",
"POST_CHECK": "dis inter brief | inc 1/10/0/4[2345]|2/10/0/3[234]",
"PRE_CHECK": "dis inter brief | inc 1/10/0/4[2345]|2/10/0/3[234]",
"NO": "1",
"ID": 2558,
"PluginKey": "hp_aseries_alt_2"
},
{
"DEVICE_NAME": "uscx002.net",
"IMPLEMENTATION": "system\nInterface range Gi1/9/0/9 to Gi1/9/0/12 Gi2/9/0/9 to Gi2/9/0/11\ndefault\nport link-mode bridge\ndescription *::HP-HSP::Available::::\nport access vlan 999\nshutdown\nreturn\nsave force",
"POST_CHECK": "dis inter brief | inc 1/9/0/9|1/9/0/1[012]|2/9/0/9|2/9/0/1[01]",
"PRE_CHECK": "dis inter brief | inc 1/9/0/9|1/9/0/1[012]|2/9/0/9|2/9/0/1[01]",
"NO": "2",
"ID": 2559,
"PluginKey": "hp_aseries_alt_2"
}
]
我一直在玩联合收割机、拉链、地图,但它总是只给我一个项目,而不是完整的项目列表。
有人可以帮我完成这项任务吗?
理想情况下,如果我们可以使用过滤器而不是循环,那将是完美的,因为我期望一个包含数千项的非常大的列表 - 这个示例只是非常小的数据提取。
谢谢!!
真诚的,
托马斯
这能给你你想要的吗?
- name: create new list
set_fact:
list2: "{{ list2 | default([]) + [item | combine({'ID': device.ID, 'PluginKey': device.PluginKey})] }}"
loop: "{{ list1 }}"
vars:
device: "{{ json2.data | selectattr('Name', 'equalto', item.DEVICE_NAME) | list | first }}"
- name: debug it
debug:
msg: "{{ list2 }}"
以下内容自愿详细且不言自明。一旦有了想法就可以随意重构。请注意,此解决方案使用过滤器(尽管它也使用一些模板)并满足您不使用不必要的任务的要求。
community.general.lists_mergeby
过滤器。该集合包含在 ansible 社区 pip 包中,但如果您仅安装了 ansible-core,则可能需要安装它:
# Check if collection is installed (example output on my current environment)
$ ansible-galaxy collection list | grep community.general
community.general 8.1.0
# Install collection if needed
$ ansible-galaxy collection install community.general
以下剧本应该非常清晰易懂:
- hosts: localhost
gather_facts: false
vars:
# Your original `list` renamed to `device_list`
# on a single json line for legibility
# Note: `list` is definitely not a good variable name
# as it may conflict with python builtin class name
device_list: [{"DEVICE_NAME":"uscx001.net","IMPLEMENTATION":"system\nInterface range Gi1/10/0/42 to Gi1/10/0/45 Gi2/10/0/32 to Gi2/10/0/34\ndefault\nport link-mode bridge\ndescription *::HP-HSP::Available::::\nport access vlan 999\nshutdown\nreturn\nsave force","POST_CHECK":"dis inter brief | inc 1/10/0/4[2345]|2/10/0/3[234]","PRE_CHECK":"dis inter brief | inc 1/10/0/4[2345]|2/10/0/3[234]","NO":"1"},{"DEVICE_NAME":"uscx002.net","IMPLEMENTATION":"system\nInterface range Gi1/9/0/9 to Gi1/9/0/12 Gi2/9/0/9 to Gi2/9/0/11\ndefault\nport link-mode bridge\ndescription *::HP-HSP::Available::::\nport access vlan 999\nshutdown\nreturn\nsave force","POST_CHECK":"dis inter brief | inc 1/9/0/9|1/9/0/1[012]|2/9/0/9|2/9/0/1[01]","PRE_CHECK":"dis inter brief | inc 1/9/0/9|1/9/0/1[012]|2/9/0/9|2/9/0/1[01]","NO":"2"}]
# Your original json on a single line for legibility,
# encapsulated in a higher level var (as I guess you get
# that result from a REST call to an API)
some_uri_response: {"json":{"offset":0,"limit":1000,"search":{},"filter_op":"and","total":701,"fields":["ID","Name","PluginKey"],"data":[{"ID":54,"Name":"inet-fw.lab.net","PluginKey":"checkpoint_gaia"},{"ID":2558,"Name":"uscx001.net","PluginKey":"hp_aseries_alt_2"},{"ID":2559,"Name":"uscx002.net","PluginKey":"hp_aseries_alt_2"},{"ID":2560,"Name":"test1.net","PluginKey":"hp_aseries_alt_2"}]}}
# Transform the list in json to duplicate key `Name`
# to `DEVICE_NAME`. The goal is to get a common attribute
# between the two lists. There are other options here
# but doing it through templating is quite adapted
# in that case.
transformed_json_list: |-
{% filter from_yaml %}
{% set transformed_result = [] %}
{% for entry in some_uri_response.json.data %}
{% set new_entry = entry | combine({'DEVICE_NAME': entry.Name}) %}
{{ transformed_result.append(new_entry) }}
{% endfor %}
{{ transformed_result }}
{% endfilter %}
# Merge the two lists on their common attribute.
# Elements which are not common will remain in the result
raw_merged_list: "{{ device_list | community.general.lists_mergeby(transformed_json_list, 'DEVICE_NAME') }}"
# Filter out elements from json list wich were
# not present in the list of devices. Here are
# inferred that devices always have the `IMPLEMENTATION`
# attribute set. Adapt if you need to be more specific.
merged_list: "{{ raw_merged_list | selectattr('IMPLEMENTATION', 'defined') }}"
tasks:
- name: Show original device list (run with -v to display)
ansible.builtin.debug:
var: device_list
verbosity: 1
- name: Show original json result (run with -v to display)
ansible.builtin.debug:
var: some_uri_response
verbosity: 1
- name: Show json list transformed with `DEVICE_NAME` added
ansible.builtin.debug:
var: transformed_list
- name: Show merged list before cleaning out unwanted elements
ansible.builtin.debug:
var: raw_merged_list
- name: Final expected list cleaned out
ansible.builtin.debug:
var: merged_list
运行 playbook 会给出(如果您想显示原始变量,请添加
-v
)
PLAY [localhost] *************************************************************************************************************************************************************************************************************
TASK [Show original device list (run with -v to display)] ********************************************************************************************************************************************************************
skipping: [localhost]
TASK [Show original json result (run with -v to display)] ********************************************************************************************************************************************************************
skipping: [localhost]
TASK [Show json list transformed with `DEVICE_NAME` added] *******************************************************************************************************************************************************************
ok: [localhost] => {
"transformed_json_list": [
{
"DEVICE_NAME": "inet-fw.lab.net",
"ID": 54,
"Name": "inet-fw.lab.net",
"PluginKey": "checkpoint_gaia"
},
{
"DEVICE_NAME": "uscx001.net",
"ID": 2558,
"Name": "uscx001.net",
"PluginKey": "hp_aseries_alt_2"
},
{
"DEVICE_NAME": "uscx002.net",
"ID": 2559,
"Name": "uscx002.net",
"PluginKey": "hp_aseries_alt_2"
},
{
"DEVICE_NAME": "test1.net",
"ID": 2560,
"Name": "test1.net",
"PluginKey": "hp_aseries_alt_2"
}
]
}
TASK [Show merged list before cleaning out unwanted elements] ****************************************************************************************************************************************************************
ok: [localhost] => {
"raw_merged_list": [
{
"DEVICE_NAME": "inet-fw.lab.net",
"ID": 54,
"Name": "inet-fw.lab.net",
"PluginKey": "checkpoint_gaia"
},
{
"DEVICE_NAME": "test1.net",
"ID": 2560,
"Name": "test1.net",
"PluginKey": "hp_aseries_alt_2"
},
{
"DEVICE_NAME": "uscx001.net",
"ID": 2558,
"IMPLEMENTATION": "system\nInterface range Gi1/10/0/42 to Gi1/10/0/45 Gi2/10/0/32 to Gi2/10/0/34\ndefault\nport link-mode bridge\ndescription *::HP-HSP::Available::::\nport access vlan 999\nshutdown\nreturn\nsave force",
"NO": "1",
"Name": "uscx001.net",
"POST_CHECK": "dis inter brief | inc 1/10/0/4[2345]|2/10/0/3[234]",
"PRE_CHECK": "dis inter brief | inc 1/10/0/4[2345]|2/10/0/3[234]",
"PluginKey": "hp_aseries_alt_2"
},
{
"DEVICE_NAME": "uscx002.net",
"ID": 2559,
"IMPLEMENTATION": "system\nInterface range Gi1/9/0/9 to Gi1/9/0/12 Gi2/9/0/9 to Gi2/9/0/11\ndefault\nport link-mode bridge\ndescription *::HP-HSP::Available::::\nport access vlan 999\nshutdown\nreturn\nsave force",
"NO": "2",
"Name": "uscx002.net",
"POST_CHECK": "dis inter brief | inc 1/9/0/9|1/9/0/1[012]|2/9/0/9|2/9/0/1[01]",
"PRE_CHECK": "dis inter brief | inc 1/9/0/9|1/9/0/1[012]|2/9/0/9|2/9/0/1[01]",
"PluginKey": "hp_aseries_alt_2"
}
]
}
TASK [Final expected list cleaned out] ***************************************************************************************************************************************************************************************
ok: [localhost] => {
"merged_list": [
{
"DEVICE_NAME": "uscx001.net",
"ID": 2558,
"IMPLEMENTATION": "system\nInterface range Gi1/10/0/42 to Gi1/10/0/45 Gi2/10/0/32 to Gi2/10/0/34\ndefault\nport link-mode bridge\ndescription *::HP-HSP::Available::::\nport access vlan 999\nshutdown\nreturn\nsave force",
"NO": "1",
"Name": "uscx001.net",
"POST_CHECK": "dis inter brief | inc 1/10/0/4[2345]|2/10/0/3[234]",
"PRE_CHECK": "dis inter brief | inc 1/10/0/4[2345]|2/10/0/3[234]",
"PluginKey": "hp_aseries_alt_2"
},
{
"DEVICE_NAME": "uscx002.net",
"ID": 2559,
"IMPLEMENTATION": "system\nInterface range Gi1/9/0/9 to Gi1/9/0/12 Gi2/9/0/9 to Gi2/9/0/11\ndefault\nport link-mode bridge\ndescription *::HP-HSP::Available::::\nport access vlan 999\nshutdown\nreturn\nsave force",
"NO": "2",
"Name": "uscx002.net",
"POST_CHECK": "dis inter brief | inc 1/9/0/9|1/9/0/1[012]|2/9/0/9|2/9/0/1[01]",
"PRE_CHECK": "dis inter brief | inc 1/9/0/9|1/9/0/1[012]|2/9/0/9|2/9/0/1[01]",
"PluginKey": "hp_aseries_alt_2"
}
]
}
PLAY RECAP *******************************************************************************************************************************************************************************************************************
localhost : ok=3 changed=0 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0