用 Ansible 中另一个列表中的相关匹配值替换列表中的键值
Replace the key value in a list with the relevant matching values from another list in Ansible
我正在尝试用另一个列表中的匹配值替换列表中字典中的键值(此处仅针对 Objectids 中的值)。不知何故,我只能替换第一个值但不能迭代整个列表。这里 input.json 中的相同键将具有来自 finallist.json 的多个匹配值,所有这些值都需要匹配并添加到获得最终预期输出中。
Input.json
[
{
"name": "DNS_One",
"objectIds": [
"DNS_One",
"DNS_One-HO",
"NTP"
]
},
{
"name": "DNS_Two",
"objectIds": [
"NTP"
]
}
]
finallist.json
[
{
"id": "123456",
"net_name": "DNS_One"
},
{
"id": "789101112",
"net_name": "DNS_One"
},
{
"id": "131415161718",
"net_name": "DNS_One-HO"
},
{
"id": "23897845",
"net_name": "NTP"
},
{
"id": "9879879546",
"net_name": "NTP"
}
]
剧本
- name: Id mapping
vars:
objectid: >-
{{
finallist
| selectattr('net_name', 'in', item.1)
| map(attribute = 'id')
| first
| default([])
}}
set_fact:
obj: >-
{{
obj | default([]) +
[item.0 | combine({'objectIds': [objectid]})]
}}
with_subelements:
- "{{ input }}"
- objectIds
ignore_errors: yes
预期输出
[
{
"name": "DNS_One",
"objectIds": [
"123456","789101112"
"131415161718",
"23897845","9879879546"
]
},
{
"name": "DNS_Two",
"objectIds": [
"23897845","9879879546"
]
}
]
读取数据并创建变量finallist和input
- set_fact:
finallist: "{{ lookup('file', 'finallist.json')|from_yaml }}"
- set_fact:
input: "{{ lookup('file', 'input.json')|from_yaml }}"
给予
finallist:
- id: '123456'
net_name: DNS_One
- id: '789101112'
net_name: DNS_One
- id: '131415161718'
net_name: DNS_One-HO
- id: '23897845'
net_name: NTP
- id: '9879879546'
net_name: NTP
input:
- name: DNS_One
objectIds:
- DNS_One
- DNS_One-HO
- NTP
- name: DNS_Two
objectIds:
- NTP
在 finallist 中,按 net_name 对项目进行分组并将列表转换为字典
- set_fact:
finaldict: "{{ finaldict|d({})|
combine({item.0: item.1|map(attribute='id')}) }}"
loop: "{{ finallist|groupby('net_name') }}"
给予
finaldict:
DNS_One:
- '123456'
- '789101112'
DNS_One-HO:
- '131415161718'
NTP:
- '23897845'
- '9879879546'
迭代输入并替换ID
- set_fact:
new: "{{ new|d([]) + [item|combine({'objectIds': _ids})] }}"
loop: "{{ input }}"
vars:
_ids: "{{ item.objectIds|map('extract', finaldict)|list }}"
给出了预期的结果
new:
- name: DNS_One
objectIds:
- ['123456', '789101112']
- ['131415161718']
- ['23897845', '9879879546']
- name: DNS_Two
objectIds:
- ['23897845', '9879879546']
如果需要,您可以展平列表
_ids: "{{ item.objectIds|map('extract', finaldict)|flatten }}"
给予
new:
- name: DNS_One
objectIds: ['123456', '789101112', '131415161718', '23897845', '9879879546']
- name: DNS_Two
objectIds: ['23897845', '9879879546']
我正在尝试用另一个列表中的匹配值替换列表中字典中的键值(此处仅针对 Objectids 中的值)。不知何故,我只能替换第一个值但不能迭代整个列表。这里 input.json 中的相同键将具有来自 finallist.json 的多个匹配值,所有这些值都需要匹配并添加到获得最终预期输出中。
Input.json
[
{
"name": "DNS_One",
"objectIds": [
"DNS_One",
"DNS_One-HO",
"NTP"
]
},
{
"name": "DNS_Two",
"objectIds": [
"NTP"
]
}
]
finallist.json
[
{
"id": "123456",
"net_name": "DNS_One"
},
{
"id": "789101112",
"net_name": "DNS_One"
},
{
"id": "131415161718",
"net_name": "DNS_One-HO"
},
{
"id": "23897845",
"net_name": "NTP"
},
{
"id": "9879879546",
"net_name": "NTP"
}
]
剧本
- name: Id mapping
vars:
objectid: >-
{{
finallist
| selectattr('net_name', 'in', item.1)
| map(attribute = 'id')
| first
| default([])
}}
set_fact:
obj: >-
{{
obj | default([]) +
[item.0 | combine({'objectIds': [objectid]})]
}}
with_subelements:
- "{{ input }}"
- objectIds
ignore_errors: yes
预期输出
[
{
"name": "DNS_One",
"objectIds": [
"123456","789101112"
"131415161718",
"23897845","9879879546"
]
},
{
"name": "DNS_Two",
"objectIds": [
"23897845","9879879546"
]
}
]
读取数据并创建变量finallist和input
- set_fact:
finallist: "{{ lookup('file', 'finallist.json')|from_yaml }}"
- set_fact:
input: "{{ lookup('file', 'input.json')|from_yaml }}"
给予
finallist:
- id: '123456'
net_name: DNS_One
- id: '789101112'
net_name: DNS_One
- id: '131415161718'
net_name: DNS_One-HO
- id: '23897845'
net_name: NTP
- id: '9879879546'
net_name: NTP
input:
- name: DNS_One
objectIds:
- DNS_One
- DNS_One-HO
- NTP
- name: DNS_Two
objectIds:
- NTP
在 finallist 中,按 net_name 对项目进行分组并将列表转换为字典
- set_fact:
finaldict: "{{ finaldict|d({})|
combine({item.0: item.1|map(attribute='id')}) }}"
loop: "{{ finallist|groupby('net_name') }}"
给予
finaldict:
DNS_One:
- '123456'
- '789101112'
DNS_One-HO:
- '131415161718'
NTP:
- '23897845'
- '9879879546'
迭代输入并替换ID
- set_fact:
new: "{{ new|d([]) + [item|combine({'objectIds': _ids})] }}"
loop: "{{ input }}"
vars:
_ids: "{{ item.objectIds|map('extract', finaldict)|list }}"
给出了预期的结果
new:
- name: DNS_One
objectIds:
- ['123456', '789101112']
- ['131415161718']
- ['23897845', '9879879546']
- name: DNS_Two
objectIds:
- ['23897845', '9879879546']
如果需要,您可以展平列表
_ids: "{{ item.objectIds|map('extract', finaldict)|flatten }}"
给予
new:
- name: DNS_One
objectIds: ['123456', '789101112', '131415161718', '23897845', '9879879546']
- name: DNS_Two
objectIds: ['23897845', '9879879546']