Как выбрать элемент из списка со значением, ближайшим к другому в Ansible - PullRequest
0 голосов
/ 11 октября 2019

У меня есть книга воспроизведения, которая возвращает следующий вывод:

ok: [Lab_Core_SW] => {
    "Test_List": [
        {
            "Firewall_IP": "10.120.193.100",
            "IP_Address": "10.120.0.0",
            "IP_and_Mask": "10.120.0.0/16",
            "Subnet_Mask": "16",
            "VRF_Name": "vrf1"
        },
        {
            "Firewall_IP": "10.120.160.36",
            "IP_Address": "10.120.46.0",
            "IP_and_Mask": "10.120.46.0/25",
            "Subnet_Mask": "25",
            "VRF_Name": "vrf2"
        },
        {
            "Firewall_IP": "10.120.187.68",
            "IP_Address": "10.120.0.0",
            "IP_and_Mask": "10.120.0.0/16",
            "Subnet_Mask": "16",
            "VRF_Name": "vrf3"
        },
        {
            "Firewall_IP": "10.109.1.66",
            "IP_Address": "10.0.0.0",
            "IP_and_Mask": "10.0.0.0/8",
            "Subnet_Mask": "8",
            "VRF_Name": "vrf4"
        },
        {
            "Firewall_IP": "10.120.184.68",
            "IP_Address": "10.120.0.0",
            "IP_and_Mask": "10.120.0.0/16",
            "Subnet_Mask": "16",
            "VRF_Name": "vrf5"
        }
    ]
}

Есть ли способ, которым я могу взять Subnet_Mask каждого элемента в списке и найти число, ближайшее к 32, а затем только распечатать этоэлемент в списке, поэтому у меня осталось следующее:

        {
            "Firewall_IP": "10.120.160.36",
            "IP_Address": "10.120.46.0",
            "IP_and_Mask": "10.120.46.0/25",
            "Subnet_Mask": "25",
            "VRF_Name": "vrf2"
        }

Я не хочу использовать when: item.Subnet_Mask >= x, так как это может либо вернуть более одного результата, либо ни одного, в зависимости от маршрутов наосновной коммутатор.

Я посмотрел на фильтр ipaddr, но, похоже, он не имеет того, что мне нужно.

Я знаю о лямбда-функции в python, но если я могу каким-либо образом связать ее с ansible, я не смог выяснить, как.

Любая помощь приветствуется

1 Ответ

0 голосов
/ 11 октября 2019

Я не уверен в вашем точном случае использования, но вы можете извлечь элемент из списка с атрибутом, который ближе всего к некоторому другому атрибуту, выполнив что-то вроде ниже. Обратите внимание, что он загружает ваш вывод из файла JSON - в вашем случае он, скорее всего, уже зарегистрирован.

play.yaml:

---
- hosts: 127.0.0.1
  connection: local
  gather_facts: no
  vars:
    obj: "{{ lookup('file', 'list.json') | from_json }}"

  tasks:
    - set_fact:
        diff: "{{ 32 - item['Subnet_Mask'] | int }}"
      loop: "{{ obj['Test_List'] }}"
      register: diff_result
    - set_fact:
        min_diff: "{{ diff_result.results | sort(attribute='ansible_facts.diff') | first }}"
    - debug:
        var: min_diff.item

Эта книга воспроизведения зацикливаетсякаждый элемент вычитает маску подсети из 32, сортирует результаты по разности и выводит элемент с наименьшей разницей.

Запуск с:

ANSIBLE_JINJA2_NATIVE=True ansible-playbook play.yaml -i 127.0.0.1,

ANSIBLE_JINJA2_NATIVE необходимо, чтобы убедиться, что diff записано как целое число вместо строки, используя set_fact.

Выход:

TASK [debug]
ok: [127.0.0.1] => {
    "min_diff.item": {
        "Firewall_IP": "10.120.160.36", 
        "IP_Address": "10.120.46.0", 
        "IP_and_Mask": "10.120.46.0/25", 
        "Subnet_Mask": "25", 
        "VRF_Name": "vrf2"
    }
}
...