访问字典上的嵌套项目

时间:2019-12-10 02:05:48

标签: json dictionary ansible

我有一个包含服务器信息和相关应用程序的json文件。

类似这样的东西:

{
  "Apps": [
   {
      "AppOwner": "Me",
      "AppNm": "Vacations"
   }
  ],
  "Hostnm": "some_server",
  "Environment": "Prod",
  "OSnm": "Windows Server 2008",
  "OSManu": "Microsoft",
  "SerialNum": "VMware-42 14 e1 37 7a 63 9b 0e-43 07 15 46 64 9c 3c 12"
}

我想创建一个包含所有应用程序和服务器的列表

例如

{
    "Vacations": [server1, server2]
},
{
    "other_app": [server2, server3]
},

为此,我一直在尝试以下方法。

- set_fact:
    apps: "{{ apps }} + {{ item.Apps | map(attribute='AppNm') | list}}"
  loop: "{{ server_changes }}"

- set_fact:
    apps_revised: "{{apps | unique}}"

- set_fact:
    apps_server: "{{ apps_revised | default([]) + [{item : []}] }}"
  with_items: "{{ apps_revised }}"

代码的第一部分将从json中获取所有具有重复项的应用程序。
代码的第二部分,将使用唯一的代码清理应用程序。
最后一部分将创建带有(服务器的)嵌套列表的应用程序列表。

问题是我不了解如何导航嵌套的 server_changes 应用程序列表,然后将服务器添加到新列表中。
大概有一种更简单的方法可以完成,因此将不胜感激。

谢谢

1 个答案:

答案 0 :(得分:0)

提供测试数据

server_changes:
  - "Apps":
      - {"AppOwner": "Me", "AppNm": "Vacations"}
    "Hostnm": "server1"
  - "Apps":
      - {"AppOwner": "Me", "AppNm": "Vacations"}
      - {"AppOwner": "Me", "AppNm": "other_app"}
    "Hostnm": "server2"
  - "Apps":
      - {"AppOwner": "Me", "AppNm": "other_app"}
    "Hostnm": "server3"

让我们简化数据。例如

- set_fact:
    my_server_changes: "{{ my_server_changes|default([]) +
                           [{'hostname': item.Hostnm,
                             'applications': item.Apps|
                                             json_query('[].AppNm')}] }}"
  loop: "{{ server_changes }}"
- debug:
    var: my_server_changes

给予

"my_server_changes": [
    {
        "applications": [
            "Vacations"
        ], 
        "hostname": "server1"
    }, 
    {
        "applications": [
            "Vacations", 
            "other_app"
        ], 
        "hostname": "server2"
    }, 
    {
        "applications": [
            "other_app"
        ], 
        "hostname": "server3"
    }
]

创建应用程序列表

- set_fact:
    my_apps: "{{ server_changes|json_query('[].Apps[].AppNm')|unique }}"
- debug:
    var: my_apps

给予

"my_apps": [
    "Vacations", 
    "other_app"
]

然后循环应用程序列表,选择包含 item combine 字典的记录< / p>

- set_fact:
    apps_server: "{{ apps_server|default({})|
                     combine({item: my_server_changes|json_query(query)}) }}"
  loop: "{{ my_apps }}"
  vars:
    query: "[?applications.contains(@, '{{ item }}')].hostname"
- debug:
    var: apps_server

给予

"apps_server": {
    "Vacations": [
        "server1", 
        "server2"
    ], 
    "other_app": [
        "server2", 
        "server3"
    ]
}