在 Ansible 中读取时如何处理 JSON 数组中丢失的键
how to deal with missing keys in JSON array when reading in Ansible
下面是我的 JSON 文件:
[
{
"?xml": {
"attributes": {
"encoding": "UTF-8",
"version": "1.0"
}
}
},
{
"domain": [
{
"name": "mydom"
},
{
"domain-version": "12.2.1.3.0"
},
{
"server": [
{
"name": "AdminServer"
},
{
"ssl": {
"name": "AdminServer"
}
},
{
"listen-port": "12400"
},
{
"listen-address": "mydom.host1.bank.com"
}
]
},
{
"server": [
{
"name": "myserv1"
},
{
"ssl": [
{
"name": "myserv1"
},
{
"login-timeout-millis": "25000"
}
]
},
{
"log": [
{
"name": "myserv1"
},
{
"file-name": "/web/bea_logs/domains/mydom/myserv1/myserv1.log"
}
]
}
]
},
{
"server": [
{
"name": "myserv2"
},
{
"ssl": {
"name": "myserv2"
}
},
{
"reverse-dns-allowed": "false"
},
{
"log": [
{
"name": "myserv2"
},
{
"file-name": "/web/bea_logs/domains/mydom/myserv2/myserv2.log"
}
]
}
]
}
]
}
]
我需要使用 ansible 代码获取日志列表的 name
和 file-name
。
myserv1_log: "/web/bea_logs/domains/mydom/myserv1/myserv1.log"
myserv2_log: "/web/bea_logs/domains/mydom/myserv2/myserv2.log"
我面临两个挑战。
server
可能并不总是 domain
数组的第 3 个键。
log
数组可能并不总是所有 server
数组的键,因此不应打印。例如。 server
名称 AdminServer 没有任何 log
列表,而 myserv1 和 myserv2 有。
我需要一个 ansible 代码来打印动态变化所需的 json。
注意:server
将始终是 domain
数组中的键
我在此处参考我的类似查询发帖:
请多多指教。
您只需测试两个键是否存在:
- hosts: localhost
gather_facts: no
vars:
json: "{{ lookup('file', './file.json') | from_json }}"
tasks:
- name: display
debug:
msg: "name: {{ servername }} --> filename: {{ filename }}"
loop: "{{ json[1].domain }}"
vars:
servername: "{{ item.server.0.name }}_log"
filename: "{{ item['server'][2]['log'][1]['file-name'] }}"
when: item.server is defined and item.server.2.log is defined
结果:
TASK [display]
skipping: [localhost] => (item={'name': 'USWL1212MRSHM01'})
skipping: [localhost] => (item={'domain-version': '12.2.1.3.0'})
skipping: [localhost] => (item={'server': [{'name': 'AdminServer'}, {'ssl': {'name': 'AdminServer'}}, {'listen-port': '12400'}, {'listen-address': 'myhost1'}]})
ok: [localhost] => (item={'server': [{'name': 'myserv1'}, {'ssl': {'name': 'myserv1'}}, {'log': [{'name': 'myserv1'}, {'file-name': '/web/bea_logs/domains/mydom/myserv1/myserv1.log'}]}]}) => {
"msg": "name: myserv1_log --> filename: /web/bea_logs/domains/mydom/myserv1/myserv1.log"
}
ok: [localhost] => (item={'server': [{'name': 'myserv2'}, {'ssl': {'name': 'myserv2'}}, {'log': [{'name': 'myserv2'}, {'file-name': '/web/bea_logs/domains/mydom/myserv2/myserv2.log'}]}]}) => {
"msg": "name: myserv2_log --> filename: /web/bea_logs/domains/mydom/myserv2/myserv2.log"
}
如您所见,当条件不成立时,将跳过操作...
您可以通过仅测试键 log
来简化,因为在您的情况下,键 log
始终链接到键 server
when: item.server.2.log is defined
下面是我的 JSON 文件:
[
{
"?xml": {
"attributes": {
"encoding": "UTF-8",
"version": "1.0"
}
}
},
{
"domain": [
{
"name": "mydom"
},
{
"domain-version": "12.2.1.3.0"
},
{
"server": [
{
"name": "AdminServer"
},
{
"ssl": {
"name": "AdminServer"
}
},
{
"listen-port": "12400"
},
{
"listen-address": "mydom.host1.bank.com"
}
]
},
{
"server": [
{
"name": "myserv1"
},
{
"ssl": [
{
"name": "myserv1"
},
{
"login-timeout-millis": "25000"
}
]
},
{
"log": [
{
"name": "myserv1"
},
{
"file-name": "/web/bea_logs/domains/mydom/myserv1/myserv1.log"
}
]
}
]
},
{
"server": [
{
"name": "myserv2"
},
{
"ssl": {
"name": "myserv2"
}
},
{
"reverse-dns-allowed": "false"
},
{
"log": [
{
"name": "myserv2"
},
{
"file-name": "/web/bea_logs/domains/mydom/myserv2/myserv2.log"
}
]
}
]
}
]
}
]
我需要使用 ansible 代码获取日志列表的 name
和 file-name
。
myserv1_log: "/web/bea_logs/domains/mydom/myserv1/myserv1.log"
myserv2_log: "/web/bea_logs/domains/mydom/myserv2/myserv2.log"
我面临两个挑战。
server
可能并不总是domain
数组的第 3 个键。log
数组可能并不总是所有server
数组的键,因此不应打印。例如。server
名称 AdminServer 没有任何log
列表,而 myserv1 和 myserv2 有。
我需要一个 ansible 代码来打印动态变化所需的 json。
注意:server
将始终是 domain
数组中的键
我在此处参考我的类似查询发帖:
请多多指教。
您只需测试两个键是否存在:
- hosts: localhost
gather_facts: no
vars:
json: "{{ lookup('file', './file.json') | from_json }}"
tasks:
- name: display
debug:
msg: "name: {{ servername }} --> filename: {{ filename }}"
loop: "{{ json[1].domain }}"
vars:
servername: "{{ item.server.0.name }}_log"
filename: "{{ item['server'][2]['log'][1]['file-name'] }}"
when: item.server is defined and item.server.2.log is defined
结果:
TASK [display]
skipping: [localhost] => (item={'name': 'USWL1212MRSHM01'})
skipping: [localhost] => (item={'domain-version': '12.2.1.3.0'})
skipping: [localhost] => (item={'server': [{'name': 'AdminServer'}, {'ssl': {'name': 'AdminServer'}}, {'listen-port': '12400'}, {'listen-address': 'myhost1'}]})
ok: [localhost] => (item={'server': [{'name': 'myserv1'}, {'ssl': {'name': 'myserv1'}}, {'log': [{'name': 'myserv1'}, {'file-name': '/web/bea_logs/domains/mydom/myserv1/myserv1.log'}]}]}) => {
"msg": "name: myserv1_log --> filename: /web/bea_logs/domains/mydom/myserv1/myserv1.log"
}
ok: [localhost] => (item={'server': [{'name': 'myserv2'}, {'ssl': {'name': 'myserv2'}}, {'log': [{'name': 'myserv2'}, {'file-name': '/web/bea_logs/domains/mydom/myserv2/myserv2.log'}]}]}) => {
"msg": "name: myserv2_log --> filename: /web/bea_logs/domains/mydom/myserv2/myserv2.log"
}
如您所见,当条件不成立时,将跳过操作...
您可以通过仅测试键 log
来简化,因为在您的情况下,键 log
始终链接到键 server
when: item.server.2.log is defined