提问人:sab 提问时间:10/23/2023 最后编辑:U880Dsab 更新时间:10/24/2023 访问量:133
如何通过Ansible检查远程服务器的“正常运行时间”,并通过邮件以CSV和HTML格式发送报告?
How to check `uptime` of Remote Server thru Ansible and send report as CSV and HTML via mail?
问:
我创建了一个 Ansbile 脚本来检查远程服务器(库存组中的近 60+ 台服务器),并将其发送到带有 CSV 和 HTML 文件的电子邮件。它正在工作,但它为每个服务器发送单独的邮件。uptime
linux
我需要它来收集输出并以 csv 和 HTML 格式发送一封包含所有服务器正常运行时间和主机名的邮件。
这是我的剧本。
main.yaml
---
- name: Generate Uptime HTML Report and Send Email
hosts: linux
gather_facts: true
vars:
email_subject: Uptime Report
email_host: xyz
email_from: xyz
email_to: xyz
email_body_template: templates/report.html.j2
csv_path: /tmp
csv_filename: report.csv
headers: Hostname,Uptime_In_Days
tasks:
- name: Get Uptime
command: uptime
register: uptime_result
- name: Extract Uptime in Days
set_fact:
uptime_days: "{{ uptime_result.stdout | regex_replace('^.*up ([0-9]+) day.*', '\\1') | int }}"
when: uptime_result.rc == 0
- name: Create CSV Data
set_fact:
csv_data:
- Hostname: "{{ inventory_hostname }}"
Uptime_In_Days: "{{ uptime_days }}"
when: uptime_result.rc == 0
- name: Transfer CSV Data File
copy:
content: "{{ csv_data | to_nice_json }}"
dest: "{{ csv_path }}/{{ csv_filename }}"
mode: '0644'
- name: Send Email
mail:
host: "{{ email_host }}"
from: "{{ email_from }}"
to: "{{ email_to }}"
subject: "[Ansible] {{ email_subject }}"
body: "{{ lookup('template', email_body_template) }}"
attach: "{{ csv_path }}/{{ csv_filename }}"
subtype: html
html.j2
<sub><table style="border: 1px solid black; border-collapse: collapse;">
<tr>
{% for header in headers.split(",") %}
<th style="border: 1px solid black; padding: 8px 16px;">{{ header }}</th>
{% endfor %}
</tr>
{% for host in csv_data %}
<tr>
{% for header in headers.split(",") %}
<td style="border: 1px solid black; padding: 8px 16px;">{{ host[header] }}</td>
{% endfor %}
</tr>
{% endfor %}
</table></sub>
答:
0赞
U880D
10/23/2023
#1
如何在 Linux 远程节点上收集
正常运行时间
?
由于您已经为了获得可用的 Ansible 事实,因此它还包含 .请参阅最小可重现示例gather_facts
ansible_uptime_seconds
---
- hosts: localhost
become: false
gather_facts: true
tasks:
- debug:
msg: "Days up: {{ (ansible_facts.uptime_seconds / 86400) | int }}"
没有必要 和 .command
set_fact
它正在工作,但它......对于每个服务器。
因此,可以直接在控制节点上为当前播放中的所有主机编写 CSV 报告。
---
- hosts: linux
become: false
gather_facts: true
vars:
csv_path: '.'
csv_filename: 'report.csv'
tasks:
- name: Write uptime into CSV
delegate_to: localhost # aka Control Node
lineinfile:
dest: "{{ csv_path }}/{{ csv_filename }}"
line: "{{ inventory_hostname }},{{ (ansible_facts.uptime_seconds / 86400) | int }}"
create: true
state: present
loop: "{{ ansible_play_hosts }}"
For How to proceed further? you may have a look into
Similar Q&A
1赞
Vladimir Botka
10/24/2023
#2
Take the attribute uptime_seconds from ansible_facts and set the variable uptime in days
- set_fact:
uptime: "{{ (ansible_facts.uptime_seconds/86400)|round(2) }}"
Declare the dictionary
host_uptime: "{{ dict(ansible_play_hosts|
zip(ansible_play_hosts|
map('extract', hostvars, 'uptime'))) }}"
gives, for example
host_uptime:
test_11: '0.52'
test_13: '0.52'
Create the templates. Fit the formats to your needs
shell> cat templates/report.html.j2
<!DOCTYPE html>
<html lang="en">
<head>
<title>Report hosts uptime</title>
</head>
<body>
<table>
<tr>
{% for header in headers.split(',') %}
<th>{{ header }}</th>
{% endfor %}
</tr>
{% for host in ansible_play_hosts %}
<tr>
<td>{{ host }}</td><td>{{ host_uptime[host] }}</td>
</tr>
{% endfor %}
</table>
</body>
</html>
shell> cat templates/report.csv.j2
{{ headers }}
{% for host,uptime in host_uptime.items() %}
{{ host }},{{ uptime }}
{% endfor %}
测试 HTML 模板
- debug:
msg: "{{ lookup('template', 'report.html.j2') }}"
给
msg: |-
<!DOCTYPE html>
<html lang="en">
<head>
<title>Report hosts uptime</title>
</head>
<body>
<table>
<tr>
<th>Host</th>
<th>Uptime_In_Days</th>
</tr>
<tr>
<td>test_11</td><td>0.52</td>
</tr>
<tr>
<td>test_13</td><td>0.52</td>
</tr>
</table>
</body>
</html>
测试 CSV 模板
- debug:
msg: "{{ lookup('template', 'report.csv.j2') }}"
给
msg: |-
Host,Uptime_In_Days
test_11,0.52
test_13,0.52
在 localhost 上写入文件
- template:
src: report.csv.j2
dest: /tmp/report.csv
mode: 0644
delegate_to: localhost
run_once: true
给
shell> cat /tmp/report.csv
Host,Uptime_In_Days
test_11,0.52
test_13,0.52
发送邮件
- mail:
host: localhost
from: "{{ ansible_user }}"
to: root
subject: '[Ansible] Report uptime'
body: "{{ lookup('template', 'report.html.j2') }}"
subtype: html
attach: /tmp/report.csv
delegate_to: localhost
run_once: true
给出(电子邮件客户端将 HTML 呈现为文本)
Return-Path: <[email protected]>
X-Original-To: root
Delivered-To: [email protected]
Received: from [127.0.0.1] (localhost [127.0.0.1])
by example.org (Postfix) with ESMTPS id 2FCC41802F6
for <root>; Tue, 24 Oct 2023 05:24:20 +0200 (CEST)
Content-Type: multipart/mixed; -charset="utf-8"; boundary="===============6826681646037083043=="
MIME-Version: 1.0
From: [email protected]
Date: Tue, 24 Oct 2023 05:24:20 +0200
Subject: [Ansible] Report uptime
X-Mailer: Ansible mail module
To: [email protected]
Cc:
Message-Id: <[email protected]>
Report hosts uptime
Host Uptime_In_Days
test_110.52
test_130.52
[report.csv application/octet-stream (65 bytes)]
用于测试的完整 playbook 示例
- name: Mail uptime table
hosts: all
gather_facts: true
vars:
headers: Host,Uptime_In_Days
host_uptime: "{{ dict(ansible_play_hosts|
zip(ansible_play_hosts|
map('extract', hostvars, 'uptime'))) }}"
tasks:
- set_fact:
uptime: "{{ (ansible_facts.uptime_seconds/86400)|round(2) }}"
- block:
- debug:
var: host_uptime
- debug:
msg: "{{ lookup('template', 'report.html.j2') }}"
- debug:
msg: "{{ lookup('template', 'report.csv.j2') }}"
when: debug|d(false)|bool
run_once: true
- block:
- template:
src: report.csv.j2
dest: /tmp/report.csv
mode: 0644
- mail:
host: localhost
from: "{{ ansible_user }}"
to: root
subject: '[Ansible] Report uptime'
body: "{{ lookup('template', 'report.html.j2') }}"
subtype: html
attach: /tmp/report.csv
when: mail_enable|d(false)|bool
delegate_to: localhost
run_once: true
评论