Создать словарь из зарегистрированной переменной с разных хостов

У меня есть задача, которая сообщает мне, открыт порт или нет в списке хостов с netstat:

- name: who is listening on port 5555
  shell: netstat -paunt | grep 5555
  register: test
  ignore_errors: true

Итак, у меня есть переменная, содержащая для каждого хоста это значение:

ok: [host1 -> localhost] => {
    "msg": "tcp        0      0 XX.XX.XX.XX:5555      0.0.0.0:*               LISTEN      -                   "
}

Что я хотел бы сделать, так это объединить все непустые вары с именем test в один словарь. Но я не знаю, как это сделать. Можно ли вообще это сделать с помощью ансибла?

Конечным результатом для меня является создание динамического словаря IP с открытым портом, и я выберу случайный из словаря, чтобы провести тест.

Я хочу создать единый словарь из всех зарегистрированных переменных с именем «test», которые содержат результат задачи «кто прослушивает порт 5555».

На данный момент я пытаюсь создать свой словарь, выполнив:

- name: fact
  set_fact:
      ip: "{{ item }}"
  with_items: "{{ test.stdout }}"
  when: test.stdout |length > 0

но он не создает словарь, содержащий результаты со всех хостов. хост создает словарь, содержащий только его результат.


person Wurstmeister    schedule 19.12.2019    source источник
comment
Можете ли вы более четко сказать, чем вы хотите заниматься? Также напишите python код, который вы пробовали до сих пор.   -  person marcos    schedule 19.12.2019
comment
все факты о хостах доступны из любого места в hostvars['name in inventory']. Ссылка: docs.ansible.com/ansible/latest/reference_appendices/   -  person Zeitounator    schedule 19.12.2019
comment
я бы хотел создать единый словарь или список, содержащий IP-адрес, к которому привязан конкретный порт, со всех моих хостов. У некоторых из них этот порт не открыт, поэтому я хочу создать список или словарь динамически. Основная цель - провести тест, в котором задействован этот конкретный порт на случайном IP-адресе из списка или словаря.   -  person Wurstmeister    schedule 19.12.2019


Ответы (1)


Пояснение к приведенному ниже примеру (не тестировалось как есть, но на аналогичной структуре данных).

  • Все факты, зарегистрированные для каждого хоста, доступны в словаре hostvars (одна ключевая запись для каждого хоста, названная по имени в инвентаре. См. доступные специальные переменные).
  • Вы можете преобразовать dict в список пар ключ / значение с помощью dict2items фильтр.
  • Вы можете использовать json_query для выбора всех элементов. имеющий существующий value.test, и перепишите список так, чтобы каждый элемент был {key: host, value: <value of stdout of test var>}
  • Затем вы можете использовать items2dict, чтобы восстановить отфильтрованные и преобразовал список ключей / значений в словарь.

Следующая игра (для запуска после фактического сбора урожая) должна дать вам то, что вы ожидаете:

- name: Consolidate test result in a single dict
  hosts: localhost
  gather_facts: false

  tasks:
    - name: Show the result
      debug:
        msg: >-
          {{
            hostvars
            | dict2items
            | json_query("[?value.test].{key: key, value: value.test.stdout}")
            | items2dict
          }}
person Zeitounator    schedule 19.12.2019
comment
Большое спасибо за ваш ответ. Кажется, он работает так, как задумано, но я, к сожалению, пока не могу его использовать по той причине, что я могу использовать только ansible 2.4, а dict2items и items2dict представлены в 2.7 и 2.8. - person Wurstmeister; 20.12.2019
comment
Ansible 2.4 очень старый. Что мешает вам установить нужную версию в вашей среде (установить как пользователь с помощью pip, использовать python virtualenv ...)? - person Zeitounator; 20.12.2019
comment
Я знаю, но, к сожалению, это не мое решение, я должен использовать только инструменты, одобренные группами. Насколько я понимаю, в ansible 2,4 я не смогу сделать это простым способом. поэтому я создам файл temps на каждой машине с результатом netstat, затем извлечу его с моего доступного сервера и объединю один файл, который я затем буду использовать. Но я сохраню ваше решение, чтобы улучшить мою книгу, когда они одобрят новую версию ansible. - person Wurstmeister; 20.12.2019