Fetch doesn't transfer when i use variable - ansible

fetch module does not transfer file when i use variable and getting message as "msg": "the remote file does not exist, not transferring, ignored". But file exits in the source directory. Please suggest if anything wrong in this.
ansible 2.1.0.0
---
- hosts: host_A
become_user: yes
gather_facts: no
tasks:
- name: list files
shell: ls -1 /root/stuff/install.1_comiskey-v01
register: dumpfiles
-debug: var=dumpfiles
- name: fetch files
fetch: src={{item}} dest=/tmp/fetched/ flat=yes
with_items: ('{{dumpfiles.stdout_lines}}')
register: test
- debug: var=test
Output:
TASK [fetch files]
*************************************************************
ok: [10.1.31.82] => (item=('[u'/root/stuff/install.1_comiskey-v01',u'/root/stuff/install.1_comiskey-v02']'))
TASK [debug] *******************************************************************
ok: [10.1.31.82] => {
"test": {
"changed": false,
"msg": "All items completed",
"results": [
{
"_ansible_item_result": true,
"_ansible_no_log": false,
"changed": false,
"file": "('[u'/root/stuff/install.1_comiskey-v01', u'/root/stuff/install.1_comiskey-v02']')",
"invocation": {
"module_args": {
"dest": "/tmp/fetched/",
"flat": "yes",
"src": "('[u'/root/stuff/install.1_comiskey-v01', u'/root/stuff/install.1_comiskey-v02']')"
},
"module_name": "fetch"
},
"item": "('[u'/root/stuff/install.1_comiskey-v01', u'/root/stuff/install.1_comiskey-v02']')",
"msg": "the remote file does not exist, not transferring, ignored"
}
]
}
}

Remove parentheses from with_items. You can note that item variable is not correct on your debug output.

Related

Ansible include task and loop register different result

