Ansible extract values from stdout_lines to use in subsequent loop - ansible

I am trying to write a role to remove all helper addresses for a Cisco Router interface. There can be one or more helper addresses returned in stdout_lines. I use filters to remove labels and extra scapes from the lines and put the results into an array to use in the subsequent command loop. I seem to get the correct info but using the value fails.
Here is my role:
---
- name: read helpers
register: helper_facts
ios_command:
commands:
- show ip interface {{ interface }} | section Helper
- set_fact:
helper_addr: []
- set_fact:
helper_addr: "{{ helper_addr }} + [ '{{ item | regex_replace ('Helper address.* ','') | trim }}' ]"
with_items: "{{ helper_facts.stdout_lines }}"
- name: remove helpers
ios_command:
commands:
- no ip helper-address {{ item }}
with_items: "{{ helper_addr }}"
Here is a snip of the output with the error I get:
ok: [ONTMDFRTR01] => (item= 172.16.0.22) => {
"ansible_facts": {
"helper_addr": [
"192.1.0.1",
"172.16.0.22"
]
},
"ansible_loop_var": "item",
"changed": false,
"item": " 172.16.0.22"
}
TASK [remove_helpers : remove helpers] **********************************************************************************
task path: /home/msimon/USPS/roles/remove_helpers/tasks/main.yml:15
Monday 03 May 2021 16:44:23 -0400 (0:00:00.704) 0:00:05.874 ************
<10.32.178.252> ESTABLISH LOCAL CONNECTION FOR USER: root
<10.32.178.252> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /root/.ansible/tmp/ansible-local-23291P_KVGE `"&& mkdir "1-258083848203070 `" && echo ansible-tmp-1620074664.59-23371-258083848203070="` echo /root/.ansible/tmp/ansible-local-232
Using module file /usr/lib/python2.7/site-packages/ansible/modules/network/ios/ios_command.py
<10.32.178.252> PUT /root/.ansible/tmp/ansible-local-23291P_KVGE/tmpuSDML5 TO /root/.ansible/tmp/ansible-local-23291P_KVG
<10.32.178.252> EXEC /bin/sh -c 'chmod u+x /root/.ansible/tmp/ansible-local-23291P_KVGE/ansible-tmp-1620074664.59-23371-24.59-23371-258083848203070/AnsiballZ_ios_command.py && sleep 0'
<10.32.178.252> EXEC /bin/sh -c '/usr/bin/python /root/.ansible/tmp/ansible-local-23291P_KVGE/ansible-tmp-1620074664.59-2
<10.32.178.252> EXEC /bin/sh -c 'rm -f -r /root/.ansible/tmp/ansible-local-23291P_KVGE/ansible-tmp-1620074664.59-23371-25
The full traceback is:
WARNING: The below traceback may *not* be related to the actual failure.
File "/tmp/ansible_ios_command_payload_IFZQ7s/ansible_ios_command_payload.zip/ansible/module_utils/network/ios/ios.py",
return connection.run_commands(commands=commands, check_rc=check_rc)
File "/tmp/ansible_ios_command_payload_IFZQ7s/ansible_ios_command_payload.zip/ansible/module_utils/connection.py", line
raise ConnectionError(to_text(msg, errors='surrogate_then_replace'), code=code)
failed: [ONTMDFRTR01] (item=192.1.0.1) => {
"ansible_loop_var": "item",
"changed": false,
"invocation": {
"module_args": {
"auth_pass": null,
"authorize": null,
"commands": [
"no ip helper-address 192.1.0.1"
],
"host": null,
"interval": 1,
"match": "all",
"password": null,
"port": null,
"provider": null,
"retries": 10,
"ssh_keyfile": null,
"timeout": null,
"username": null,
"wait_for": null
}
},
"item": "192.1.0.1",
"msg": "no ip helper-address 192.1.0.1\r\nno ip helper-address 192.1.0.1\r\n ^\r\n% Invalid input detected at '^' m
}```

Thanks to mdaniel's comment I found the answer. I cut this from a larger playbook and left out the commands to setup the interface ("config t" , "int GigabitEthernet0/0/0") needed before the no helper_addres command. My role is now working as expected. Thanks, I hope this helps someone else.

Related

How to decode a Base64 var to a binary file with Ansible module

