Calling Netscaler CLI commands from Ansible - ansible

I'm trying to use the "cli_command" module from Ansible to configure Netscaler appliances.
For 2 of them, running version "12.0 - build 60.9.nc" a simple task like this works perfectly :
- name: call NS CLI
cli_command:
command: show nsconf
register: cs_vserver
delegate_to: netscaler_dmz
Changing, the "delegate_to" to an appliance running version "NS11.1: Build 56.19.nc", I get the error :
The full traceback is: WARNING: The below traceback may not be
related to the actual failure. File
"/tmp/ansible_cli_command_payload_4w503v/ansible_cli_command_payload.zip/ansible/modules/network/cli/cli_command.py",
line 167, in main File
"/tmp/ansible_cli_command_payload_4w503v/ansible_cli_command_payload.zip/ansible/module_utils/connection.py",
line 185, in rpc
raise ConnectionError(to_text(msg, errors='surrogate_then_replace'), code=code) fatal: [localhost ->
172.26.58.112]: FAILED! => {
"changed": false,
"invocation": {
"module_args": {
"answer": null,
"check_all": false,
"command": "show nsconf",
"newline": true,
"prompt": null,
"sendonly": false
}
},
"msg": "command timeout triggered, timeout value is 30 secs.\nSee the timeout setting options in the Network Debug and Troubleshooting
Guide." }
Authentication uses RSA keys for all 3 devices, logs show welcome banner and connection is fine (manual connection using ssh works fine too), but soon after above error occurs.
Strangely, Netscaler is not listed in the list of availiable network platforms (https://docs.ansible.com/ansible/latest/network/user_guide/platform_index.html#settings-by-platform) but using parameters as follow work fine on the two others Netscalers (inventory file) :
all:
hosts:
localhost:
ansible_connection: local
netscaler_dmz_int: <= OK
ansible_host: 192.168.XXX.XXX
ansible_connection: network_cli
ansible_network_os: ios
ansible_user: nsroot
netscaler_dmz_prod: <= OK
ansible_host: 192.168.XXX.XXX
ansible_connection: network_cli
ansible_network_os: ios
ansible_user: nsroot
netscaler_dc: <= KO
ansible_host: 172.26.XXX.XXX
ansible_connection: network_cli
ansible_network_os: ios
ansible_user: nsroot
Upgrading firmware is not feasible in the short terms.
Does the problem come from the older version ? Is there a more adequate parameters to make it woorks on all 3 devices ?
Thanks.

Problem solved thanks to 2 collegues : the fact that the prompt of the Citrix device, once connected, was only showing ">" instead of a more complexe one like "user_device_name>" was causing the paramiko module to wait indefinitly ending with a timeout.
Before :
The cli_command result :
2021-08-06 10:37:07,728 p=4783 u=xxxxx n=p=4783 u=xxxxx | paramiko [xxx.xx.xx.xxx] | Authentication (publickey) successful!
2021-08-06 10:37:34,487 p=4646 u=xxxxx n=ansible | persistent connection idle timeout triggered, timeout value is 30 secs.
It's possible to change this prompt for the specific user used for connection, "nsroot" here :
After :
The connection was sucessful afterward.

Related

Ansible SSH key mismatch

I wrote the following Ansible playbook:
---
- name: Create VLAN
hosts: exos_device
connection: ansible.netcommon.network_cli
vars:
ansible_user: admin
ansible_password: password
ansible_network_os: community.network.exos
tasks:
- name: Create VLAN 4050
community.network.exos_config:
lines:
- create vlan TESTVLAN tag 4050
match: exact
save_when: always
Where I'm trying to create a new vlan on an Extreme Networks machine (ExtremeXOS version 16.2.5.4). But when I execute it I keep getting the following error:
fatal: [10.12.2.10]: FAILED! => {
"changed": false,
"module_stderr": "ssh connection failed: ssh connect failed: kex error : no match for method server host key algo: server [ssh-rsa], client [rsa-sha2-512,rsa-sha2-256,ssh-ed25519,ecdsa-sha2-nistp521,ecdsa-sha2-nistp384,ecdsa-sha2-nistp256]",
"module_stdout": "",
"msg": "MODULE FAILURE\nSee stdout/stderr for the exact error"
}
I think this error indicates that there is a mismatch between the SSH key algorithms that the client (Ansible controller) and the server (the EXOS machine) support.
What is the best way to resolve this issue?
I've already tried specifying an algorithm inside the ansible.cfg file like this:
[defaults]
inventory = inventory.ini
ssh_args = -oKexAlgorithms=ssh-rsa
But with no success.

Ansible Reload Cisco Devices Hangs

I have a task that reloads a number of Cisco Routers and Cisco Firewalls. For some reason the playbook always hangs at this task after the playbook have already reloaded the first device. The reload command is actually sent to the second device and I can see the device restart but the task will eventually fail.
Output:
Task [Reload Host Device]
fatal: [firewall2]: FAILED! => {"changed: false, "msg": "command timeout triggered, timeout value is 30 secs. \nsee the timeout setting options in the Network Debug and Troubleshooting Guide."} ...ignoring
Task:
- name: Reload Host Device
cli_command:
command: "reload"
prompt:
- "Proceed with reload?"
answer:
- "y"
ignore_errors: yes
According the given description, task and error message
command timeout triggered ... see the timeout setting options in the Network Debug and Troubleshooting Guide.
the devices which Ansible are connects to are going to restart faster than Ansible and the module cli_command can maintain his own connection. Meaning, close and disconnect the session.
According the Command Reference and Cisco Router: Auto restart in x seconds you may try with
- name: Schedule Host Device Reload in 1 min
cli_command:
command: "reload in 1"
prompt:
- "Proceed with reload?"
answer:
- "y"
register: result
- name: Show result
debug:
var: result
Further Reading
An other approach which was used in the past for Linux systems
How to automate system reboots using the Ansible?

Ansible SSH and Playbook

The current version Ubuntu I have is 20.10, the version of Ansible 2.9.9.
I have Eve NG with Cisco VIRL Routers on IOS 15.6
First I came across that Ubuntu was unable to SSH to cisco router, due to no matching key exchange method found. Their offer: diffie-hellman-group1-sha1, I found a work around using ~/.ssh/config. File using the following link
~/.ssh/config file:
Host 192.168.100.2
KexAlgorithms=+diffie-hellman-group1-sha1
Host 192.168.100.3
KexAlgorithms=+diffie-hellman-group1-sha1_
Now I am trying to deploy my first playbook.
When I try to run the playbook I get the following error:
fatal: [CSR-1]: FAILED! => {"changed": false, "msg": "Connection type ssh is not valid for this module"}
fatal: [CSR-2]: FAILED! => {"changed": false, "msg": "Connection type ssh is not valid for this module"}
I can SSH from Ubuntu to each router as I used ~/.ssh/config, but I don’t know how to make sure Ansible to use the ~/.ssh/config file.
I try in ansible.cfg file ssh_args = -F /home/a/.ssh/config ß the location of the SSH file, but cannot seem to get it working.
I have spent several hours Google around, but cannot find a fix.
ansible.cfg
[defaults]
inventory =./host
host_key_checking = False
retry_files_enabled = False
gathering = explicit
Interpreter_python = /usr/bin/python3
ssh_args = -F /home/n/etc/ssh/ssh_config.d/*.conf
Playbook:
hosts: CSR_Routers
tasks:
name: Show Version
ios_command:
commands: show version
all.yml:
ansible_user: "cisco"
ansible_ssh_pass: "cisco"
ansible_connection: "ssh"
ansible_network_os: "iso"
ansbile_connection: "network_cli"
If you see into the documentation don't use SSH as connection type, but network_cli. So - you don't talk to the device via default ssh, but via network_cli. Put that as a host specific var into your inventory.
all:
hosts:
CSR_01:
ansible_host: 192.168.100.2
ansible_connection: "network_cli"
ansible_network_os: "ios"
ansible_user: "cisco"
ansible_password: "cisco"
ansible_become: yes
ansible_become_method: enable
ansible_become_password: "cisco"
children:
CSR_Routers:
hosts:
CSR_01:
Based on your playbook, this inventory contains a group "CSR_Routers" and the only device on it is CSR_01 with IP 192.168.100.2. The connection type of that device is not ssh but network_cli.
remove the ssh_args from your ansible.cfg
remove ansible_ssh_pass, ansible_connection, ansible_user, ansible_network_os, ansbile_connection from your all.yml. This should be host specific (be aware of other devices in your inventory that are not an IOS device
So you call your playbook with:
ansible-playbook -i inventory.yaml playbook.yml
Also - have a look at the IOS specific documentation in Ansible
SSH FIX - after posted in Reddit
nano /etc/ssh/ssh_config
KexAlgorithms +diffie-hellman-group1-sha1
Ciphers +aes256-cbc,aes192-cbc,aes128-cbc,3des-cbc
systemctl restart ssh
nano /etc/ansible/ansible.cfg
[defaults]
host_key_checking=False
timeout = 30
Video with details
https://www.youtube.com/playlist?app=desktop&list=PLov64niDpWBId50D_wuraYWuQ-d02PiR1

Error when I am trying to execute show version into a Cisco device

I am trying to learn Ansible but I have some problems: I did a simple playbook, my first one, but it didn't work well: I am able to connect to my device with user teste and password teste and also execute the command.
fatal: [ansible_user=teste]: FAILED! => {"changed": false, "msg":
"command timeout triggered, timeout value is 10 secs.\nSee the timeout
setting options in the Network Debug and Troubleshooting Guide."}
fatal: [ansible_password=teste]: FAILED! => {"changed": false, "msg":
"command timeout triggered, timeout value is 10 secs.\nSee the timeout
setting options in the Network Debug and Troubleshooting Guide."}
fatal: [192.168.0.103]: FAILED! => {"changed": false, "msg": "command
timeout triggered, timeout value is 10 secs.\nSee the timeout setting
options in the Network Debug and Troubleshooting Guide."}
This is my playbook:
---
- name: First Play
hosts: routers
gather_facts: False
connection: local
tasks:
- name: Fist Task
ios_command:
commands: show version
register: version
Do you have any idea of what I am doing wrong?
well, I have to change my host file:
this way did not work:
[routers]
192.168.0.103
ansible_user=teste
ansible_password=teste
after check in the internet, I tried this way and worked fine:
[routers]
192.168.0.103
[routers:vars]
ansible_user=teste
ansible_password=teste
ansible_connection=network_cli
ansible_network_os=ios
The was issue was resolved after adding the username and password in the hosts file

Ansible: clear host errors after handler call

What I Do
For Bare Metal deployment, I configure interfaces on CentOS 7 servers via ansible 2.7.9.
Sometimes, the interface definitions change
- name: Copy sysctl and ifcfg- files from templates.
template: src={{ item.src }} dest={{ item.dest }}
with_items:
[...]
- { src: 'network.j2', dest: '/etc/sysconfig/network' }
notify:
- Restart network service
- Wait for reconnect
- Reset host errors
which is why I call a handler to restart the network.service when a change happens:
- name: Restart network service
service:
name: network
state: restarted
- name: Reset host errors
meta: clear_host_errors
- name: Wait for reconnect
wait_for_connection:
connect_timeout: 20
sleep: 5
delay: 5
timeout: 600
What I want
I can't get ansible to not quit the run when the Restart network service handler fails. Since the service restart is working fine on the host itself, I either want the restart to always exit with RC=0 or clear the host error after the failing handler call. In the following list, is there anything I am missing or doing wrong?
What I tried
ignore errors: true, failed_when: false, changed_when: false directives. Either with shell/command module or service module in the restart network handler block.
meta: clear_host_errors directly below the - name: Copy sysctl and ifcfg- files from templates. block
calling meta: clear_host_errors as a handler
Having the handler Restart network service exit with || true
async/poll variants for Restart network service
setting Pipelining to false
I always end up with:
RUNNING HANDLER [os : Restart network service] *******************************************************************
fatal: [host-redacted]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: Shared connection to aa.bb.cc.dd closed.", "unreachable": true}
RUNNING HANDLER [os : Reset host errors] *************************************************************************
fatal: [host-redacted]: FAILED! => {"changed": false, "module_stderr": "Shared connection to aa.bb.cc.dd closed.\r\n", "module_stdout": "", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 0}
RUNNING HANDLER [os : Wait for reconnect] ************************************************************************
Where is the correct placement for meta: clear_host_errors in this case?
Some additional info
restart of network.service takes about ~40 seconds. (Tried async: 120 and poll: 30)
established, non-ansible SSH connections recover with enough timeout
re-run of ansible directly after the first exit work fine
Interestingly enough, the skipping works fine with ignore_errors: true when using Mitogen:
TASK [os : Restart network service] ******************************************************************************************************************************************************************************************************
skipping: [host-redacted]
skipping: [host-redacted]
fatal: [host-redacted]: FAILED! => {"msg": "EOF on stream; last 300 bytes received: 'ssh: connect to host aa.bb.cc.dd port 22: Connection refused\\r\\n'"}
...ignoring
This starts to look like a bug to me.

Resources