简体   繁体   English

ansible - 思科 IOS 和“重新加载”命令

[英]ansible - cisco IOS and "reload" command

I would like to send command "reload in " to Cisco IOS, but that specific command needs to be confirmed like below:我想向 Cisco IOS 发送命令“reload in”,但需要确认该特定命令,如下所示:

#reload in 30
Reload scheduled in 30 minutes by admin on vty0 (192.168.253.15)
Proceed with reload? [confirm]

It semms like ios_command module doesn't handle such case.好像 ios_command 模块不处理这种情况。 My configuration:我的配置:

 tasks:
   - name: do reload in case of "catting off"
     ios_command:
      commands: reload in 30
      commands: y
      provider: "{{ cli }}"

And response from playbook:以及剧本的回应:

TASK [do reload in case of "catting off"] **************************************
    task path: /etc/ansible/test1.yml:14
    <192.168.0.33> ESTABLISH LOCAL CONNECTION FOR USER: root
    <192.168.0.33> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo $HOME/.ansible/tmp/ansible-tmp-1476454008.17-103724241654271 `" && echo ansible-tmp-1476454008.17-103724241654271="` echo $HOME/.ansible/tmp/ansible-tmp-1476454008.17-103724241654271 `" ) && sleep 0'
    <192.168.0.33> PUT /tmp/tmpAJiZR2 TO /root/.ansible/tmp/ansible-tmp-1476454008.17-103724241654271/ios_command
    <192.168.0.33> EXEC /bin/sh -c 'LANG=pl_PL.UTF-8 LC_ALL=pl_PL.UTF-8 LC_MESSAGES=pl_PL.UTF-8 /usr/bin/python /root/.ansible/tmp/ansible-tmp-1476454008.17-103724241654271/ios_command; rm -rf "/root/.ansible/tmp/ansible-tmp-1476454008.17-103724241654271/" > /dev/null 2>&1 && sleep 0'
    fatal: [192.168.0.33]: FAILED! => {"changed": false, "commands": ["y"], "failed": true, "invocation": {"module_args": {"auth_pass": null, "authorize": false, "commands": ["y"], "host": "192.168.0.33", "interval": 1, "password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER", "port": 22, "provider": "{'username': 'admin', 'host': '192.168.0.33', 'password': '********'}", "retries": 10, "ssh_keyfile": null, "timeout": 10, "username": "admin", "waitfor": null}, "module_name": "ios_command"}, "msg": "matched error in response: y\r\n                   ^\r\n% Invalid input detected at '^' marker.\r\n\r\nsw7.test.lab#"}

How can I handle this?我该如何处理?


updated:更新:

If I try to use expect module in YAML file like this:如果我尝试像这样在 YAML 文件中使用 expect 模块:

 name: some tests
  hosts: sw-test
  gather_facts: False
#  connection: local

  tasks:
  - name: do reload in case of "catting off"
    expect:
     command: reload in 30
     responses:
      'Reload scheduled in 30 minutes by admin on vty0 (192.168.253.20)\nProceed with reload? \[confirm\]' : y
     echo: yes

But there is a problem with connection:但是连接有问题:

oot@Kali:/etc/ansible# ansible-playbook test3 -u admin -k -vvvv 
Using /etc/ansible/ansible.cfg as config file
SSH password: 
Loaded callback default of type stdout, v2.0

PLAYBOOK: test3 ****************************************************************
1 plays in test3

PLAY [some tests] **************************************************************

TASK [do reload in case of "catting off"] **************************************
task path: /etc/ansible/test3:9
<192.168.0.33> ESTABLISH SSH CONNECTION FOR USER: admin
<192.168.0.33> SSH: EXEC sshpass -d12 ssh -C -vvv -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o User=admin -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/ansible-ssh-%h-%p-%r 192.168.0.33 '/bin/sh -c '"'"'( umask 77 && mkdir -p "` echo $HOME/.ansible/tmp/ansible-tmp-1476882070.37-92402455055985 `" && echo ansible-tmp-1476882070.37-92402455055985="` echo $HOME/.ansible/tmp/ansible-tmp-1476882070.37-92402455055985 `" ) && sleep 0'"'"''
<192.168.0.33> PUT /tmp/tmp30wGsF TO "` echo $HOME/.ansible/tmp/ansible-tmp-1476882070.37-92402455055985 `" ) && sleep 0'"/expect
<192.168.0.33> SSH: EXEC sshpass -d12 sftp -o BatchMode=no -b - -C -vvv -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o User=admin -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/ansible-ssh-%h-%p-%r '[192.168.0.33]'
fatal: [192.168.0.33]: UNREACHABLE! => {"changed": false, "msg": "SSH Error: data could not be sent to the remote host. Make sure this host can be reached over ssh", "unreachable": true}
    to retry, use: --limit @/etc/ansible/test3.retry

PLAY RECAP *********************************************************************
192.168.0.33               : ok=0    changed=0    unreachable=1    failed=0   


root@Kali:/etc/ansible# ansible-playbook test3 -u admin -k -vvvv -c ssh
Using /etc/ansible/ansible.cfg as config file
SSH password: 
Loaded callback default of type stdout, v2.0

PLAYBOOK: test3 ****************************************************************
1 plays in test3

PLAY [some tests] **************************************************************

TASK [do reload in case of "catting off"] **************************************
task path: /etc/ansible/test3:9
<192.168.0.33> ESTABLISH SSH CONNECTION FOR USER: admin
<192.168.0.33> SSH: EXEC sshpass -d12 ssh -C -vvv -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o User=admin -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/ansible-ssh-%h-%p-%r 192.168.0.33 '/bin/sh -c '"'"'( umask 77 && mkdir -p "` echo $HOME/.ansible/tmp/ansible-tmp-1476882145.78-139203779538157 `" && echo ansible-tmp-1476882145.78-139203779538157="` echo $HOME/.ansible/tmp/ansible-tmp-1476882145.78-139203779538157 `" ) && sleep 0'"'"''
<192.168.0.33> PUT /tmp/tmpY5qqyW TO "` echo $HOME/.ansible/tmp/ansible-tmp-1476882145.78-139203779538157 `" ) && sleep 0'"/expect
<192.168.0.33> SSH: EXEC sshpass -d12 sftp -o BatchMode=no -b - -C -vvv -o 

ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o User=admin -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/ansible-ssh-%h-%p-%r '[192.168.0.33]'
    fatal: [192.168.0.33]: UNREACHABLE! => {"changed": false, "msg": "SSH Error: data could not be sent to the remote host. Make sure this host can be reached over ssh", "unreachable": true}
        to retry, use: --limit @/etc/ansible/test3.retry

    PLAY RECAP *********************************************************************
    192.168.0.33               : ok=0    changed=0    unreachable=1    failed=0   

root@Kali:/etc/ansible# ansible-playbook test3 -u admin -k -vvvv -c local
Using /etc/ansible/ansible.cfg as config file
SSH password: 
Loaded callback default of type stdout, v2.0

PLAYBOOK: test3 ****************************************************************
1 plays in test3

PLAY [some tests] **************************************************************

TASK [do reload in case of "catting off"] **************************************
task path: /etc/ansible/test3:9
<192.168.0.33> ESTABLISH LOCAL CONNECTION FOR USER: root
<192.168.0.33> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo $HOME/.ansible/tmp/ansible-tmp-1476882426.62-172601217553809 `" && echo ansible-tmp-1476882426.62-172601217553809="` echo $HOME/.ansible/tmp/ansible-tmp-1476882426.62-172601217553809 `" ) && sleep 0'
<192.168.0.33> PUT /tmp/tmpdq1pYy TO /root/.ansible/tmp/ansible-tmp-1476882426.62-172601217553809/expect
<192.168.0.33> EXEC /bin/sh -c 'chmod u+x /root/.ansible/tmp/ansible-tmp-1476882426.62-172601217553809/ /root/.ansible/tmp/ansible-tmp-1476882426.62-172601217553809/expect && sleep 0'
<192.168.0.33> EXEC /bin/sh -c 'LANG=pl_PL.UTF-8 LC_ALL=pl_PL.UTF-8 LC_MESSAGES=pl_PL.UTF-8 /usr/bin/python /root/.ansible/tmp/ansible-tmp-1476882426.62-172601217553809/expect; rm -rf "/root/.ansible/tmp/ansible-tmp-1476882426.62-172601217553809/" > /dev/null 2>&1 && sleep 0'
fatal: [192.168.0.33]: FAILED! => {"changed": false, "failed": true, "invocation": {"module_args": {"chdir": null, "command": "reload in 30", "creates": null, "echo": true, "removes": null, "responses": {"Reload scheduled in 30 minutes by admin on vty0 (192.168.253.20)\\nProceed with reload? \\[confirm\\]": "y"}, "timeout": 30}, "module_name": "expect"}, "msg": "The command was not found or was not executable: reload."}

