Вопрос или проблема
У меня есть мой сценарий playbook yml ниже:
---
- name: Загрузить файлы с FTP
hosts: localhost
gather_facts: false
vars_prompt:
- name: target_host
prompt: "IP-адрес целевого хоста: "
- name: auth_method
prompt: "Метод аутентификации (пароль/ключ): "
tasks:
- name: Собрать учетные данные целевого хоста
when: auth_method == 'password'
vars_prompt:
- name: ssh_user
prompt: "Имя пользователя SSH: "
- name: ssh_pass
prompt: "Пароль SSH: "
private: true
- name: Собрать путь к ключу для целевого хоста
when: auth_method == 'key'
vars_prompt:
- name: ssh_user
prompt: "Имя пользователя SSH: "
- name: key_path
prompt: "Путь к SSH-ключу: "
- name: Собрать учетные данные FTP
vars_prompt:
- name: ftp_username
prompt: "Имя пользователя FTP: "
- name: ftp_password
prompt: "Пароль FTP: "
private: true
- name: Загрузить файлы с FTP на целевом хосте
hosts: "{{ target_host }}"
gather_facts: false
remote_user: "{{ ssh_user }}"
become: true
become_user: root
become_method: sudo
tasks:
- name: Создать директорию для обновления, если она не существует
file:
path: /root/upgrade
state: directory
- name: Загрузить файл с FTP
get_url:
url: "ftp://something.com/{{ file_path }}"
dest: "/root/upgrade/{{ file_path }}"
force: yes
timeout: 30
remote_src: yes
validate_certs: false
url_username: "{{ ftp_username }}"
url_password: "{{ ftp_password }}"
register: download_result
ignore_errors: true
- name: Проверить, успешно ли загружен файл
debug:
msg: "Файл '{{ file_path }}' успешно загружен."
when: download_result is success
- name: Вывести сообщение об ошибке, если загрузка файла не удалась
debug:
msg: "Не удалось загрузить файл '{{ file_path }}'. Пожалуйста, проверьте путь к файлу или учетные данные FTP."
when: download_result is failed and file_path != 'q'
- name: Завершить playbook, если нажата 'q'
meta: end_play
when: file_path == 'q'
Я проверил отступы, и, как мне кажется, все правильно. Но при попытке запустить его возникает следующая ошибка:
root@DESKTOP-VLCQSJO:/home/ridhoswasta/tassta-automation# ansible-playbook download-files.yml
[WARNING]: предоставленный список хостов пуст, доступен только localhost. Обратите внимание, что неявный localhost не совпадает
'всем'
ERROR! неожиданный тип параметра в действии: <class 'ansible.parsing.yaml.objects.AnsibleSequence'>
Ошибка, видимо, находится в '/home/ridhoswasta/tassta-automation/download-files.yml': строка 13, колонка 7, но может
быть и в другом месте файла в зависимости от точной синтаксической проблемы.
Обидная строка, похоже, выглядит так:
tasks:
- name: Собрать учетные данные целевого хоста
^ здесь
root@DESKTOP-VL
Есть ли какие-то советы о том, что может быть не так?
Спасибо!
vars_prompt может использоваться только в play. Никакие задачи, блоки или роли. См. Ключевые слова playbook. В задаче вы можете использовать pause. Например,
shell> cat pb.yml
- hosts: localhost
vars_prompt:
- name: target_host
prompt: IP целевого хоста
private: false
- name: auth_method
prompt: Метод аутентификации (пароль/ключ)
private: false
vars:
ssh_user: "{{ ssh_user_out.user_input }}"
ssh_pass: "{{ ssh_pass_out.user_input }}"
tasks:
- name: Пароль
when: auth_method == 'password'
block:
- pause:
prompt: Имя пользователя SSH
register: ssh_user_out
- pause:
prompt: Пароль SSH
echo: false
register: ssh_pass_out
- debug:
msg: |
target_host: {{ target_host }}
auth_method: {{ auth_method }}
ssh_user: {{ ssh_user }}
ssh_pass: {{ ssh_pass }}
дает
shell> ansible-playbook pb.yml
IP целевого хоста: 10.1.0.10
Метод аутентификации (пароль/ключ): пароль
PLAY [localhost] ******************************************************************************
TASK [pause] **********************************************************************************
[pause]
Имя пользователя SSH:
admin^Mok: [localhost]
TASK [pause] **********************************************************************************
[pause]
Пароль SSH (вывод скрыт):
ok: [localhost]
TASK [debug] **********************************************************************************
ok: [localhost] =>
msg: |-
target_host: 10.1.0.10
auth_method: пароль
ssh_user: admin
ssh_pass: 1234
PLAY RECAP ************************************************************************************
localhost: ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Ответ или решение
Судя по предоставленной информации, вы сталкиваетесь с ошибкой в вашем Ansible Playbook, связанной с неправильным использованием переменных ввода (vars_prompt
). Давайте подробно разберем вашу проблему и предложим корректное решение.
Проблема
Вы получили сообщение об ошибке:
ERROR! unexpected parameter type in action: <class 'ansible.parsing.yaml.objects.AnsibleSequence'>
Это указывает на то, что в вашем Playbook есть неправильное место, где вы пытаетесь использовать vars_prompt
. Дело в том, что vars_prompt
может использоваться только на уровне Playbook и не может находиться внутри блока задач (tasks
). Это основная причина, вызвавшая данную ошибку.
Корректировка
На основе предоставленной информации о вашей задаче, давайте перепишем ваш Playbook, чтобы устранить данную ошибку.
---
- name: Запрос данных у пользователя
hosts: localhost
gather_facts: false
vars_prompt:
- name: target_host
prompt: "IP целевого хоста: "
- name: auth_method
prompt: "Метод аутентификации (пароль/ключ): "
tasks:
- name: Собрать учетные данные для целевого хоста (пароль)
when: auth_method == 'password'
pause:
prompt: "SSH Username: "
register: ssh_user_out
- name: Собрать пароль для SSH (только с паролем)
when: auth_method == 'password'
pause:
prompt: "SSH Password: "
echo: false
register: ssh_pass_out
- name: Собрать путь к ключу SSH (только с ключом)
when: auth_method == 'key'
pause:
prompt: "Path to SSH Key: "
register: key_path_out
- name: Собрать учетные данные FTP
pause:
prompt: "FTP Username: "
register: ftp_user_out
- name: Собрать пароль FTP
pause:
prompt: "FTP Password: "
echo: false
register: ftp_pass_out
- name: Загрузка файлов с FTP на целевом хосте
hosts: "{{ target_host }}"
gather_facts: false
remote_user: "{{ ssh_user_out.user_input if auth_method == 'password' else key_path_out.user_input }}"
become: true
become_user: root
become_method: sudo
tasks:
- name: Создать директорию для обновления, если она не существует
file:
path: /root/upgrade
state: directory
- name: Загрузить файл с FTP
get_url:
url: "ftp://something.com/{{ file_path }}"
dest: "/root/upgrade/{{ file_path }}"
force: yes
timeout: 30
remote_src: yes
validate_certs: false
url_username: "{{ ftp_user_out.user_input }}"
url_password: "{{ ftp_pass_out.user_input }}"
register: download_result
ignore_errors: true
- name: Проверить успешность загрузки файла
debug:
msg: "Файл '{{ file_path }}' успешно загружен."
when: download_result is success
- name: Показать сообщение об ошибке, если загрузка не удалась
debug:
msg: "Не удалось загрузить файл '{{ file_path }}'. Проверьте путь к файлу или учетные данные FTP."
when: download_result is failed and file_path != 'q'
- name: Завершить исполнение плейбука, если нажата 'q'
meta: end_play
when: file_path == 'q'
Объяснение исправлений
-
vars_prompt на уровне плейбука: Перенос
vars_prompt
в верхнюю часть плейбука обеспечивает корректное использование переменных. -
Использование pause: Для сбора данных от пользователя в задачах теперь используется модуль
pause
, который позволяет запрашивать данные, как это было сделано в вашем примере. -
Динамическое назначение переменной remote_user: Мы используем условные операторы для выбора между переменной
ssh_user
иkey_path
, основываясь на выбранном методе аутентификации.
Заключение
Теперь ваш исправленный Playbook должен работать правильно без упомянутых ошибок. Убедитесь, что вы протестировали его в среде, где Ansible имеет доступ к целевым хостам и FTP-серверу. Если у вас возникнут дополнительные вопросы или потребуется помощь, не стесняйтесь задавать их.