【问题标题】:Ansible - accessing dict of dict of dictsAnsible - 访问字典的字典
【发布时间】:2020-01-16 01:34:52
【问题描述】:

我有一个具有以下数据结构的外部数据文件:

---
server1:
  service_name:
    jboss_prod_1:
      enabled: "True"
      started: "True"
    jboss_prod_2:
      enabled: "True"
      started: "True"
    jboss_prod_3:
      enabled: "True"
      started: "True"
    jboss_prod_4:
      enabled: "False"
      started: "False"
    jboss_prod_5:
      enabled: "False"
      started: "False"

server2:
  service_name:
    jboss_prod_3:
      enabled: "True"
      started: "True"
    jboss_prod_5:
      enabled: "True"
      started: "True"
    jboss_prod_7:
      enabled: "True"
      started: "True"
    jboss_prod_9:
      enabled: "False"
      started: "False"
    jboss_prod_13:
      enabled: "False"
      started: "False"

我一直在尝试找到一种方法,通过输出显示服务器名称、其上的服务以及它们的启用和启动的 2 个值。到目前为止,我可以很好地到达第 3 层,但不能一直到达第 4 层,因为“服务名称”的值是未知的——我无法假设它的值或顺序。

这行得通:

---
- name: test creating a dictionary from external file
  hosts: localhost
  gather_facts: False
  tasks:
    - name: load the file
      include_vars:
        name: service_map
        file: vars/service_map.yml

    - name: SHOW ME THE MONEY!
      loop: "{{ lookup('dict', service_map) }}"
      debug:
        msg: "{{item.value}}"                                                                                                                                                                      
      with_dict:
        - "{{item.value.service_name}}"

并产生这个输出:

PLAY [test creating a dictionary from external file] **********************************************************************************************************************************************

TASK [load the file] ******************************************************************************************************************************************************************************
ok: [localhost]

TASK [SHOW ME THE MONEY!] *************************************************************************************************************************************************************************
ok: [localhost] => (item={'value': u'server1', 'key': u'key'}) => {
    "msg": "server1"
}
ok: [localhost] => (item={'value': {u'service_name': {u'jboss_prod_2': {u'started': u'True', u'enabled': u'True'}, u'jboss_prod_3': {u'started': u'True', u'enabled': u'True'}, u'jboss_prod_1': {u'started': u'True', u'enabled': u'True'}, u'jboss_prod_4': {u'started': u'False', u'enabled': u'False'}, u'jboss_prod_5': {u'started': u'False', u'enabled': u'False'}}}, 'key': u'value'}) => {
    "msg": {
        "service_name": {
            "jboss_prod_1": {
                "enabled": "True", 
                "started": "True"
            }, 
            "jboss_prod_2": {
                "enabled": "True", 
                "started": "True"
            }, 
            "jboss_prod_3": {
                "enabled": "True", 
                "started": "True"
            }, 
            "jboss_prod_4": {
                "enabled": "False", 
                "started": "False"
            }, 
            "jboss_prod_5": {
                "enabled": "False", 
                "started": "False"
            }
        }
    }
}
ok: [localhost] => (item={'value': u'server2', 'key': u'key'}) => {
    "msg": "server2"
}
ok: [localhost] => (item={'value': {u'service_name': {u'jboss_prod_3': {u'started': u'True', u'enabled': u'True'}, u'jboss_prod_5': {u'started': u'True', u'enabled': u'True'}, u'jboss_prod_9': {u'started': u'False', u'enabled': u'False'}, u'jboss_prod_7': {u'started': u'True', u'enabled': u'True'}, u'jboss_prod_13': {u'started': u'False', u'enabled': u'False'}}}, 'key': u'value'}) => {
    "msg": {
        "service_name": {
            "jboss_prod_13": {
                "enabled": "False", 
                "started": "False"
            }, 
            "jboss_prod_3": {
                "enabled": "True", 
                "started": "True"
            }, 
            "jboss_prod_5": {
                "enabled": "True", 
                "started": "True"
            }, 
            "jboss_prod_7": {
                "enabled": "True", 
                "started": "True"
            }, 
            "jboss_prod_9": {
                "enabled": "False", 
                "started": "False"
            }
        }
    }
}