NO MORE HOSTS LEFT *************************************************************
    to retry, use: --limit @/etc/ansible/test3.retry

PLAY RECAP *********************************************************************
192.168.0.33               : ok=0    changed=0    unreachable=0    failed=1   

UPDATED更新

I've installed ansible 2.3 and tried as follows:我已经安装了 ansible 2.3 并尝试如下:

  tasks:
    - name: do reload in case of "catting off"
      ios_command:
       commands:
        - reload in 30
        - y
       wait_for:
       - result[0] contains "Proceed with reload"
       provider: "{{ cli }}"

But still, I get an error.但是,我仍然收到错误消息。 I think that this is because ios module always wait for a promt as a response.我认为这是因为 ios 模块总是等待提示作为响应。 And additionaly confirmation of reload command is without "Enter" after pressing "y" so this could be another problem.并且在按“y”后重新加载命令的额外确认没有“Enter”,所以这可能是另一个问题。

  $ sudo  ansible-playbook test1.yml -vvvv
    Using /etc/ansible/ansible.cfg as config file
    Loading callback plugin default of type stdout, v2.0 from /usr/local/lib/python2.7/dist-packages/ansible/plugins/callback/__init__.pyc

    PLAYBOOK: test1.yml ************************************************************
    1 plays in test1.yml

    PLAY [testowe dzialania] *******************************************************

    TASK [do reload in case of "catting off"] **************************************
    task path: /home/user1/test1.yml:13
    Using module file /usr/local/lib/python2.7/dist-packages/ansible/modules/core/network/ios/ios_command.py
    <192.168.0.33> ESTABLISH LOCAL CONNECTION FOR USER: root
    <192.168.0.33> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo $HOME/.ansible/tmp/ansible-tmp-1477557527.56-157304653717324 `" && echo ansible-tmp-1477557527.56-157304653717324="` echo $HOME/.ansible/tmp/ansible-tmp-1477557527.56-157304653717324 `" ) && sleep 0'
    <192.168.0.33> PUT /tmp/tmphf8EWO TO /home/mszczesniak/.ansible/tmp/ansible-tmp-1477557527.56-157304653717324/ios_command.py
    <192.168.0.33> EXEC /bin/sh -c 'chmod u+x /home/mszczesniak/.ansible/tmp/ansible-tmp-1477557527.56-157304653717324/ /home/mszczesniak/.ansible/tmp/ansible-tmp-1477557527.56-157304653717324/ios_command.py && sleep 0'
    <192.168.0.33> EXEC /bin/sh -c '/usr/bin/python /home/mszczesniak/.ansible/tmp/ansible-tmp-1477557527.56-157304653717324/ios_command.py; rm -rf "/home/user1/.ansible/tmp/ansible-tmp-1477557527.56-157304653717324/" > /dev/null 2>&1 && sleep 0'
    fatal: [192.168.0.33]: FAILED! => {
        "changed": false,
        "failed": true,
        "invocation": {
            "module_args": {
                "auth_pass": null,
                "authorize": false,
                "commands": [
                    "reload in 30",
                    "y"
                ],
                "host": "192.168.0.33",
                "interval": 1,
                "match": "all",
                "password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
                "port": null,
                "provider": {
                    "host": "192.168.0.33",
                    "password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
                    "username": "admin"
                },
                "retries": 10,
                "ssh_keyfile": null,
                "timeout": 10,
                "transport": null,
                "use_ssl": true,
                "username": "admin",
                "validate_certs": true,
                "wait_for": [
                    "result[0] contains \"Proceed with reload\""
                ]
            },
            "module_name": "ios_command"
        },
        "msg": "timeout trying to send command: reload in 30\r"
    }
            to retry, use: --limit @/home/user1/test1.retry

    PLAY RECAP *********************************************************************
    192.168.0.33               : ok=0    changed=0    unreachable=0    failed=1

Can anyone have any idea how to resolve that problem in ansible or maby the only way is to use pure python script or write own ansible module?谁能知道如何解决 ansible 中的问题,或者唯一的方法是使用纯 python 脚本或编写自己的 ansible 模块?

You can use:您可以使用:

- name: reload device
  ios_command:
    commands:
      - "reload in 1\ny"
    provider: "{{ cli }}"

This will reload the device in 1 minute and the reload prompt gets accepted.这将在 1 分钟内重新加载设备并接受重新加载提示。 It works well for ansible because the default prompt of ios will come back (reload gets triggered in 1 minute).它适用于 ansible,因为 ios 的默认提示将返回(重新加载在 1 分钟内触发)。

Regards, Simon问候, 西蒙

Ansible 2.2 only仅 Ansible 2.2

You could use something like this:你可以使用这样的东西:

  - name: send reload command inc confirmation
    ios_command:
      commands: 
        - reload in 30
        - y
      wait_for: 
        - result[0] contains "Proceed with reload" 
      provider: "{{ cli }}"

Not tested but similar to last example for ios_command module.未测试但类似于ios_command模块的最后一个示例。

Take care with Ansible 2.2 though, it's not released yet and new releases of Ansible can have significant regressions.不过,请注意 Ansible 2.2,它尚未发布,并且 Ansible 的新版本可能会有显着的回归。

Ansible 2.0+ includes the expect module but that requires Python on the remote device, so it won't work on IOS or similar devices. Ansible 2.0+ 包含expect 模块,但它需要远程设备上的 Python,因此它不能在 IOS 或类似设备上运行。

commands parameter of ios_command module expects a YAML formated list of commands. ios_command模块的commands参数需要一个YAML格式的命令列表。 However in the code example provided commands parameter is set multiple times.但是在代码示例中提供的commands参数设置了多次。 Try the ios_command task like this:尝试像这样的ios_command任务:

- name: do reload in case of "catting off"
  ios_command:
    commands:
      - reload in 30
      - y
  provider: "{{ cli }}"

It appears that the simplest method would be to use the 'raw' module to send raw SSH commands to the device.似乎最简单的方法是使用“原始”模块向设备发送原始 SSH 命令。

This avoids having to use expect and having to play around with the ios_command module.这避免了必须使用 expect 和不得不玩弄 ios_command 模块。

The raw module will run the commands without caring what responses or prompts the device.原始模块将运行命令而不关心什么响应或提示设备。

Below worked for me with ansible-playbook 2.9.0 and Python 3.7.下面使用 ansible-playbook 2.9.0 和 Python 3.7 为我工作。 Please note that, on line with - command , make sure to use double quote " instead of single one ' . And don't forget to put \\n at the end of command.请注意,在使用- command ,请确保使用双引号"而不是单引号' 。并且不要忘记将\\n放在命令的末尾。

    - name: Reloading switch using ios_command.
      ios_command:
        commands: 
          - command: "reload\n"
            prompt: 'Proceed with reload? [confirm]'
            answer: "\r"

I have simiar problem.我有类似的问题。 Need to reload cisco device and then getting prompts:需要重新加载cisco设备然后得到提示:

  1. save?救?
  2. [confirm] [确认]

How to answer that correctly?如何正确回答?

  • name: Reloading in 1 min if not online cisco.ios.ios_command: commands: - command: reload in 1 prompt: 'System configuration has been modified. name: Reloading in 1 min if not online cisco.ios.ios_command: commands: - command: reload in 1 prompt: '系统配置已修改。 Save?救? [yes/no]:' answer: 'n' answer: 'y' [是/否]:' 回答:'n' 回答:'y'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM