Comparing the Mounts in ansible - ansible

I have a requirement in ansible to compare the mount counts before and after the maintenance, for this i am using the below tasks. We need to compare the premounts and postmounts and if there is difference in the value, it should throw a message to check the host. Please advise.
- name: Take premount counts
shell: df -h |awk ' NR>1{print $1}'|grep -v "tmpfs"|wc -l
register: premounts
- name: Take postmount counts
shell: df -h |awk ' NR>1{print $1}'|grep -v "tmpfs"|wc -l
register: postmounts

I think you are looking for the assert module. You can use this to print a message or fail as per condition.
Example:
- name: Take premount counts
shell: df -h |awk ' NR>1{print $1}'|grep -v "tmpfs"|wc -l
register: premounts
- name: Take postmount counts
shell: df -h |awk ' NR>1{print $1}'|grep -v "tmpfs"|wc -l
register: postmounts
- assert:
that:
- premounts == postmounts
fail_msg: "Premounts: {{ premounts }} and postmounts: {{ postmounts }} do not match!"
success_msg: "Mounts match."
Instead of running the df command and getting number of mounts, you can use the Ansible fact ansible_mounts to get this count also.
Example:
- set_fact:
premounts: "{{ ansible_mounts|count }}"
# some tasks in between
# Gather facts again
- setup:
- set_fact:
postmounts: "{{ ansible_mounts|count }}"
- assert:
that:
- premounts == postmounts
fail_msg: "Premounts: {{ premounts }} and postmounts: {{ postmounts }} do not match!"
success_msg: "Mounts match."

Try as below:
- name: Take premount counts
shell: df -h |awk ' NR>1{print $1}'|grep -v "tmpfs"|wc -l
register: premounts
- name: Take postmount counts
shell: df -h |awk ' NR>1{print $1}'|grep -v "tmpfs"|wc -l
register: postmounts
- debug:
msg: 'There are difference in the mount count, check it'
when: premounts.stdout_lines[0] | int != postmounts.stdout_lines[0] | int

Related

Want to use awk command within ansible playbook items

This is my playbook which is not working if I put the 4th item with awk command with double quote like below:
tasks:
- shell: "{{item}}"
with_items:
- hostname
- df -kh
- uptime
- grep -i diameter /tmp/PSC-CIPDiameter_8.1_*_1.stat.0 | awk -F"," '{ if ($4!=0 || $5!=0|| $6!=0) print "Diameter Time : "$1 " Success: "$3 " Fail: " $4" Timeout: " $5" Reject: " $6}'
register: test
- debug:
msg: "{{test.results|map(attribute='stdout_lines')|list}}"
Put the awk code into the file created from the template. This way, you can test the code separately and improve the readability of the code. For example, the template
shell> cat templates/script01.j2.awk
{
if ($4!=0 || $5!=0|| $6!=0)
print "Diameter Time:" $1 " Success:" $3 " Fail:" $4 " Timeout:" $5 " Reject:"$6;
}
and the playbook
- hosts: localhost
tasks:
- template:
src: script01.j2.awk
dest: script01.awk
- shell: "{{ item }}"
loop:
- uptime
- "echo 1,2,3,4,5,6 | awk -F',' -f script01.awk"
register: test
- debug:
msg: "{{ test.results|map(attribute='stdout')|list }}"
give
"msg": [
" 17:05:13 up 3 days, 13:42, 1 user, load average: 1.93, 1.45, 1.74",
"Diameter Time:1 Success:3 Fail:4 Timeout:5 Reject:6"
]

How to use register in this context? (Ansible)