PLAY RECAP ****************************************************************************************************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0 

但我需要查看是否可以获得列出服务器、服务名称和 2 个状态的内容。希望这是足够的信息,有人可以帮助我。我对 Ansible 比较陌生,对复杂数据结构的迭代让我感到厌烦。

【问题讨论】:

    标签: ansible yaml ansible-2.x


    【解决方案1】:

    问:列出服务器、服务名称,然后是 2 个状态。

    A:下面的任务完成了这项工作

    - set_fact:
        service_map2: "{{ service_map2|default({})|
                          combine({item.key:
                                   item.value.service_name}) }}"
      loop: "{{ service_map|dict2items }}"
    

    字典service_map2“列出服务器、服务名称和两种状态”

    "service_map2": {
        "server1": {
            "jboss_prod_1": {
                "enabled": "True", 
                "started": "True"
            }, 
            "jboss_prod_2": {
                "enabled": "True", 
                "started": "True"
            }, 
            ...
    

    注意事项

    1) 使用 json_query 从字典中选择信息。例如

    A) 列出未启用的服务

    - set_fact:
        result: "{{ result|default({})|
                    combine({item.key: item.value|dict2items|json_query(query)})
                    }}"
      loop: "{{ service_map2|dict2items }}"
      vars:
        query: "[?value.enabled=='False'].key"
    - debug:
        var: result
    

    给予

    "result": {
        "server1": [
            "jboss_prod_4", 
            "jboss_prod_5"
        ], 
        "server2": [
            "jboss_prod_9", 
            "jboss_prod_13"
        ]
    }
    

    B) 列出已启动的服务

        query: "[?value.started=='True'].key"
    

    给予

    "result": {
        "server1": [
            "jboss_prod_2", 
            "jboss_prod_3", 
            "jboss_prod_1"
        ], 
        "server2": [
            "jboss_prod_3", 
            "jboss_prod_5", 
            "jboss_prod_7"
        ]
    }
    

    C) 列出服务器、服务名称和未启用服务的状态。

        query: "[?value.enabled=='False'].{service: key,
                                           enabled: value.enabled,
                                           started: value.started}"
    

    给予

    "result": {
        "server1": [
            {
                "enabled": "False", 
                "service": "jboss_prod_4", 
                "started": "False"
            }, 
            {
                "enabled": "False", 
                "service": "jboss_prod_5", 
                "started": "False"
            }
        ], 
        "server2": [
            {
                "enabled": "False", 
                "service": "jboss_prod_9", 
                "started": "False"
            }, 
            {
                "enabled": "False", 
                "service": "jboss_prod_13", 
                "started": "False"
            }
        ]
    }
    

    2) 下面的任务创建列表service_map2 而不是字典。

    - set_fact:
        service_map2: "{{ service_map2|default([]) +
                          [{item.key:
                            item.value.service_name}] }}"
      loop: "{{ service_map|dict2items }}"
    


    3) 不需要创建service_map2。原始数据 service_map 可用于列出所选服务器、服务名称和 2 个状态
    - set_fact:
        result: "{{ result|default({})|
                    combine({item.key: item.value.service_name|
                                       dict2items|
                                       json_query(query)})
                    }}"
      loop: "{{ service_map|dict2items }}"
      vars:
        query: "[ ...
    

    【讨论】:

      猜你喜欢
      • 2021-11-16
      • 1970-01-01
      • 2020-01-09
      • 2023-03-22
      • 1970-01-01
      • 1970-01-01
      • 2023-03-21
      • 1970-01-01
      • 2020-12-28
      相关资源
      最近更新 更多