failed_when do not work with telnet output - ansible

I will try to set a telnet task to failed if "instance" is in the output message, but it didn't work.
here is the log:
TASK [ISAM Log to log1 and log2] **************************************************************************************************************************************
task path: /Users/sascha.mueller/Downloads/isam_log.yml:9
changed: [1.2.3.4] => {
"changed": true,
"failed_when_result": false,
"output": [
"configure system syslog no route dslamlog msg-type all\r\n\r\nError : instance does not exist\r\n\r\nISAM-ISAM_7363_Labor_Zw>#",
"configure system syslog no destination dslamlog\r\n\r\nError : instance does not exist\r\n\r\nISAM-ISAM_7363_Labor_Zw>#"
]
}
TASK [fail the play if the previous command did not succeed] **********************************************************************************************************
task path: /Users/sascha.mueller/Downloads/isam_log.yml:27
skipping: [1.2.3.4] => {
"changed": false,
"skip_reason": "Conditional result was False"
}
I also tried command_output.stderr e.g. but all these values doesn't exist
---
-
hosts: all
connection: local
become: no
tasks:
- name: ISAM Log to log1 and log2
ignore_unreachable: yes
telnet:
user: bla
password: blubb
login_prompt: "login: "
password_prompt: "password: "
timeout: 5
prompts:
- "[#|$]"
command:
- configure system syslog no route dslamlog msg-type all
- configure system syslog no destination dslamlog
register: command_output
failed_when: "'instance' in command_output.output"
- name: fail the play if the previous command did not succeed
fail:
msg: "the command failed"
when: "'instance' in command_output.output"
Is it possible to check this with an telnet command or to direct check it with variable.output or only with variable.stderr?

You can see in your example that output is a list:
"output": [
"configure system syslog no route dslamlog msg-type all\r\n\r\nError : instance does not exist\r\n\r\nISAM-ISAM_7363_Labor_Zw>#",
"configure system syslog no destination dslamlog\r\n\r\nError : instance does not exist\r\n\r\nISAM-ISAM_7363_Labor_Zw>#"
]
When you ask if "'instance' in command_output.output", you are asking if there is an item in outout that is the string instance. That is, your expression would evaluate to true if output looked like this:
"output": [
"this item does not match",
"instance"
]
What you really want to ask is "does any item in output contain the string instance?". The simplest way to do that is probably by concatenating all the lines into a single string:
"'instance' in ''.join(command_output.output)"
You should be able to use this in either you failed_when condition:
- name: ISAM Log to log1 and log2
ignore_unreachable: yes
telnet:
user: bla
password: blubb
login_prompt: "login: "
password_prompt: "password: "
timeout: 5
prompts:
- "[#|$]"
command:
- configure system syslog no route dslamlog msg-type all
- configure system syslog no destination dslamlog
register: command_output
failed_when: "'instance' in ''.join(command_output.output)"
Or in the when statement on your fail task:
- name: fail the play if the previous command did not succeed
fail:
msg: "the command failed"
when: "'instance' in ''.join(command_output.output)"

Related

Save ansible variable in local file

I am executing a PS script on a windows host and want to store its stdout in a file on an ansible local machine. I have a playbook like following:
---
- name: Check Antivirus software
hosts: all
become: false
gather_facts: no
tasks:
- name: Get AV details
win_shell: |
echo "script printing data on stdout"
register: result
- name: save response
copy:
content: '{{ result.stdout }}'
dest: '{{ response_file }}'
delegate_to: localhost
From the above playbook, 1st task gets executed without any issues. But 2nd task gives the following error.
TASK [save response] *******************************************************************************************************************************************
fatal: [20.15.102.192 -> localhost]: UNREACHABLE! => {"changed": false, "msg": "ntlm: HTTPSConnectionPool(host='localhost', port=5986): Max retries exceeded with url: /wsman (Caused by NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0x7f4940760208>: Failed to establish a new connection: [Errno 111] Connection refused',))", "unreachable": true}
I also tried local_action which is also giving the same error.

I'm having RpcTimeoutError commit-configuration

