Преобразовать список объектов (строка, строка) в словарь (строка, список <string>) в Ansible - PullRequest
1 голос
/ 25 июня 2019

У меня есть список объектов (каждый объект содержит два атрибута типа string), которые мне нужно преобразовать в словарь.Первый атрибут объекта станет ключом, второй атрибут объекта придется объединить в список строк.

Я прошел через несколько решений, но не смог найти именно то, что мне нужно.

Пример ввода:

[
    {
        "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 ]

2 голосов
/ 25 июня 2019

Задачи ниже

- 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 голос
/ 25 июня 2019

Вот так я бы подошел к проблеме.Решение в основном основано на использовании фильтра json_query

Во-первых, вам необходим список всех уникальных имен в списке объектов, чтобы вы могли зацикливаться на нем и извлекатьсоответствующие значения.Это делается путем фильтрации переменной input с помощью следующего выражения шаблона jinja2 {{ input | json_query("[].name") | unique }}

Теперь нам просто нужно перебрать этот список и снова отфильтровать переменную input.На этот раз мы хотим извлечь плоский список всех значений для всех объектов, имеющих данное имя.Это делается с помощью следующего примера выражения jinja2: {{ input | json_query("[?name=='a_unique_name'].value") }}

Остальное - просто вопрос правильной установки фактов, либо в новом списке, либо в hashmap по вашему запросу.Я сделал оба в следующем примере playbook.

Примечание. В этом примере я использовал сложенные блоки yaml с контролем пробела (>-), чтобы упростить запись (ограничение выхода кавычек ...) и чтение (длинные строки).Трещина...).Если вы не знакомы с ними, вы можете проверить https://yaml -multiline.info / для полного обзора всех опций.

Playbook

---
- 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   


Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...