简体   繁体   中英

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:

#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. 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:

 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:

  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. And additionaly confirmation of reload command is without "Enter" after pressing "y" so this could be another problem.

  $ 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?

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. It works well for ansible because the default prompt of ios will come back (reload gets triggered in 1 minute).

Regards, Simon

Ansible 2.2 only

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.

Take care with Ansible 2.2 though, it's not released yet and new releases of Ansible can have significant regressions.

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.

commands parameter of ios_command module expects a YAML formated list of commands. However in the code example provided commands parameter is set multiple times. Try the ios_command task like this:

- 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.

This avoids having to use expect and having to play around with the ios_command module.

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. 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.

    - 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:

  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. Save? [yes/no]:' answer: 'n' answer: 'y'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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