I'm trying to use a module as an included task so I can loop several items and register the credentials in a variable.
Files:
main.yml:
---
- hosts: localhost
gather_facts: False
tasks:
- include: tasks/myvault/get-vault.yml
with_items:
- demo
register: output
- debug:
msg: "{{output}}"
get-vault.yml:
- name: Retrieve secret from Vault
community.hashi_vault.vault_kv2_get:
url: https://myvaul
path: "{{ item }}"
auth_method: token
token: '{{ mytoken }}'
namespace: MyNamespace
validate_certs: no
output:
ok: [localhost] => {
"msg": {
"changed": false,
"msg": "All items completed",
"results": [
{
"ansible_loop_var": "item",
"include": "tasks/myvault/get-vault.yml",
"include_args": {},
"item": "demo"
}
],
"skipped": false
}
}
The output doesn't display the "real" result of the task.
If I remove:
register: output and put it in get-vault.yml, here is the result:
ok: [localhost] => {
"msg": {
"changed": false,
"data": {
"data": {
"password": "Password",
"username": "Username"
}, ...
How can I get this result returned when I register the output from my included task?

How to check the size of a file list

With Ansible, I need to check if files in directory are bigger than 50M.
I do a set_fact with result of ls and then I loop to stat all files. This works, but I am not able to parse the result to create a fail condition when files are bigger than 50M.
I do this :
- shell: ls -1 "{{ logs_directory }}"*.log
register: list_logs
- set_fact:
list_logs: "{{ list_logs.stdout_lines }}"
- debug:
msg: "{{ list_logs}}"
- name: Get size
stat:
path: "{{ item }}"
with_items: "{{ list_logs }}"
register: size_log
- name: debug
fail:
msg: "Problem with log size > 50M"
when: 'size_log.stat.size / 1024 / 1024 | int > 50'
It works if I have only 1 file, but with multiple servers and multiple files, it doesn't work... How to parse the size_log_result?
Here an example of output size_log :
ok: [192.168.1.2] => {
"msg": {
"changed": false,
"msg": "All items completed",
"results": [
{
"ansible_loop_var": "item",
"changed": false,
"failed": false,
"invocation": {
"module_args": {
"path": "/var/logs/admin.log"
}
},
"item": "/var/logs/admin.log",
"stat": {
"size": 21711,
}
},
{
"ansible_loop_var": "item",
"changed": false,
"failed": false,
"invocation": {
"module_args": {
"path": "/var/logs/database.log"
}
},
"item": "/var/logs/database.log",
"stat": {
"size": 11162,
}
}
]
}
}
ok: [192.168.1.5] => {
"msg": {
"changed": false,
"msg": "All items completed",
"results": [
{
"ansible_loop_var": "item",
"changed": false,
"failed": false,
"invocation": {
"module_args": {
"path": "/var/logs/database.log"
}
},
"item": "/var/logs/database.log",
"stat": {
"size": 128453958,
}
}
]
}
}
It looks to me like you are reinventing the wheel here, when the find module seems to answer you use case perfectly already.
Given:
- hosts: localhost
gather_facts: no
tasks:
####
## You do not need this task, it is just to create a file
## big enough for demonstration purpose
####
- community.general.filesize:
path: /var/log/heavy.log
size: 51m
- find:
paths: /var/log
patterns: '*.log'
size: 51m
register: _logs
- fail:
msg: >-
Due to file(s): {{
_logs.files | map(attribute='path') | join(', ')
}}
when: _logs.files | length > 0
This will yield:
TASK [community.general.filesize] *********************************
ok: [localhost]
TASK [find] *******************************************************
ok: [localhost]
TASK [fail] *******************************************************
fatal: [localhost]: FAILED! => changed=false
msg: 'Due to file(s): /var/log/heavy.log'

Ansible getent module's loop output results parsing

I am trying to check if a number of users are present or not in the managed node using getent module and create a list of users who are not present.
The piece of code is:
- getent:
database: passwd
key: "{{ item }}"
fail_key: no
register: x
loop:
- "user1"
- "user2"
- debug: var=x.results
- set_fact:
fail_list: "{{ x.results | }}"
I am stuck at this point.
Is there any way I can save the users who are not present to the variable fail_list as a list?
In the above example, user1 is not present and user2 is present in the managed node.
The ansible version I am using is 2.9 and the debug output is a list of dicts as below:
"x.results": [
{
"ansible_facts": {
"getent_passwd": {
"user1": null
}
},
"ansible_loop_var": "item",
"changed": false,
"failed": false,
"invocation": {
"module_args": {
"database": "passwd",
"fail_key": false,
"key": "user1",
"service": null,
"split": null
}
},
"item": "user1",
"msg": "One or more supplied key could not be found in the database."
},
{
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python",
"getent_passwd": {
"user2": [
"x",
"0",
"0",
"user2",
"/home/user2",
"/bin/bash"
]
}
},
"ansible_loop_var": "item",
"changed": false,
"failed": false,
"invocation": {
"module_args": {
"database": "passwd",
"fail_key": false,
"key": "user2",
"service": null,
"split": null
}
},
"item": "user2"
},
Run getent once and search the list of users. For example
- hosts: localhost
tasks:
- getent:
database: passwd
- debug:
msg: User {{ item }} exists.
loop:
- root
- user1
- user2
when: item in my_users
vars:
my_users: "{{ getent_passwd.keys()|list }}"
gives
ok: [localhost] => (item=root) => {
"msg": "User root exists."
}
skipping: [localhost] => (item=user1)
skipping: [localhost] => (item=user2)

filter out text from a complex json object created by an ansible register of gentent module using a json_qry

Specifically I want a "string" of account IDs that are missing from a list I give the task on a server in my inventory.
I run the getent module in the task and I register the result which seems to be a complext JSON object with the data I want as a ket called "item" buried in an array of objects called "results" which is itself an object of "result".
I'm attempting to parse the "result" object for any key called "failed" that has a value of true and extract that object's key value for "item" which is the account id.
I need a boast to get beyond my lack of understanding.
thanks!
Nothing I've tried works. I'm not sure if it's my syntax or a lack of understanding how to parse or "interpret" the JSON object stored in "result"
I think my syntax for the qry variable is asking for any array element in results (an array of objects) which has a key called "failed" with a value of true and if a match is found, return the value of its "item" key. I know if it worked it would return a list. what I need is a string, but I haven't been able to get any result except an empty list [].
I've tried many variations, but the result is always blank.
qry: "result.results[?failed == true].item"
qry: "results[?failed == true].item"
qry: "[?failed == true].item"
Here is the JSON object returned by ansible "debug: var=result "
TASK [debug] *******************************************************************
ok: [x.y.z.abc.com] => {
"result": {
"changed": false,
"failed": true,
"msg": "All items completed",
"results": [
{
"_ansible_item_result": true,
"_ansible_no_log": false,
"_ansible_parsed": true,
"changed": false,
"failed": true,
"invocation": {
"module_args": {
"database": "passwd",
"fail_key": true,
"key": "abc123",
"split": null
}
},
"item": "abc123",
"msg": "One or more supplied key could not be found in the database."
},
{
"_ansible_item_result": true,
"_ansible_no_log": false,
"_ansible_parsed": true,
"changed": false,
"failed": true,
"invocation": {
"module_args": {
"database": "passwd",
"fail_key": true,
"key": "pubsub",
"split": null
}
},
"item": "pubsub",
"msg": "One or more supplied key could not be found in the database."
}
]
}
}
Here is the playbook section of code:
- name: "Account checks"
ignore_errors: True
with_items:
- abc123
- pubsub
getent: database=passwd key={{ item }}
register: result
- debug: var=result
- debug: msg="Account id is {{ result | json_query(qry) }} "
vars:
qry: "result.results[?failed == true].item"
Here is the output of my json_qry call:
TASK [debug] *******************************************************************
ok: [xyz.abc.com] => {}
MSG:
Account id is
What I want is something like:
"Account id is abc123, pubsub"
result is the top construct you are passing to json_query so it does not exists as top element when it starts processing the data. Moreover, checking for a field without comparison will make sure that field exists and that its value is not false.
Therefore, the correct query to get your info is: results[?failed].item
As you already guessed, this will return a list of item strings for all failed results. You just have to loop over that list to get the individual values.
Below a sample playbook. I changed one failed value to false in your sample data to illustrate.
---
- name: Parse result list with json_query
hosts: localhost
gather_facts: false
vars:
"result": {
"changed": false,
"failed": true,
"msg": "All items completed",
"results": [
{
"_ansible_item_result": true,
"_ansible_no_log": false,
"_ansible_parsed": true,
"changed": false,
"failed": true,
"invocation": {
"module_args": {
"database": "passwd",
"fail_key": true,
"key": "abc123",
"split": null
}
},
"item": "abc123",
"msg": "One or more supplied key could not be found in the database."
},
{
"_ansible_item_result": true,
"_ansible_no_log": false,
"_ansible_parsed": true,
"changed": false,
"failed": false,
"invocation": {
"module_args": {
"database": "passwd",
"fail_key": true,
"key": "pubsub",
"split": null
}
},
"item": "pubsub",
"msg": "One or more supplied key could not be found in the database."
}
]
}
tasks:
- name: Get item value of failed results
vars:
query: results[?failed].item
debug:
msg: "The user id is {{ item }}"
loop: "{{ result | json_query(query) }}"
which gives:
PLAY [Parse result list with json_query] PLAY RECAP **********************************
TASK [Get item value of failed results] PLAY RECAP ***********************************
ok: [localhost] => (item=abc123) => {
"msg": "The user id is abc123"
}
PLAY RECAP ***********************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

Ansible: how to print var name while looping?

I have this inside setup/tasks/apps.yml:
- name: Mac App Store | Install apps.
shell: mas list | grep {{ item.id }} || mas install {{ item.id }}
with_items: "{{ mac_store_apps }}"
register: result
changed_when: result.stdout.find('Installed') != -1
I know I can use:
loop_control:
label: '{{ item.name }}'
But I want to print something like:
Attempting to Install {{ item.name }}
before each execution. How can that be done?
There is no way to generate output before each iteration of your loop; Ansible only produces output when a task (or an iteration of a looping task) is complete. If you are concerned that package installation can take a while and you want to provide some feedback, you could just print out a notice in advance, as in:
- debug:
msg: "Note: package installation may take several minutes to complete"
You can sort of get what you want by placing your install task in a separate file, and then calling include_tasks in a loop. For example, if we have the following playbook:
---
- hosts: localhost
gather_facts: false
vars:
mac_store_apps:
- name: foo
- name: bar
- name: baz
- name: qux
tasks:
- name: "Mac App Store | Install apps."
include_tasks: ./install.yml
with_items: "{{ mac_store_apps }}"
- debug:
var: all_results
And the following tasks in install.yml:
---
- name: "Mac App Store | Install {{ item.name }}"
shell: "true"
register: result
- name: Store result
set_fact:
all_results: "{{ all_results|default([]) + [{'item': item, 'result': result}] }}"
We will see as output:
PLAY [localhost] ******************************************************************************
TASK [Mac App Store | Install apps.] **********************************************************
included: /home/lars/tmp/ansible/install.yml for localhost => (item={u'name': u'foo'})
included: /home/lars/tmp/ansible/install.yml for localhost => (item={u'name': u'bar'})
included: /home/lars/tmp/ansible/install.yml for localhost => (item={u'name': u'baz'})
included: /home/lars/tmp/ansible/install.yml for localhost => (item={u'name': u'qux'})
TASK [Mac App Store | Install foo] ************************************************************
changed: [localhost]
TASK [Store result] ***************************************************************************
ok: [localhost]
TASK [Mac App Store | Install bar] ************************************************************
changed: [localhost]
TASK [Store result] ***************************************************************************
ok: [localhost]
TASK [Mac App Store | Install baz] ************************************************************
changed: [localhost]
TASK [Store result] ***************************************************************************
ok: [localhost]
TASK [Mac App Store | Install qux] ************************************************************
changed: [localhost]
TASK [Store result] ***************************************************************************
ok: [localhost]
TASK [debug] **********************************************************************************
ok: [localhost] => {
"all_results": [
{
"item": {
"name": "foo"
},
"result": {
"changed": true,
"cmd": "true",
"delta": "0:00:00.002398",
"end": "2019-04-23 11:19:25.146497",
"failed": false,
"rc": 0,
"start": "2019-04-23 11:19:25.144099",
"stderr": "",
"stderr_lines": [],
"stdout": "",
"stdout_lines": []
}
},
{
"item": {
"name": "bar"
},
"result": {
"changed": true,
"cmd": "true",
"delta": "0:00:00.002245",
"end": "2019-04-23 11:19:25.285859",
"failed": false,
"rc": 0,
"start": "2019-04-23 11:19:25.283614",
"stderr": "",
"stderr_lines": [],
"stdout": "",
"stdout_lines": []
}
},
{
"item": {
"name": "baz"
},
"result": {
"changed": true,
"cmd": "true",
"delta": "0:00:00.002406",
"end": "2019-04-23 11:19:25.426909",
"failed": false,
"rc": 0,
"start": "2019-04-23 11:19:25.424503",
"stderr": "",
"stderr_lines": [],
"stdout": "",
"stdout_lines": []
}
},
{
"item": {
"name": "qux"
},
"result": {
"changed": true,
"cmd": "true",
"delta": "0:00:00.002232",
"end": "2019-04-23 11:19:25.574214",
"failed": false,
"rc": 0,
"start": "2019-04-23 11:19:25.571982",
"stderr": "",
"stderr_lines": [],
"stdout": "",
"stdout_lines": []
}
}
]
}
PLAY RECAP ************************************************************************************
localhost : ok=13 changed=4 unreachable=0 failed=0

Resources