我正在使用 ansible 来扫描带有 Clam 防病毒软件的主机,并且我通过电子邮件收到报告。报告包含所有内容,我只想接收标准输出行。有什么办法可以做到这一点吗?我根据以下内容编写了电子邮件模板https://gist.github.com/halberom/0aea275632d2b47af0536e5def01d4d2 虽然唯一不一样的是我已经通过管道传输到漂亮的 json:
The {{ host }} says {{ hostvars[host]['result']['stdout'] | to_nice_json }}
我得到的错误是:
无法使用 to_nice_json 转换数据,回退到 to_json:“dict object”没有属性“stdout”。该任务包含一个带有未定义变量的选项,错误为 ansible no_log:false
如果我删除,['stdout']
则电子邮件报告将如下所示:
ClamAV scan was performed on host_server
{
"changed": true,
"msg": "All items completed",
"results": [
{
"ansible_loop_var": "item",
"changed": true,
"cmd": [
"clamscan",
"-r",
"-i",
"/usr/bin"
],
"delta": "0:00:37.293719",
"end": "2021-09-09 18:47:55.626094",
"failed": false,
"invocation": {
"module_args": {
"_raw_params": "clamscan -r -i /usr/bin",
"_uses_shell": false,
"argv": null,
"chdir": null,
"creates": null,
"executable": null,
"removes": null,
"stdin": null,
"stdin_add_newline": true,
"strip_empty_ends": true,
"warn": true
}
},
"item": "/usr/bin",
"rc": 0,
"start": "2021-09-09 18:47:18.332375",
"stderr": "",
"stderr_lines": [],
"stdout": "\n----------- SCAN SUMMARY -----------\nKnown viruses: 8563204\nEngine version: 0.103.2\nScanned directories: 1\nScanned files: 701\nInfected files: 0\nData scanned: 110.08 MB\nData read: 109.50 MB (ratio 1.01:1)\nTime: 37.113 sec (0 m 37 s)\nStart Date: 2021:09:09 18:47:18\nEnd Date: 2021:09:09 18:47:55",
"stdout_lines": [
"",
"----------- SCAN SUMMARY -----------",
"Known viruses: 8563204",
"Engine version: 0.103.2",
"Scanned directories: 1",
"Scanned files: 701",
"Infected files: 0",
"Data scanned: 110.08 MB",
"Data read: 109.50 MB (ratio 1.01:1)",
"Time: 37.113 sec (0 m 37 s)",
"Start Date: 2021:09:09 18:47:18",
"End Date: 2021:09:09 18:47:55 "
]
}
]
}
有没有办法在我的报告中只获取 stdout_lines ?我尝试在 shell 命令中使用 grep 但失败
答案1
从您的调试来看,result
是来自 shell 任务的注册变量,其中clamav
在路径列表上运行循环。
如中所述ansible 循环文档,注册的 var 被修改为包含一个results
列表,其中每个元素都是使用当前迭代项运行模块的单独结果(例如/usr/bin
在您的示例中)。
在这种情况下,result.stdout
不存在(正如您的错误消息清楚地报告的那样),但作为一个具体示例,result.results.0.stdout
它确实存在于您的示例中。
尽管如果循环中始终只有单个路径,这会起作用,但您可能希望从每个结果中获取所有标准输出的列表。在这种情况下您可以使用:
result.results | map(attribute='stdout')
如果我们将其放回到您的特定模板中,能够为任何给定的提供输出host
,这将给出:
The {{ host }} says {{ hostvars[host].result.results | map(attribute='stdout') | to_nice_json }}
请注意,此处转到 json 可能并不是电子邮件的最佳选择,并且上面的内容会丢失有关扫描的原始路径的信息。另一种选择可能是简单地循环结果并仅打印出您需要的信息:
This is report for host {{ host }}
----------------------------------
{% for scan_result in hostvars[host].result.results %}
Scan performed in directory {{ scan_result.item }}:
{{ scan_result.stdout }}
{% endfor %}