Рейтинг:1

Лучший способ переформатировать JSON с помощью Ansible?

флаг cn
raw

У меня есть этот JSON в переменной:

{
"device_vlans": {
    "1": {
        "имя": "по умолчанию",
        "интерфейсы": [
            "Гигабитный Ethernet1/1",
            "Гигабитный Ethernet1/2",
            "Гигабитный Ethernet1/3"
        ]
    },
    "20": {
        "имя": "VLAN20",
        "интерфейсы": [
            "Гигабитный Ethernet1/2"
        ]
    },
    "30": {
        "имя": "VLAN30",
        "интерфейсы": [
            "Гигабитный Ethernet1/3"
        ]
    }
}

Но мне нужно, чтобы это выглядело примерно так:

{
"device_vlans": {
    "Гигабитный Ethernet1/1": {
        "влан": [
            "1"
        ]
    },
    "Гигабитный Ethernet1/2": {
        "влан": [
            "1",
            "20"
        ]
    },
    "Гигабитный Ethernet1/3": {
        "влан": [
            "1",
            "30"
        ]
    }
}

В настоящее время я перебираю все интерфейсы устройства, и внутри этого цикла я перебираю все элементы в переменной device_vlans с помощью когда: элемент == интерфейс. Это очень медленно и вызывает у меня проблемы.

Есть ли лучший способ сделать это с помощью ansible?

Я подумал о пользовательском фильтре, это было бы решением?

Рейтинг:2
флаг br

Создайте список устройств и интерфейсов

    - set_fact:
        dev_ifc: "{{ dev_ifc|d([]) + [{'dev': item.1, 'ifc': item.0.key}] }}"
      with_subelements:
        - "{{device_vlans|dict2items}}"
        - значение.интерфейсы

дает

  dev_ifc:
    - {dev: GigabitEthernet1/1, ifc: '1'}
    - {dev: GigabitEthernet1/2, ifc: '1'}
    - {dev: GigabitEthernet1/3, ifc: '1'}
    - {dev: GigabitEthernet1/2, ifc: '20'}
    - {dev: GigabitEthernet1/3, ifc: '30'}

Затем сгруппируйте список по устройствам и создайте словарь

    - set_fact:
        device_vlans: "{{ dict(key|zip(val)) }}"
      вары:
        arr: "{{ dev_ifc|groupby('dev') }}"
        ключ: "{{ обр|карта('первый')|список }}"
        val: "{{ обр|карта('последняя')|
                     карта ('json_query', '[].ifc') |
                     map('community.general.dict_kv', 'интерфейсы')|
                     список }}"

дает

  device_vlans:
    Гигабитный Ethernet1/1:
      интерфейсы: ['1']
    Гигабитный Ethernet1/2:
      интерфейсы: ['1', '20']
    Гигабитный Ethernet1/3:
      интерфейсы: ['1', '30']

Можно избежать итерации в задаче. Вместо этого поместите итерацию в Jinja2. Например, поместите объявления ниже как соответствующий

    dev_ifc_str: |-
      {% для ifc в device_vlans.keys() %}
      {% для разработчиков в device_vlans[ifc]['interfaces'] %}
      - {dev: {{dev}}, ifc: {{ifc}}}
      {% конец для %}
      {% конец для %}
    dev_ifc: "{{ dev_ifc_str|from_yaml }}"
    device_vlans2: "{{ dict(_key|zip(_val)) }}"
    _arr: "{{ dev_ifc|groupby('dev') }}"
    _key: "{{ _arr|карта('первый')|список }}"
    _val: "{{ _arr|карта('последняя')|
                   карта ('json_query', '[].ifc') |
                   map('community.general.dict_kv', 'интерфейсы')|
                   список }}"
флаг cn
raw
Я получаю сообщение об ошибке с возвращаемой переменной `val`` у вас есть решение ?
флаг br
Добавьте фильтр *list* в канал. Я обновил код.
флаг cn
raw
Спасибо ! @vladimir-botka

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.