问题描述
我想过滤临时 ansible 命令的 JSON 输出 - 例如获取多台主机的facts"的长列表,并只显示一个可能是几个级别的深度,例如 ansible_lsb.description
,因此我可以快速比较他们正在运行的软件版本,检查准确的时间或时区等.
I'd like to filter the JSON output of ad-hoc ansible commands - e.g. grab the long list of "facts" for multiple hosts, and show only one that could be several levels deep, such as ansible_lsb.description
, so I can quickly compare what versions of software they're running, check accurate times or timezones, whatever.
这有效:
ansible myserver -m setup -a 'filter=ansible_lsb'
myserver | SUCCESS => {
"ansible_facts": {
"ansible_lsb": {
"codename": "wheezy",
"description": "Debian GNU/Linux 7.11 (wheezy)",
"id": "Debian",
"major_release": "7",
"release": "7.11"
}
},
"changed": false
}
但是,正如 设置模块文档 所述,过滤器选项仅过滤ansible_facts 下的第一级子键",因此失败:
However, as the setup module docs state, "the filter option filters only the first level subkey below ansible_facts", so this fails:
ansible myserver -m setup -a 'filter=ansible_lsb.description'
myserver | SUCCESS => {
"ansible_facts": {},
"changed": false
}
(虽然作为参考,您可以在其他地方使用点表示法,例如任务的 有条件时)
(though for reference, you can use dot notation in other places such as a task's when conditional)
有没有办法在显示输出之前过滤 JSON 键?
Is there a way to filter the JSON keys before the output is displayed?
推荐答案
标准 setup
模块只能对顶级"事实应用过滤器.
Standard setup
module can apply filter only on "top-level" facts.
为了实现您想要的效果,您可以使用 setup
名称制作一个动作插件来应用自定义过滤器.
To achieve what you want, you can make an action plugin with setup
name to apply custom filters.
工作示例./action_plugins/setup.py
:
from ansible.plugins.action import ActionBase
class ActionModule(ActionBase):
def run(self, tmp=None, task_vars=None):
def lookup(obj, path):
return reduce(dict.get, path.split('.'), obj)
result = super(ActionModule, self).run(tmp, task_vars)
myfilter = self._task.args.get('myfilter', None)
module_args = self._task.args.copy()
if myfilter:
module_args.pop('myfilter')
module_return = self._execute_module(module_name='setup', module_args=module_args, task_vars=task_vars, tmp=tmp)
if not module_return.get('failed') and myfilter:
return {"changed":False, myfilter:lookup(module_return['ansible_facts'], myfilter)}
else:
return module_return
它调用原始setup
模块剥离myfilter
参数,然后如果任务没有失败并且设置了myfilter,则使用简单的reduce 实现过滤结果.查找功能非常简单,因此它不适用于列表,只能用于对象.
It calls original setup
module stripping myfilter
parameter, then filters result with simple reduce implementation if task is not failed and myfilter is set. Lookup function is very simple, so it will not work with lists, only with objects.
结果:
$ ansible myserver -m setup -a "myfilter=ansible_lsb.description"
myserver | SUCCESS => {
"ansible_lsb.description": "Ubuntu 12.04.4 LTS",
"changed": false
}
这篇关于Ansible ad-hoc 命令按键或属性过滤 JSON 输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!