Ansible中如何根据键值合并2JSON
How to merge 2 JSON based on the key value in Ansible
我有 2 个 JSON,如下所示。我想根据子网值比较 JSON1 和 JSON2,如果 subnet in JSON1 & localsubnet 在 JSON2 匹配中,然后我想从 JSON2 复制特定本地子网下的行(useVpn)并将其放在 JSON1 中的子网下。请找到预期的结果。
JSON1:
[
{
"ansible_loop_var": "item",
"cache_control": "no-cache, no-store, max-age=0, must-revalidate",
"changed": false,
"connection": "close",
"content": "[{}]",
"content_type": "application/json; charset=utf-8",
"cookies": {},
"cookies_string": "",
"date": "Mon, 18 Oct 2021 13:26:25 GMT",
"elapsed": 1,
"expires": "Fri, 01 Jan 1990 00:00:00 GMT",
"failed": false,
"invocation": {
"module_args": {
"attributes": null,
"body": null,
"body_format": "raw",
"ca_path": null,
"client_cert": null,
"client_key": null,
"creates": null,
"dest": null,
"follow_redirects": "safe",
"force": false,
"force_basic_auth": false,
"group": null,
"headers": {
"Accept": "application/json",
"Content-Type": "application/json"
},
"http_agent": "ansible-httpget",
"method": "GET",
"mode": null,
"owner": null,
"remote_src": false,
"removes": null,
"return_content": true,
"selevel": null,
"serole": null,
"setype": null,
"seuser": null,
"src": null,
"status_code": [
200
],
"timeout": 30,
"unix_socket": null,
"unsafe_writes": false,
"validate_certs": false
}
},
"item": "555",
"json": [
{
"applianceIp": "11.11.11.12",
"dhcpBootOptionsEnabled": false,
"dhcpHandling": "Run a DHCP server",
"dhcpLeaseTime": "1 day",
"fixedIpAssignments": {},
"id": 1,
"name": "Default",
"networkId": "888",
"reservedIpRanges": [],
"subnet": "11.11.11.11/28"
}
],
"msg": "OK (unknown bytes)",
"pragma": "no-cache",
"redirected": false,
"server": "nginx/1.21.3",
"status": 200,
"strict_transport_security": "max-age=15552000; includeSubDomains",
"transfer_encoding": "chunked"
},
{
"ansible_loop_var": "item",
"cache_control": "no-cache, no-store, max-age=0, must-revalidate",
"changed": false,
"connection": "close",
"content": "[{}]",
"content_type": "application/json; charset=utf-8",
"cookies": {},
"cookies_string": "",
"date": "Mon, 18 Oct 2021 13:26:27 GMT",
"elapsed": 0,
"expires": "Fri, 01 Jan 1990 00:00:00 GMT",
"failed": false,
"invocation": {
"module_args": {
"attributes": null,
"body": null,
"body_format": "raw",
"ca_path": null,
"client_cert": null,
"client_key": null,
"creates": null,
"dest": null,
"follow_redirects": "safe",
"force": false,
"force_basic_auth": false,
"group": null,
"headers": {
"Accept": "application/json",
"Content-Type": "application/json"
},
"http_agent": "ansible-httpget",
"method": "GET",
"mode": null,
"owner": null,
"remote_src": false,
"removes": null,
"return_content": true,
"selevel": null,
"serole": null,
"setype": null,
"seuser": null,
"src": null,
"status_code": [
200
],
"timeout": 30,
"unix_socket": null,
"unsafe_writes": false
}
},
"item": "555",
"json": [
{
"applianceIp": "10.10.10.11",
"dhcpBootOptionsEnabled": false,
"dhcpHandling": "Run a DHCP server",
"dhcpLeaseTime": "1 day",
"fixedIpAssignments": {},
"id": 1,
"name": "INTERNAL",
"networkId": "555",
"reservedIpRanges": [],
"subnet": "10.10.10.10/28"
}
],
"msg": "OK (unknown bytes)",
"pragma": "no-cache",
"redirected": false,
"server": "nginx/1.21.3",
"status": 200,
"strict_transport_security": "max-age=15552000; includeSubDomains",
"transfer_encoding": "chunked"
},
{
"ansible_loop_var": "item",
"cache_control": "no-cache, no-store, max-age=0, must-revalidate",
"changed": false,
"connection": "close",
"content": "[{}]",
"content_type": "application/json; charset=utf-8",
"cookies": {},
"cookies_string": "",
"date": "Mon, 18 Oct 2021 13:26:29 GMT",
"elapsed": 0,
"expires": "Fri, 01 Jan 1990 00:00:00 GMT",
"failed": false,
"invocation": {
"module_args": {
"attributes": null,
"body": null,
"body_format": "raw",
"ca_path": null,
"client_cert": null,
"client_key": null,
"creates": null,
"dest": null,
"follow_redirects": "safe",
"force": false,
"force_basic_auth": false,
"group": null,
"headers": {
"Accept": "application/json",
"Content-Type": "application/json"
},
"http_agent": "ansible-httpget",
"method": "GET",
"mode": null,
"owner": null,
"remote_src": false,
"removes": null,
"return_content": true,
"selevel": null,
"serole": null,
"setype": null,
"seuser": null,
"src": null,
"status_code": [
200
],
"timeout": 30,
"unix_socket": null,
"unsafe_writes": false,
"url_password": null
}
},
"item": "abc",
"json": [
{
"applianceIp": "1.5.6.7",
"dhcpBootOptionsEnabled": false,
"dhcpHandling": "Run a DHCP server",
"dhcpLeaseTime": "1 day",
"fixedIpAssignments": {},
"id": 1,
"name": "Default",
"networkId": "abc",
"reservedIpRanges": [],
"subnet": "1.5.6.7/28"
},
{
"applianceIp": "1.2.3.5",
"dhcpBootOptionsEnabled": false,
"dhcpHandling": "Run a DHCP server",
"dhcpLeaseTime": "1 day",
"fixedIpAssignments": {},
"groupPolicyId": "100",
"id": 123,
"name": "Test",
"networkId": "abc",
"reservedIpRanges": [],
"subnet": "1.2.3.4/24"
},
{
"applianceIp": "1.1.3.1",
"dhcpBootOptionsEnabled": false,
"dhcpHandling": "Run a DHCP server",
"dhcpLeaseTime": "1 day",
"dhcpOptions": [],
"dnsNameservers": "upstream_dns",
"fixedIpAssignments": {},
"id": 111,
"name": "sss",
"networkId": "123",
"reservedIpRanges": [],
"subnet": "1.1.3.0/24"
}
],
"msg": "OK (unknown bytes)",
"pragma": "no-cache",
"redirected": false,
"server": "nginx/1.21.3",
"status": 200,
"strict_transport_security": "max-age=15552000; includeSubDomains",
"x_xss_protection": "1; mode=block"
}
]
JSON2:
{
"changed": false,
"msg": "All items completed",
"results": [
{
"ansible_loop_var": "item",
"cache_control": "no-cache, no-store, max-age=0, must-revalidate",
"changed": false,
"connection": "close",
"content": "{}",
"content_type": "application/json; charset=utf-8",
"cookies": {},
"cookies_string": "",
"date": "Mon, 18 Oct 2021 13:26:04 GMT",
"elapsed": 0,
"expires": "Fri, 01 Jan 1990 00:00:00 GMT",
"failed": false,
"invocation": {
"module_args": {
"attributes": null,
"body": null,
"body_format": "raw",
"ca_path": null,
"client_cert": null,
"client_key": null,
"creates": null,
"dest": null,
"follow_redirects": "safe",
"force": false,
"force_basic_auth": false,
"group": null,
"headers": {
"Accept": "application/json",
"Content-Type": "application/json"
},
"http_agent": "ansible-httpget",
"method": "GET",
"mode": null,
"owner": null,
"remote_src": false,
"removes": null,
"return_content": true,
"selevel": null,
"serole": null,
"setype": null,
"seuser": null,
"src": null,
"status_code": [
200
],
"timeout": 30,
"unix_socket": null,
"unsafe_writes": false
}
},
"item": "123",
"json": {
"hubs": [
{
"hubId": "123",
"useDefaultRoute": true
}
],
"mode": "spoke",
"subnets": [
{
"localSubnet": "11.11.11.11/28",
"useVpn": true
},
{
"localSubnet": "0.0.0.0/0",
"useVpn": false
}
]
},
"msg": "OK (unknown bytes)",
"pragma": "no-cache",
"redirected": false,
"server": "nginx/1.21.3",
"status": 200,
"x_ua_compatible": "IE=Edge,chrome=1",
"x_xss_protection": "1; mode=block"
},
{
"ansible_loop_var": "item",
"cache_control": "no-cache, no-store, max-age=0, must-revalidate",
"changed": false,
"connection": "close",
"content": "{}",
"content_type": "application/json; charset=utf-8",
"cookies": {},
"cookies_string": "",
"date": "Mon, 18 Oct 2021 13:26:06 GMT",
"elapsed": 0,
"expires": "Fri, 01 Jan 1990 00:00:00 GMT",
"failed": false,
"invocation": {
"module_args": {
"attributes": null,
"body": null,
"body_format": "raw",
"ca_path": null,
"client_cert": null,
"client_key": null,
"creates": null,
"dest": null,
"follow_redirects": "safe",
"force": false,
"force_basic_auth": false,
"group": null,
"headers": {
"Accept": "application/json",
"Content-Type": "application/json"
},
"http_agent": "ansible-httpget",
"method": "GET",
"mode": null,
"owner": null,
"remote_src": false,
"removes": null,
"return_content": true,
"selevel": null,
"serole": null,
"setype": null,
"seuser": null,
"src": null,
"status_code": [
200
],
"timeout": 30,
}
},
"item": "def",
"json": {
"hubs": [
{
"hubId": "def",
"useDefaultRoute": false
}
],
"mode": "spoke",
"subnets": [
{
"localSubnet": "10.10.10.10/28",
"useVpn": true
}
]
},
"msg": "OK (unknown bytes)",
"pragma": "no-cache",
"redirected": false,
"server": "nginx/1.21.3",
"status": 200,
"x_xss_protection": "1; mode=block"
},
{
"ansible_loop_var": "item",
"cache_control": "no-cache, no-store, max-age=0, must-revalidate",
"changed": false,
"connection": "close",
"content": "{}",
"content_type": "application/json; charset=utf-8",
"cookies": {},
"cookies_string": "",
"date": "Mon, 18 Oct 2021 13:26:07 GMT",
"elapsed": 0,
"expires": "Fri, 01 Jan 1990 00:00:00 GMT",
"failed": false,
"invocation": {
"module_args": {
"attributes": null,
"body": null,
"body_format": "raw",
"ca_path": null,
"client_cert": null,
"client_key": null,
"creates": null,
"dest": null,
"follow_redirects": "safe",
"force": false,
"force_basic_auth": false,
"group": null,
"headers": {
"Accept": "application/json",
"Content-Type": "application/json"
},
"http_agent": "ansible-httpget",
"method": "GET",
"mode": null,
"status_code": [
200
],
"timeout": 30,
"validate_certs": false
}
},
"item": "abc",
"json": {
"hubs": [
{
"hubId": "abc",
"useDefaultRoute": false
}
],
"mode": "spoke",
"subnets": [
{
"localSubnet": "1.5.6.7/28",
"useVpn": true
},
{
"localSubnet": "1.2.3.4/24",
"useVpn": false
},
{
"localSubnet": "1.1.3.0/24",
"useVpn": false
}
]
},
"msg": "OK (unknown bytes)",
"x_xss_protection": "1; mode=block"
}
],
"skipped": false
}
预期结果:
{
"applianceIp": "1.1.1.3",
"subnet": "1.1.1.1/28",
"useVpn": true
}
代码:
- name: Combine corresponding UseVpn value to each element in json1 inside the result variable
vars:
vpn_value: >-
{{
json2.results[0].json.subnets
| selectattr('localSubnet', '==', item.subnet)
| map(attribute='useVpn')
| first
| default(false, true)
}}
set_fact:
result: >-
{{
result | default([])
+
[item | combine({'useVpn': vpn_value})]
}}
loop: "{{ json1[0].json }}"
- debug:
msg:
- "{{ result }}"
这里的人们通常期望您提供一个您已经尝试过的示例实现,如果您想在这里度过一些美好的时光,您应该认真考虑下一个问题(阅读 how to ask and creating an MCVE)。
同时,因为我也知道 ansible 中的数据操作很容易让初学者迷失方向,这里有可能得到你的结果,它会引入几个你需要经历一次或另一次的过滤器和模块。
我强烈建议您阅读以下文档章节以理解下面的示例:
以下剧本:
---
- hosts: localhost
gather_facts: false
vars:
json1: [ { "applianceIp": "1.1.1.3", "subnet": "1.1.1.1/28" } ]
json2: { "hubs": [ { "hubId": "abs", "useDefaultRoute": true } ], "mode": "spoke", "subnets": [ { "localSubnet": "1.1.1.1/28", "useVpn": true }, { "localSubnet": "0.0.0.0/0", "useVpn": false } ] }
tasks:
- name: Combine corresponding UseVpn value to each element in json1 inside the result variable
vars:
vpn_value: >-
{{
json2.subnets
| selectattr('localSubnet', '==', item.subnet)
| map(attribute='useVpn')
| first
| default(false, true)
}}
set_fact:
result: >-
{{
result | default([])
+
[item | combine({'useVpn': vpn_value})]
}}
loop: "{{ json1 }}"
- name: Show the result
debug:
var: result
给出:
PLAY [localhost] ***********************************************************************************************************************************************************************************************************************
TASK [Combine corresponding UseVpn value to each element in json1 inside the result variable] *********************************************************************************************************************************************************************
ok: [localhost] => (item={'applianceIp': '1.1.1.3', 'subnet': '1.1.1.1/28'})
TASK [Show the result] *****************************************************************************************************************************************************************************************************************
ok: [localhost] => {
"result": [
{
"applianceIp": "1.1.1.3",
"subnet": "1.1.1.1/28",
"useVpn": true
}
]
}
PLAY RECAP *****************************************************************************************************************************************************************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
我有 2 个 JSON,如下所示。我想根据子网值比较 JSON1 和 JSON2,如果 subnet in JSON1 & localsubnet 在 JSON2 匹配中,然后我想从 JSON2 复制特定本地子网下的行(useVpn)并将其放在 JSON1 中的子网下。请找到预期的结果。
JSON1:
[
{
"ansible_loop_var": "item",
"cache_control": "no-cache, no-store, max-age=0, must-revalidate",
"changed": false,
"connection": "close",
"content": "[{}]",
"content_type": "application/json; charset=utf-8",
"cookies": {},
"cookies_string": "",
"date": "Mon, 18 Oct 2021 13:26:25 GMT",
"elapsed": 1,
"expires": "Fri, 01 Jan 1990 00:00:00 GMT",
"failed": false,
"invocation": {
"module_args": {
"attributes": null,
"body": null,
"body_format": "raw",
"ca_path": null,
"client_cert": null,
"client_key": null,
"creates": null,
"dest": null,
"follow_redirects": "safe",
"force": false,
"force_basic_auth": false,
"group": null,
"headers": {
"Accept": "application/json",
"Content-Type": "application/json"
},
"http_agent": "ansible-httpget",
"method": "GET",
"mode": null,
"owner": null,
"remote_src": false,
"removes": null,
"return_content": true,
"selevel": null,
"serole": null,
"setype": null,
"seuser": null,
"src": null,
"status_code": [
200
],
"timeout": 30,
"unix_socket": null,
"unsafe_writes": false,
"validate_certs": false
}
},
"item": "555",
"json": [
{
"applianceIp": "11.11.11.12",
"dhcpBootOptionsEnabled": false,
"dhcpHandling": "Run a DHCP server",
"dhcpLeaseTime": "1 day",
"fixedIpAssignments": {},
"id": 1,
"name": "Default",
"networkId": "888",
"reservedIpRanges": [],
"subnet": "11.11.11.11/28"
}
],
"msg": "OK (unknown bytes)",
"pragma": "no-cache",
"redirected": false,
"server": "nginx/1.21.3",
"status": 200,
"strict_transport_security": "max-age=15552000; includeSubDomains",
"transfer_encoding": "chunked"
},
{
"ansible_loop_var": "item",
"cache_control": "no-cache, no-store, max-age=0, must-revalidate",
"changed": false,
"connection": "close",
"content": "[{}]",
"content_type": "application/json; charset=utf-8",
"cookies": {},
"cookies_string": "",
"date": "Mon, 18 Oct 2021 13:26:27 GMT",
"elapsed": 0,
"expires": "Fri, 01 Jan 1990 00:00:00 GMT",
"failed": false,
"invocation": {
"module_args": {
"attributes": null,
"body": null,
"body_format": "raw",
"ca_path": null,
"client_cert": null,
"client_key": null,
"creates": null,
"dest": null,
"follow_redirects": "safe",
"force": false,
"force_basic_auth": false,
"group": null,
"headers": {
"Accept": "application/json",
"Content-Type": "application/json"
},
"http_agent": "ansible-httpget",
"method": "GET",
"mode": null,
"owner": null,
"remote_src": false,
"removes": null,
"return_content": true,
"selevel": null,
"serole": null,
"setype": null,
"seuser": null,
"src": null,
"status_code": [
200
],
"timeout": 30,
"unix_socket": null,
"unsafe_writes": false
}
},
"item": "555",
"json": [
{
"applianceIp": "10.10.10.11",
"dhcpBootOptionsEnabled": false,
"dhcpHandling": "Run a DHCP server",
"dhcpLeaseTime": "1 day",
"fixedIpAssignments": {},
"id": 1,
"name": "INTERNAL",
"networkId": "555",
"reservedIpRanges": [],
"subnet": "10.10.10.10/28"
}
],
"msg": "OK (unknown bytes)",
"pragma": "no-cache",
"redirected": false,
"server": "nginx/1.21.3",
"status": 200,
"strict_transport_security": "max-age=15552000; includeSubDomains",
"transfer_encoding": "chunked"
},
{
"ansible_loop_var": "item",
"cache_control": "no-cache, no-store, max-age=0, must-revalidate",
"changed": false,
"connection": "close",
"content": "[{}]",
"content_type": "application/json; charset=utf-8",
"cookies": {},
"cookies_string": "",
"date": "Mon, 18 Oct 2021 13:26:29 GMT",
"elapsed": 0,
"expires": "Fri, 01 Jan 1990 00:00:00 GMT",
"failed": false,
"invocation": {
"module_args": {
"attributes": null,
"body": null,
"body_format": "raw",
"ca_path": null,
"client_cert": null,
"client_key": null,
"creates": null,
"dest": null,
"follow_redirects": "safe",
"force": false,
"force_basic_auth": false,
"group": null,
"headers": {
"Accept": "application/json",
"Content-Type": "application/json"
},
"http_agent": "ansible-httpget",
"method": "GET",
"mode": null,
"owner": null,
"remote_src": false,
"removes": null,
"return_content": true,
"selevel": null,
"serole": null,
"setype": null,
"seuser": null,
"src": null,
"status_code": [
200
],
"timeout": 30,
"unix_socket": null,
"unsafe_writes": false,
"url_password": null
}
},
"item": "abc",
"json": [
{
"applianceIp": "1.5.6.7",
"dhcpBootOptionsEnabled": false,
"dhcpHandling": "Run a DHCP server",
"dhcpLeaseTime": "1 day",
"fixedIpAssignments": {},
"id": 1,
"name": "Default",
"networkId": "abc",
"reservedIpRanges": [],
"subnet": "1.5.6.7/28"
},
{
"applianceIp": "1.2.3.5",
"dhcpBootOptionsEnabled": false,
"dhcpHandling": "Run a DHCP server",
"dhcpLeaseTime": "1 day",
"fixedIpAssignments": {},
"groupPolicyId": "100",
"id": 123,
"name": "Test",
"networkId": "abc",
"reservedIpRanges": [],
"subnet": "1.2.3.4/24"
},
{
"applianceIp": "1.1.3.1",
"dhcpBootOptionsEnabled": false,
"dhcpHandling": "Run a DHCP server",
"dhcpLeaseTime": "1 day",
"dhcpOptions": [],
"dnsNameservers": "upstream_dns",
"fixedIpAssignments": {},
"id": 111,
"name": "sss",
"networkId": "123",
"reservedIpRanges": [],
"subnet": "1.1.3.0/24"
}
],
"msg": "OK (unknown bytes)",
"pragma": "no-cache",
"redirected": false,
"server": "nginx/1.21.3",
"status": 200,
"strict_transport_security": "max-age=15552000; includeSubDomains",
"x_xss_protection": "1; mode=block"
}
]
JSON2:
{
"changed": false,
"msg": "All items completed",
"results": [
{
"ansible_loop_var": "item",
"cache_control": "no-cache, no-store, max-age=0, must-revalidate",
"changed": false,
"connection": "close",
"content": "{}",
"content_type": "application/json; charset=utf-8",
"cookies": {},
"cookies_string": "",
"date": "Mon, 18 Oct 2021 13:26:04 GMT",
"elapsed": 0,
"expires": "Fri, 01 Jan 1990 00:00:00 GMT",
"failed": false,
"invocation": {
"module_args": {
"attributes": null,
"body": null,
"body_format": "raw",
"ca_path": null,
"client_cert": null,
"client_key": null,
"creates": null,
"dest": null,
"follow_redirects": "safe",
"force": false,
"force_basic_auth": false,
"group": null,
"headers": {
"Accept": "application/json",
"Content-Type": "application/json"
},
"http_agent": "ansible-httpget",
"method": "GET",
"mode": null,
"owner": null,
"remote_src": false,
"removes": null,
"return_content": true,
"selevel": null,
"serole": null,
"setype": null,
"seuser": null,
"src": null,
"status_code": [
200
],
"timeout": 30,
"unix_socket": null,
"unsafe_writes": false
}
},
"item": "123",
"json": {
"hubs": [
{
"hubId": "123",
"useDefaultRoute": true
}
],
"mode": "spoke",
"subnets": [
{
"localSubnet": "11.11.11.11/28",
"useVpn": true
},
{
"localSubnet": "0.0.0.0/0",
"useVpn": false
}
]
},
"msg": "OK (unknown bytes)",
"pragma": "no-cache",
"redirected": false,
"server": "nginx/1.21.3",
"status": 200,
"x_ua_compatible": "IE=Edge,chrome=1",
"x_xss_protection": "1; mode=block"
},
{
"ansible_loop_var": "item",
"cache_control": "no-cache, no-store, max-age=0, must-revalidate",
"changed": false,
"connection": "close",
"content": "{}",
"content_type": "application/json; charset=utf-8",
"cookies": {},
"cookies_string": "",
"date": "Mon, 18 Oct 2021 13:26:06 GMT",
"elapsed": 0,
"expires": "Fri, 01 Jan 1990 00:00:00 GMT",
"failed": false,
"invocation": {
"module_args": {
"attributes": null,
"body": null,
"body_format": "raw",
"ca_path": null,
"client_cert": null,
"client_key": null,
"creates": null,
"dest": null,
"follow_redirects": "safe",
"force": false,
"force_basic_auth": false,
"group": null,
"headers": {
"Accept": "application/json",
"Content-Type": "application/json"
},
"http_agent": "ansible-httpget",
"method": "GET",
"mode": null,
"owner": null,
"remote_src": false,
"removes": null,
"return_content": true,
"selevel": null,
"serole": null,
"setype": null,
"seuser": null,
"src": null,
"status_code": [
200
],
"timeout": 30,
}
},
"item": "def",
"json": {
"hubs": [
{
"hubId": "def",
"useDefaultRoute": false
}
],
"mode": "spoke",
"subnets": [
{
"localSubnet": "10.10.10.10/28",
"useVpn": true
}
]
},
"msg": "OK (unknown bytes)",
"pragma": "no-cache",
"redirected": false,
"server": "nginx/1.21.3",
"status": 200,
"x_xss_protection": "1; mode=block"
},
{
"ansible_loop_var": "item",
"cache_control": "no-cache, no-store, max-age=0, must-revalidate",
"changed": false,
"connection": "close",
"content": "{}",
"content_type": "application/json; charset=utf-8",
"cookies": {},
"cookies_string": "",
"date": "Mon, 18 Oct 2021 13:26:07 GMT",
"elapsed": 0,
"expires": "Fri, 01 Jan 1990 00:00:00 GMT",
"failed": false,
"invocation": {
"module_args": {
"attributes": null,
"body": null,
"body_format": "raw",
"ca_path": null,
"client_cert": null,
"client_key": null,
"creates": null,
"dest": null,
"follow_redirects": "safe",
"force": false,
"force_basic_auth": false,
"group": null,
"headers": {
"Accept": "application/json",
"Content-Type": "application/json"
},
"http_agent": "ansible-httpget",
"method": "GET",
"mode": null,
"status_code": [
200
],
"timeout": 30,
"validate_certs": false
}
},
"item": "abc",
"json": {
"hubs": [
{
"hubId": "abc",
"useDefaultRoute": false
}
],
"mode": "spoke",
"subnets": [
{
"localSubnet": "1.5.6.7/28",
"useVpn": true
},
{
"localSubnet": "1.2.3.4/24",
"useVpn": false
},
{
"localSubnet": "1.1.3.0/24",
"useVpn": false
}
]
},
"msg": "OK (unknown bytes)",
"x_xss_protection": "1; mode=block"
}
],
"skipped": false
}
预期结果:
{
"applianceIp": "1.1.1.3",
"subnet": "1.1.1.1/28",
"useVpn": true
}
代码:
- name: Combine corresponding UseVpn value to each element in json1 inside the result variable
vars:
vpn_value: >-
{{
json2.results[0].json.subnets
| selectattr('localSubnet', '==', item.subnet)
| map(attribute='useVpn')
| first
| default(false, true)
}}
set_fact:
result: >-
{{
result | default([])
+
[item | combine({'useVpn': vpn_value})]
}}
loop: "{{ json1[0].json }}"
- debug:
msg:
- "{{ result }}"
这里的人们通常期望您提供一个您已经尝试过的示例实现,如果您想在这里度过一些美好的时光,您应该认真考虑下一个问题(阅读 how to ask and creating an MCVE)。
同时,因为我也知道 ansible 中的数据操作很容易让初学者迷失方向,这里有可能得到你的结果,它会引入几个你需要经历一次或另一次的过滤器和模块。
我强烈建议您阅读以下文档章节以理解下面的示例:
以下剧本:
---
- hosts: localhost
gather_facts: false
vars:
json1: [ { "applianceIp": "1.1.1.3", "subnet": "1.1.1.1/28" } ]
json2: { "hubs": [ { "hubId": "abs", "useDefaultRoute": true } ], "mode": "spoke", "subnets": [ { "localSubnet": "1.1.1.1/28", "useVpn": true }, { "localSubnet": "0.0.0.0/0", "useVpn": false } ] }
tasks:
- name: Combine corresponding UseVpn value to each element in json1 inside the result variable
vars:
vpn_value: >-
{{
json2.subnets
| selectattr('localSubnet', '==', item.subnet)
| map(attribute='useVpn')
| first
| default(false, true)
}}
set_fact:
result: >-
{{
result | default([])
+
[item | combine({'useVpn': vpn_value})]
}}
loop: "{{ json1 }}"
- name: Show the result
debug:
var: result
给出:
PLAY [localhost] ***********************************************************************************************************************************************************************************************************************
TASK [Combine corresponding UseVpn value to each element in json1 inside the result variable] *********************************************************************************************************************************************************************
ok: [localhost] => (item={'applianceIp': '1.1.1.3', 'subnet': '1.1.1.1/28'})
TASK [Show the result] *****************************************************************************************************************************************************************************************************************
ok: [localhost] => {
"result": [
{
"applianceIp": "1.1.1.3",
"subnet": "1.1.1.1/28",
"useVpn": true
}
]
}
PLAY RECAP *****************************************************************************************************************************************************************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0