Thanks for your time reading this (probably dumb question)...
I have the following playbook:
- hosts: all
gather_facts: true
vars:
ansible_python_interpreter: /usr/bin/python
tasks:
- name: Get shard status.
shell:
cmd: |
mongo node1:27020 --eval "sh.status()" | grep shards -A 4 | awk -F ':|,|/' '{ print $2 " ", " ", $5,$7,$9}' | sed -e '1 i Shard Nodes' | column -t
when: ansible_fqdn == 'node1'
register: shards_status
- name: Get replica status from SHARD1.
shell:
cmd: |
mongo --eval 'printjson(rs.status())' | grep -E "stateStr|name" | awk -F ':' '{ print $2 }' | sed 's/"//g'| sed 's/,//g'| xargs -n2 | sed -e '1 i Server Status' | column -t
when: ansible_fqdn == 'node1'
register: shard1
- name: Get replica status from SHARD2.
shell:
cmd: |
mongo --eval 'printjson(rs.status())' | grep -E "stateStr|name" | awk -F ':' '{ print $2 }' | sed 's/"//g'| sed 's/,//g'| xargs -n2 | sed -e '1 i Server Status' | column -t
when: ansible_fqdn == 'node2'
register: shard2
- name: Get replica status from SHARD3.
shell:
cmd: |
mongo --eval 'printjson(rs.status())' | grep -E "stateStr|name" | awk -F ':' '{ print $2 }' | sed 's/"//g'| sed 's/,//g'| xargs -n2 | sed -e '1 i Server Status' | column -t
when: ansible_fqdn == 'node3'
register: shard3
- name: Get replica status from SHARD4.
shell:
cmd: |
mongo --eval 'printjson(rs.status())' | grep -E "stateStr|name" | awk -F ':' '{ print $2 }' | sed 's/"//g'| sed 's/,//g'| xargs -n2 | sed -e '1 i Server Status' | column -t
when: ansible_fqdn == 'node4'
register: shard4
- name: Append logs.
lineinfile:
dest: /tmp/status.txt
line: "{{ item }}"
insertafter: EOF
with_items:
- "{{ shards_status.stdout }}"
- "{{ shard1.stdout }}"
- "{{ shard2.stdout }}"
- "{{ shard3.stdout }}"
- "{{ shard4.stdout }}"
delegate_to: localhost
I want to have in one file (/tmp/status.txt) the result of the above vars (shard1,2,3,4). The issue is, if I run the playbook, I got the following message:
TASK [Append logs.] ****************************************************************************************************************************************************************************************
fatal: [node1]: FAILED! => {"failed": true, "msg": "'dict object' has no attribute 'stdout'"}
fatal: [node2]: FAILED! => {"failed": true, "msg": "'dict object' has no attribute 'stdout'"}
fatal: [node3]: FAILED! => {"failed": true, "msg": "'dict object' has no attribute 'stdout'"}
fatal: [node4]: FAILED! => {"failed": true, "msg": "'dict object' has no attribute 'stdout'"}
Any idea of how I can achieve this?
I have tried accessing into the dic, running only that task from one node and multiple workarounds.. but no luck
I believe this failure is because each time you are guarding your tasks with when: ansible_fqdn == 'node1'.
So when ansible is executing this playbook in node1, its executing all node1 tasks and then when it reaches the Append logs. task it tries to dump the stdout from node2. But since we are running in node1, node2 dictionary is empty, hence 'dict object' has no attribute 'stdout'.
One solution would be to give it a default value, for example
with_items:
- "{{ shards_status.stdout | default("") }}"
- "{{ shard1.stdout | default("") }}"
- "{{ shard2.stdout | default("") }}"
- "{{ shard3.stdout | default("") }}"
- "{{ shard4.stdout | default("") }}"
default value for dictionary in jinja2 (ansible)
But the proper ansible solution would be to change your playbook and way of thinking.
With an inventory like this
[mongo]
shard1 get_shard_status=true
shard2
shard3
shard4
your playbook could look something like this
- hosts: mongo
vars:
get_shard_status: false
tasks:
- name: get shard status
shell: mongo node1:27020 --eval "sh.status()" | grep shards -A 4 | awk -F ':|,|/' '{ print $2 " ", " ", $5,$7,$9}' | sed -e '1 i Shard Nodes' | column -t
register: shard_status
when: get_shard_status
- name: get the replica status
shell: mongo --eval 'printjson(rs.status())' | grep -E "stateStr|name" | awk -F ':' '{ print $2 }' | sed 's/"//g'| sed 's/,//g'| xargs -n2 | sed -e '1 i Server Status' | column -t
register: replicas
- name: dump status to localhost
lineinfile:
line: "{{ shard_status + '\n' | default('') }}{{ replicas.stdout }}"
state: present
become: false
dest: "/tmp/foobar"
delegate_to: localhost
With this way, if you had another mongo node, you would only modify your inventory and not your playbook and you also dont have to guard the replicas.stdout with a | default("") as you are always executing that in your nodes.

Ansible not interpreting variable

Good morning, everyone,
I am currently creating a Playbook that allows me to make an inventory of the different services on the Linux park of my company.
The problem is the following, none of my variables are interpreted. Here is the playbook in question :
- hosts: all
become: true
become_method: sudo
tasks:
- name: Get running process
shell: netstat -lntp
register: process
- name: Check Apache Packages
shell: yum list installed httpd | grep httpd | awk '{print $2}' | cut -d '-' -f1
register: Apache
when: process.stdout.find('httpd') != -1
- name: Check Tomcat Packages
shell: yum list installed tomcat | grep tomcat | awk '{print $2}' | cut -d '-' -f1
register: Tomcat
when: process.stdout.find('tomcat') != -1
- name: Check Mariadb / MySQL Packages
shell: yum list installed mariadb | grep mariadb | awk '{print $2}' | cut -d '-' -f1
register: Mariadb
when: process.stdout.find('mariadb') != -1 or process.stdout.find('mysql') != -1
- name: Write Output to CSV
blockinfile:
create: yes
path: /etc/ansible/projets/Inventoring/Output.csv
marker: ""
block: "{{ inventory_hostname }};Apache={{ Apache.stdout }};Tomcat={{ Tomcat.stdout }};Mariadb={{ Mariadb.stdout }}"
delegate_to: localhost
And an example of the CSV output that doesn't work:
{{ inventory_hostname }};OS={{ OSVersion.stdout }};Apache={{ Apache.stdout }};Tomcat={{ Tomcat.stdout }};Mariadb={{ Mariadb.stdout }}
Thank you in advance for your help.

Ansible multiple variable contains multiple values

i have some ansible task below :
- name: counting object from json
shell: >
jq '.results[].stdout_lines | length' backup/{{ inventory_hostname }}_rsl.json | wc -l
register: jsondata
- name: counting object converting
shell: >
seq 0 {{ jsondata.stdout|int - 1 }} | tr '\n' ' ' | xargs | sed 's/[[:space:]]/,/g'
register: seq
- name: get interface
shell: >
cat backup/{{ inventory_hostname }}_{{ item }}_rsl_result_nows.json | cut -d, -f1
register: interface
with_items:
- "{{ seq.stdout.split(',') | list }}"
- name: get rsl value
shell: >
cat backup/{{ inventory_hostname }}_{{ item }}_rsl_result_nows.json | cut -d, -f2-
register: rslvalue
with_items:
- "{{ seq.stdout.split(',') | list }}"
- name: post to DB via curl
shell: >
curl -d "ip_address={{ inventory_hostname }}&hostname={{ varhostname.stdout }}&interface={{ interface }}&rslvalue={{ rslvalue }}" -X POST http://dev.trm.net:8088/ip_planning/rsl/postrsl -v
i want to post data with the same hostname but different interface and some other attributes.
This my curl command that i want :
curl -d "ip_address=IP_A&hostname=HOST_A&interface=IFACE_1&rslvalue=1,2,3,4,5" -X POST http://dev.trm.net:8088/ip_planning/rsl/postrsl -v
curl -d "ip_address=IP_A&hostname=HOST_A&interface=IFACE_2&rslvalue=5,4,3,2,1" -X POST http://dev.trm.net:8088/ip_planning/rsl/postrsl -v
curl -d "ip_address=IP_B&hostname=HOST_B&interface=IFACE_1&rslvalue=11,21,31,41,51" -X POST http://dev.trm.net:8088/ip_planning/rsl/postrsl -v
i'm tired a full-day, please help me. i've tried from my ansible script above but error
"msg": "The task includes an option with an undefined variable. The error was: 'item' is undefined
You have {{ item.interface.stdout }} in the last task, but with_items is not present.
Also when you use item in the shell command, use as "{{item}}"
a little improvement make me small fun...
- name: post to DB via curl
shell: >
curl -d "ip_address={{ inventory_hostname }}&hostname={{ varhostname.stdout }}&interface={{ item }}&rslvalue={{ item }}" -X POST http://dev.tr$
with_items:
- "{{ rslvalue.results | map(attribute='stdout') | list }}"
- "{{ interface.results | map(attribute='stdout') | list }}"
but "item" variable always print "rslvalue" result. how to declare "item" with multiple with_items ??

complex loop in ansible with_together

How do I skip empty item in list if I use with_together?
see the code below:
- name: get data_files list
shell: ls -l data_files | awk -F " " {'print $9'}
register: csv_file_list
- debug: var=csv_file_list
- name: get table name list
shell: ls -l data_files/ | awk -F " " {'print $9'} | sed -e "s/.csv//g" | sed -e "s/-/./g"
register: table_list
- debug: var=table_list
- name: copy table from csv to demo db
shell: psql -U postgres -d demo -c "\copy {{ item.1 }} from /home/ubuntu/data_files/{{ item.0 }} DELIMITER ',' CSV HEADER"
with_together:
- csv_file_list.stdout_lines
- table_list.stdout_lines
when: {{ item.1 }} != ''
Test if item.1 is not none.
when: item.1 != None

Resources