Кто-нибудь знает, как объединить весь вывод в 1 оповещение по электронной почте? Я создал playbook, чтобы проверить файловую систему, доступную только для чтения, и предупредить, когда она ее обнаружит. но проблема в том, что если 2 сервера имеют проблему, я получаю 2 предупреждения по электронной почте. мне нужно одно оповещение для всех проблемных хостов. Любая помощь будет оценена по достоинству. :) Я много чего пробовал, но получаю одно предупреждение для отдельных хостов, и мой почтовый ящик переполняется.
---
- hosts: free
remote_user: snail
gather_facts: false
tasks:
- name: run echo Command
shell: if grep "[[:space:]]ro[[:space:],]" /proc/mounts | grep -v tmpfs > /dev/null ; then echo 'read-only-FS';else echo 'all_good'; fi
register: outcome
- name: get the IP address
shell: hostname
register: host_name
- name: Send Mail Alert
local_action: mail
host="mailxxxx"
subject="[Read-Only FS] Testing Mail"
body="Read-Only FileSystem on {{ host_name.stdout }}"
to="snail@google.com"
from="root"
when: outcome.stdout == "read-only-FS"
Самое простое, о чем я могу думать, это следующее:
delegate_to=localhost
и run_once=True
. Если есть файл, его следует удалить. (файловый модуль с state=absent
)serial=1
может быть вариант, delegate_to = localhost.Если есть необходимость, могу сделать простой POC.
РЕДАКТИРОВАТЬ:
---
- hosts: tmp1, tmp2
# user, become etc should normaly be set in ansible.cfg
user: ansible
become: true
vars:
mail_body_file: "/tmp/ansible-mailing-tmp123"
tasks:
- name: Check if there is {{mail_body_file}}
file:
state: absent
path: "{{mail_body_file}}"
delegate_to: localhost
run_once: true
become: false
- name: Task looking for change, command always reports change so I used it for testing
command: "echo 123"
register: my_test
- name: Create {{mail_body_file}}
file:
state: touch
path: "{{mail_body_file}}"
delegate_to: localhost
run_once: true
become: false
# Use shell because lineinfile has race condition
# with echo >> we put race condition problem on filesystem
- name: add line about change on host
shell: "echo {{inventory_hostname}} has change >> {{mail_body_file}}"
delegate_to: localhost
when: my_test.changed
become: false
- name: get the mail body to variable
register: mail_body
command: "cat {{mail_body_file}}"
delegate_to: localhost
run_once: True
- name: mail about change
mail:
body: "{{mail_body.stdout}}"
to: "there@was.my.mail"
from: "root"
subject: "Test"
delegate_to: localhost
run_once: True
Обратите внимание, что ты должен проверить это.
Подобный сценарий может сработать.
У нас есть две отдельные игры в playbook, в первой игре мы подключаемся к удаленным хостам и собираем результаты. Во второй игре мы запускаемся на локальном хосте и отправляем почту. Используется встроенный шаблон jinja, который будет перебирать все хосты, соответствующие шаблону хостов, определенному в hosts_pattern
.
---
- name: gather data
hosts: linux_systems
gather_facts: false
tasks:
- name: Command to check systems for ead only mounts
shell: >
if grep "[[:space:]]ro[[:space:],]" /proc/mounts |
grep -v tmpfs > /dev/null ; then
echo 'read-only-FS';else echo 'all_good'; fi
register: read_only_check
- name: Get the output of `hostname`
command: hostname
register: host_name
- name: email report
hosts: localhost
gather_facts: false
vars:
hosts_pattern: linux_systems
tasks:
- name: Email report of systems with read only filesystems
mail:
host: some-smtp.server.example.com
port: 25
to: John Smith <john.smith@example.com>
subject: "[Read-Only FS] Testing Mail"
body: |
Report from playbook check_readonly_filesystems.
{% for host_item in lookup('inventory_hostnames', hosts_pattern, wantlist=True) %}
{% if read_only_check is defined and
read_only_check.stdout is defined and
read_only_check.stdout == "read-only-FS" %}
Read only - {{ hostvars[host_item]['inventory_hostname'] }} aka {{ hostvars[host_item]['host_name'].stdout }}
{% else %}
Good host - {{ hostvars[host_item]['inventory_hostname'] }} aka {{ hostvars[host_item]['host_name'].stdout }}
{% endif %}
{% endfor %}