我写了一本Ansible剧本,提示我以交互方式为SSH和SUDO输入密码,如下所示。
$ ansible-playbook -i test --limit dev app_name.yml -vv --tags=stop
SSH password:
SUDO password[defaults to SSH password]:
Ansible提供了各种选项,例如在group_vars下的ansible_ssh_password中定义密码,但它似乎对我不起作用,因为我无法在目标服务器中安装sshpass,也不允许对我的sudoers进行任何更改文件。
我尝试从下面的一个预期脚本执行ansible-playbook
#!/usr/bin/expect -f
set password PASSWORD
set where_to_execute [lindex $argv 0]
set which_app_to_execute [lindex $argv 1]
set what_to_execute [lindex $argv 2]
send "ansible-playbook -i test --limit $where_to_execute $which_app_to_execute -vv --tags=$what_to_execute \r"
expect "SSH password:"
send "$password \r"
expect "SUDO password*"
send "$password \r"
expect "$"
send "exit \r"
不幸的是,这也无法正常工作,因为SSH进程不是由期望产生的。有没有人尝试过这种方法并让事情有效。请建议。感谢。
答案 0 :(得分:3)
你期望脚本的问题在于你实际上并没有在那里运行ansible命令(或任何命令)。
您使用
send "ansible-playbook -i test --limit $where_to_execute $which_app_to_execute -vv --tags=$what_to_execute \r"
将发送该字符串发送到......据我所知。它无处可去。
您想要做的是spawn
该ansible命令,然后使用expect与之通信。
这样的事情:
spawn ansible-playbook -i test --limit $where_to_execute $which_app_to_execute -vv --tags=$what_to_execute
如果ansible命令可能需要一段时间,您可能还需要设置timeout
值(以防止expect
在它没有足够快地返回时杀死它。)
答案 1 :(得分:1)
它适用于我使用expect的python实现。 pexpect
使用pip安装pexpect:pip install pexpect
您可以将此代码用作期望脚本的变通方法:
#!/usr/bin/python
import pexpect
def main(args):
#Setup variables
password, where, which, what = args
cmd = "ansible-playbook -i test --limit %s %s -vv --tags=%s" % (where, which, what)
child = pexpect.spawn(cmd)
child.sendline(password)
child.expect('SSH password:')
child.sendline(password)
child.expect('SUDO password*')
child.expect(pexpect.EOF)
print child.before
if __name__ == '__main__':
main(sys.argv[1:])
这是最简单的例子,但它对我来说很好。
./myscript.py mypassword dev app_name.yml stop
正如@Etan Reisner指出的那样,你的代码与我的pexpect代码之间的主要区别在于spawn
ansible命令。期望上面的代码也可以正常工作:
#!/usr/bin/expect -f
spawn /usr/bin/ansible -m ping myserver --ask-pass
expect "SSH password:"
send "mypassword\r"
expect "$ "