I am using juniper module for Ansible, however I'm having the issue below. Do you have any idea ?
fatal: [172.31.30.158]: FAILED! => {"changed": false, "msg": "Failure checking the configuraton: RpcTimeoutError(host: 172.31.30.158, cmd: commit-configuration, timeout: 10)"}
Playbook:
- name: "Configure Device"
hosts: junos
connection: local
timeout: 50
gather_facts: no
tasks:
- name: "Configure op script"
juniper.device.config:
config_mode: "private"
check_commit_wait: 20
load: "set"
src: "test.txt"
register: response
- name: "Print the config changes"
debug:
var: response

How to get response of Ansible telnet module

Below are couple of IP addresses and their telnet response (output)
telnet 10.9.9.112 22
Trying 10.9.9.112......
telnet 10.9.9.143 22
Trying 10.9.9.143.....
telnet: connect to address 10.9.9.143: Connection refused.
For the first IP 10.9.9.112 there is no connection and firewall blocks any connection from source to destination. The output simply says Trying .... and stays that way without printing anything else.
For the second IP 10.9.9.143 i get Connection refused immediately in the output and the control back to the prompt.
I wish to grab both scenarios in when condition and perform different activities for both the cases.
I tried to use Ansible's telnet module but I don't know how to grab both the different outputs in the registered variable.
In my case it prints the same message for both the IPs.
Ansible output for first ip:
TASK [debug] *************************************
ok: [localhost] => {
"msg": "HERE:{u'msg': u'Timeout when waiting for 10.9.9.112', u'failed': True, 'changed': False, u'elapsed': 4}"
Ansible Output for second ip:
TASK [debug] *************************************
ok: [localhost] => {
"msg": "HERE:{u'msg': u'Timeout when waiting for 10.9.9.143', u'failed': True, 'changed': False, u'elapsed': 3}"
The only difference I see is the value for elapsed.
Here is my playbook.
---
- name: "Play 1"
hosts: localhost
tasks:
- wait_for:
hosts: "{{ item }}"
port: 22
state: started
delay: 3
timeout: 90
ignore_errors: yes
register: telnetout
loop:
- 10.9.9.112
- 10.9.9.143
- debug:
msg: "HERE: {{ telnetout }}"
telnet module unfortunately does not record Connection Refused message in the output.
We have to use raw module instead like below.
---
- name: "Play 1"
hosts: localhost
tasks:
- raw: "timeout --signal=9 2 telnet {{ item }} 22"
ignore_errors: yes
register: telnetout
loop:
- 10.9.9.112
- 10.9.9.143
- debug:
msg: "HERE: {{ telnetout }}"

Print custom message from until loop in ansible

I am trying to run a command multiple times and check if the output contains some string in it("hi"). I am purposefully simulating failure and expecting the until loop to fail. Everything is good till this point.
Now, I need to have some custom message stating why the until loop or the task failed. For Example: "Your command failed to print hi"
So Question is, How can I print custom message from until loop if the loop failed to pass withing the retries.
Playbook:
-->cat until.yml
---
- hosts: localhost
gather_facts: no
tasks:
- name: "check command"
shell: echo hello
register: var
until: var.stdout.find('hi') != -1
retries: 5
delay: 1
playbook output:
-->ansible-playbook until.yml
PLAY [localhost] *************************************************************************************************************************************************************************************************************************
TASK [check command] ********************************************************************************************************************************************************************************************************
FAILED - RETRYING: who triggered the playbook (5 retries left).
FAILED - RETRYING: who triggered the playbook (4 retries left).
FAILED - RETRYING: who triggered the playbook (3 retries left).
FAILED - RETRYING: who triggered the playbook (2 retries left).
FAILED - RETRYING: who triggered the playbook (1 retries left).
fatal: [localhost]: FAILED! => {
"attempts": 5,
"changed": true,
"cmd": "echo hello",
"delta": "0:00:00.003004",
"end": "2019-12-03 10:04:14.731488",
"rc": 0,
"start": "2019-12-03 10:04:14.728484"
}
STDOUT:
hello
PLAY RECAP *******************************************************************************************************************************************************************************************************************************
localhost : ok=0 changed=0 unreachable=0 failed=1
You can divide your task into two tasks:
First task will poll for the desired output using until loop. But we have used ignore_errors: True , so that until loop will not fail the playbook. We will just capture the result.
In second task , use assert to print success_msg for success case and fail_msg for failure case.
Following is tweaked ,minimum working example:
---
- hosts: localhost
gather_facts: no
tasks:
- name: "check command"
shell: echo hello
register: var
until: var.stdout.find('hi') != -1
retries: 5
delay: 1
ignore_errors: true
- name: "Print result"
assert:
that: var.stdout|regex_search('hi')
fail_msg: "COuld not find HI in command output"
success_msg: "Hi is present in Command output"
Have a look at block error handling which can be used for this purpose.
Basic overview:
- block:
- name: A task that may fail.
debug:
msg: "I may fail"
failed_when: true
register: might_fail_exec
rescue:
- name: fail nicely with a msg
fail:
msg: "The task that might fail has failed. Here is some info from the task: {{ might_fail_exec }}"

junos_command module not returning output

I have an Ansible script where i am simply using junos_command module to get users list from Juniper switch, below is the snippet of my code. I keep getting the RuntimeWarning whenever i try to run this. Moreover I have been successfully able to run commands like 'show version' using the below code itself. Please help
Script:
name: / GET USERS / Get list of all the current users on switch
action: junos_command
args: { commands: 'show configuration system login',
provider: "{{ netconf }}" }
register: curr_users_on_switch
Error:
TASK [/ GET USERS / Get list of all the current users on switch] ***************
fatal: [rlab-er1]: FAILED! => {"changed": false, "failed": true, "module_stderr": "/home/mbhadoria/.local/lib/python2.7/site-packages/jnpr/junos/device.py:429: RuntimeWarning: CLI command is for debug use only!
\n warnings.warn(\"CLI command is for debug use only!\", RuntimeWarning)\nTraceback (most recent call last):
\n File \"/tmp/ansible_lVOmPp/ansible_module_junos_command.py\", line 261, in <module>
\n main()
\n File \"/tmp/ansible_lVOmPp/ansible_module_junos_command.py\", line 233, in main
\n xmlout.append(xml_to_string(response[index]))
\n File \"/tmp/ansible_lVOmPp/ansible_modlib.zip/ansible/module_utils/junos.py\", line 79, in xml_to_string\n File \"src/lxml/lxml.etree.pyx\", line 3350, in lxml.etree.tostring (src/lxml/lxml.etree.c:84534)\nTypeError: Type 'str' cannot be serialized.
\n", "module_stdout": "", "msg": "MODULE FAILURE", "parsed": false}
junos_command only support operation junos commands. What you are trying to run is configurational command. Hence you see "show version" which is operational command working but not "show configuration system login".
For such configuration data you can should use rpc option (get-configuration) with junos_command.
junos_command:
rpcs:
- "get_configuration
You can also use junos_get_config.
http://junos-ansible-modules.readthedocs.io/en/latest/junos_get_config.html
or junos_rpc
https://github.com/Juniper/ansible-junos-stdlib/blob/master/library/junos_rpc
ex:
- name: Junos OS version
hosts: all
connection: local
gather_facts: no
tasks:
- name: Get rpc run
junos_rpc:
host={{ inventory_hostname }}
user=xxxx
passwd=xxx
rpc=get-config
dest=get_config.conf
filter_xml="<configuration><system><login/></system></configuration>"
register: junos
or
tasks:
- name: Get rpc run
junos_get_config:
host: "{{ inventory_hostname }}"
user: xxxx
passwd: xxxx
logfile: get_config.log
dest: "{{ inventory_hostname }}.xml"
format: xml
filter: "system/login"
TASK [Get rpc run] *************************************************************
......
PLAY RECAP *********************************************************************
xxxk : ok=1 changed=1 unreachable=0 failed=0

Resources