I am reading a base64 file from HashiCorp’s vault with the help of the hashi_vault module. Sample of code:
- name: Vault get b64.pfx file
set_fact:
b64_pfx: "{{ lookup('hashi_vault',
'secret={{ path_pfx }} token={{ token }} url={{ url }} cacert={{ role_path}}/files/CA.pem')}}"
Then as a next step I need to decode this base64 var to a binary format and store it in in a file. I am currently using shell module to do the work. Sample of code:
- name: Decode Base64 file to binary
shell: "echo {{ b64_pfx }} | base64 --decode > {{ pfxFile }}"
delegate_to: localhost
I was looking online for possible solutions e.g. (
Copy module with base64-encoded binary file adds extra character and How to upload encrypted file using ansible vault?).
But the only working solution that I can found is using the shell module. Since this is an old problem is there any workaround on this?
Update:
Do not use Python 2.7 as there seems to be a bug on the b64decode filter (sample below):
<localhost> ESTABLISH LOCAL CONNECTION FOR USER: root
<localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /tmp/ansible-tmp-1573819503.84-50241917358990 `" && echo ansible-tmp-1573819503.84-50241917358990="` echo /tmp/ansible-tmp-1573819503.84-50241917358990 `" ) && sleep 0'
Using module file /usr/lib/python2.7/site-packages/ansible/modules/commands/command.py
<localhost> PUT /tmp/ansible-local-18pweKi1/tmpjQGOz8 TO /tmp/ansible-tmp-1573819503.84-50241917358990/AnsiballZ_command.py
<localhost> EXEC /bin/sh -c 'chmod u+x /tmp/ansible-tmp-1573819503.84-50241917358990/ /tmp/ansible-tmp-1573819503.84-50241917358990/AnsiballZ_command.py && sleep 0'
<localhost> EXEC /bin/sh -c '/usr/bin/python /tmp/ansible-tmp-1573819503.84-50241917358990/AnsiballZ_command.py && sleep 0'
<localhost> EXEC /bin/sh -c 'rm -f -r /tmp/ansible-tmp-1573819503.84-50241917358990/ > /dev/null 2>&1 && sleep 0'
changed: [hostname -> localhost] => {
"changed": true,
"cmd": "shasum -a 1 /tmp/binary_file\nshasum -a 1 /tmp/binary_file.ansible\n",
"delta": "0:00:00.126279",
"end": "2019-11-15 13:05:04.227933",
"invocation": {
"module_args": {
"_raw_params": "shasum -a 1 /tmp/binary_file\nshasum -a 1 /tmp/binary_file.ansible\n",
"_uses_shell": true,
"argv": null,
"chdir": null,
"creates": null,
"executable": null,
"removes": null,
"stdin": null,
"stdin_add_newline": true,
"strip_empty_ends": true,
"warn": true
}
},
"rc": 0,
"start": "2019-11-15 13:05:04.101654",
"stderr": "",
"stderr_lines": [],
"stdout": "4a71465d449a0337329e76106569e39d6aaa5ef0 /tmp/binary_file\nead5cb632f3ee80ce129ef5fe02396686c2761e0 /tmp/binary_file.ansible",
"stdout_lines": [
"4a71465d449a0337329e76106569e39d6aaa5ef0 /tmp/binary_file",
"ead5cb632f3ee80ce129ef5fe02396686c2761e0 /tmp/binary_file.ansible"
]
}
Solution: use Python 3 with b64decode filter (sample below):
<localhost> ESTABLISH LOCAL CONNECTION FOR USER: root
<localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /tmp/ansible-tmp-1573819490.9511943-224511378311227 `" && echo ansible-tmp-1573819490.9511943-224511378311227="` echo /tmp/ansible-tmp-1573819490.9511943-224511378311227 `" ) && sleep 0'
Using module file /usr/local/lib/python3.6/site-packages/ansible/modules/commands/command.py
<localhost> PUT /tmp/ansible-local-18epk_0jsv/tmp4t3gnm7u TO /tmp/ansible-tmp-1573819490.9511943-224511378311227/AnsiballZ_command.py
<localhost> EXEC /bin/sh -c 'chmod u+x /tmp/ansible-tmp-1573819490.9511943-224511378311227/ /tmp/ansible-tmp-1573819490.9511943-224511378311227/AnsiballZ_command.py && sleep 0'
<localhost> EXEC /bin/sh -c '/usr/bin/python /tmp/ansible-tmp-1573819490.9511943-224511378311227/AnsiballZ_command.py && sleep 0'
<localhost> EXEC /bin/sh -c 'rm -f -r /tmp/ansible-tmp-1573819490.9511943-224511378311227/ > /dev/null 2>&1 && sleep 0'
changed: [hostname -> localhost] => {
"changed": true,
"cmd": "shasum -a 1 /tmp/binary_file\nshasum -a 1 /tmp/binary_file.ansible\n",
"delta": "0:00:00.135427",
"end": "2019-11-15 13:04:51.239969",
"invocation": {
"module_args": {
"_raw_params": "shasum -a 1 /tmp/binary_file\nshasum -a 1 /tmp/binary_file.ansible\n",
"_uses_shell": true,
"argv": null,
"chdir": null,
"creates": null,
"executable": null,
"removes": null,
"stdin": null,
"stdin_add_newline": true,
"strip_empty_ends": true,
"warn": true
}
},
"rc": 0,
"start": "2019-11-15 13:04:51.104542",
"stderr": "",
"stderr_lines": [],
"stdout": "4a71465d449a0337329e76106569e39d6aaa5ef0 /tmp/binary_file\n4a71465d449a0337329e76106569e39d6aaa5ef0 /tmp/binary_file.ansible",
"stdout_lines": [
"4a71465d449a0337329e76106569e39d6aaa5ef0 /tmp/binary_file",
"4a71465d449a0337329e76106569e39d6aaa5ef0 /tmp/binary_file.ansible"
]
}
Since Python 2 is reaching the end of life in (January 1, 2020) there is no point of raising the bug.
Using the b64decode filter at least on ansible 2.9 does what you want:
- copy:
dest: '{{ pfxFile }}'
content: '{{ b64_pfx | b64decode }}'
delegate_to: localhost
I confirmed it writes only the specified bytes (no trailing whitespace) and is binary safe.
If you tried that behavior, and it doesn't work for you, then update your question to say that and to include the version of ansible you are using. I also think that bug you linked to has been fixed, because I tried their exact case on ansible 2.9 and it did the right thing:
- hosts: localhost
connection: local
gather_facts: no
tasks:
- set_fact:
string_in_base64: 'sxZARwIVokeqOMGPygc1S20CaGPiKDRGRzg0oSVGmCF2oXHua+9fVhriUQRd8vkmvpHoBmSsI6Y='
- copy:
dest: binary_file.ansible
content: '{{ string_in_base64 | b64decode }}'
- shell: |
echo '{{ string_in_base64 }}' | base64 --decode > binary_file
shasum -a 1 binary_file
shasum -a 1 binary_file.ansible
{
"changed": true,
"cmd": "echo 'sxZARwIVokeqOMGPygc1S20CaGPiKDRGRzg0oSVGmCF2oXHua+9fVhriUQRd8vkmvpHoBmSsI6Y=' | base64 --decode > binary_file\nshasum -a 1 binary_file\nshasum -a 1 binary_file.ansible\n",
"delta": "0:00:00.162251",
"end": "2019-11-13 13:10:56.683186",
"rc": 0,
"start": "2019-11-13 13:10:56.520935",
"stderr": "",
"stderr_lines": [],
"stdout": "7e88df04cf47019ae22e9c658b62c26b706c6ea5 binary_file\n7e88df04cf47019ae22e9c658b62c26b706c6ea5 binary_file.ansible",
"stdout_lines": [
"7e88df04cf47019ae22e9c658b62c26b706c6ea5 binary_file",
"7e88df04cf47019ae22e9c658b62c26b706c6ea5 binary_file.ansible"
]
}
This is simpler than the other answers. Just pipe the function at the end of the lookup()
- name: Vault get b64.pfx file
set_fact:
b64_pfx: "{{ lookup('hashi_vault',
'secret={{ path_pfx }} token={{ token }} url={{ url }} cacert={{ role_path}}/files/CA.pem') | b64decode }}"

