在 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 代码获取日志列表的 namefile-name

myserv1_log: "/web/bea_logs/domains/mydom/myserv1/myserv1.log"
myserv2_log: "/web/bea_logs/domains/mydom/myserv2/myserv2.log"

我面临两个挑战。

  1. server 可能并不总是 domain 数组的第 3 个键。
  2. 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