在Ansible

时间:2019-06-25 13:34:35

标签: ansible

我有一个对象列表(每个对象包含两个字符串类型的属性),我需要将其转换为Dictionary。该对象的第一个属性将成为键,该对象的第二个属性将必须组合成字符串列表。

我经历了几种解决方案,但找不到确切的需求。

输入示例:

[
    {
        "name": "AAA",
        "value": "111"
    },
    {
        "name": "AAA",
        "value": "222"
    },
    {
        "name": "BBB",
        "value": "333"
    },
    {
        "name": "BBB",
        "value": "444"
    },
    {
        "name": "CCC",
        "value": "555"
    }
]

所需的输出(两者均可行):

[
    {
        "name": "AAA",
        "value": [ "111", "222" ]
    },
    {
        "name": "BBB",
        "value": [ "333", "444" ]
    },
    {
        "name": "CCC",
        "value": [ "555" ]
    }
]
[
    "AAA": [ "111", "222" ],
    "BBB": [ "333", "444" ],
    "CCC": [ "555" ]
]

2 个答案:

答案 0 :(得分:2)

以下任务

- set_fact:
    my_list: "{{ my_list|default([]) +
                 [{item.0: item.1|json_query('[].value')}] }}"
  loop: "{{ input|groupby('name') }}"
- debug:
    var: my_list

给予

"my_list": [
    {
        "AAA": [
            "111", 
            "222"
        ]
    }, 
    {
        "BBB": [
            "333", 
            "444"
        ]
    }, 
    {
        "CCC": [
            "555"
        ]
    }
]

答案 1 :(得分:1)

这就是我要解决的问题。该解决方案主要基于json_query filter

的使用

首先,您需要在对象列表中包含所有唯一名称的列表,以便可以对其进行循环并提取相应的值。这是通过使用以下jinja2模板表达式input

过滤{{ input | json_query("[].name") | unique }}变量来完成的

现在,我们只需要遍历该列表并再次过滤input变量。这次,我们要提取具有给定名称的所有对象的所有值的平面列表。这是通过以下示例jinja2表达式完成的:{{ input | json_query("[?name=='a_unique_name'].value") }}

剩下的只是根据您的要求在新列表或哈希图中正确设置事实的问题。我在下面的示例剧本中都做了。

注意:在本示例中,我使用了带有空格控制(>-)的yaml折叠块,以简化编写(限制引号转义...)和读取(长行分割...)。如果您不熟悉它们,可以查看https://yaml-multiline.info/以获取所有选项的完整概述。

剧本

---
- name: Rearrange var example
  hosts: localhost
  gather_facts: false

  vars:

     input: [
      { "name": "AAA", "value": "111" },
      { "name": "AAA", "value": "222" },
      { "name": "BBB", "value": "333" },
      { "name": "BBB", "value": "444" },
      { "name": "CCC", "value": "555" }
     ]

  tasks:

    - name: Create list and dict vars
      vars:
        jsquery: >-
          [?name=='{{ item }}'].value
      set_fact:
        list_var: >-
          {{
            list_var | default([])
            +
            [{'name': item, 'value': input | json_query(jsquery)}]
          }}
        dict_var: >-
          {{
            dict_var | default({})
            | combine ({ item: input | json_query(jsquery)})
          }}
      loop: "{{ input | json_query('[].name') | unique }}"


    - name: Show calculated list and dict vars
      debug:
        var: "{{ item }}"
      loop:
        - list_var
        - dict_var

哪个给:

PLAY [Rearrange var example]  ************************************************

TASK [Create list and dict vars] *********************************************
ok: [localhost] => (item=AAA)
ok: [localhost] => (item=BBB)
ok: [localhost] => (item=CCC)

TASK [Show calculated vars] **************************************************
ok: [localhost] => (item=list_var) => {
    "ansible_loop_var": "item",
    "item": "list_var",
    "list_var": [
        {
            "name": "AAA",
            "value": [
                "111",
                "222"
            ]
        },
        {
            "name": "BBB",
            "value": [
                "333",
                "444"
            ]
        },
        {
            "name": "CCC",
            "value": [
                "555"
            ]
        }
    ]
}
ok: [localhost] => (item=dict_var) => {
    "ansible_loop_var": "item",
    "dict_var": {
        "AAA": [
            "111",
            "222"
        ],
        "BBB": [
            "333",
            "444"
        ],
        "CCC": [
            "555"
        ]
    },
    "item": "dict_var"
}

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