Ansible + JMESPath: возвращает имя ключа, если содержит совпадения с вложенными данными - PullRequest
0 голосов
/ 07 ноября 2019

Исходные данные - это словарь JSON, в котором имена ключей верхнего уровня непредсказуемы. Мне нужно имя этого ключа TL, когда вложенные данные внутри совпадают со строкой, которая у меня есть.

Я пытаюсь сделать это с помощью фильтра json_query внутри Ansible 2.9.

Я пробовал различные запросы JMESPath ипроверил их документацию, но все, что я нашел, похоже, требует заранее знать имена этих ключей.

Вот пример данных, которые выводятся из модуля ansible ios_facts для интерфейсов:

{
        "GigabitEthernet0/9": {
            "description": "server",
            "ipv4": [],
            "macaddress": "b8zz.xxxx.7709",
            "type": "Gigabit Ethernet"
        },
        "Vlan13": {
            "description": null,
            "ipv4": [
                {
                    "address": "10.20.30.19",
                    "subnet": "24"
                }
            ],
            "macaddress": "b8zz.xxx.yy41",
            "type": "EtherSVI"
        }
}

Вот игровая книга, с которой я работаю:

---
- name: Cisco IOS - Mgmt Int
  connection: network_cli
  gather_facts: false
  hosts: switch01
  vars:
     netdb: "{{ hostvars[inventory_hostname]['ansible_net_interfaces'] }}"
  tasks:
    - name: get ios facts
      ios_facts:
        gather_subset: interfaces
    - name: json_query
      set_fact:
        mgmtinf: "{{ netdb | json_query(query) }}"
      vars:
        # this gets me true/false
        query: "[Vlan13.ipv4[0].address.contains(@, '10.20.30.19')]"
    - name: output json_query
      debug:
        var: mgmtinf

Выше приведен верный / ложный результат, если результат совпадает. Проблема в том, что я вручную определил интерфейс для просмотра «Vlan13». Поэтому мне нужен способ использовать итератор для этого ключа TL, а затем вернуть значение этого итератора в той части цикла, где происходит совпадение.

1 Ответ

1 голос
/ 07 ноября 2019

Вы не указали все свои требования для выбора подходящего названия ключа, но следующее должно поставить вас в нужное русло.

Ключевые моменты:

  • Использовать dict2tems filter , чтобы преобразовать dict верхнего уровня в список {key: X, value: Y} объектов
  • Используйте jmespath для:
    1. Отфильтруйте элементы, соответствующие vlans (я использовал "Vlan *"«в моем примере)
    2. Отфильтруйте список ips для каждого ipv4 элемента, чтобы он соответствовал только вашему желаемому IP.

Примечание : to_json | from_json в моем выражении необходимо для преодоления текущей ошибки в связи между ansible и jmespath (отображение типов строк).

Вот пример задачи, иллюстрирующей вышеприведенноесценарий.

    - name: Filter out specific ip elements on my vlans
      vars:
        vals: {
          "GigabitEthernet0/9": {
            "description": "server",
            "ipv4": [],
            "macaddress": "b8zz.xxxx.7709",
            "type": "Gigabit Ethernet"
          },
          "Vlan13": {
            "description": null,
            "ipv4": [
            {
              "address": "10.20.30.19",
              "subnet": "24"
            }
            ],
            "macaddress": "b8zz.xxx.yy41",
            "type": "EtherSVI"
          }
        }
        query: >-
          [?starts_with(key, 'Vlan')].value.ipv4[] | [?contains(address, '10.20.30.19')]
      debug:
        msg: >-
          {{ vals | dict2items | to_json | from_json | json_query(query) }}

И результат, который я получаю с вашими текущими значениями:

TASK [Filter out specific ip elements on my vlans] *************************************************************************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": [
        {
            "address": "10.20.30.19",
            "subnet": "24"
        }
    ]
}

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