Ansible: доступ к переменным и экспорт в CSV файл

Вопрос или проблема

переменные:

сервера:
  - имя: centos
    порт: 22

задачи:

- имя: Проверка удаленного порта
  wait_for: host={{ item.name }} port={{ item.port }} timeout=1
  ignore_errors: True
  register: out
  with_items: "{{ сервера }}"

- debug: var=out

- имя: Сохранить удаленный порт   
  shell: echo "{{ item.host }}" > /tmp/x_output.csv
  args:
    executable: /bin/bash
  with_items: "{{ out.results }}"

ВЫВОД

ИГРА [все] **************************************************************************************************************************

ЗАДАЧА [Сбор фактов] **************************************************************************************************************
ок: [centos]

ЗАДАЧА [telnet : Проверка удаленного порта] ************************************************************************************************
ок: [centos] => (item={u'name': u'centos', u'port': u'22'})

ЗАДАЧА [telnet : debug] ***************************************************************************************************************
ок: [centos] => {
    "out": {
        "changed": false,
        "msg": "Все элементы завершены",
        "results": [
            {
                "_ansible_ignore_errors": true,
                "_ansible_item_result": true,
                "_ansible_no_log": false,
                "_ansible_parsed": true,
                "changed": false,
                "elapsed": 0,
                "failed": false,
                "invocation": {
                    "module_args": {
                        "active_connection_states": [
                            "ESTABLISHED",
                            "FIN_WAIT1",
                            "FIN_WAIT2",
                            "SYN_RECV",
                            "SYN_SENT",
                            "TIME_WAIT"
                        ],
                        "connect_timeout": 5,
                        "delay": 0,
                        "exclude_hosts": null,
                        "host": "centos",
                        "msg": null,
                        "path": null,
                        "port": 22,
                        "search_regex": null,
                        "sleep": 1,
                        "state": "started",
                        "timeout": 1
                    }
                },
                "item": {
                    "name": "centos",
                    "port": "22"
                },
                "path": null,
                "port": 22,
                "search_regex": null,
                "state": "started"
            }
        ]
    }
}

ЗАДАЧА [telnet : Сохранить удаленный порт] ****************************************************************************************************
фатально: [centos]: FAILED! => {"msg": "Задача включает опцию с неопределенной переменной. Ошибка: 'dict object' не имеет атрибута 'host'\n\nОшибка, похоже, произошла в '/home/xxxxxx/ansible/tso-playbook/roles/telnet/tasks/main.yml': строка 17, столбец 3, но может быть\nв другом месте файла в зависимости от точной синтаксической проблемы.\n\nПроблемная строка выглядит следующим образом:\n\n\n- имя: Сохранить удаленный порт\n  ^ здесь\n\nтип исключения: <class 'ansible.errors.AnsibleUndefinedVariable'>\nисключение: 'dict object' не имеет атрибута 'host'"}
        для повтора используйте: --limit @/home/xxxxxxx/ansible/tso-playbook/telnet.retry

РЕЗЮМЕ ИГРЫ **************************************************************************************************************************
centos                     : ok=3    changed=0    unreachable=0    failed=1

Примечание: это мой первый раз, когда я публикую здесь, не знаю, как правильно исправить строку за строкой… Я просто хочу получить доступ к out.host, который ‘centos’ и сохранить его в csv файл, конечно, мне нужно сделать больше, но это первое, что мне нужно сделать, пожалуйста, помогите! Спасибо.

---

- имя: Сохранить удаленный порт   
  shell: echo {{ item.changed }} > /tmp/x_output.csv

  args:
    executable: /bin/bash

  with_items: "{{ out.results }}"

Это единственное, на что я могу сослаться, item.changed, который “Ложь”, но все остальные я не могу.

Почему?

Как вы можете видеть в отладке, которую вы опубликовали, в отличие от ключа changed, в элементах списка results нет ключа host.

Один есть внутри словаря invocation, поэтому:

shell: echo "{{ item.invocation.module_args.host }}" > /tmp/x_output.csv

Хотя это значение, которое вы определили сами, а не возвращаемое значение.

Ответ или решение

Для данной задачи в Ansible вы хотите извлечь информацию о хосте и его порте, а затем сохранить эту информацию в CSV-файл. Ниже приведен исправленный пример кода, который соответствует вашим требованиям. В исправлении я учёл, что ключа host в результатах нет, и вместо этого использовал invocation.module_args.host для доступа к имени хоста.

---
- hosts: all
  vars:
    servers:
      - name: centos
        port: 22

  tasks:
    - name: Проверка доступности порта на удалённом хосте
      wait_for:
        host: "{{ item.name }}"
        port: "{{ item.port }}"
        timeout: 1
      ignore_errors: true
      register: out
      with_items: "{{ servers }}"

    - debug: var=out

    - name: Сохранение информации о портах в CSV файл   
      lineinfile:
        path: /tmp/x_output.csv
        line: "{{ item.invocation.module_args.host }},{{ item.invocation.module_args.port }}"
        create: yes
      with_items: "{{ out.results }}"
      when: item.failed is not defined or not item.failed

Объяснение внесенных изменений:

  1. Использование invocation.module_args.host: Как уже упоминали в комментариях, для доступа к имени хоста нужно использовать поле invocation.module_args.host. Это позволит вам правильно извлечь имя хоста из результатов предыдущей задачи.

  2. Заменить shell на lineinfile: Вместо использования команды shell с echo, я использовал модуль lineinfile, который обеспечивает более безопасное и удобное управление файлами. Это также позволяет избежать проблем с параллельным доступом к файлам.

  3. Условие с when: Добавлено условие when, чтобы избежать попыток сохранить информацию о портах, если запрос завершился неудачно. Оно проверяет, не был ли элемент в списке итогов failed.

Этот подход правильно сохраняет данные о порте и хосте в формате CSV, что должно удовлетворить ваши требования. Убедитесь, что у вас есть все необходимые права доступа для записи в файл /tmp/x_output.csv на целевом хосте.

Оцените материал
Добавить комментарий

Капча загружается...