How to check the size of a file list - ansible

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'

Related

Ansible - How to print out this list of dictionaries

I have this output from Windows auditpol.
I have difficulty to figure out how to print a certain output from the var query.
- name: check audit
win_command: auditpol /get /subcategory:{{ item }}
with_items:
- '"{{policy}}"'
register:
query
- debug: var=query.results
ok: [ipcprdixn201] => {
"query.results": [
{
"ansible_loop_var": "item",
"changed": true,
"cmd": "auditpol /get /subcategory:\"Other System Events\"",
"delta": "0:00:00.171888",
"end": "2022-11-24 06:04:11.903563",
"failed": false,
"item": "\"Other System Events\"",
"rc": 0,
"start": "2022-11-24 06:04:11.731675",
"stderr": "",
"stderr_lines": [],
"stdout": "System audit policy\r\r\nCategory/Subcategory Setting\r\nSystem\r\n Other System Events No Auditing\r\r\n",
"stdout_lines": [
"System audit policy",
"",
"Category/Subcategory Setting",
"System",
" Other System Events No Auditing",
""
]
}
]
}
- debug: msg="{{ query.results | type_debug }}"
ok: [ipcprdixn201] => {
"msg": "dict"
}
- debug: msg="{{ query | type_debug }}"
ok: [ipcprdixn201] => {
"msg": "list"
}
How do I print out one of the list, i.e. stdout_lines?
Thank you.
Reference: https://pythonexamples.org/python-list-of-dictionaries/
- debug: var=query.results[0]['stdout_lines']
ok: [ipcprdixn201] => {
"query.results[0]['stdout_lines']": [
"System audit policy",
"",
"Category/Subcategory Setting",
"System",
" Other System Events No Auditing",
""
]
}

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?

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)

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

Fetch doesn't transfer when i use variable

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.

Resources