How to manipulate this result in Ansible

I have a problem for manipulating data in Ansible.
My main goal is to purge ADRCI log.
In a first time, i'm listing the databases that are launched with users Oracle and Grid with the shell module
- name: Generate List of databases started with user oracle
shell: "ps -ef | grep smon | grep -v grep | grep oracle | awk '{print $NF}' | awk -F '_' '{print $NF}'"
register: list_oracle_bases
Then i want to get the homes to purge with an other shell command :
- name: Get databases homes
register: get_homes
environment:
ORACLE_SID: "{{ item }}"
ORAENV_ASK: "NO"
become: true
become_user: oracle
become_method: su
shell: ". oraenv 1>/dev/null 2>&- && adrci exec='show homes' | grep -v 'ADR Homes:'"
with_items:
- "{{ list_oracle_bases.stdout_lines }}"
And here comes my problem i've got this result for {{ get_homes }}
ok: [host1] => {
"msg": {
"changed": true,
"msg": "All items completed",
"results": [
{
"_ansible_ignore_errors": null,
"_ansible_item_label": "ANSIBLE1",
"_ansible_item_result": true,
"_ansible_no_log": false,
"_ansible_parsed": true,
"changed": true,
"cmd": ". oraenv 1>/dev/null 2>&- && adrci exec='show homes' | grep -v 'ADR Homes:'",
"delta": "0:00:00.028970",
"end": "2019-03-18 11:29:29.708709",
"failed": false,
"invocation": {
"module_args": {
"_raw_params": ". oraenv 1>/dev/null 2>&- && adrci exec='show homes' | grep -v 'ADR Homes:'",
"_uses_shell": true,
"argv": null,
"chdir": null,
"creates": null,
"executable": null,
"removes": null,
"stdin": null,
"warn": true
}
},
"item": "ANSIBLE1",
"rc": 0,
"start": "2019-03-18 11:29:29.679739",
"stderr": "",
"stderr_lines": [],
"stdout": "diag/rdbms/ansible1/ANSIBLE1",
"stdout_lines": [
"diag/rdbms/ansible1/ANSIBLE1"
]
}
]
}
}
I tried to get get_homes.results.stdout_lines but i've got the following error when i want to display it in a debug statement.
FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'list object' has no attribute 'stdout_lines'\n\nThe error appears to have been in '/tmp/sylvain/roles/test/tasks/query.yml': line 59, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n - debug:\n ^ here\n"}
What is the correct way to get that stdout_lines ("diag/rdbms/ansible1/ANSIBLE1") in a variable.
Regards
Sylvain
results is an array, because you have created it in a loop (with_items). The correct syntax is:
get_homes.results[0].stdout_lines
for the first and so on for the rest.
In order to get the list of home directories you have to filter the results array by the attribute you need. And in the end you have to flatten the array of arrays. Here is a mcve:
---
- name: filter
hosts: localhost
connection: local
tasks:
- shell: |-
echo ~{{ item }}
with_items:
- man
- lp
- mail
register: get_homes
ignore_errors: true
changed_when: false
- debug: var=get_homes
- set_fact:
homes: >-
{{ get_homes.results | map(attribute='stdout_lines') | list | flatten }}
- debug: var=homes

Ansible command using variable input fails to execute

Below I'm trying to get a command running involving input from previous output, in this case copy flash:file01 flash:file02 with 2 derived from the REGEX_FILTERING task.
- name: REGEX_FILTERING
command: "cat /home/ubuntu/show_switch.txt"
register: line1
- debug: var="{{ line1.stdout_lines | regex_replace('(?<!\*).?') }}"
register: number
- name: COMMAND_INPUT
cli_command:
command: 'copy flash:file01 flash:file0 {{ number }}'
prompt: '[confirm]'
answer: ''
Here's the error message:
<ommited>
"stdout_lines": [
"Switch/Stack Mac Address : d4a0.2ae9.ec00",
" H/W Current",
"----------------------------------------------------------",
" 1 Member 001f.9df6.2d80 5 0 Ready ",
"*2 Master d4a0.2ae9.ec00 15 0 Ready ",
" 3 Member 0016.c733.cd00 5 0 Ready"
]
}
TASK [debug] *****************************************************************************************************************************************************************************
task path: /home/ubuntu/test1.yml:109
ok: [CSR1] => {
"2": "2"
}
TASK [COMMAND_INPUT] *********************************************************************************************************************************************************************
task path: /home/ubuntu/test1.yml:112
<192.168.255.133> ESTABLISH LOCAL CONNECTION FOR USER: ubuntu
<192.168.255.133> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/ubuntu/.ansible/tmp/ansible-local-7528uUJSLh/ansible-tmp-1542986468.48-164922344690120 `" && echo ansible-tmp-1542986468.48-164922344690120="` echo /home/ubuntu/.ansible/tmp/ansible-local-7528uUJSLh/ansible-tmp-1542986468.48-164922344690120 `" ) && sleep 0'
Using module file /usr/lib/python2.7/dist-packages/ansible/modules/network/cli/cli_command.py
<192.168.255.133> PUT /home/ubuntu/.ansible/tmp/ansible-local-7528uUJSLh/tmpkozHVx TO /home/ubuntu/.ansible/tmp/ansible-local-7528uUJSLh/ansible-tmp-1542986468.48-164922344690120/AnsiballZ_cli_command.py
<192.168.255.133> EXEC /bin/sh -c 'chmod u+x /home/ubuntu/.ansible/tmp/ansible-local-7528uUJSLh/ansible-tmp-1542986468.48-164922344690120/ /home/ubuntu/.ansible/tmp/ansible-local-7528uUJSLh/ansible-tmp-1542986468.48-164922344690120/AnsiballZ_cli_command.py && sleep 0'
<192.168.255.133> EXEC /bin/sh -c '/usr/bin/python /home/ubuntu/.ansible/tmp/ansible-local-7528uUJSLh/ansible-tmp-1542986468.48-164922344690120/AnsiballZ_cli_command.py && sleep 0'
<192.168.255.133> EXEC /bin/sh -c 'rm -f -r /home/ubuntu/.ansible/tmp/ansible-local-7528uUJSLh/ansible-tmp-1542986468.48-164922344690120/ > /dev/null 2>&1 && sleep 0'
The full traceback is:
WARNING: The below traceback may *not* be related to the actual failure.
File "/tmp/ansible_cli_command_payload_U1p385/__main__.py", line 150, in main
response = connection.get(**module.params)
File "/tmp/ansible_cli_command_payload_U1p385/ansible_cli_command_payload.zip/ansible/module_utils/connection.py", line 173, in __rpc__
raise ConnectionError(to_text(msg, errors='surrogate_then_replace'), code=code)
fatal: [CSR1]: FAILED! => {
"changed": false,
"invocation": {
"module_args": {
"answer": [
""
],
"check_all": false,
"command": "copy flash:file01 flash:file0 {'failed': False, u'2': u'2', 'changed': False}",
"prompt": [
"[confirm]"
],
"sendonly": false
}
},
"msg": "copy flash:file01 flash:file0 {'failed': False, u'2': u'2', 'changed': False}\r\n ^\r\n% Invalid input detected at '^' marker.\r\n\r\nCSR1#\r\nCSR1#"
"command": "copy flash:file01 flash:file0 {'failed': False, u'2': u'2', 'changed': False}",
Is happening because the register: number is not in fact the number, rather it's the ansible result of the debug: output. Since number is a python dict, when it is injected into your command, it is just serialized as if str() were called upon the dict
It is far more likely that what you want is to capture that variable locally in the task, to make it just be the result of the jinja2 expression, and not the result of an ansible task:
- cli_command:
command: 'copy flash:file01 flash:file0 {{ number }}'
vars:
number: "{{ line1.stdout_lines | regex_replace('(?<!\*).?') }}"
I also suspect you will be happier with line1.stdout, which is a str of the entire output, versus line1.stdout_lines which is a list of str, making the regex_replace on a list kind of weird -- I'm surprised it actually even let you do that, to be honest

Concatenate variable with a fact in Ansible

I am trying to use a variable and the results of a previous task as input. Here is my code.
---
- hosts: localhost
vars:
v_hostname: XXXXXXXXXXXXX
v_datacentre: DC-UK-LON-GS
v_username: YYYYYYYY
v_password: XXXXXXXX
connection: local
gather_facts: false
tasks:
- name: Find the folder for the VM
vmware_guest_find:
hostname: "{{ v_hostname }}"
datacenter: "{{ v_datacentre }}"
username: "{{ v_username }}"
password: "{{ v_password }}"
validate_certs: no
name: MYVMNAME
register: folder
- debug:
msg:
- "{{ folder.folders }}"
- name: Gather facts from VM
connection: local
gather_facts: false
vmware_guest_facts:
hostname: "{{ v_hostname }}"
datacenter: "{{ v_datacentre }}"
username: "{{ v_username }}"
password: "{{ v_password }}"
validate_certs: no
folder: "{{ v_datacentre }}{{ folder.folders }}"
name: MYVMNAME
The last line tries to use the defined variable v_datacentre and append the value from the registered fact from the previous task. However the concatenation produces some unwanted wrapping chars:
ansible-playbook 2.4.2.0
config file = /etc/ansible/ansible.cfg
configured module search path = [u'/export/home/ansible/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/site-packages/ansible
executable location = /bin/ansible-playbook
python version = 2.7.5 (default, May 3 2017, 07:55:04) [GCC 4.8.5 20150623 (Red Hat 4.8.5-14)]
Using /etc/ansible/ansible.cfg as config file
Parsed /export/home/ansible/inventory_prod inventory source with ini plugin
[WARNING]: Ignoring invalid attribute: gather_facts
PLAYBOOK: mainvm.yml *****************************************************************************************************************************************
1 plays in mainvm.yml
PLAY [localhost] *********************************************************************************************************************************************
META: ran handlers
TASK [TEST1] *************************************************************************************************************************************************
task path: /export/home/ansible/mainvm.yml:12
Using module file /usr/lib/python2.7/site-packages/ansible/modules/cloud/vmware/vmware_guest_find.py
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: ansible
<127.0.0.1> EXEC /bin/sh -c 'echo ~ && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /export/home/ansible/.ansible/tmp/ansible-tmp-1523621823.18-119950066241401 `" && echo ansible-tmp-1523621823.18-119950066241401="` echo /export/home/ansible/.ansible/tmp/ansible-tmp-1523621823.18-119950066241401 `" ) && sleep 0'
<127.0.0.1> PUT /tmp/tmpM_Pf2B TO /export/home/ansible/.ansible/tmp/ansible-tmp-1523621823.18-119950066241401/vmware_guest_find.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /export/home/ansible/.ansible/tmp/ansible-tmp-1523621823.18-119950066241401/ /export/home/ansible/.ansible/tmp/ansible-tmp-1523621823.18-119950066241401/vmware_guest_find.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '/usr/bin/python2 /export/home/ansible/.ansible/tmp/ansible-tmp-1523621823.18-119950066241401/vmware_guest_find.py; rm -rf "/export/home/ansible/.ansible/tmp/ansible-tmp-1523621823.18-119950066241401/" > /dev/null 2>&1 && sleep 0'
ok: [localhost] => {
"changed": false,
"folders": [
"/vm/LON-GS-AD/LON-GS-AD-UNIX"
],
"invocation": {
"module_args": {
"datacenter": "DC-UK-LON-GS",
"hostname": "XXXXXXXXXXXXX",
"name": "MYVMNAME",
"password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
"username": "XXXXXXXX",
"uuid": null,
"validate_certs": false
}
}
}
TASK [debug] *************************************************************************************************************************************************
task path: /export/home/ansible/mainvm.yml:23
ok: [localhost] => {
"msg": [
[
"/vm/LON-GS-AD/LON-GS-AD-UNIX"
]
]
}
TASK [Gather facts from standalone ESXi server] **************************************************************************************************************
task path: /export/home/ansible/mainvm.yml:28
Using module file /usr/lib/python2.7/site-packages/ansible/modules/cloud/vmware/vmware_guest_facts.py
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: ansible
<127.0.0.1> EXEC /bin/sh -c 'echo ~ && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /export/home/ansible/.ansible/tmp/ansible-tmp-1523621827.79-78942665802166 `" && echo ansible-tmp-1523621827.79-78942665802166="` echo /export/home/ansible/.ansible/tmp/ansible-tmp-1523621827.79-78942665802166 `" ) && sleep 0'
<127.0.0.1> PUT /tmp/tmp43NXf_ TO /export/home/ansible/.ansible/tmp/ansible-tmp-1523621827.79-78942665802166/vmware_guest_facts.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /export/home/ansible/.ansible/tmp/ansible-tmp-1523621827.79-78942665802166/ /export/home/ansible/.ansible/tmp/ansible-tmp-1523621827.79-78942665802166/vmware_guest_facts.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '/usr/bin/python2 /export/home/ansible/.ansible/tmp/ansible-tmp-1523621827.79-78942665802166/vmware_guest_facts.py; rm -rf "/export/home/ansible/.ansible/tmp/ansible-tmp-1523621827.79-78942665802166/" > /dev/null 2>&1 && sleep 0'
fatal: [localhost]: FAILED! => {
"changed": false,
"invocation": {
"module_args": {
"datacenter": "XXXXXX",
"folder": "DC-UK-LON-GS[u'/vm/LON-GS-AD/LON-GS-AD-UNIX']",
"hostname": "XXXXXXXXXXXXX",
"name": "MYVMNAME",
"name_match": "first",
"password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
"username": "XXXXXXXX",
"uuid": null,
"validate_certs": false
}
},
"msg": "Unable to gather facts for non-existing VM MYVMNAME"
}
to retry, use: --limit #/export/home/ansible/mainvm.retry
PLAY RECAP ***************************************************************************************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=1
The results of folder.folders is correctly printed by debug but in the last step the concatenation gives:
"folder": "DC-UK-LON-GS[u'/vm/LON-GS-AD/LON-GS-AD-UNIX']",
I confess to being a bit of an Ansible newbie but I don't understand where the [u' and ] come from. I just want to use the combined strings as input. Can anyone please explain or show solution or point me at some beginners documents for this sort of variable use?
Thanks.
So after some further playing turns out that the vmware_guest_find returns a list (and it's in the docs!!!) so I need to either pick the 1st item if there will only be one group or loop though them.
folder: "{{ v_datacentre }}{{ folder.folders[0] }}"
This does the job.

Ansible: How to select specific field using register

I am using a package specific command for which there is no existing module. The output (stdout) of the command is either 0 or 1. I'm trying assign the value of stdout to a variable for later use in the playbook. However, I cannot seem to isolate the stdout, which is clearly being captured.
ok: [hostname1] => {
"dmstate": {
"changed": true,
"msg": "All items completed",
"results": [
{
"_ansible_item_result": true,
"_ansible_no_log": false,
"_ansible_parsed": true,
"changed": true,
"cmd": "/usr/bin/ssh -q hostname1 \"/opt/REDACTED/bin/dmctl -s localhost:8426/dmbroker get DomainManager::hostname1-ampm1::state\"",
"delta": "0:00:01.808716",
"end": "2017-09-06 13:28:04.853221",
"invocation": {
"module_args": {
"_raw_params": "/usr/bin/ssh -q hostname1 \"/opt/REDACTED/bin/dmctl -s localhost:8426/dmbroker get DomainManager::hostname1-ampm1::state\"",
"_uses_shell": true,
"chdir": null,
"creates": null,
"executable": null,
"removes": null,
"warn": true
}
},
"item": "hostname1-ampm1",
"rc": 0,
"start": "2017-09-06 13:28:03.044505",
"stderr": "",
"stderr_lines": [],
"stdout": "0",
"stdout_lines": [
"0"
]
}
]
}
}
What I tried was using set_fact: to isolate and search the dmstate.results, but I cannot figure out the correct syntax.
tasks:
- name: check status
shell: '/usr/bin/ssh -q {{ inventory_hostname }} "/opt/REDACTED/bin/dmctl -s localhost:8426/dmbroker get DomainManager::{{ item }}::state" '
register: dmstate
with_items: "{{ myprocess }}"
- name: find stdout value
set_fact: stdout_value="{{ item.stdout }}"
when: item.dmstate.results.stdout == "stdout"
with_items: dmstate.results
- name: show value of stdout
debug: var=stdout_value
The results of this are here:
fatal: [hostname1]: FAILED! => {"failed": true, "msg": "The conditional check 'item.dmstate.results.stdout == \"stdout\"' failed. The error was: error while evaluating conditional (item.dmstate.results.stdout == \"stdout\"): 'AnsibleUnsafeText' object has no attribute 'dmstate'\n\n
Once you are using with_items, item contains the inner value, so item.dmstate.results.stdout has no sense, you have to use item.stdout (like you do in the set_fact).
Even with this fix, your item will be skipped every time because you are testing the stdout value against the "stdout" string, but you say that stdout is only "0" or "1".
I think you could simply remove the when clause.
Another problem: each item will overwrite the value of stdout_value, so at the end you will only get the last value.

Resources